diff --git a/build_scripts/Windows/retroshare.nsi b/build_scripts/Windows/retroshare-Qt4.nsi similarity index 100% rename from build_scripts/Windows/retroshare.nsi rename to build_scripts/Windows/retroshare-Qt4.nsi diff --git a/build_scripts/Windows/retroshare-Qt5.nsi b/build_scripts/Windows/retroshare-Qt5.nsi new file mode 100644 index 000000000..d946d286e --- /dev/null +++ b/build_scripts/Windows/retroshare-Qt5.nsi @@ -0,0 +1,486 @@ +; Script generated with the Venis Install Wizard & modified by defnax +; Reworked by Thunder + +# Needed defines +;!define BUILDADD "" +;!define SOURCEDIR "" +;!define RELEASEDIR "" +;!define QTDIR "" +;!define MINGWDIR "" + +# Optional defines +;!define OUTDIR "" + +# Check needed defines +!ifndef BUILDADD +!error "BUILDADD is not defined" +!endif + +!ifndef SOURCEDIR +!error "SOURCEDIR is not defined" +!endif + +!ifndef RELEASEDIR +!error "RELEASEDIR is not defined" +!endif +!ifndef QTDIR +!error "QTDIR is not defined" +!endif +!ifndef MINGWDIR +!error "MINGWDIR is not defined" +!endif + +# Check optional defines +!ifdef OUTDIR +!define OUTDIR_ "${OUTDIR}\" +!else +!define OUTDIR "" +!define OUTDIR_ "" +!endif + +# Get version from executable +!GetDllVersion "${RELEASEDIR}\retroshare-gui\src\release\RetroShare06.exe" VERSION_ + +!define VERSION ${VERSION_1}.${VERSION_2}.${VERSION_3}${BUILDADD} +;!define REVISION ${VERSION_4} + +# Check version +!ifndef REVISION +!error "REVISION is not defined" +!endif + +!ifndef REVISION +!error "REVISION is not defined" +!endif + +# Date +!define /date Date "%Y%m%d" + +# Application name and version +!define APPNAME "RetroShare" +!define APPNAMEANDVERSION "${APPNAME} ${VERSION}" +!define PUBLISHER "RetroShare Team" + +# Install path +!define INSTDIR_NORMAL "$ProgramFiles\${APPNAME}" +!define INSTDIR_PORTABLE "$Desktop\${APPNAME}" + +!define DATADIR_NORMAL "$APPDATA\${APPNAME}" +!define DATADIR_PORTABLE "$INSTDIR\Data" + +# Main Install settings +Name "${APPNAMEANDVERSION}" +InstallDirRegKey HKLM "Software\${APPNAME}" "" +OutFile "${OUTDIR_}RetroShare-${VERSION}-${Date}-${REVISION}-setup.exe" +BrandingText "${APPNAMEANDVERSION}" +RequestExecutionlevel highest +# Use compression +SetCompressor /SOLID LZMA + +# Global variables +Var PortableMode +Var InstDirNormal +Var InstDirPortable +Var DataDir +Var StyleSheetDir + +# Modern interface settings +!include Sections.nsh +!include nsDialogs.nsh +!include "MUI.nsh" + +# Interface Settings +!define MUI_ABORTWARNING +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP "${SOURCEDIR}\build_scripts\Windows\HeaderImage.bmp" +;!define MUI_WELCOMEFINISHPAGE_BITMAP "...bmp" + +# 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 + +# 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" + +# Installer pages +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" +Page Custom PortableModePageCreate PortableModePageLeave +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE dir_leave +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Set languages (first is default language) +!insertmacro MUI_RESERVEFILE_LANGDLL + +# Installer languages +!define MUI_LANGDLL_ALLLANGUAGES + +# Translations +!macro LANG_LOAD LANGUAGE LANGCODE LANGID LICENCEFILE + !insertmacro MUI_LANGUAGE "${LANGUAGE}" +; !verbose off + !define LANG "${LANGUAGE}" + !include "lang\${LANGCODE}.nsh" + LangString LANGUAGEID "${LANG_${LANG}}" "1031" + LicenseLangString myLicenseData ${LANGCODE} ${LICENCEFILE} +; !verbose on + !undef LANG +!macroend + +!macro LANG_STRING NAME VALUE + LangString "${NAME}" "${LANG_${LANG}}" "${VALUE}" +!macroend + +!insertmacro LANG_LOAD "English" "en" "1033" "${SOURCEDIR}\retroshare-gui\src\license\license.txt" +!insertmacro LANG_LOAD "French" "fr" "1036" "${SOURCEDIR}\retroshare-gui\src\license\license-FR.txt" +!insertmacro LANG_LOAD "German" "de" "1031" "${SOURCEDIR}\retroshare-gui\src\license\license-GER.txt" +!insertmacro LANG_LOAD "Turkish" "tr" "1055" "${SOURCEDIR}\retroshare-gui\src\license\license-TR.txt" +!insertmacro LANG_LOAD "SimpChinese" "zh_CN" "2052" "${SOURCEDIR}\retroshare-gui\src\license\license.txt" +!insertmacro LANG_LOAD "Polish" "pl" "1045" "${SOURCEDIR}\retroshare-gui\src\license\license.txt" +!insertmacro LANG_LOAD "Spanish" "es" "1034" "${SOURCEDIR}\retroshare-gui\src\license\license.txt" +!insertmacro LANG_LOAD "Russian" "ru" "1049" "${SOURCEDIR}\retroshare-gui\src\license\license.txt" +!insertmacro LANG_LOAD "Catalan" "ca_ES" "1027" "${SOURCEDIR}\retroshare-gui\src\license\license.txt" + +LicenseData $(myLicenseData) + +# Main binaries +Section $(Section_Main) Section_Main + ;Set Section required + SectionIn RO + + ; Set Section properties + SetOverwrite on + + ; Clears previous error logs +; Delete "$INSTDIR\*.log" + + ; Main binaries + SetOutPath "$INSTDIR" + File /oname=RetroShare.exe "${RELEASEDIR}\retroshare-gui\src\release\RetroShare06.exe" + File /oname=retroshare-nogui.exe "${RELEASEDIR}\retroshare-nogui\src\release\RetroShare06-nogui.exe" + + ; Qt binaries + File "${QTDIR}\bin\Qt5Core.dll" + File "${QTDIR}\bin\Qt5Gui.dll" + File "${QTDIR}\bin\Qt5Multimedia.dll" + File "${QTDIR}\bin\Qt5Network.dll" + File "${QTDIR}\bin\Qt5PrintSupport.dll" + File "${QTDIR}\bin\Qt5Svg.dll" + File "${QTDIR}\bin\Qt5Widgets.dll" + File "${QTDIR}\bin\Qt5Xml.dll" + + ; Qt audio + SetOutPath "$INSTDIR\audio" + File /r "${QTDIR}\plugins\audio\qtaudio_windows.dll" + + ; Qt platforms + SetOutPath "$INSTDIR\platforms" + File /r "${QTDIR}\plugins\platforms\qwindows.dll" + + ; MinGW binaries + SetOutPath "$INSTDIR" + File "${MINGWDIR}\bin\libstdc++-6.dll" + File "${MINGWDIR}\bin\libgcc_s_dw2-1.dll" + File "${MINGWDIR}\bin\libwinpthread-1.dll" + + ; External binaries + File "${SOURCEDIR}\..\libs\bin\miniupnpc.dll" + File "${SOURCEDIR}\..\libs\bin\libeay32.dll" + File "${SOURCEDIR}\..\libs\bin\ssleay32.dll" + + ; Other files + File "${SOURCEDIR}\retroshare-gui\src\changelog.txt" + File "${SOURCEDIR}\libbitdht\src\bitdht\bdboot.txt" + + ; Image formats + SetOutPath "$INSTDIR\imageformats" + File /r "${QTDIR}\plugins\imageformats\qgif.dll" + File /r "${QTDIR}\plugins\imageformats\qicns.dll" + File /r "${QTDIR}\plugins\imageformats\qico.dll" + File /r "${QTDIR}\plugins\imageformats\qjp2.dll" + File /r "${QTDIR}\plugins\imageformats\qjpeg.dll" + File /r "${QTDIR}\plugins\imageformats\qmng.dll" + File /r "${QTDIR}\plugins\imageformats\qsvg.dll" + File /r "${QTDIR}\plugins\imageformats\qtga.dll" + File /r "${QTDIR}\plugins\imageformats\qtiff.dll" + File /r "${QTDIR}\plugins\imageformats\qwbmp.dll" + File /r "${QTDIR}\plugins\imageformats\qwebp.dll" + + ; Sounds + SetOutPath "$INSTDIR\sounds" + File /r "${SOURCEDIR}\retroshare-gui\src\sounds\*.*" + + ; Translations + SetOutPath "$INSTDIR\translations" + File /r "${SOURCEDIR}\retroshare-gui\src\translations\*.qm" + File /r "${QTDIR}\translations\qt_*.qm" + File /r "${QTDIR}\translations\qtbase_*.qm" + File /r "${QTDIR}\translations\qtscript_*.qm" + File /r "${QTDIR}\translations\qtquick1_*.qm" + File /r "${QTDIR}\translations\qtmultimedia_*.qm" + File /r "${QTDIR}\translations\qtxmlpatterns_*.qm" + + ; WebUI + SetOutPath "$INSTDIR\webui" + File /r "${SOURCEDIR}\libresapi\src\webfiles\*.*" + + ; License + SetOutPath "$INSTDIR\license" + File /r "${SOURCEDIR}\retroshare-gui\src\license\*.*" +SectionEnd + +# Plugins +SectionGroup $(Section_Plugins) Section_Plugins +Section $(Section_Plugin_FeedReader) Section_Plugin_FeedReader + SetOutPath "$DataDir\extensions6" + File "${RELEASEDIR}\plugins\FeedReader\release\FeedReader.dll" +SectionEnd + +Section $(Section_Plugin_VOIP) Section_Plugin_VOIP + SetOutPath "$DataDir\extensions6" + File "${RELEASEDIR}\plugins\VOIP\release\VOIP.dll" +SectionEnd +SectionGroupEnd + +# Data (Styles) +Section $(Section_Data) Section_Data + ; Set Section properties + SetOverwrite on + + ; Chat style + SetOutPath "$StyleSheetDir\stylesheets\Bubble" + File /r "${SOURCEDIR}\retroshare-gui\src\gui\qss\chat\Bubble\*.*" + SetOutPath "$StyleSheetDir\stylesheets\Bubble_Compact" + File /r "${SOURCEDIR}\retroshare-gui\src\gui\qss\chat\Bubble_Compact\*.*" + + ; Stylesheets + SetOutPath "$INSTDIR\qss" + File /r "${SOURCEDIR}\retroshare-gui\src\qss\*.*" +SectionEnd + +;Section $(Section_Link) Section_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 + +# Shortcuts +SectionGroup $(Section_Shortcuts) Section_Shortcuts +Section $(Section_StartMenu) Section_StartMenu + SetOutPath "$INSTDIR" + 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 +SectionEnd + +Section $(Section_Desktop) Section_Desktop + CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 +SectionEnd + +Section $(Section_QuickLaunch) Section_QuickLaunch + CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 +SectionEnd +SectionGroupEnd + +Section $(Section_AutoStart) Section_AutoStart + WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroShare" "$INSTDIR\${APPNAME}.exe -m" +SectionEnd + +;Section $(Section_AutoStart) Section_AutoStart +; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe -m" 0 +;SectionEnd + +Section -FinishSection + ${If} $PortableMode = 0 + 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}" "DisplayVersion" "${VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayIcon" "$INSTDIR\RetroShare.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "Publisher" "${PUBLISHER}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "NoModify" "1" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "NoRepair" "1" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" + WriteUninstaller "$INSTDIR\uninstall.exe" + ${Else} + ; Create the file the application uses to detect portable mode + FileOpen $0 "$INSTDIR\portable" w + FileClose $0 + ${EndIf} +SectionEnd + +# Descriptions +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Main} $(Section_Main_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Data} $(Section_Data_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Shortcuts} $(Section_Shortcuts_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_StartMenu} $(Section_StartMenu_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Desktop} $(Section_Desktop_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_QuickLaunch} $(Section_QuickLaunch_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Plugins} $(Section_Plugins_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Plugin_FeedReader} $(Section_Plugin_FeedReader_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Plugin_VOIP} $(Section_Plugin_VOIP_Desc) +; !insertmacro MUI_DESCRIPTION_TEXT ${Section_Link} $(Section_Link_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_AutoStart} $(Section_AutoStart_Desc) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +# Uninstall +Section "Uninstall" + ; 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" "RetroShare" + + ; 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" + + ; Don't remove the directory, otherwise + ; we lose the XPGP keys. + ; Should make this an option though... + RMDir /r "${DATADIR_NORMAL}\extensions6" + RMDir /r "${DATADIR_NORMAL}\stylesheets" +SectionEnd + +Function .onInit + StrCpy $InstDirNormal "${INSTDIR_NORMAL}" + StrCpy $InstDirPortable "${INSTDIR_PORTABLE}" + + StrCpy $PortableMode 0 + StrCpy $INSTDIR "$InstDirNormal" + StrCpy $DataDir "${DATADIR_NORMAL}" + + InitPluginsDir + Push $R1 + File /oname=$PLUGINSDIR\spltmp.bmp "${SOURCEDIR}\retroshare-gui\src\gui\images\logo\logo_splash.png" + advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp + Pop $R1 + Pop $R1 + !insertmacro MUI_LANGDLL_DISPLAY +FunctionEnd + +# Installation mode + +Function RequireAdmin + UserInfo::GetAccountType + Pop $8 + ${If} $8 != "admin" + MessageBox MB_ICONSTOP "You need administrator rights to install ${APPNAME}" + SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED + Abort + ${EndIf} +FunctionEnd + +Function SetModeDestinationFromInstdir + ${If} $PortableMode = 0 + StrCpy $InstDirNormal $INSTDIR + ${Else} + StrCpy $InstDirPortable $INSTDIR + ${EndIf} +FunctionEnd + +Function PortableModePageCreate + Call SetModeDestinationFromInstdir ; If the user clicks BACK on the directory page we will remember their mode specific directory + !insertmacro MUI_HEADER_TEXT $(Page_InstallMode) $(Page_InstallMode_Desc) + nsDialogs::Create 1018 + Pop $0 + ${NSD_CreateRadioButton} 5u 25u -10u 8u $(Page_InstallMode_Standard) + Pop $1 + ${NSD_CreateLabel} 18u 40u -10u 24u $(Page_InstallMode_Standard_Desc) + Pop $0 + ${NSD_CreateRadioButton} 5u 75u -10u 8u $(Page_InstallMode_Portable) + Pop $2 + ${NSD_CreateLabel} 18u 90u -10u 24u $(Page_InstallMode_Portable_Desc) + Pop $0 + ${If} $PortableMode = 0 + SendMessage $1 ${BM_SETCHECK} ${BST_CHECKED} 0 + ${Else} + SendMessage $2 ${BM_SETCHECK} ${BST_CHECKED} 0 + ${EndIf} + nsDialogs::Show +FunctionEnd + +Function PortableModePageLeave + ${NSD_GetState} $1 $0 + ${If} $0 <> ${BST_UNCHECKED} + StrCpy $PortableMode 0 + StrCpy $INSTDIR $InstDirNormal + Call RequireAdmin + ; Enable sections + SectionSetText ${Section_Shortcuts} $(Section_Shortcuts) + SectionSetText ${Section_StartMenu} $(Section_StartMenu) + SectionSetText ${Section_Desktop} $(Section_Desktop) + SectionSetText ${Section_QuickLaunch} $(Section_QuickLaunch) + SectionSetText ${Section_AutoStart} $(Section_AutoStart) + !insertmacro SelectSection ${Section_Shortcuts} + !insertmacro SelectSection ${Section_AutoStart} + !insertmacro SelectSection ${Section_StartMenu} + !insertmacro SelectSection ${Section_Desktop} + !insertmacro SelectSection ${Section_QuickLaunch} + ${Else} + StrCpy $PortableMode 1 + StrCpy $INSTDIR $InstDirPortable + ; Disable sections + !insertmacro UnselectSection ${Section_Shortcuts} + !insertmacro UnselectSection ${Section_AutoStart} + !insertmacro UnselectSection ${Section_StartMenu} + !insertmacro UnselectSection ${Section_Desktop} + !insertmacro UnselectSection ${Section_QuickLaunch} + SectionSetText ${Section_Shortcuts} "" + SectionSetText ${Section_StartMenu} "" + SectionSetText ${Section_Desktop} "" + SectionSetText ${Section_QuickLaunch} "" + SectionSetText ${Section_AutoStart} "" + ${EndIf} +FunctionEnd + +Function dir_leave + ${If} $PortableMode = 0 + StrCpy $DataDir "${DATADIR_NORMAL}" + StrCpy $StyleSheetDir $DataDir + ${Else} + StrCpy $DataDir "${DATADIR_PORTABLE}" + StrCpy $StyleSheetDir $INSTDIR + ${EndIf} +FunctionEnd diff --git a/libretroshare/src/dht/p3bitdht_relay.cc b/libretroshare/src/dht/p3bitdht_relay.cc index 8b04a3e2f..d71f3e7c5 100644 --- a/libretroshare/src/dht/p3bitdht_relay.cc +++ b/libretroshare/src/dht/p3bitdht_relay.cc @@ -299,10 +299,10 @@ bool p3BitDht::loadList(std::list& load) return false; } - std::cerr << "BITDHT Load Item:"; - std::cerr << std::endl; + //std::cerr << "BITDHT Load Item:"; + //std::cerr << std::endl; - config->print(std::cerr, 0); + //config->print(std::cerr, 0); std::list servers; int peers[RSDHT_RELAY_NUM_CLASS] = {0}; @@ -320,16 +320,16 @@ bool p3BitDht::loadList(std::list& load) { /* add to RELAY_SERVER List */ servers.push_back(value); - std::cerr << "p3BitDht::loadList() Found Server: " << value; - std::cerr << std::endl; + //std::cerr << "p3BitDht::loadList() Found Server: " << value; + //std::cerr << std::endl; } else if (0 == strncmp(key.c_str(), "RELAY_MODE", 10)) { mode = atoi(value.c_str()); haveMode = true; - std::cerr << "p3BitDht::loadList() Found Mode: " << mode; - std::cerr << std::endl; + //std::cerr << "p3BitDht::loadList() Found Mode: " << mode; + //std::cerr << std::endl; } else if (0 == strncmp(key.c_str(), "RELAY_CLASS", 11)) { @@ -358,24 +358,24 @@ bool p3BitDht::loadList(std::list& load) if (key[13] == 'C') { - std::cerr << "p3BitDht::loadList() Found Count(" << idx << "): "; - std::cerr << val; - std::cerr << std::endl; + //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; + //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; + //std::cerr << "p3BitDht::loadList() Unknown Key:value: " << key; + //std::cerr << ":" << value; + //std::cerr << std::endl; } } diff --git a/libretroshare/src/grouter/grouteritems.cc b/libretroshare/src/grouter/grouteritems.cc index cab25c43e..a964aabc4 100644 --- a/libretroshare/src/grouter/grouteritems.cc +++ b/libretroshare/src/grouter/grouteritems.cc @@ -142,25 +142,44 @@ RsGRouterGenericDataItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataI ok &= getRawUInt32(data, pktsize, &offset, &item->service_id); ok &= getRawUInt32(data, pktsize, &offset, &item->data_size); - if(item->data_size > rssize || offset > rssize - item->data_size) // better than if(item->data_size + offset > rssize) + if(item->data_size > 0) // This happens when the item data has been deleted from the cache { - std::cerr << __PRETTY_FUNCTION__ << ": Cannot read beyond item size. Serialisation error!" << std::endl; - delete item; - return NULL ; - } + if(item->data_size > rssize || offset > rssize - item->data_size) // better than if(item->data_size + offset > rssize) + { + std::cerr << __PRETTY_FUNCTION__ << ": Cannot read beyond item size. Serialisation error!" << std::endl; + delete item; + return NULL ; + } - if( NULL == (item->data_bytes = (uint8_t*)rs_malloc(item->data_size))) - { - delete item; - return NULL ; - } + if( NULL == (item->data_bytes = (uint8_t*)rs_malloc(item->data_size))) + { + delete item; + return NULL ; + } - memcpy(item->data_bytes,&((uint8_t*)data)[offset],item->data_size) ; - offset += item->data_size ; + memcpy(item->data_bytes,&((uint8_t*)data)[offset],item->data_size) ; + offset += item->data_size ; + } + else + item->data_bytes = NULL ; ok &= item->signature.GetTlv(data, pktsize, &offset) ; - ok &= getRawUInt32(data, pktsize, &offset, &item->randomized_distance); + ok &= getRawUInt32(data, pktsize, &offset, &item->duplication_factor); + + // make sure the duplication factor is not altered by friends. In the worst case, the item will duplicate a bit more. + + if(item->duplication_factor < 1) + { + item->duplication_factor = 1 ; + std::cerr << "(II) correcting GRouter item duplication factor from 0 to 1, to ensure backward compat." << std::endl; + } + if(item->duplication_factor > GROUTER_MAX_DUPLICATION_FACTOR) + { + std::cerr << "(WW) correcting GRouter item duplication factor of " << item->duplication_factor << ". This is very unexpected." << std::endl; + item->duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ; + } + ok &= getRawUInt32(data, pktsize, &offset, &item->flags); if (offset != rssize || !ok) @@ -382,7 +401,7 @@ uint32_t RsGRouterGenericDataItem::serial_size() const s += 4 ; // service id s += data_size ; // data s += signature.TlvSize() ; // signature - s += 4 ; // randomized distance + s += 4 ; // duplication_factor s += 4 ; // flags return s ; @@ -483,7 +502,7 @@ bool RsGRouterGenericDataItem::serialise(void *data,uint32_t& size) const ok &= signature.SetTlv(data, tlvsize, &offset) ; - ok &= setRawUInt32(data, tlvsize, &offset, randomized_distance) ; + ok &= setRawUInt32(data, tlvsize, &offset, duplication_factor) ; ok &= setRawUInt32(data, tlvsize, &offset, flags) ; if (offset != tlvsize) @@ -796,7 +815,7 @@ std::ostream& RsGRouterGenericDataItem::print(std::ostream& o, uint16_t) o << " Data size: " << data_size << std::endl ; o << " Data hash: " << RsDirUtil::sha1sum(data_bytes,data_size) << std::endl ; o << " signature key: " << signature.keyId << std::endl; - o << " randomized dist:" << randomized_distance << std::endl; + o << " duplication fac:" << duplication_factor << std::endl; o << " flags: " << flags << std::endl; return o ; diff --git a/libretroshare/src/grouter/grouteritems.h b/libretroshare/src/grouter/grouteritems.h index ad87d1051..63952fc23 100644 --- a/libretroshare/src/grouter/grouteritems.h +++ b/libretroshare/src/grouter/grouteritems.h @@ -133,7 +133,7 @@ class RsGRouterGenericDataItem: public RsGRouterAbstractMsgItem, public RsGRoute uint32_t data_size ; uint8_t *data_bytes; - uint32_t randomized_distance ; // number of hops (tunnel wise. Does not preclude of the real distance) + uint32_t duplication_factor ; // number of duplicates allowed. Should be capped at each de-serialise operation! // utility methods for signing data virtual uint32_t signed_data_size() const ; diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index a6bb063cf..31bed1375 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -203,7 +203,7 @@ void GRouterMatrix::debugDump() const std::cerr << " " << it->first << ": from " << it->second.friend_id << " " << now - it->second.time_stamp << " secs ago." << std::endl; } -bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector& friends, std::vector& probas) const +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 // @@ -239,6 +239,7 @@ bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, cons return false ; } const std::vector& w(it2->second) ; + maximum = 0.0f ; for(uint32_t i=0;i& friends, std::vector& probas) const ; + 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 diff --git a/libretroshare/src/grouter/groutertypes.h b/libretroshare/src/grouter/groutertypes.h index 3c4897b0a..4341b5d65 100644 --- a/libretroshare/src/grouter/groutertypes.h +++ b/libretroshare/src/grouter/groutertypes.h @@ -44,6 +44,8 @@ static const uint32_t RS_GROUTER_MAX_KEEP_TRACKING_CLUES = 86400*10 ; // m 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. @@ -54,6 +56,8 @@ static const uint32_t MAX_GROUTER_DATA_SIZE = 2*1024*1024 ; // 2M 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 time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 10 ; // Output everything static const time_t RS_GROUTER_AUTOWASH_PERIOD = 10 ; // Autowash every minute. Not a costly operation. diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index e11358970..f8bccaa0f 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -190,6 +190,7 @@ #include "services/p3idservice.h" #include "turtle/p3turtle.h" #include "gxs/rsgixs.h" +#include "retroshare/rspeers.h" #include "p3grouter.h" #include "grouteritems.h" @@ -855,6 +856,34 @@ void p3GRouter::handleTunnels() } } +void p3GRouter::locked_sendToPeers(RsGRouterGenericDataItem *data_item,const std::map& peers_and_duplication_factors) +{ + // slice the data appropriately and send. + + uint32_t saved_duplication_factor = data_item->duplication_factor ; // this little trick avoids copying the item for each peer before slicing it up + + for(std::map::const_iterator itpid(peers_and_duplication_factors.begin());itpid!=peers_and_duplication_factors.end();++itpid) + { + std::list chunks ; + data_item->duplication_factor = itpid->second; + + sliceDataItem(data_item,chunks) ; + + for(std::list::const_iterator it2(chunks.begin());it2!=chunks.end();++it2) + locked_sendTransactionData(itpid->first,*(*it2) ) ; + +#ifdef GROUTER_DEBUG + std::cerr << " sending " << chunks.size() << " slices to peer " << itpid->first << " 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. @@ -885,17 +914,45 @@ void p3GRouter::routePendingObjects() { // Look for tunnels and friends where to send the data. Send to both. - std::list peers ; + std::map peers_and_duplication_factors ; if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS) - locked_collectAvailableTunnels(it->second.tunnel_hash,peers); + locked_collectAvailableTunnels(it->second.tunnel_hash,it->second.data_item->duplication_factor,peers_and_duplication_factors); - // For now, disable friends. We'll first check that the good old tunnel system works as before. + 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,peers, it->second.incoming_routes.ids, it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN); + 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.empty()) + 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; @@ -908,33 +965,8 @@ void p3GRouter::routePendingObjects() #endif it->second.routing_flags |= GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS ; } - continue ; } - // slice the data appropriately and send. - - std::list chunks ; - sliceDataItem(it->second.data_item,chunks) ; - -#ifdef GROUTER_DEBUG - if(!peers.empty()) - std::cerr << " sending to peers:" << std::endl; -#endif - for(std::list::const_iterator itpid(peers.begin());itpid!=peers.end();++itpid) - for(std::list::const_iterator it2(chunks.begin());it2!=chunks.end();++it2) - locked_sendTransactionData(*itpid,*(*it2) ) ; - - // delete temporary items - - for(std::list::const_iterator cit=chunks.begin();cit!=chunks.end();++cit) - delete *cit; - - // 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 if(it->second.data_status == RS_GROUTER_DATA_STATUS_ONGOING && now > MAX_TRANSACTION_ACK_WAITING_TIME + it->second.data_transaction_TS) { @@ -1014,70 +1046,161 @@ void p3GRouter::routePendingObjects() IndicateConfigChanged() ; } -void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,std::list& friend_peers,const std::set& incoming_routes,bool is_origin) +void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,const std::set& incoming_routes,uint32_t duplication_factor, std::map& friend_peers_and_duplication_factors) { - // The strategy is the following: + // 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), - - std::set ids ; - mServiceControl->getPeersConnected(getServiceInfo().mServiceType,ids) ; - - std::vector probas; - std::vector tmp_peers; - - // remove previous peers - - for(std::set::const_iterator it(ids.begin());it!=ids.end();++it) - if(incoming_routes.find(*it) == incoming_routes.end()) - tmp_peers.push_back(*it) ; - - if(tmp_peers.empty()) - return ; - - _routing_matrix.computeRoutingProbabilities(gxs_id, tmp_peers, probas) ; + + // 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 << " getting connected friends, computing routing probabilities" << 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 mac_count=" << max_count << ", proba threshold=" << probability_threshold << std::endl; -#endif + float probability_threshold = RS_GROUTER_PROBABILITY_THRESHOLD_FOR_RANDOM_ROUTING ; std::vector > mypairs ; for(uint32_t i=0;i >::const_reverse_iterator it = mypairs.rbegin();it!=mypairs.rend() && n= probability_threshold ) + for(int i=mypairs.size()-1;i>=0 && nfirst << std::dec ; grouter_debug() << " data hash: " << it->second.item_hash ; - grouter_debug() << " client id: " << std::hex << it->second.client_id << std::dec; + grouter_debug() << " client: " << std::hex << it->second.client_id << std::dec; grouter_debug() << " Flags: " << std::hex << it->second.routing_flags << std::dec; - grouter_debug() << " Destination: " << it->second.data_item->destination_key ; - grouter_debug() << " Received: " << now - it->second.received_time_TS << " secs ago."; - grouter_debug() << " Last sent: " << now - it->second.last_sent_TS << " secs ago."; - grouter_debug() << " Transaction TS: " << now - it->second.data_transaction_TS << " secs ago."; - grouter_debug() << " Data Status: " << statusString[it->second.data_status] << std::endl; - grouter_debug() << " Tunl Status: " << statusString[it->second.tunnel_status] << std::endl; - grouter_debug() << " Receipt ok: " << (it->second.receipt_item != NULL) << std::endl; + 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; @@ -2251,8 +2378,8 @@ void p3GRouter::debugDump() grouter_debug() << " Routing matrix: " << std::endl; - if(_debug_enabled) - _routing_matrix.debugDump() ; + // if(_debug_enabled) + // _routing_matrix.debugDump() ; } diff --git a/libretroshare/src/grouter/p3grouter.h b/libretroshare/src/grouter/p3grouter.h index 45072425f..82b64881e 100644 --- a/libretroshare/src/grouter/p3grouter.h +++ b/libretroshare/src/grouter/p3grouter.h @@ -272,8 +272,9 @@ private: //bool locked_getGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id); bool locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& item); - void locked_collectAvailableFriends(const GRouterKeyId &gxs_id,std::list& friend_peers, const std::set& incoming_routes,bool is_origin); - void locked_collectAvailableTunnels(const TurtleFileHash& hash,std::list& tunnel_peers); + 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 // diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 34fa83c2c..182f1be69 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -591,7 +591,7 @@ void RsGxsNetService::syncWithPeers() grp->PeerId(*sit); grp->updateTS = updateTS; - NxsBandwidthRecorder::recordEvent(mServType,grp) ; + //NxsBandwidthRecorder::recordEvent(mServType,grp) ; #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; @@ -626,7 +626,11 @@ void RsGxsNetService::syncWithPeers() sit = peers.begin(); - float sending_probability = NxsBandwidthRecorder::computeCurrentSendingProbability() ; + // Jan. 26, 2016. This has been disabled, since GXS has been fixed, groups will not re-ask for data. So even if outqueues are filled up by multiple + // attempts of the same request, the transfer will eventually end up. The code for NxsBandwidthRecorder should be kept for a while, + // just in case. + + // float sending_probability = NxsBandwidthRecorder::computeCurrentSendingProbability() ; #ifdef NXS_NET_DEBUG_2 std::cerr << " syncWithPeers(): Sending probability = " << sending_probability << std::endl; #endif @@ -682,22 +686,24 @@ void RsGxsNetService::syncWithPeers() msg->grpId = grpId; msg->updateTS = updateTS; - NxsBandwidthRecorder::recordEvent(mServType,msg) ; + //NxsBandwidthRecorder::recordEvent(mServType,msg) ; - if(RSRandom::random_f32() < sending_probability) - { - sendItem(msg); + //if(RSRandom::random_f32() < sending_probability) + //{ + + sendItem(msg); + #ifdef NXS_NET_DEBUG_5 GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl; #endif - } - else - { - delete msg ; -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl; -#endif - } + //} + //else + //{ + // delete msg ; + //#ifdef NXS_NET_DEBUG_0 + // GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl; + //#endif + //} } } @@ -2308,7 +2314,6 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " and updating mClientGrpUpdateMap for peer " << peerFrom << " of new time stamp " << nice_time_stamp(time(NULL),updateTS) << std::endl; #endif -#warning should not we conservatively use the most recent one, in case the peer has reset its mServerGrpUpdate time?? What happens if the peer unsubscribed a recent group? item->grpUpdateTS = updateTS; item->peerId = peerFrom; @@ -2591,7 +2596,12 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) mDataStore->retrieveGxsGrpMetaData(grpMetaMap); RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId]; -#warning TODO: what if grpMeta is NULL? + 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 diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index e7d85275a..d428a7ae8 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -101,7 +101,6 @@ bool p3GxsTunnelService::registerClientService(uint32_t service_id,RsGxsTunnelSe int p3GxsTunnelService::tick() { - static time_t last_dump = 0 ; #ifdef DEBUG_GXS_TUNNEL time_t now = time(NULL); diff --git a/libretroshare/src/pqi/pqipersongrp.cc b/libretroshare/src/pqi/pqipersongrp.cc index e6a44d5cd..09430369c 100644 --- a/libretroshare/src/pqi/pqipersongrp.cc +++ b/libretroshare/src/pqi/pqipersongrp.cc @@ -434,9 +434,9 @@ int pqipersongrp::removePeer(const RsPeerId& id) std::map::iterator it; #ifdef PGRP_DEBUG -#endif std::cerr << "pqipersongrp::removePeer() id: " << id; std::cerr << std::endl; +#endif RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ diff --git a/libretroshare/src/retroshare/rsgrouter.h b/libretroshare/src/retroshare/rsgrouter.h index acd3aee10..f0bec2677 100644 --- a/libretroshare/src/retroshare/rsgrouter.h +++ b/libretroshare/src/retroshare/rsgrouter.h @@ -50,6 +50,7 @@ public: time_t last_tunnel_attempt_time; time_t last_sent_time; bool receipt_available ; + uint32_t duplication_factor ; uint32_t data_status ; uint32_t tunnel_status ; uint32_t data_size ; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index a1cb0f351..d5d55c53e 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -296,8 +296,17 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) d.hiddenNodeAddress = ps.hiddenDomain; d.hiddenNodePort = ps.hiddenPort; d.hiddenType = ps.hiddenType; - d.localAddr = sockaddr_storage_iptostring(ps.localaddr); - d.localPort = sockaddr_storage_port(ps.localaddr); + + 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 = ""; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index a01e49340..0473d0e3c 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -354,7 +354,6 @@ int p3MsgService::checkOutgoingMessages() * if online, send */ - time_t now = time(NULL); bool changed = false ; std::list output_queue ; diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index 4fc818018..a1fc2960a 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -1872,6 +1872,7 @@ void p3turtle::monitorTunnels(const RsFileHash& hash,RsTurtleClientService *clie // 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 ; diff --git a/plugins/Common/retroshare_plugin.pri b/plugins/Common/retroshare_plugin.pri index 52fc91dea..5030d6ee7 100644 --- a/plugins/Common/retroshare_plugin.pri +++ b/plugins/Common/retroshare_plugin.pri @@ -28,6 +28,14 @@ win32 { QMAKE_CFLAGS += -Wextra QMAKE_CXXFLAGS += -Wextra + 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 + } + # solve linker warnings because of the order of the libraries QMAKE_LFLAGS += -Wl,--start-group diff --git a/retroshare-gui/src/gui/SoundManager.cpp b/retroshare-gui/src/gui/SoundManager.cpp index 5a839a49e..79a2056af 100644 --- a/retroshare-gui/src/gui/SoundManager.cpp +++ b/retroshare-gui/src/gui/SoundManager.cpp @@ -85,6 +85,7 @@ void SoundManager::soundEvents(SoundEvents &events) events.addEvent(tr("Chatmessage"), tr("New Msg"), SOUND_NEW_CHAT_MESSAGE, QFileInfo(baseDir, "incomingchat.wav").absoluteFilePath()); events.addEvent(tr("Message"), tr("Message arrived"), SOUND_MESSAGE_ARRIVED, QFileInfo(baseDir, "receive.wav").absoluteFilePath()); events.addEvent(tr("Download"), tr("Download complete"), SOUND_DOWNLOAD_COMPLETE, QFileInfo(baseDir, "ft_complete.wav").absoluteFilePath()); + events.addEvent(tr("Lobby"), tr("Message arrived"), SOUND_NEW_LOBBY_MESSAGE, QFileInfo(baseDir, "incomingchat.wav").absoluteFilePath()); /* add plugin events */ int pluginCount = rsPlugins->nbPlugins(); @@ -243,9 +244,9 @@ void SoundManager::playFile(const QString &filename) bool played = false ; #if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) - if (!QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).isEmpty()) + if (!QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).isEmpty()) #else - if (QSound::isAvailable()) + if (QSound::isAvailable()) #endif { QSound::play(playFilename); diff --git a/retroshare-gui/src/gui/SoundManager.h b/retroshare-gui/src/gui/SoundManager.h index ae929f161..fc9270e53 100644 --- a/retroshare-gui/src/gui/SoundManager.h +++ b/retroshare-gui/src/gui/SoundManager.h @@ -29,6 +29,7 @@ #define SOUND_USER_ONLINE "User_go_Online" #define SOUND_MESSAGE_ARRIVED "MessageArrived" #define SOUND_DOWNLOAD_COMPLETE "DownloadComplete" +#define SOUND_NEW_LOBBY_MESSAGE "NewLobbyMessage" class SoundEvents { diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp index 943f15f16..b2b2573c0 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp @@ -18,6 +18,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. + * + * ccr . 2016 Jan 26 + * + * Play sound on incoming messages. + * ****************************************************************/ #include @@ -42,6 +47,7 @@ #include "gui/gxs/GxsIdChooser.h" #include "gui/gxs/GxsIdDetails.h" #include "util/HandleRichText.h" +#include "gui/SoundManager.h" #include @@ -400,7 +406,8 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg) name = QString::fromUtf8(msg.peer_alternate_nickname.c_str()) + " (" + QString::fromStdString(gxs_id.toStdString()) + ")" ; ui.chatWidget->addChatMsg(msg.incoming, name, gxs_id, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); - emit messageReceived(msg.incoming, id(), sendTime, name, message) ; + emit messageReceived(msg.incoming, id(), sendTime, name, message) ; + SoundManager::play(SOUND_NEW_LOBBY_MESSAGE); // This is a trick to translate HTML into text. QTextEdit editor; diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index a08ce7857..7c149a4b5 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -127,6 +127,7 @@ ChatWidget::ChatWidget(QWidget *parent) : connect(ui->actionChooseColor, SIGNAL(triggered()), this, SLOT(chooseColor())); 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->hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); @@ -923,7 +924,7 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gx QString strGxsId = ""; if (!gxsId.isNull()) strGxsId = QString::fromStdString(gxsId.toStdString()); - formatMsg.replace(QString(""),QString("").arg(strGxsId)); + formatMsg.replace(QString(""),QString("").arg(strGxsId)); QTextCursor textCursor = QTextCursor(ui->textBrowser->textCursor()); textCursor.movePosition(QTextCursor::End); @@ -979,6 +980,7 @@ void ChatWidget::contextMenuTextBrowser(QPoint point) contextMnu->addSeparator(); contextMnu->addAction(ui->actionClearChatHistory); contextMnu->addAction(ui->actionQuote); + contextMnu->addAction(ui->actionDropPlacemark); QTextCursor cursor = ui->textBrowser->cursorForPosition(point); if(ImageUtil::checkImage(cursor)) @@ -1698,6 +1700,11 @@ void ChatWidget::quote() } } +void ChatWidget::dropPlacemark() +{ + ui->textBrowser->append("----------"); +} + void ChatWidget::saveImage() { QPoint point = ui->actionSave_image->data().toPoint(); diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h index 1b3c518e8..1aa2d9e4a 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.h +++ b/retroshare-gui/src/gui/chat/ChatWidget.h @@ -186,6 +186,7 @@ private slots: bool fileSaveAs(); void quote(); + void dropPlacemark(); void saveImage(); private: diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui index 05e2c9240..c2f4e2504 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.ui +++ b/retroshare-gui/src/gui/chat/ChatWidget.ui @@ -1052,6 +1052,14 @@ border-image: url(:/images/closepressed.png) Quotes the selected text + + + Drop Placemark + + + Insert horizontal rule + + diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp index bbe15e84f..f6eb99e13 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp @@ -254,10 +254,10 @@ void FriendSelectionWidget::loadRequest(const TokenQueue */*queue*/, const Token for(uint32_t i=0;isetItemData(index, (type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE); chooser->setItemIcon(index, icons.empty() ? QIcon() : icons[0]); - std::cerr << "ID=" << details.mId << ", chooser->flags()=" << chooser->flags() << ", flags=" << details.mFlags ; + //std::cerr << "ID=" << details.mId << ", chooser->flags()=" << chooser->flags() << ", flags=" << details.mFlags ; if((chooser->flags() & IDCHOOSER_NON_ANONYMOUS) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) { - std::cerr << " - disabling ID - entry = " << index << std::endl; + //std::cerr << " - disabling ID - entry = " << index << std::endl; chooser->setEntryEnabled(index,false) ; } std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/mainpagestack.cpp b/retroshare-gui/src/gui/mainpagestack.cpp index 778a446ac..6e9124d62 100644 --- a/retroshare-gui/src/gui/mainpagestack.cpp +++ b/retroshare-gui/src/gui/mainpagestack.cpp @@ -20,6 +20,26 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ +/* ccr . 2015 Aug 01 . Resize Main page and Main window. + * + * On very small legacy CRTs of about 15" (38 cm) RetroShare pages are + * initially too deep (too tall) to fit the screen at 1024x768 + * resolution. Some can be shrunk down manually from their initial + * size. Others cannot. This patch tries to allow each page to be + * shrunk somewhat. Then code that runs elsewhere to fit the logical + * Main window into the physical screen will have a better chance of + * success. Notably, on Linux -- Gnome3 -- X11 systems, only when the + * Main window first fits entirely into the physical screen, can it + * then be maximized. + * + * This code is borrowed from a Stack Overflow post: + * + * o Darkgaze. "Resize QStackedWidget to the Page Which Is Opened." 23 + * Jan. 2013. Online posting. Stack Overflow. 1 Aug. 2015 + * . + * + */ + #include #include "mainpagestack.h" @@ -34,6 +54,7 @@ void MainPageStack::add(MainPage *page, QAction *action) { _pages.insert(action, page); + page->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); /* 2015 Aug 01 */ insertWidget(count(), page); } @@ -61,3 +82,14 @@ MainPageStack::showPage(QAction *pageAction) setCurrentWidget(_pages.value(pageAction)); } +/** Adjusts the size of the Main page and the Main window. */ +void +MainPageStack::onCurrentChanged(int index) /* 2015 Aug 01 */ +{ + QWidget* pWidget = widget(index); + Q_ASSERT(pWidget); + pWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + pWidget->adjustSize(); + adjustSize(); +} + diff --git a/retroshare-gui/src/gui/mainpagestack.h b/retroshare-gui/src/gui/mainpagestack.h index 53988f50e..ca8aa50f9 100644 --- a/retroshare-gui/src/gui/mainpagestack.h +++ b/retroshare-gui/src/gui/mainpagestack.h @@ -50,6 +50,8 @@ public: public slots: /** Displays the page associated with the activated action. */ void showPage(QAction *pageAction); + /** Adjusts the size of the Main page and the Main window. */ + void onCurrentChanged(int index); private: /** Maps an action to a Main page. */ diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index bd4002ed6..752cb4086 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -420,6 +420,10 @@ void MessageComposer::processSettings(bool bLoad) int index = Settings->value("ShowType", 0).toInt(); ui.filterComboBox->setCurrentIndex(index); + RsGxsId resp_to_id ( Settings->value("LastRespondTo").toString().toStdString()); + + if(!resp_to_id.isNull()) + ui.respond_to_CB->setDefaultId(resp_to_id); } else { // save settings @@ -433,6 +437,7 @@ void MessageComposer::processSettings(bool bLoad) // state of filter combobox Settings->setValue("ShowType", ui.filterComboBox->currentIndex()); + Settings->setValue("LastRespondTo",ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString()); } Settings->endGroup(); @@ -1280,7 +1285,7 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) 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 diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp index 60a6519ba..1ec95b2f3 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp @@ -43,15 +43,16 @@ #include "util/QtVersion.h" #include "util/misc.h" -#define COL_ID 0 -#define COL_NICKNAME 1 -#define COL_DESTINATION 2 -#define COL_DATASTATUS 3 -#define COL_TUNNELSTATUS 4 -#define COL_DATASIZE 5 -#define COL_DATAHASH 6 -#define COL_RECEIVED 7 -#define COL_SEND 8 +#define COL_ID 0 +#define COL_NICKNAME 1 +#define COL_DESTINATION 2 +#define COL_DATASTATUS 3 +#define COL_TUNNELSTATUS 4 +#define COL_DATASIZE 5 +#define COL_DATAHASH 6 +#define COL_RECEIVED 7 +#define COL_SEND 8 +#define COL_DUPLICATION_FACTOR 9 static const int PARTIAL_VIEW_SIZE = 5 ; static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ; @@ -187,6 +188,7 @@ void GlobalRouterStatistics::updateContent() item -> setData(COL_DATAHASH, Qt::DisplayRole, QString::fromStdString(cache_infos[i].item_hash.toStdString())); item -> setData(COL_RECEIVED, Qt::DisplayRole, QString::number(now - cache_infos[i].routing_time)); item -> setData(COL_SEND, Qt::DisplayRole, QString::number(now - cache_infos[i].last_sent_time)); + item -> setData(COL_DUPLICATION_FACTOR, Qt::DisplayRole, QString::number(cache_infos[i].duplication_factor)); } } @@ -333,6 +335,9 @@ void GlobalRouterStatisticsWidget::updateContent() mMinWheelZoneX = ox+2*cellx ; mMinWheelZoneY = oy ; + RsGxsId current_id ; + float current_width=0 ; + for(std::map >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it,++n) if(n >= mCurrentN-PARTIAL_VIEW_SIZE/2 && n <= mCurrentN+PARTIAL_VIEW_SIZE/2) { @@ -355,12 +360,19 @@ void GlobalRouterStatisticsWidget::updateContent() { current_probs = it->second ; current_oy = oy ; + current_id = it->first ; + current_width = ox+matrix_info.friend_ids.size()*cellx+fm_monospace.width(ids); } oy += celly ; //} } + + RsIdentityDetails iddetails ; + if(rsIdentity->getIdDetails(current_id,iddetails)) + painter.drawText(current_width+cellx, current_oy+celly, QString::fromUtf8(iddetails.mNickname.c_str())) ; + mMaxWheelZoneY = oy+celly ; painter.setPen(QColor::fromRgb(0,0,0)) ; @@ -382,7 +394,7 @@ void GlobalRouterStatisticsWidget::updateContent() painter.drawLine(x1,y1,x1,y2); painter.drawLine(x1,y2,x1 + total_length - i*cellx,y2) ; - painter.drawText(cellx+ x1 + total_length - i*cellx,y2+(0.35)*celly, QString::fromUtf8(peer_ssl_details.name.c_str()) + " ("+QString::number(current_probs[i])+")"); + painter.drawText(cellx+ x1 + total_length - i*cellx,y2+(0.35)*celly, QString::fromUtf8(peer_ssl_details.name.c_str()) + " - " + QString::fromUtf8(peer_ssl_details.location.c_str()) + " ("+QString::number(current_probs[i])+")"); } oy += celly * (2+matrix_info.friend_ids.size()); diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui index 38890fa2f..b8499a5bb 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui @@ -35,7 +35,7 @@ 0 0 593 - 159 + 156 @@ -101,6 +101,11 @@ Send + + + Branching factor + + diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 83a7ddd99..b561a119b 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -157,6 +157,14 @@ win32 { QMAKE_CFLAGS += -Wextra QMAKE_CXXFLAGS += -Wextra + 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 + } + # solve linker warnings because of the order of the libraries QMAKE_LFLAGS += -Wl,--start-group diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index d9fe77a1a..b3c2c0bd6 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -72,6 +72,14 @@ win32 { # solve linker warnings because of the order of the libraries QMAKE_LFLAGS += -Wl,--start-group + 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 + } + for(lib, LIB_DIR):LIBS += -L"$$lib" LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz LIBS += -lcrypto -lws2_32 -lgdi32