PeerFinder work

This commit is contained in:
Vinnie Falco
2013-09-30 09:35:29 -07:00
parent 41879d8511
commit 4fe63f9f0d
44 changed files with 2327 additions and 489 deletions

View File

@@ -67,6 +67,7 @@ SOURCES += \
../../src/ripple/beast/ripple_beastc.c \ ../../src/ripple/beast/ripple_beastc.c \
../../src/ripple/http/ripple_http.cpp \ ../../src/ripple/http/ripple_http.cpp \
../../src/ripple/json/ripple_json.cpp \ ../../src/ripple/json/ripple_json.cpp \
../../src/ripple/peerfinder/ripple_peerfinder.cpp \
../../src/ripple/rpc/ripple_rpc.cpp \ ../../src/ripple/rpc/ripple_rpc.cpp \
../../src/ripple/sophia/ripple_sophia.c \ ../../src/ripple/sophia/ripple_sophia.c \
../../src/ripple/sslutil/ripple_sslutil.cpp \ ../../src/ripple/sslutil/ripple_sslutil.cpp \

View File

@@ -66,6 +66,49 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\json\ripple_json.cpp" /> <ClCompile Include="..\..\src\ripple\json\ripple_json.cpp" />
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Config.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Endpoint.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\EndpointCache.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Manager.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Slots.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\SourceStrings.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Tests.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\ripple_peerfinder.cpp" />
<ClCompile Include="..\..\src\ripple\rpc\impl\Handler.cpp"> <ClCompile Include="..\..\src\ripple\rpc\impl\Handler.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -1022,12 +1065,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple_core\peerfinder\PeerFinder.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple_core\ripple_core.cpp" /> <ClCompile Include="..\..\src\ripple_core\ripple_core.cpp" />
<ClCompile Include="..\..\src\ripple_data\crypto\Base58Data.cpp"> <ClCompile Include="..\..\src\ripple_data\crypto\Base58Data.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -1587,6 +1624,20 @@
<ClInclude Include="..\..\src\ripple\json\impl\json_autolink.h" /> <ClInclude Include="..\..\src\ripple\json\impl\json_autolink.h" />
<ClInclude Include="..\..\src\ripple\json\impl\json_batchallocator.h" /> <ClInclude Include="..\..\src\ripple\json\impl\json_batchallocator.h" />
<ClInclude Include="..\..\src\ripple\json\ripple_json.h" /> <ClInclude Include="..\..\src\ripple\json\ripple_json.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\api\Callback.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\api\Config.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\api\Endpoint.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\api\Manager.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\api\Types.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\EndpointCache.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Logic.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\PeerInfo.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Slots.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Source.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\SourceStrings.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Store.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\impl\StoreSqdb.h" />
<ClInclude Include="..\..\src\ripple\peerfinder\ripple_peerfinder.h" />
<ClInclude Include="..\..\src\ripple\rpc\api\Handler.h" /> <ClInclude Include="..\..\src\ripple\rpc\api\Handler.h" />
<ClInclude Include="..\..\src\ripple\rpc\api\Manager.h" /> <ClInclude Include="..\..\src\ripple\rpc\api\Manager.h" />
<ClInclude Include="..\..\src\ripple\rpc\api\Service.h" /> <ClInclude Include="..\..\src\ripple\rpc\api\Service.h" />
@@ -1610,6 +1661,7 @@
<ClInclude Include="..\..\src\ripple\testoverlay\api\SimplePayload.h" /> <ClInclude Include="..\..\src\ripple\testoverlay\api\SimplePayload.h" />
<ClInclude Include="..\..\src\ripple\testoverlay\api\StateBase.h" /> <ClInclude Include="..\..\src\ripple\testoverlay\api\StateBase.h" />
<ClInclude Include="..\..\src\ripple\testoverlay\ripple_testoverlay.h" /> <ClInclude Include="..\..\src\ripple\testoverlay\ripple_testoverlay.h" />
<ClInclude Include="..\..\src\ripple\types\api\AgedHistory.h" />
<ClInclude Include="..\..\src\ripple\types\api\Base58.h" /> <ClInclude Include="..\..\src\ripple\types\api\Base58.h" />
<ClInclude Include="..\..\src\ripple\types\api\base_uint.h" /> <ClInclude Include="..\..\src\ripple\types\api\base_uint.h" />
<ClInclude Include="..\..\src\ripple\types\api\Blob.h" /> <ClInclude Include="..\..\src\ripple\types\api\Blob.h" />
@@ -1635,7 +1687,6 @@
<ClInclude Include="..\..\src\ripple\validators\api\Source.h" /> <ClInclude Include="..\..\src\ripple\validators\api\Source.h" />
<ClInclude Include="..\..\src\ripple\validators\api\Types.h" /> <ClInclude Include="..\..\src\ripple\validators\api\Types.h" />
<ClInclude Include="..\..\src\ripple\validators\api\Manager.h" /> <ClInclude Include="..\..\src\ripple\validators\api\Manager.h" />
<ClInclude Include="..\..\src\ripple\validators\impl\AgedHistory.h" />
<ClInclude Include="..\..\src\ripple\validators\impl\ChosenList.h" /> <ClInclude Include="..\..\src\ripple\validators\impl\ChosenList.h" />
<ClInclude Include="..\..\src\ripple\validators\impl\Logic.h" /> <ClInclude Include="..\..\src\ripple\validators\impl\Logic.h" />
<ClInclude Include="..\..\src\ripple\validators\impl\SourceDesc.h" /> <ClInclude Include="..\..\src\ripple\validators\impl\SourceDesc.h" />
@@ -1793,7 +1844,6 @@
<ClInclude Include="..\..\src\ripple_core\nodestore\impl\Factories.h" /> <ClInclude Include="..\..\src\ripple_core\nodestore\impl\Factories.h" />
<ClInclude Include="..\..\src\ripple_core\nodestore\NodeStore.h" /> <ClInclude Include="..\..\src\ripple_core\nodestore\NodeStore.h" />
<ClInclude Include="..\..\src\ripple_core\nodestore\tests\TestBase.h" /> <ClInclude Include="..\..\src\ripple_core\nodestore\tests\TestBase.h" />
<ClInclude Include="..\..\src\ripple_core\peerfinder\PeerFinder.h" />
<ClInclude Include="..\..\src\ripple_core\ripple_core.h" /> <ClInclude Include="..\..\src\ripple_core\ripple_core.h" />
<ClInclude Include="..\..\src\ripple_data\crypto\Base58Data.h" /> <ClInclude Include="..\..\src\ripple_data\crypto\Base58Data.h" />
<ClInclude Include="..\..\src\ripple_data\crypto\CKey.h" /> <ClInclude Include="..\..\src\ripple_data\crypto\CKey.h" />

View File

@@ -103,9 +103,6 @@
<Filter Include="[2] Old Ripple\ripple_core\functional"> <Filter Include="[2] Old Ripple\ripple_core\functional">
<UniqueIdentifier>{548037f2-eb8a-41bd-95dc-05f58cdbc041}</UniqueIdentifier> <UniqueIdentifier>{548037f2-eb8a-41bd-95dc-05f58cdbc041}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="[2] Old Ripple\ripple_core\peerfinder">
<UniqueIdentifier>{d1648d3f-7d71-495d-afc9-576ed00d7185}</UniqueIdentifier>
</Filter>
<Filter Include="[2] Old Ripple\ripple_data"> <Filter Include="[2] Old Ripple\ripple_data">
<UniqueIdentifier>{df861e00-baa6-43d4-bbbf-df61d66ee414}</UniqueIdentifier> <UniqueIdentifier>{df861e00-baa6-43d4-bbbf-df61d66ee414}</UniqueIdentifier>
</Filter> </Filter>
@@ -232,6 +229,15 @@
<Filter Include="[1] Ripple\sslutil\impl"> <Filter Include="[1] Ripple\sslutil\impl">
<UniqueIdentifier>{794194cf-e641-4838-ba78-82482c6e87c0}</UniqueIdentifier> <UniqueIdentifier>{794194cf-e641-4838-ba78-82482c6e87c0}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="[1] Ripple\peerfinder">
<UniqueIdentifier>{6bda410a-7901-479d-9cc1-63c339057c92}</UniqueIdentifier>
</Filter>
<Filter Include="[1] Ripple\peerfinder\api">
<UniqueIdentifier>{908c91d8-3d3b-4c5e-ba85-dffc6f9b41f0}</UniqueIdentifier>
</Filter>
<Filter Include="[1] Ripple\peerfinder\impl">
<UniqueIdentifier>{cd1585a6-bc32-477d-88cd-275159dafa83}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\ripple_basics\containers\RangeSet.cpp"> <ClCompile Include="..\..\src\ripple_basics\containers\RangeSet.cpp">
@@ -789,9 +795,6 @@
<ClCompile Include="..\..\src\protobuf_core.cpp"> <ClCompile Include="..\..\src\protobuf_core.cpp">
<Filter>[0] Libraries\protobuf</Filter> <Filter>[0] Libraries\protobuf</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple_core\peerfinder\PeerFinder.cpp">
<Filter>[2] Old Ripple\ripple_core\peerfinder</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple_core\functional\Config.cpp"> <ClCompile Include="..\..\src\ripple_core\functional\Config.cpp">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClCompile> </ClCompile>
@@ -1059,6 +1062,30 @@
<ClCompile Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.cpp"> <ClCompile Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.cpp">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\ripple_peerfinder.cpp">
<Filter>[1] Ripple\peerfinder</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Endpoint.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Config.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Manager.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Tests.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\Slots.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\EndpointCache.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\peerfinder\impl\SourceStrings.cpp">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h"> <ClInclude Include="..\..\src\ripple_basics\containers\KeyCache.h">
@@ -1728,9 +1755,6 @@
<Filter>[2] Old Ripple\ripple_app\misc</Filter> <Filter>[2] Old Ripple\ripple_app\misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\BeastConfig.h" /> <ClInclude Include="..\..\src\BeastConfig.h" />
<ClInclude Include="..\..\src\ripple_core\peerfinder\PeerFinder.h">
<Filter>[2] Old Ripple\ripple_core\peerfinder</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\Config.h"> <ClInclude Include="..\..\src\ripple_core\functional\Config.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude> </ClInclude>
@@ -2106,15 +2130,57 @@
<ClInclude Include="..\..\src\ripple_basics\containers\BlackList.h"> <ClInclude Include="..\..\src\ripple_basics\containers\BlackList.h">
<Filter>[2] Old Ripple\ripple_basics\containers</Filter> <Filter>[2] Old Ripple\ripple_basics\containers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\validators\impl\AgedHistory.h">
<Filter>[1] Ripple\validators\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.h"> <ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrackImp.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h"> <ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h">
<Filter>[2] Old Ripple\ripple_core\functional</Filter> <Filter>[2] Old Ripple\ripple_core\functional</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\types\api\AgedHistory.h">
<Filter>[1] Ripple\types\api</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\ripple_peerfinder.h">
<Filter>[1] Ripple\peerfinder</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\api\Types.h">
<Filter>[1] Ripple\peerfinder\api</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\api\Endpoint.h">
<Filter>[1] Ripple\peerfinder\api</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\api\Config.h">
<Filter>[1] Ripple\peerfinder\api</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\api\Callback.h">
<Filter>[1] Ripple\peerfinder\api</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Logic.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Store.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\StoreSqdb.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Slots.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\PeerInfo.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\EndpointCache.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\Source.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\impl\SourceStrings.h">
<Filter>[1] Ripple\peerfinder\impl</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\peerfinder\api\Manager.h">
<Filter>[1] Ripple\peerfinder\api</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto"> <CustomBuild Include="..\..\src\ripple_data\protocol\ripple.proto">

View File

@@ -13,6 +13,7 @@ OSX = bool(platform.mac_ver()[0])
FreeBSD = bool('FreeBSD' == platform.system()) FreeBSD = bool('FreeBSD' == platform.system())
Linux = bool('Linux' == platform.system()) Linux = bool('Linux' == platform.system())
Ubuntu = bool(Linux and 'Ubuntu' == platform.linux_distribution()[0]) Ubuntu = bool(Linux and 'Ubuntu' == platform.linux_distribution()[0])
Debian = bool(Linux and 'debian' == platform.linux_distribution()[0])
Archlinux = bool(Linux and ('','','') == platform.linux_distribution()) #Arch still has issues with the platform module Archlinux = bool(Linux and ('','','') == platform.linux_distribution()) #Arch still has issues with the platform module
# #
@@ -21,7 +22,7 @@ Archlinux = bool(Linux and ('','','') == platform.linux_distribution()) #Arch s
BOOST_HOME = os.environ.get("RIPPLED_BOOST_HOME", None) BOOST_HOME = os.environ.get("RIPPLED_BOOST_HOME", None)
if OSX or Ubuntu or Archlinux: if OSX or Ubuntu or Debian or Archlinux:
CTAGS = 'ctags' CTAGS = 'ctags'
elif FreeBSD: elif FreeBSD:
CTAGS = 'exctags' CTAGS = 'exctags'
@@ -157,6 +158,7 @@ COMPILED_FILES.extend (['src/ripple/beast/ripple_beastc.c'])
COMPILED_FILES.extend([ COMPILED_FILES.extend([
'src/ripple/http/ripple_http.cpp', 'src/ripple/http/ripple_http.cpp',
'src/ripple/json/ripple_json.cpp', 'src/ripple/json/ripple_json.cpp',
'src/ripple/peerfinder/ripple_peerfinder.cpp',
'src/ripple/rpc/ripple_rpc.cpp', 'src/ripple/rpc/ripple_rpc.cpp',
'src/ripple/sophia/ripple_sophia.c', 'src/ripple/sophia/ripple_sophia.c',
'src/ripple/sslutil/ripple_sslutil.cpp', 'src/ripple/sslutil/ripple_sslutil.cpp',

View File

@@ -17,7 +17,6 @@
*/ */
//============================================================================== //==============================================================================
#ifndef BEAST_BEASTCONFIG_H_INCLUDED #ifndef BEAST_BEASTCONFIG_H_INCLUDED
#define BEAST_BEASTCONFIG_H_INCLUDED #define BEAST_BEASTCONFIG_H_INCLUDED
@@ -164,13 +163,10 @@
#define RIPPLE_USE_NEW_VALIDATORS 0 #define RIPPLE_USE_NEW_VALIDATORS 0
#endif #endif
// This is only here temporarily. Use it to turn off the sending of // Turning this on will use the new PeerFinder logic to establish connections
// "ANNOUNCE" messages if you suspect that you're having problems // to other peers. Even with this off, PeerFinder will still send mtENDPOINTS
// because of it. // messages as needed, and collect legacy IP endpoint information.
#ifndef RIPPLE_USE_MT_ANNOUNCE //
#define RIPPLE_USE_MT_ANNOUNCE 0
#endif
#ifndef RIPPLE_USE_PEERFINDER #ifndef RIPPLE_USE_PEERFINDER
#define RIPPLE_USE_PEERFINDER 0 #define RIPPLE_USE_PEERFINDER 0
#endif #endif

View File

@@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_CALLBACK_H_INCLUDED
#define RIPPLE_PEERFINDER_CALLBACK_H_INCLUDED
#include "Endpoint.h"
#include "Types.h"
namespace ripple {
namespace PeerFinder {
/** The Callback receives PeerFinder notifications.
The notifications are sent on a thread owned by the PeerFinder,
so it is best not to do too much work in here. Just post functor
to another worker thread or job queue and return.
*/
struct Callback
{
/** Sends a set of Endpoint records to the specified peer. */
virtual void sendPeerEndpoints (PeerID const& id,
std::vector <Endpoint> const& endpoints) = 0;
/** Initiate outgoing Peer connections to the specified set of endpoints. */
virtual void connectPeerEndpoints (std::vector <IPEndpoint> const& list) = 0;
/** Impose a load charge on the specified peer. */
virtual void chargePeerLoadPenalty (PeerID const& id) = 0;
};
}
}
#endif

View File

@@ -0,0 +1,45 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_CONFIG_H_INCLUDED
#define RIPPLE_PEERFINDER_CONFIG_H_INCLUDED
namespace ripple {
namespace PeerFinder {
/** Configuration for the Manager. */
struct Config
{
Config ();
static int const minOutCount = 10;
static int const outPercent = 15;
int maxPeerCount;
/** True if we want to accept incoming connections. */
bool wantIncoming;
uint16 listeningPort;
std::string featureList;
};
}
}
#endif

View File

@@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_ENDPOINT_H_INCLUDED
#define RIPPLE_PEERFINDER_ENDPOINT_H_INCLUDED
#include "Types.h"
namespace ripple {
namespace PeerFinder {
/** Describes a connectible peer address along with some metadata. */
struct Endpoint
{
Endpoint ();
IPEndpoint address;
uint16 port;
int hops;
uint32 incomingSlotsAvailable;
uint32 incomingSlotsMax;
uint32 uptimeMinutes;
std::string featureList;
};
inline bool operator< (Endpoint const& lhs, Endpoint const& rhs)
{
return lhs.address < rhs.address;
}
inline bool operator== (Endpoint const& lhs, Endpoint const& rhs)
{
return lhs.address == rhs.address;
}
}
}
#endif

View File

@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_MANAGER_H_INCLUDED
#define RIPPLE_PEERFINDER_MANAGER_H_INCLUDED
namespace ripple {
namespace PeerFinder {
/** Maintains a set of IP addresses used for getting into the network. */
class Manager : public Stoppable
{
protected:
explicit Manager (Stoppable& parent);
public:
/** Create a new Manager. */
static Manager* New (Stoppable& parent,
Callback& callback, Journal journal);
/** Destroy the object.
Any pending source fetch operations are aborted.
There may be some listener calls made before the
destructor returns.
*/
virtual ~Manager () { }
/** Set the configuration for the manager.
The new settings will be applied asynchronously.
Thread safety:
Can be called from any threads at any time.
*/
virtual void setConfig (Config const& config) = 0;
/** Add a set of strings as fallback IPEndpoint sources.
@param name A label used for diagnostics.
*/
virtual void addStrings (std::string const& name,
std::vector <std::string> const& strings) = 0;
/** Add a URL as a fallback location to obtain IPEndpoint sources.
@param name A label used for diagnostics.
*/
virtual void addURL (std::string const& name,
std::string const& url) = 0;
/** Called when a new peer connection is established.
Internally, we add the peer to our tracking table, validate that
we can connect to it, and begin advertising it to others after
we are sure that its connection is stable.
*/
virtual void onPeerConnected (PeerID const& id,
IPEndpoint const& address,
bool inbound) = 0;
/** Called when an existing peer connection drops for whatever reason.
Internally, we mark the peer as no longer connected, calculate
stability metrics, and consider whether we should try to reconnect
to it or drop it from our list.
*/
virtual void onPeerDisconnected (PeerID const& id) = 0;
/** Called when mtENDPOINTS is received. */
virtual void onPeerEndpoints (PeerID const& id,
std::vector <Endpoint> const& endpoints) = 0;
/** Called when a legacy IP/port address is received (from mtPEER). */
virtual void onPeerLegacyEndpoint (IPEndpoint const& ep) = 0;
};
}
}
#endif

View File

@@ -0,0 +1,32 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_TYPES_H_INCLUDED
#define RIPPLE_PEERFINDER_TYPES_H_INCLUDED
namespace ripple {
namespace PeerFinder {
/** Used to identify peers. */
typedef RipplePublicKey PeerID;
}
}
#endif

View File

@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../api/Config.h"
namespace ripple {
namespace PeerFinder {
Config::Config ()
: maxPeerCount (20)
, wantIncoming (false)
, listeningPort (0)
{
}
}
}

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "../api/Endpoint.h"
namespace ripple {
namespace PeerFinder {
Endpoint::Endpoint ()
: port (0)
, hops (0)
, incomingSlotsAvailable (0)
, incomingSlotsMax (0)
, uptimeMinutes (0)
{
}
}
}

View File

@@ -0,0 +1,19 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================

View File

@@ -0,0 +1,46 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_ENDPOINTCACHE_H_INCLUDED
#define RIPPLE_PEERFINDER_ENDPOINTCACHE_H_INCLUDED
#include "../../ripple/types/api/AgedHistory.h"
#include "../api/Types.h"
namespace ripple {
namespace PeerFinder {
/** This container holds the master set of Endpoints. */
class EndpointCache
{
public:
EndpointCache ();
~EndpointCache ();
// Informs the cache we've received an endpoint.
void update (Endpoint const& ep);
private:
};
}
}
#endif

View File

@@ -0,0 +1,496 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_LOGIC_H_INCLUDED
#define RIPPLE_PEERFINDER_LOGIC_H_INCLUDED
#include "../../ripple/types/api/AgedHistory.h"
#include "PeerInfo.h"
#include "Slots.h"
#include "Store.h"
#include <set>
#include "beast/modules/beast_core/system/BeforeBoost.h"
#include <boost/regex.hpp>
#include <boost/unordered_set.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
namespace ripple {
namespace PeerFinder {
// Tunable constants
enum
{
// How often we will try to make outgoing connections
secondsPerConnect = 10,
// How often we send or accept mtENDPOINTS messages per peer
secondsPerEndpoints = 5,
// How many Endpoint to send in each mtENDPOINTS
numberOfEndpoints = 10,
// The most Endpoint we will accept in mtENDPOINTS
numberOfEndpointsMax = 20,
// How many legacy endpoints to keep in our cache
numberOfLegacyEndpoints = 1000,
// How often legacy endpoints are updated in the database
legacyEndpointUpdateSeconds = 60 * 60
};
//--------------------------------------------------------------------------
/*
typedef boost::multi_index_container <
Endpoint, boost::multi_index::indexed_by <
boost::multi_index::hashed_unique <
BOOST_MULTI_INDEX_MEMBER(PeerFinder::Endpoint,IPEndpoint,address)>
>
> EndpointCache;
*/
// Describes an Endpoint in the global Endpoint table
// This includes the Endpoint as well as some additional information
//
struct EndpointInfo
{
Endpoint endpoint;
};
inline bool operator< (EndpointInfo const& lhs, EndpointInfo const& rhs)
{
return lhs.endpoint < rhs.endpoint;
}
inline bool operator== (EndpointInfo const& lhs, EndpointInfo const& rhs)
{
return lhs.endpoint == rhs.endpoint;
}
typedef AgedHistory <std::set <IPEndpoint> > LegacyEndpoints;
//--------------------------------------------------------------------------
typedef boost::multi_index_container <
PeerInfo, boost::multi_index::indexed_by <
boost::multi_index::hashed_unique <
BOOST_MULTI_INDEX_MEMBER(PeerFinder::PeerInfo,PeerID,id),
PeerID::hasher>,
boost::multi_index::hashed_unique <
BOOST_MULTI_INDEX_MEMBER(PeerFinder::PeerInfo,beast::IPEndpoint,address),
IPEndpoint::hasher>
>
> Peers;
//------------------------------------------------------------------------------
/** The Logic for maintaining the list of Peer addresses.
We keep this in a separate class so it can be instantiated
for unit tests.
*/
class Logic
{
public:
struct State
{
State ()
{
}
// Fresh endpoints are ones we have seen recently via mtENDPOINTS.
// These are best to give out to someone who needs additional
// connections as quickly as possible, since it is very likely
// that the fresh endpoints have open incoming slots.
//
//EndpointCache fresh;
// Reliable endpoints are ones which are highly likely to be
// connectible over long periods of time. They might not necessarily
// have an incoming slot, but they are good for bootstrapping when
// there are no peers yet. Typically these are what we would want
// to store in a database or local config file for a future launch.
//Endpoints reliable;
};
//----------------------------------------------------------------------
Callback& m_callback;
Store& m_store;
Journal m_journal;
Config m_config;
// A list of dynamic sources consulted as a fallback
std::vector <ScopedPointer <Source> > m_sources;
// The current tally of peer slot statistics
Slots m_slots;
// Our view of the current set of connected peers.
Peers m_peers;
LegacyEndpoints m_legacyEndpoints;
bool m_legacyEndpointsDirty;
//----------------------------------------------------------------------
Logic (Callback& callback, Store& store, Journal journal)
: m_callback (callback)
, m_store (store)
, m_journal (journal)
, m_legacyEndpointsDirty (false)
{
}
//----------------------------------------------------------------------
// Load persistent state information from the Store
//
void load ()
{
typedef std::vector <IPEndpoint> List;
List list;
m_store.loadLegacyEndpoints (list);
for (List::const_iterator iter (list.begin());
iter != list.end(); ++iter)
m_legacyEndpoints->insert (*iter);
m_legacyEndpoints.swap();
m_journal.debug << "Loaded " << list.size() << " legacy endpoints";
}
// Called when a peer's id is unexpectedly not found
//
void peerNotFound (PeerID const& id)
{
m_journal.fatal << "Missing peer " << id;
}
// Returns a suitable Endpoint representing us.
//
Endpoint thisEndpoint ()
{
// Why would someone call this if we don't want incoming?
bassert (m_config.wantIncoming);
Endpoint ep;
// ep.address = ?
ep.port = m_config.listeningPort;
ep.hops = 0;
ep.incomingSlotsAvailable = m_slots.inboundSlots;
ep.incomingSlotsMax = m_slots.inboundSlotsMaximum;
ep.uptimeMinutes = m_slots.uptimeMinutes();
return ep;
}
// Returns true if the Endpoint contains no invalid data.
//
bool validEndpoint (Endpoint const& endpoint)
{
if (! endpoint.address.isPublic())
return false;
if (endpoint.port == 0)
return false;
return false;
}
// Prunes invalid endpoints from a list
//
void pruneEndpoints (std::vector <Endpoint>& list)
{
for (std::vector <Endpoint>::iterator iter (list.begin());
iter != list.end(); ++iter)
{
while (! validEndpoint (*iter))
{
m_journal.error << "Pruned invalid endpoint " << iter->address;
iter = list.erase (iter);
if (iter == list.end())
break;
}
}
}
// Send mtENDPOINTS for the specified peer
//
void sendEndpoints (PeerInfo const& peer)
{
typedef std::vector <Endpoint> List;
std::vector <Endpoint> endpoints;
// fill in endpoints
// Add us to the list if we want incoming
if (m_slots.inboundSlots > 0)
endpoints.push_back (thisEndpoint ());
if (! endpoints.empty())
m_callback.sendPeerEndpoints (peer.id, endpoints);
}
// Assembles a list from the legacy endpoint container
//
void createLegacyEndpointList (std::vector <IPEndpoint>& list)
{
list.clear ();
list.reserve (m_legacyEndpoints.front().size() +
m_legacyEndpoints.back().size());
for (LegacyEndpoints::container_type::const_iterator iter (
m_legacyEndpoints.front().begin()); iter != m_legacyEndpoints.front().end(); ++iter)
list.push_back (*iter);
for (LegacyEndpoints::container_type::const_iterator iter (
m_legacyEndpoints.back().begin()); iter != m_legacyEndpoints.back().end(); ++iter)
list.push_back (*iter);
}
// Make outgoing connections to bring us up to desired out count
//
void makeOutgoingConnections ()
{
if (m_slots.outDesired > m_slots.outboundCount)
{
std::vector <IPEndpoint> list;
createLegacyEndpointList (list);
std::random_shuffle (list.begin(), list.end());
int needed = m_slots.outDesired - m_slots.outboundCount;
if (needed > list.size())
needed = list.size();
#if RIPPLE_USE_PEERFINDER
m_callback.connectPeerEndpoints (list);
#endif
}
}
// Fetch the list of IPEndpoint from the specified source
//
void fetch (Source& source)
{
m_journal.debug << "Fetching " << source.name();
Source::IPEndpoints endpoints;
source.fetch (endpoints, m_journal);
if (! endpoints.empty())
{
for (Source::IPEndpoints::const_iterator iter (endpoints.begin());
iter != endpoints.end(); ++iter)
m_legacyEndpoints->insert (*iter);
if (m_legacyEndpoints->size() > (numberOfLegacyEndpoints/2))
{
m_legacyEndpoints.swap();
m_legacyEndpoints->clear();
}
m_legacyEndpointsDirty = true;
}
}
//----------------------------------------------------------------------
void setConfig (Config const& config)
{
m_config = config;
m_slots.update (m_config);
}
void addStaticSource (Source* source)
{
ScopedPointer <Source> p (source);
fetch (*source);
}
void addSource (Source* source)
{
m_sources.push_back (source);
}
void onUpdate ()
{
m_journal.debug << "Processing Update";
}
// Send mtENDPOINTS for each peer as needed
//
void sendEndpoints ()
{
if (! m_peers.empty())
{
m_journal.debug << "Sending mtENDPOINTS";
RelativeTime const now (RelativeTime::fromStartup());
for (Peers::iterator iter (m_peers.begin());
iter != m_peers.end(); ++iter)
{
PeerInfo const& peer (*iter);
if (peer.whenSendEndpoints <= now)
{
sendEndpoints (peer);
peer.whenSendEndpoints = now +
RelativeTime (secondsPerEndpoints);
}
}
}
}
void onPeerConnected (PeerID const& id,
IPEndpoint const& address, bool inbound)
{
m_journal.debug << "Peer connected: " << address;
std::pair <Peers::iterator, bool> result (
m_peers.insert (
PeerInfo (id, address, inbound)));
if (result.second)
{
//PeerInfo const& peer (*result.first);
m_slots.addPeer (m_config, inbound);
}
else
{
// already exists!
m_journal.error << "Duplicate peer " << id;
//m_callback.disconnectPeer (id);
}
}
void onPeerDisconnected (PeerID const& id)
{
Peers::iterator iter (m_peers.find (id));
if (iter != m_peers.end())
{
// found
PeerInfo const& peer (*iter);
m_journal.debug << "Peer disconnected: " << peer.address;
m_slots.dropPeer (m_config, peer.inbound);
m_peers.erase (iter);
}
else
{
m_journal.debug << "Peer disconnected: " << id;
peerNotFound (id);
}
}
// Processes a list of Endpoint received from a peer.
//
void onPeerEndpoints (PeerID const& id, std::vector <Endpoint> endpoints)
{
pruneEndpoints (endpoints);
Peers::iterator iter (m_peers.find (id));
if (iter != m_peers.end())
{
RelativeTime const now (RelativeTime::fromStartup());
PeerInfo const& peer (*iter);
if (now >= peer.whenReceiveEndpoints)
{
m_journal.debug << "Received " << endpoints.size() <<
"Endpoint descriptors from " << peer.address;
// We charge a load penalty if the peer sends us more than
// numberOfEndpoints peers in a single message
if (endpoints.size() > numberOfEndpoints)
{
m_journal.warning << "Charging peer " << peer.address <<
" for sending too many endpoints";
m_callback.chargePeerLoadPenalty(id);
}
// process the list
peer.whenReceiveEndpoints = now + secondsPerEndpoints;
}
else
{
m_journal.warning << "Charging peer " << peer.address <<
" for sending too quickly";
// Peer sent mtENDPOINTS too often
m_callback.chargePeerLoadPenalty (id);
}
}
else
{
peerNotFound (id);
}
}
void onPeerLegacyEndpoint (IPEndpoint const& ep)
{
if (ep.isPublic())
{
// insert into front container
std::pair <LegacyEndpoints::container_type::iterator, bool> result (
m_legacyEndpoints->insert (ep));
// erase from back container if its new
if (result.second)
{
std::size_t const n (m_legacyEndpoints.back().erase (ep));
if (n == 0)
{
m_legacyEndpointsDirty = true;
m_journal.trace << "Legacy endpoint: " << ep;
}
}
if (m_legacyEndpoints->size() > (numberOfLegacyEndpoints/2))
{
m_legacyEndpoints.swap();
m_legacyEndpoints->clear();
}
}
}
// Updates the Store with the current set of legacy endpoints
//
void storeLegacyEndpoints ()
{
if (!m_legacyEndpointsDirty)
return;
std::vector <IPEndpoint> list;
createLegacyEndpointList (list);
m_journal.debug << "Updating " << list.size() << " legacy endpoints";
m_store.storeLegacyEndpoints (list);
m_legacyEndpointsDirty = false;
}
};
}
}
#endif

View File

@@ -78,10 +78,10 @@ network graph
We define these values: We define these values:
PeerCount (calculated) peerCount (calculated)
The number of currently connected and established peers The number of currently connected and established peers
OutCount (calculated) outCount (calculated)
The number of peers in PeerCount that are outbound connections. The number of peers in PeerCount that are outbound connections.
MinOutCount (hard-coded constant) MinOutCount (hard-coded constant)
@@ -95,7 +95,7 @@ We define these values:
that a peer wishes to maintain. Setting MaxPeerCount equal to that a peer wishes to maintain. Setting MaxPeerCount equal to
or below MinOutCount would disallow incoming connections. or below MinOutCount would disallow incoming connections.
OutDesiredPercent (a baked-in program constant for now) OutPercent (a baked-in program constant for now)
The peer's target value for OutCount. When the value of OutCount The peer's target value for OutCount. When the value of OutCount
is below this number, the peer will employ the Outgoing Strategy is below this number, the peer will employ the Outgoing Strategy
to raise its value of OutCount. This value is initially a constant to raise its value of OutCount. This value is initially a constant
@@ -170,214 +170,214 @@ Gnutella 0.6 Protocol
Revised Gnutella Ping Pong Scheme Revised Gnutella Ping Pong Scheme
By Christopher Rohrs and Vincent Falco By Christopher Rohrs and Vincent Falco
http://rfc-gnutella.sourceforge.net/src/pong-caching.html http://rfc-gnutella.sourceforge.net/src/pong-caching.html
*/ */
//------------------------------------------------------------------------------
class PeerFinderImp #include "Logic.h"
: public PeerFinder #include "StoreSqdb.h"
, private ThreadWithCallQueue::EntryPoints
, private DeadlineTimer::Listener namespace ripple {
, LeakChecked <PeerFinderImp> namespace PeerFinder {
class ManagerImp
: public Manager
, public Thread
, public DeadlineTimer::Listener
, public LeakChecked <ManagerImp>
{ {
public: public:
// Tunable constants ServiceQueue m_queue;
enum Journal m_journal;
{ StoreSqdb m_store;
// How often our timer goes off to consult outside sources for IPs Logic m_logic;
secondsPerUpdate = 1 * 60 * 60, // once per hour DeadlineTimer m_connectTimer;
// How often we announce our IP DeadlineTimer m_endpointsTimer;
secondsPerBroadcast = 5 * 60, RelativeTime m_whenStoreLegacyEndpoints;
// The minimum number of peers we want
numberOfPeersMinimum = 4,
numberOfPeersMaximum = 10,
// The minimum number of seconds a connection ought to be sustained
// before we consider it "stable"
secondsForStability = 60, // one minute
};
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/** The Logic for maintaining the list of Peer addresses. ManagerImp (Stoppable& stoppable, Callback& callback, Journal journal)
We keep this in a separate class so it can be instantiated : Manager (stoppable)
for unit tests. , Thread ("PeerFinder")
*/ , m_journal (journal)
class Logic , m_store (journal)
, m_logic (callback, m_store, journal)
, m_connectTimer (this)
, m_endpointsTimer (this)
{ {
Callback &m_callback; #if BEAST_MSVC
if (beast_isRunningUnderDebugger())
public:
explicit Logic (Callback& callback)
: m_callback (callback)
{ {
m_journal.sink().set_console (true);
m_journal.sink().set_severity (Journal::kLowestSeverity);
} }
// Called on the PeerFinder thread
void onUpdateConnectionsStatus (
Connections const& connections)
{
if (connections.numberTotal () < numberOfPeersMinimum)
{
// do something
}
else
{
// do something?
}
}
void onPeerConnected (
const PeerId& id)
{
}
void onPeerDisconnected (
const PeerId& id)
{
}
void onAcceptTimer()
{
m_callback.onAnnounceAddress ();
}
};
//--------------------------------------------------------------------------
public:
explicit PeerFinderImp (Callback& callback)
: m_logic (callback)
, m_thread ("PeerFinder")
, m_acceptTimer (this)
, m_updateTimer (this)
{
m_thread.start (this);
}
~PeerFinderImp ()
{
}
void updateConnectionsStatus (Connections& connections)
{
// Queue the call to the logic
m_thread.call (&Logic::onUpdateConnectionsStatus,
&m_logic, connections);
}
void onPeerConnected(const PeerId& id)
{
m_thread.call (&Logic::onPeerConnected,
&m_logic, id);
}
void onPeerDisconnected(const PeerId& id)
{
m_thread.call (&Logic::onPeerDisconnected,
&m_logic, id);
}
//--------------------------------------------------------------------------
void onAcceptTimer ()
{
#if 0
static int x = 0;
if(x == 0)
Debug::breakPoint ();
x++;
#endif #endif
} }
~ManagerImp ()
{
}
//--------------------------------------------------------------------------
//
// PeerFinder
//
void setConfig (Config const& config)
{
m_queue.dispatch (bind (&Logic::setConfig, &m_logic, config));
}
void addStrings (std::string const& name,
std::vector <std::string> const& strings)
{
m_queue.dispatch (bind (&Logic::addStaticSource, &m_logic,
SourceStrings::New (name, strings)));
}
void addURL (std::string const& name, std::string const& url)
{
}
void onPeerConnected (PeerID const& id,
IPEndpoint const& address, bool incoming)
{
m_queue.dispatch (bind (&Logic::onPeerConnected, &m_logic,
id, address, incoming));
}
void onPeerDisconnected (const PeerID& id)
{
m_queue.dispatch (bind (&Logic::onPeerDisconnected, &m_logic, id));
}
void onPeerLegacyEndpoint (IPEndpoint const& ep)
{
m_queue.dispatch (bind (&Logic::onPeerLegacyEndpoint, &m_logic,
ep));
}
void onPeerEndpoints (PeerID const& id,
std::vector <Endpoint> const& endpoints)
{
m_queue.dispatch (beast::bind (&Logic::onPeerEndpoints, &m_logic,
id, endpoints));
}
//--------------------------------------------------------------------------
//
// Stoppable
//
void onPrepare (Journal journal)
{
}
void onStart (Journal journal)
{
startThread();
}
void onStop (Journal journal)
{
if (this->Thread::isThreadRunning ())
{
m_journal.debug << "Stopping";
m_connectTimer.cancel();
m_endpointsTimer.cancel();
m_queue.dispatch (bind (&Thread::signalThreadShouldExit, this));
}
else
{
stopped();
}
}
//--------------------------------------------------------------------------
void onDeadlineTimer (DeadlineTimer& timer) void onDeadlineTimer (DeadlineTimer& timer)
{ {
// This will make us fall into the idle proc as needed if (timer == m_connectTimer)
//
if (timer == m_updateTimer)
m_thread.interrupt ();
else if (timer == m_acceptTimer)
m_thread.call (&Logic::onAcceptTimer, &m_logic);
}
void threadInit ()
{ {
m_updateTimer.setRecurringExpiration (secondsPerUpdate); m_queue.dispatch (bind (&Logic::makeOutgoingConnections, &m_logic));
m_acceptTimer.setRecurringExpiration (secondsPerBroadcast); m_connectTimer.setExpiration (secondsPerConnect);
} }
else if (timer == m_endpointsTimer)
void threadExit ()
{ {
m_queue.dispatch (bind (&Logic::sendEndpoints, &m_logic));
m_endpointsTimer.setExpiration (secondsPerEndpoints);
}
} }
bool threadIdle () // Checks to see if its time to update legacy endpoints
void storeLegacyEndpoints()
{ {
bool interrupted = false; RelativeTime const now (RelativeTime::fromStartup());
if (now >= m_whenStoreLegacyEndpoints)
// This is where you can go into a loop and do stuff {
// like process the lists, and what not. Just be m_logic.storeLegacyEndpoints ();
// sure to call: m_whenStoreLegacyEndpoints = now
// + RelativeTime (legacyEndpointUpdateSeconds);
// @code }
// interrupted = interruptionPoint ();
// @encode
//
// From time to time. If it returns true then you
// need to exit this function so that Thread can
// process its asynchronous call queue and then come
// back into threadIdle()
return interrupted;
} }
private: void init ()
Logic m_logic; {
ThreadWithCallQueue m_thread; m_journal.debug << "Initializing";
DeadlineTimer m_acceptTimer;
DeadlineTimer m_updateTimer; File const file (File::getSpecialLocation (
File::userDocumentsDirectory).getChildFile ("PeerFinder.sqlite"));
m_journal.debug << "Opening database at '" << file.getFullPathName() << "'";
Error error (m_store.open (file));
if (error)
{
m_journal.fatal <<
"Failed to open '" << file.getFullPathName() << "'";
}
if (! error)
{
m_logic.load ();
}
m_connectTimer.setExpiration (secondsPerConnect);
m_endpointsTimer.setExpiration (secondsPerEndpoints);
m_queue.post (bind (&Logic::makeOutgoingConnections, &m_logic));
}
void run ()
{
m_journal.debug << "Started";
m_whenStoreLegacyEndpoints = RelativeTime::fromStartup()
+ RelativeTime (legacyEndpointUpdateSeconds);
init ();
while (! this->threadShouldExit())
{
storeLegacyEndpoints();
m_queue.run_one();
}
stopped();
}
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
PeerFinder* PeerFinder::New (PeerFinder::Callback& callback) Manager::Manager (Stoppable& parent)
: Stoppable ("PeerFinder", parent)
{ {
return new PeerFinderImp (callback);
} }
//------------------------------------------------------------------------------ Manager* Manager::New (Stoppable& parent, Callback& callback, Journal journal)
class PeerFinderTests : public UnitTest,
public PeerFinder::Callback
{ {
public: return new ManagerImp (parent, callback, journal);
void testValidityChecks () }
{
beginTestCase ("ip validation");
fail ("there's no code!");
}
void runTest ()
{
PeerFinderImp::Logic logic (*this);
beginTestCase ("logic");
logic.onAcceptTimer ();
}
void onAnnounceAddress ()
{
}
PeerFinderTests () : UnitTest ("PeerFinder", "ripple", runManual)
{
}
};
static PeerFinderTests peerFinderTests;
}
}

View File

@@ -0,0 +1,70 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_PEERINFO_H_INCLUDED
#define RIPPLE_PEERFINDER_PEERINFO_H_INCLUDED
#include "../../ripple/types/api/AgedHistory.h"
#include "../api/Types.h"
#include <set>
namespace ripple {
namespace PeerFinder {
typedef AgedHistory <std::set <Endpoint> > Endpoints;
//--------------------------------------------------------------------------
// we keep one of these for each connected peer
struct PeerInfo
{
PeerInfo (PeerID const& id_,
IPEndpoint const& address_,
bool inbound_)
: id (id_)
, address (address_)
, inbound (inbound_)
, whenSendEndpoints (RelativeTime::fromStartup())
, whenReceiveEndpoints (RelativeTime::fromStartup())
{
}
PeerID id;
IPEndpoint address;
bool inbound;
// The time after which we will send the peer mtENDPOINTS
RelativeTime mutable whenSendEndpoints;
// The time after which we will accept mtENDPOINTS from the peer
// This is to prevent flooding or spamming. Receipt of mtENDPOINTS
// sooner than the allotted time should impose a load charge.
//
RelativeTime mutable whenReceiveEndpoints;
// All the Endpoint records we have received from this peer
Endpoints mutable endpoints;
};
}
}
#endif

View File

@@ -0,0 +1,99 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
namespace ripple {
namespace PeerFinder {
Slots::Slots ()
: startTime (0)
, peerCount (0)
, inboundCount (0)
, outboundCount (0)
, outDesired (0)
, inboundSlots (0)
, inboundSlotsMaximum (0)
, m_roundUpwards (Random::getSystemRandom().nextBool())
{
}
void Slots::update (Config const& config)
{
if (! config.wantIncoming)
{
inboundSlots = 0;
inboundSlotsMaximum = 0;
}
else
{
double outDesiredFraction (
config.maxPeerCount * (Config::outPercent * .01));
if (m_roundUpwards)
outDesired = int (std::ceil (outDesiredFraction));
else
outDesired = int (std::floor (outDesiredFraction));
if (outDesired < Config::minOutCount)
outDesired = Config::minOutCount;
if (config.maxPeerCount >= outDesired)
inboundSlotsMaximum = config.maxPeerCount - outDesired;
else
inboundSlotsMaximum = 0;
inboundSlots = std::max (inboundSlotsMaximum - inboundCount, 0);
}
}
void Slots::addPeer (Config const& config, bool inbound)
{
if (peerCount == 0)
startTime = Time::getCurrentTime();
++peerCount;
if (inbound)
++inboundCount;
else
++outboundCount;
update (config);
}
void Slots::dropPeer (Config const& config, bool inbound)
{
--peerCount;
if (inbound)
--inboundCount;
else
--outboundCount;
if (peerCount == 0)
startTime = Time (0);
update (config);
}
uint32 Slots::uptimeMinutes () const
{
if (startTime.isNotNull())
return (Time::getCurrentTime()-startTime).inMinutes();
return 0;
}
}
}

View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_SLOTS_H_INCLUDED
#define RIPPLE_PEERFINDER_SLOTS_H_INCLUDED
#include "../api/Config.h"
namespace ripple {
namespace PeerFinder {
class Slots
{
public:
Slots ();
void update (Config const& config);
void addPeer (Config const& config, bool inbound);
void dropPeer (Config const& config, bool inbound);
uint32 uptimeMinutes () const;
// Most recent time when we went from 0 to 1 peers
Time startTime;
// Current total of connected peers that have HELLOed
int peerCount;
// The portion of peers which are incoming connections
int inboundCount;
// The portion of peers which are outgoing connections
int outboundCount;
// The number of outgoing peer connections we want (calculated)
int outDesired;
// The number of available incoming slots (calculated)
int inboundSlots;
// The maximum number of incoming slots (calculated)
int inboundSlotsMaximum;
private:
bool m_roundUpwards;
};
}
}
#endif

View File

@@ -0,0 +1,42 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_SOURCE_H_INCLUDED
#define RIPPLE_PEERFINDER_SOURCE_H_INCLUDED
namespace ripple {
namespace PeerFinder {
/** A source of IPEndpoint for peers. */
class Source
{
public:
typedef std::vector <IPEndpoint> IPEndpoints;
virtual ~Source () { }
virtual std::string const& name () = 0;
virtual void cancel () { }
virtual void fetch (IPEndpoints& list, Journal journal) = 0;
};
}
}
#endif

View File

@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "SourceStrings.h"
namespace ripple {
namespace PeerFinder {
class SourceStringsImp : public SourceStrings
{
public:
SourceStringsImp (std::string const& name, Strings const& strings)
: m_name (name)
, m_strings (strings)
{
}
~SourceStringsImp ()
{
}
std::string const& name ()
{
return m_name;
}
void fetch (IPEndpoints& list, Journal journal)
{
list.resize (0);
list.reserve (m_strings.size());
for (int i = 0; i < m_strings.size (); ++i)
{
IPEndpoint ep (
IPEndpoint::from_string_altform (
m_strings [i]));
if (! ep.empty())
list.push_back (ep);
}
}
private:
std::string m_name;
Strings m_strings;
};
//------------------------------------------------------------------------------
SourceStrings* SourceStrings::New (std::string const& name, Strings const& strings)
{
return new SourceStringsImp (name, strings);
}
}
}

View File

@@ -0,0 +1,40 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_SOURCESTRINGS_H_INCLUDED
#define RIPPLE_PEERFINDER_SOURCESTRINGS_H_INCLUDED
#include "Source.h"
namespace ripple {
namespace PeerFinder {
/** Provides an IPEndpoint list from a set of strings. */
class SourceStrings : public Source
{
public:
typedef std::vector <std::string> Strings;
static SourceStrings* New (std::string const& name, Strings const& strings);
};
}
}
#endif

View File

@@ -0,0 +1,42 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_STORE_H_INCLUDED
#define RIPPLE_PEERFINDER_STORE_H_INCLUDED
namespace ripple {
namespace PeerFinder {
/** Abstract persistence for PeerFinder data. */
class Store
{
public:
virtual ~Store () { }
virtual void loadLegacyEndpoints (
std::vector <IPEndpoint>& list) = 0;
virtual void storeLegacyEndpoints (
std::vector <IPEndpoint> const& list) = 0;
};
}
}
#endif

View File

@@ -0,0 +1,202 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_STORESQDB_H_INCLUDED
#define RIPPLE_PEERFINDER_STORESQDB_H_INCLUDED
#include "beast/modules/beast_sqdb/beast_sqdb.h"
#include "Store.h"
namespace ripple {
namespace PeerFinder {
/** Database persistence for PeerFinder using SQLite */
class StoreSqdb : public Store
{
private:
Journal m_journal;
sqdb::session m_session;
public:
explicit StoreSqdb (Journal journal = Journal())
: m_journal (journal)
{
}
~StoreSqdb ()
{
}
Error open (File const& file)
{
Error error (m_session.open (file.getFullPathName ()));
if (!error)
error = init ();
return error;
}
void loadLegacyEndpoints (
std::vector <IPEndpoint>& list)
{
list.clear ();
Error error;
// Get the count
std::size_t count;
if (! error)
{
m_session.once (error) <<
"SELECT COUNT(*) FROM LegacyEndpoints "
,sqdb::into (count)
;
}
if (error)
{
report (error, __FILE__, __LINE__);
return;
}
list.reserve (count);
{
std::string s;
sqdb::statement st = (m_session.prepare <<
"SELECT ipv4 FROM LegacyEndpoints "
,sqdb::into (s)
);
if (st.execute_and_fetch (error))
{
do
{
IPEndpoint ep (IPEndpoint::from_string (s));
if (! ep.empty())
list.push_back (ep);
}
while (st.fetch (error));
}
}
if (error)
{
report (error, __FILE__, __LINE__);
}
}
void storeLegacyEndpoints (
std::vector <IPEndpoint> const& list)
{
typedef std::vector <IPEndpoint> List;
Error error;
sqdb::transaction tr (m_session);
m_session.once (error) <<
"DELETE FROM LegacyEndpoints";
if (! error)
{
std::string s;
sqdb::statement st = (m_session.prepare <<
"INSERT INTO LegacyEndpoints ( "
" ipv4 "
") VALUES ( "
" ? "
");"
,sqdb::use (s)
);
for (List::const_iterator iter (list.begin());
!error && iter != list.end(); ++iter)
{
IPEndpoint const& ep (*iter);
s = ep.to_string();
st.execute_and_fetch (error);
}
}
if (! error)
{
error = tr.commit();
}
if (error)
{
tr.rollback ();
report (error, __FILE__, __LINE__);
}
}
private:
Error init ()
{
Error error;
sqdb::transaction tr (m_session);
if (! error)
{
m_session.once (error) <<
"PRAGMA encoding=\"UTF-8\"";
}
if (! error)
{
m_session.once (error) <<
"CREATE TABLE IF NOT EXISTS LegacyEndpoints ( "
" id INTEGER PRIMARY KEY AUTOINCREMENT, "
" ipv4 TEXT UNIQUE NOT NULL "
");"
;
}
if (! error)
{
error = tr.commit();
}
if (error)
{
tr.rollback ();
report (error, __FILE__, __LINE__);
}
return error;
}
void report (Error const& error, char const* fileName, int lineNumber)
{
if (error)
{
m_journal.error <<
"Failure: '"<< error.getReasonText() << "' " <<
" at " << Debug::getSourceLocation (fileName, lineNumber);
}
}
};
}
}
#endif

View File

@@ -0,0 +1,42 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "Logic.h"
namespace ripple {
namespace PeerFinder {
class PeerFinderTests : public UnitTest
{
public:
void runTest ()
{
beginTestCase ("logic");
pass ();
}
PeerFinderTests () : UnitTest ("PeerFinder", "ripple", runManual)
{
}
};
static PeerFinderTests peerFinderTests;
}
}

View File

@@ -0,0 +1,37 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "BeastConfig.h"
#include "ripple_peerfinder.h"
namespace ripple {
using namespace beast;
}
# include "impl/Source.h"
# include "impl/SourceStrings.h"
#include "impl/SourceStrings.cpp"
#include "impl/Config.cpp"
#include "impl/Endpoint.cpp"
#include "impl/EndpointCache.cpp"
#include "impl/Manager.cpp"
#include "impl/Slots.cpp"
#include "impl/Tests.cpp"

View File

@@ -0,0 +1,37 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_H_INCLUDED
#define RIPPLE_PEERFINDER_H_INCLUDED
#include "beast/modules/beast_core/beast_core.h"
namespace ripple {
using namespace beast;
}
#include "../types/api/RipplePublicKey.h"
#include "api/Types.h"
#include "api/Endpoint.h"
#include "api/Config.h"
#include "api/Callback.h"
#include "api/Manager.h"
#endif

View File

@@ -18,11 +18,10 @@
//============================================================================== //==============================================================================
#ifndef RIPPLE_VALIDATORS_AGEDHISTORY_H_INCLUDED #ifndef RIPPLE_TYPES_AGEDHISTORY_H_INCLUDED
#define RIPPLE_VALIDATORS_AGEDHISTORY_H_INCLUDED #define RIPPLE_TYPES_AGEDHISTORY_H_INCLUDED
namespace ripple { namespace ripple {
namespace Validators {
// Simple container swapping template // Simple container swapping template
template <class Container> template <class Container>
@@ -71,7 +70,6 @@ private:
Container* m_p2; Container* m_p2;
}; };
}
} }
#endif #endif

View File

@@ -21,6 +21,9 @@
#ifndef RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED #ifndef RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED
#define RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED #define RIPPLE_TYPES_RIPPLEPUBLICKEY_H_INCLUDED
#include "CryptoIdentifier.h"
#include "IdentifierType.h"
namespace ripple { namespace ripple {
class RipplePublicKeyTraits class RipplePublicKeyTraits

View File

@@ -42,6 +42,7 @@ namespace ripple {
using namespace beast; using namespace beast;
} }
#include "api/AgedHistory.h"
# include "api/Blob.h" # include "api/Blob.h"
# include "api/Base58.h" # include "api/Base58.h"
# include "api/ByteOrder.h" # include "api/ByteOrder.h"

View File

@@ -20,8 +20,6 @@
#ifndef RIPPLE_VALIDATORS_LOGIC_H_INCLUDED #ifndef RIPPLE_VALIDATORS_LOGIC_H_INCLUDED
#define RIPPLE_VALIDATORS_LOGIC_H_INCLUDED #define RIPPLE_VALIDATORS_LOGIC_H_INCLUDED
#include "AgedHistory.h"
namespace ripple { namespace ripple {
namespace Validators { namespace Validators {

View File

@@ -253,7 +253,7 @@ public:
void onPrepare (Journal journal) void onPrepare (Journal journal)
{ {
#if RIPPLE_USE_NEW_VALIDATORS #if RIPPLE_USE_NEW_VALIDATORS
journal.info << "Preparing"; journal.info << "Validators preparing";
addRPCHandlers(); addRPCHandlers();
#endif #endif
@@ -262,7 +262,7 @@ public:
void onStart (Journal journal) void onStart (Journal journal)
{ {
#if RIPPLE_USE_NEW_VALIDATORS #if RIPPLE_USE_NEW_VALIDATORS
journal.info << "Starting"; journal.info << "Validators starting";
// Do this late so the sources have a chance to be added. // Do this late so the sources have a chance to be added.
m_queue.dispatch (bind (&ManagerImp::setCheckSources, this)); m_queue.dispatch (bind (&ManagerImp::setCheckSources, this));
@@ -273,7 +273,7 @@ public:
void onStop (Journal journal) void onStop (Journal journal)
{ {
journal.info << "Stopping"; journal.info << "Validators stopping";
if (this->Thread::isThreadRunning()) if (this->Thread::isThreadRunning())
{ {

View File

@@ -159,11 +159,12 @@ void StoreSqdb::update (SourceDesc& desc, bool updateFetchResults)
if (! error) if (! error)
{ {
error = tr.commit (); error = tr.commit();
} }
if (error) if (error)
{ {
tr.rollback ();
report (error, __FILE__, __LINE__); report (error, __FILE__, __LINE__);
} }
} }

View File

@@ -51,8 +51,7 @@ class ApplicationImp
: public Application : public Application
, public RootStoppable , public RootStoppable
, public DeadlineTimer::Listener , public DeadlineTimer::Listener
, LeakChecked <ApplicationImp> , public LeakChecked <ApplicationImp>
, PeerFinder::Callback
{ {
private: private:
static ApplicationImp* s_instance; static ApplicationImp* s_instance;
@@ -136,8 +135,6 @@ public:
, m_loadManager (LoadManager::New (*this, LogJournal::get <LoadManagerLog> ())) , m_loadManager (LoadManager::New (*this, LogJournal::get <LoadManagerLog> ()))
, mPeerFinder (PeerFinder::New (*this))
, m_sweepTimer (this) , m_sweepTimer (this)
, mShutdown (false) , mShutdown (false)
@@ -283,11 +280,6 @@ public:
return *m_peers; return *m_peers;
} }
PeerFinder& getPeerFinder ()
{
return *mPeerFinder;
}
// VFALCO TODO Move these to the .cpp // VFALCO TODO Move these to the .cpp
bool running () bool running ()
{ {
@@ -861,7 +853,6 @@ private:
ScopedPointer <Validations> mValidations; ScopedPointer <Validations> mValidations;
ScopedPointer <ProofOfWorkFactory> mProofOfWorkFactory; ScopedPointer <ProofOfWorkFactory> mProofOfWorkFactory;
ScopedPointer <LoadManager> m_loadManager; ScopedPointer <LoadManager> m_loadManager;
ScopedPointer <PeerFinder> mPeerFinder;
DeadlineTimer m_sweepTimer; DeadlineTimer m_sweepTimer;
bool volatile mShutdown; bool volatile mShutdown;

View File

@@ -43,7 +43,6 @@ class SerializedLedgerEntry;
class TransactionMaster; class TransactionMaster;
class TxQueue; class TxQueue;
class LocalCredentials; class LocalCredentials;
class PeerFinder;
class DatabaseCon; class DatabaseCon;
@@ -113,7 +112,6 @@ public:
virtual TransactionMaster& getMasterTransaction () = 0; virtual TransactionMaster& getMasterTransaction () = 0;
virtual TxQueue& getTxQueue () = 0; virtual TxQueue& getTxQueue () = 0;
virtual LocalCredentials& getLocalCredentials () = 0; virtual LocalCredentials& getLocalCredentials () = 0;
virtual PeerFinder& getPeerFinder () = 0;
virtual DatabaseCon* getRpcDB () = 0; virtual DatabaseCon* getRpcDB () = 0;
virtual DatabaseCon* getTxnDB () = 0; virtual DatabaseCon* getTxnDB () = 0;

View File

@@ -17,13 +17,12 @@
*/ */
//============================================================================== //==============================================================================
SETUP_LOG (Peer) SETUP_LOG (Peer)
class PeerImp; class PeerImp;
// Don't try to run past receiving nonsense from a peer // Don't try to run past receiving nonsense from a peer
// #define TRUST_NETWORK // #define TRUST_NETWORKHEAD
// Node has this long to verify its identity from connection accepted or connection attempt. // Node has this long to verify its identity from connection accepted or connection attempt.
#define NODE_VERIFY_SECONDS 15 #define NODE_VERIFY_SECONDS 15
@@ -41,11 +40,6 @@ private:
public: public:
//---------------------------------------------------------------------------
//
//
//
ScopedPointer <MultiSocket> m_socket; ScopedPointer <MultiSocket> m_socket;
boost::asio::io_service::strand m_strand; boost::asio::io_service::strand m_strand;
@@ -64,12 +58,6 @@ public:
return *m_socket; return *m_socket;
} }
//
//
//
//---------------------------------------------------------------------------
public:
PeerImp (boost::asio::io_service& io_service, PeerImp (boost::asio::io_service& io_service,
boost::asio::ssl::context& ssl_context, boost::asio::ssl::context& ssl_context,
uint64 peerID, uint64 peerID,
@@ -89,6 +77,7 @@ public:
, mMinLedger (0) , mMinLedger (0)
, mMaxLedger (0) , mMaxLedger (0)
, mActivityTimer (io_service) , mActivityTimer (io_service)
, m_remoteAddressSet (false)
{ {
WriteLog (lsDEBUG, Peer) << "CREATING PEER: " << addressToString (this); WriteLog (lsDEBUG, Peer) << "CREATING PEER: " << addressToString (this);
} }
@@ -126,6 +115,9 @@ private:
protocol::TMStatusChange mLastStatus; protocol::TMStatusChange mLastStatus;
protocol::TMHello mHello; protocol::TMHello mHello;
bool m_remoteAddressSet;
IPEndpoint m_remoteAddress;
public: public:
static char const* getCountedObjectName () { return "Peer"; } static char const* getCountedObjectName () { return "Peer"; }
@@ -308,6 +300,14 @@ private:
if (proxyInfo.protocol == "TCP4") if (proxyInfo.protocol == "TCP4")
{ {
m_remoteAddressSet = true;
m_remoteAddress = IPEndpoint (IPEndpoint::V4 (
proxyInfo.sourceAddress.value [0],
proxyInfo.sourceAddress.value [1],
proxyInfo.sourceAddress.value [2],
proxyInfo.sourceAddress.value [3]),
proxyInfo.sourcePort);
// Set remote IP and port number from PROXY handshake // Set remote IP and port number from PROXY handshake
mIpPort.first = proxyInfo.sourceAddress.toString ().toStdString (); mIpPort.first = proxyInfo.sourceAddress.toString ().toStdString ();
mIpPort.second = proxyInfo.sourcePort; mIpPort.second = proxyInfo.sourcePort;
@@ -362,6 +362,7 @@ private:
void recvGetContacts (protocol::TMGetContacts & packet); void recvGetContacts (protocol::TMGetContacts & packet);
void recvGetPeers (protocol::TMGetPeers & packet, Application::ScopedLockType& masterLockHolder); void recvGetPeers (protocol::TMGetPeers & packet, Application::ScopedLockType& masterLockHolder);
void recvPeers (protocol::TMPeers & packet); void recvPeers (protocol::TMPeers & packet);
void recvEndpoints (protocol::TMEndpoints & packet);
void recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& packet); void recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& packet);
void recvPing (protocol::TMPing & packet); void recvPing (protocol::TMPing & packet);
void recvErrorMessage (protocol::TMErrorMsg & packet); void recvErrorMessage (protocol::TMErrorMsg & packet);
@@ -390,7 +391,7 @@ void PeerImp::handleWrite (const boost::system::error_code& error, size_t bytes_
// Call on IO strand // Call on IO strand
#ifdef BEAST_DEBUG #ifdef BEAST_DEBUG
// if (!error) // if (!error)
// Log::out() << "PeerImp::handleWrite bytes: "<< bytes_transferred; // Log::out() << "Peer::handleWrite bytes: "<< bytes_transferred;
#endif #endif
mSendingPacket.reset (); mSendingPacket.reset ();
@@ -463,6 +464,8 @@ void PeerImp::detach (const char* rsn, bool onIOStrand)
{ {
getApp().getPeers ().peerDisconnected (shared_from_this (), mNodePublic); getApp().getPeers ().peerDisconnected (shared_from_this (), mNodePublic);
getApp().getPeers().getPeerFinder().onPeerDisconnected (RipplePublicKey (mNodePublic));
mNodePublic.clear (); // Be idempotent. mNodePublic.clear (); // Be idempotent.
} }
@@ -739,9 +742,9 @@ void PeerImp::processReadBuffer ()
// Log::out() << "PRB(" << type << "), len=" << (mReadbuf.size()-PackedMessage::kHeaderBytes); // Log::out() << "PRB(" << type << "), len=" << (mReadbuf.size()-PackedMessage::kHeaderBytes);
#endif #endif
// Log::out() << "PeerImp::processReadBuffer: " << mIpPort.first << " " << mIpPort.second; // Log::out() << "Peer::processReadBuffer: " << mIpPort.first << " " << mIpPort.second;
LoadEvent::autoptr event (getApp().getJobQueue ().getLoadEventAP (jtPEER, "PeerImp::read")); LoadEvent::autoptr event (getApp().getJobQueue ().getLoadEventAP (jtPEER, "Peer::read"));
{ {
Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__); Application::ScopedLockType lock (getApp ().getMasterLock (), __FILE__, __LINE__);
@@ -758,7 +761,7 @@ void PeerImp::processReadBuffer ()
{ {
case protocol::mtHELLO: case protocol::mtHELLO:
{ {
event->reName ("PeerImp::hello"); event->reName ("Peer::hello");
protocol::TMHello msg; protocol::TMHello msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -770,7 +773,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtCLUSTER: case protocol::mtCLUSTER:
{ {
event->reName ("PeerImp::cluster"); event->reName ("Peer::cluster");
protocol::TMCluster msg; protocol::TMCluster msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -781,7 +784,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtERROR_MSG: case protocol::mtERROR_MSG:
{ {
event->reName ("PeerImp::errormessage"); event->reName ("Peer::errormessage");
protocol::TMErrorMsg msg; protocol::TMErrorMsg msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -793,7 +796,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtPING: case protocol::mtPING:
{ {
event->reName ("PeerImp::ping"); event->reName ("Peer::ping");
protocol::TMPing msg; protocol::TMPing msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -805,7 +808,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtGET_CONTACTS: case protocol::mtGET_CONTACTS:
{ {
event->reName ("PeerImp::getcontacts"); event->reName ("Peer::getcontacts");
protocol::TMGetContacts msg; protocol::TMGetContacts msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -817,7 +820,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtCONTACT: case protocol::mtCONTACT:
{ {
event->reName ("PeerImp::contact"); event->reName ("Peer::contact");
protocol::TMContact msg; protocol::TMContact msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -829,7 +832,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtGET_PEERS: case protocol::mtGET_PEERS:
{ {
event->reName ("PeerImp::getpeers"); event->reName ("Peer::getpeers");
protocol::TMGetPeers msg; protocol::TMGetPeers msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -841,7 +844,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtPEERS: case protocol::mtPEERS:
{ {
event->reName ("PeerImp::peers"); event->reName ("Peer::peers");
protocol::TMPeers msg; protocol::TMPeers msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -851,9 +854,21 @@ void PeerImp::processReadBuffer ()
} }
break; break;
case protocol::mtENDPOINTS:
{
event->reName ("Peer::endpoints");
protocol::TMEndpoints msg;
if(msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size() - PackedMessage::kHeaderBytes))
recvEndpoints (msg);
else
WriteLog (lsWARNING, Peer) << "parse error: " << type;
}
break;
case protocol::mtSEARCH_TRANSACTION: case protocol::mtSEARCH_TRANSACTION:
{ {
event->reName ("PeerImp::searchtransaction"); event->reName ("Peer::searchtransaction");
protocol::TMSearchTransaction msg; protocol::TMSearchTransaction msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -865,7 +880,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtGET_ACCOUNT: case protocol::mtGET_ACCOUNT:
{ {
event->reName ("PeerImp::getaccount"); event->reName ("Peer::getaccount");
protocol::TMGetAccount msg; protocol::TMGetAccount msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -877,7 +892,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtACCOUNT: case protocol::mtACCOUNT:
{ {
event->reName ("PeerImp::account"); event->reName ("Peer::account");
protocol::TMAccount msg; protocol::TMAccount msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -889,7 +904,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtTRANSACTION: case protocol::mtTRANSACTION:
{ {
event->reName ("PeerImp::transaction"); event->reName ("Peer::transaction");
protocol::TMTransaction msg; protocol::TMTransaction msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -901,7 +916,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtSTATUS_CHANGE: case protocol::mtSTATUS_CHANGE:
{ {
event->reName ("PeerImp::statuschange"); event->reName ("Peer::statuschange");
protocol::TMStatusChange msg; protocol::TMStatusChange msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -913,7 +928,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtPROPOSE_LEDGER: case protocol::mtPROPOSE_LEDGER:
{ {
event->reName ("PeerImp::propose"); event->reName ("Peer::propose");
boost::shared_ptr<protocol::TMProposeSet> msg = boost::make_shared<protocol::TMProposeSet> (); boost::shared_ptr<protocol::TMProposeSet> msg = boost::make_shared<protocol::TMProposeSet> ();
if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -925,7 +940,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtGET_LEDGER: case protocol::mtGET_LEDGER:
{ {
event->reName ("PeerImp::getledger"); event->reName ("Peer::getledger");
protocol::TMGetLedger msg; protocol::TMGetLedger msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -937,7 +952,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtLEDGER_DATA: case protocol::mtLEDGER_DATA:
{ {
event->reName ("PeerImp::ledgerdata"); event->reName ("Peer::ledgerdata");
boost::shared_ptr<protocol::TMLedgerData> msg = boost::make_shared<protocol::TMLedgerData> (); boost::shared_ptr<protocol::TMLedgerData> msg = boost::make_shared<protocol::TMLedgerData> ();
if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -949,7 +964,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtHAVE_SET: case protocol::mtHAVE_SET:
{ {
event->reName ("PeerImp::haveset"); event->reName ("Peer::haveset");
protocol::TMHaveTransactionSet msg; protocol::TMHaveTransactionSet msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -961,7 +976,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtVALIDATION: case protocol::mtVALIDATION:
{ {
event->reName ("PeerImp::validation"); event->reName ("Peer::validation");
boost::shared_ptr<protocol::TMValidation> msg = boost::make_shared<protocol::TMValidation> (); boost::shared_ptr<protocol::TMValidation> msg = boost::make_shared<protocol::TMValidation> ();
if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -987,7 +1002,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtGET_OBJECTS: case protocol::mtGET_OBJECTS:
{ {
event->reName ("PeerImp::getobjects"); event->reName ("Peer::getobjects");
boost::shared_ptr<protocol::TMGetObjectByHash> msg = boost::make_shared<protocol::TMGetObjectByHash> (); boost::shared_ptr<protocol::TMGetObjectByHash> msg = boost::make_shared<protocol::TMGetObjectByHash> ();
if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg->ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -999,7 +1014,7 @@ void PeerImp::processReadBuffer ()
case protocol::mtPROOFOFWORK: case protocol::mtPROOFOFWORK:
{ {
event->reName ("PeerImp::proofofwork"); event->reName ("Peer::proofofwork");
protocol::TMProofWork msg; protocol::TMProofWork msg;
if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes)) if (msg.ParseFromArray (&mReadbuf[PackedMessage::kHeaderBytes], mReadbuf.size () - PackedMessage::kHeaderBytes))
@@ -1011,7 +1026,7 @@ void PeerImp::processReadBuffer ()
default: default:
event->reName ("PeerImp::unknown"); event->reName ("Peer::unknown");
WriteLog (lsWARNING, Peer) << "Unknown Msg: " << type; WriteLog (lsWARNING, Peer) << "Unknown Msg: " << type;
WriteLog (lsWARNING, Peer) << strHex (&mReadbuf[0], mReadbuf.size ()); WriteLog (lsWARNING, Peer) << strHex (&mReadbuf[0], mReadbuf.size ());
} }
@@ -1033,7 +1048,6 @@ void PeerImp::recvHello (protocol::TMHello& packet)
uint32 maxTime = ourTime + 20; uint32 maxTime = ourTime + 20;
#ifdef BEAST_DEBUG #ifdef BEAST_DEBUG
if (packet.has_nettime ()) if (packet.has_nettime ())
{ {
int64 to = ourTime; int64 to = ourTime;
@@ -1137,6 +1151,23 @@ void PeerImp::recvHello (protocol::TMHello& packet)
// Consider us connected. No longer accepting mtHELLO. // Consider us connected. No longer accepting mtHELLO.
mHelloed = true; mHelloed = true;
{
if (! m_remoteAddressSet)
{
boost::asio::ip::address addr (
getNativeSocket().remote_endpoint().address());
if (addr.is_v4())
{
boost::asio::ip::address_v4::bytes_type bytes (addr.to_v4().to_bytes());
m_remoteAddress = IPEndpoint (IPEndpoint::V4 (
bytes[0], bytes[1], bytes[2], bytes[3]), 0);
}
}
getApp().getPeers().getPeerFinder().onPeerConnected (
RipplePublicKey (mNodePublic), m_remoteAddress, m_isInbound);
}
// XXX Set timer: connection is in grace period to be useful. // XXX Set timer: connection is in grace period to be useful.
// XXX Set timer: connection idle (idle may vary depending on connection type.) // XXX Set timer: connection idle (idle may vary depending on connection type.)
@@ -1617,6 +1648,12 @@ void PeerImp::recvPeers (protocol::TMPeers& packet)
addr.s_addr = packet.nodes (i).ipv4 (); addr.s_addr = packet.nodes (i).ipv4 ();
{
IPEndpoint::V4 v4 (ntohl (addr.s_addr));
IPEndpoint ep (v4, packet.nodes (i).ipv4port ());
getApp().getPeers().getPeerFinder().onPeerLegacyEndpoint (ep);
}
std::string strIP (inet_ntoa (addr)); std::string strIP (inet_ntoa (addr));
int iPort = packet.nodes (i).ipv4port (); int iPort = packet.nodes (i).ipv4port ();
@@ -1629,6 +1666,58 @@ void PeerImp::recvPeers (protocol::TMPeers& packet)
} }
} }
void PeerImp::recvEndpoints (protocol::TMEndpoints& packet)
{
std::vector <PeerFinder::Endpoint> endpoints;
endpoints.reserve (packet.endpoints().size());
for (int i = 0; i < packet.endpoints ().size (); ++i)
{
PeerFinder::Endpoint endpoint;
protocol::TMEndpoint const& tm (packet.endpoints(i));
// hops
endpoint.hops = tm.hops();
// ipv4
if (endpoint.hops > 0)
{
in_addr addr;
addr.s_addr = tm.ipv4().ipv4();
IPEndpoint::V4 v4 (ntohl (addr.s_addr));
endpoint.address = IPEndpoint (v4, 0);
endpoint.port = tm.ipv4().ipv4port ();
}
else
{
// This Endpoint describes the peer we are connected to.
// We will take the remote address seen on the socket and
// store that in the Endpoint. If this is the first time,
// then we'll verify that their listener can receive incoming
// by performing a connectivity test.
//
bassert (m_remoteAddressSet);
endpoint.address = m_remoteAddress.withPort (0);
endpoint.port = tm.ipv4().ipv4port ();
}
// slots
endpoint.incomingSlotsAvailable = tm.slots();
// maxSlots
endpoint.incomingSlotsMax = tm.maxslots();
// uptimeMinutes
endpoint.uptimeMinutes = tm.uptimeminutes();
endpoints.push_back (endpoint);
}
getApp().getPeers().getPeerFinder().onPeerEndpoints (
PeerFinder::PeerID (mNodePublic), endpoints);
}
void PeerImp::recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& ptr) void PeerImp::recvGetObjectByHash (const boost::shared_ptr<protocol::TMGetObjectByHash>& ptr)
{ {
protocol::TMGetObjectByHash& packet = *ptr; protocol::TMGetObjectByHash& packet = *ptr;

View File

@@ -17,26 +17,82 @@
*/ */
//============================================================================== //==============================================================================
SETUP_LOG (Peers) SETUP_LOG (Peers)
class PeerFinderLog;
template <> char const* LogPartition::getPartitionName <PeerFinderLog> () { return "PeerFinder"; }
class PeersImp class PeersImp
: public Peers : public Peers
, public Stoppable , public Stoppable
, public PeerFinder::Callback
, public LeakChecked <PeersImp> , public LeakChecked <PeersImp>
{ {
public: public:
enum enum
{ {
/** Frequency of policy enforcement. /** Frequency of policy enforcement. */
*/
policyIntervalSeconds = 5 policyIntervalSeconds = 5
}; };
typedef RippleRecursiveMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
typedef std::pair<RippleAddress, Peer::pointer> naPeer;
typedef std::pair<IPAndPortNumber, Peer::pointer> pipPeer;
typedef std::map<IPAndPortNumber, Peer::pointer>::value_type vtPeer;
ScopedPointer <PeerFinder::Manager> m_peerFinder;
boost::asio::io_service& m_io_service;
boost::asio::ssl::context& m_ssl_context;
LockType mPeerLock;
uint64 mLastPeer;
int mPhase;
// PeersImp we are connecting with and non-thin peers we are connected to.
// Only peers we know the connection ip for are listed.
// We know the ip and port for:
// - All outbound connections
// - Some inbound connections (which we figured out).
boost::unordered_map<IPAndPortNumber, Peer::pointer> mIpMap;
// Non-thin peers which we are connected to.
// PeersImp we have the public key for.
typedef boost::unordered_map<RippleAddress, Peer::pointer>::value_type vtConMap;
boost::unordered_map<RippleAddress, Peer::pointer> mConnectedMap;
// Connections with have a 64-bit identifier
boost::unordered_map<uint64, Peer::pointer> mPeerIdMap;
Peer::pointer mScanning;
boost::asio::deadline_timer mScanTimer;
std::string mScanIp;
int mScanPort;
void scanHandler (const boost::system::error_code& ecResult);
boost::asio::deadline_timer mPolicyTimer;
void policyHandler (const boost::system::error_code& ecResult);
// PeersImp we are establishing a connection with as a client.
// int miConnectStarting;
bool peerAvailable (std::string& strIp, int& iPort);
bool peerScanSet (const std::string& strIp, int iPort);
Peer::pointer peerConnect (const std::string& strIp, int iPort);
//--------------------------------------------------------------------------
PeersImp (Stoppable& parent, PeersImp (Stoppable& parent,
boost::asio::io_service& io_service, boost::asio::io_service& io_service,
boost::asio::ssl::context& ssl_context) boost::asio::ssl::context& ssl_context)
: Stoppable ("Peers", parent) : Stoppable ("Peers", parent)
, m_peerFinder (PeerFinder::Manager::New (
*this, *this, LogJournal::get <PeerFinderLog> ()))
, m_io_service (io_service) , m_io_service (io_service)
, m_ssl_context (ssl_context) , m_ssl_context (ssl_context)
, mPeerLock (this, "PeersImp", __FILE__, __LINE__) , mPeerLock (this, "PeersImp", __FILE__, __LINE__)
@@ -47,6 +103,127 @@ public:
{ {
} }
//--------------------------------------------------------------------------
//
// PeerFinder
//
// Maps Config settings to PeerFinder::Config
void preparePeerFinder()
{
PeerFinder::Config config;
// config.maxPeerCount = ?
config.wantIncoming =
(! getConfig ().PEER_PRIVATE) &&
(getConfig().peerListeningPort != 0);
if (config.wantIncoming)
config.listeningPort = getConfig().peerListeningPort;
config.featureList = "";
m_peerFinder->setConfig (config);
// Add the static IPs from the rippled.cfg file
m_peerFinder->addStrings ("rippled.cfg", getConfig().IPS);
}
void sendPeerEndpoints (PeerFinder::PeerID const& id,
std::vector <PeerFinder::Endpoint> const& endpoints)
{
bassert (! endpoints.empty());
typedef std::vector <PeerFinder::Endpoint> List;
protocol::TMEndpoints tm;
for (List::const_iterator iter (endpoints.begin());
iter != endpoints.end(); ++iter)
{
PeerFinder::Endpoint const& ep (*iter);
protocol::TMEndpoint& tme (*tm.add_endpoints());
if (ep.address.isV4())
tme.mutable_ipv4()->set_ipv4(
toNetworkByteOrder (ep.address.v4().value));
else
tme.mutable_ipv4()->set_ipv4(0);
tme.mutable_ipv4()->set_ipv4port (ep.port);
tme.set_hops (ep.hops);
tme.set_slots (ep.incomingSlotsAvailable);
tme.set_maxslots (ep.incomingSlotsMax);
tme.set_uptimeminutes (ep.uptimeMinutes);
tme.set_features (ep.featureList);
}
PackedMessage::pointer msg (
boost::make_shared <PackedMessage> (
tm, protocol::mtENDPOINTS));
std::vector <Peer::pointer> list = getPeerVector ();
BOOST_FOREACH (Peer::ref peer, list)
{
if (peer->isConnected() &&
PeerFinder::PeerID (peer->getNodePublic()) == id)
{
peer->sendPacket (msg, false);
break;
}
}
}
void connectPeerEndpoints (std::vector <IPEndpoint> const& list)
{
typedef std::vector <IPEndpoint> List;
for (List::const_iterator iter (list.begin());
iter != list.end(); ++iter)
peerConnect (iter->withPort (0), iter->port());
}
void chargePeerLoadPenalty (PeerFinder::PeerID const& id)
{
std::vector <Peer::pointer> list = getPeerVector ();
BOOST_FOREACH (Peer::ref peer, list)
{
if (peer->isConnected() &&
PeerFinder::PeerID (peer->getNodePublic()) == id)
{
peer->applyLoadCharge (LT_UnwantedData);
break;
}
}
}
//--------------------------------------------------------------------------
//
// Stoppable
//
void onPrepare (Journal)
{
preparePeerFinder();
}
void onStart (Journal)
{
}
void onStop (Journal)
{
// VFALCO TODO Clean this up and do it right, based on sockets
stopped();
}
//--------------------------------------------------------------------------
PeerFinder::Manager& getPeerFinder()
{
return *m_peerFinder;
}
// Begin enforcing connection policy. // Begin enforcing connection policy.
void start (); void start ();
@@ -102,55 +279,6 @@ public:
// configured connections // configured connections
void makeConfigured (); void makeConfigured ();
private:
typedef RippleRecursiveMutex LockType;
typedef LockType::ScopedLockType ScopedLockType;
typedef std::pair<RippleAddress, Peer::pointer> naPeer;
typedef std::pair<IPAndPortNumber, Peer::pointer> pipPeer;
typedef std::map<IPAndPortNumber, Peer::pointer>::value_type vtPeer;
boost::asio::io_service& m_io_service;
boost::asio::ssl::context& m_ssl_context;
LockType mPeerLock;
uint64 mLastPeer;
int mPhase;
// PeersImp we are connecting with and non-thin peers we are connected to.
// Only peers we know the connection ip for are listed.
// We know the ip and port for:
// - All outbound connections
// - Some inbound connections (which we figured out).
boost::unordered_map<IPAndPortNumber, Peer::pointer> mIpMap;
// Non-thin peers which we are connected to.
// PeersImp we have the public key for.
typedef boost::unordered_map<RippleAddress, Peer::pointer>::value_type vtConMap;
boost::unordered_map<RippleAddress, Peer::pointer> mConnectedMap;
// Connections with have a 64-bit identifier
boost::unordered_map<uint64, Peer::pointer> mPeerIdMap;
Peer::pointer mScanning;
boost::asio::deadline_timer mScanTimer;
std::string mScanIp;
int mScanPort;
void scanHandler (const boost::system::error_code& ecResult);
boost::asio::deadline_timer mPolicyTimer;
void policyHandler (const boost::system::error_code& ecResult);
// PeersImp we are establishing a connection with as a client.
// int miConnectStarting;
bool peerAvailable (std::string& strIp, int& iPort);
bool peerScanSet (const std::string& strIp, int iPort);
Peer::pointer peerConnect (const std::string& strIp, int iPort);
}; };
void splitIpPort (const std::string& strIpPort, std::string& strIp, int& iPort) void splitIpPort (const std::string& strIpPort, std::string& strIp, int& iPort)
@@ -167,16 +295,18 @@ void PeersImp::start ()
if (getConfig ().RUN_STANDALONE) if (getConfig ().RUN_STANDALONE)
return; return;
#if ! RIPPLE_USE_PEERFINDER
// Start running policy. // Start running policy.
policyEnforce (); policyEnforce ();
// Start scanning. // Start scanning.
scanRefresh (); scanRefresh ();
#endif
} }
bool PeersImp::getTopNAddrs (int n, std::vector<std::string>& addrs) bool PeersImp::getTopNAddrs (int n, std::vector<std::string>& addrs)
{ {
#if ! RIPPLE_USE_PEERFINDER
// Try current connections first // Try current connections first
std::vector<Peer::pointer> peers = getPeerVector(); std::vector<Peer::pointer> peers = getPeerVector();
BOOST_FOREACH(Peer::ref peer, peers) BOOST_FOREACH(Peer::ref peer, peers)
@@ -206,6 +336,7 @@ bool PeersImp::getTopNAddrs (int n, std::vector<std::string>& addrs)
} }
// FIXME: Should uniqify addrs // FIXME: Should uniqify addrs
#endif
return true; return true;
} }
@@ -214,6 +345,7 @@ bool PeersImp::savePeer (const std::string& strIp, int iPort, char code)
{ {
bool bNew = false; bool bNew = false;
#if ! RIPPLE_USE_PEERFINDER
Database* db = getApp().getWalletDB ()->getDB (); Database* db = getApp().getWalletDB ()->getDB ();
std::string ipAndPort = sqlEscape (str (boost::format ("%s %d") % strIp % iPort)); std::string ipAndPort = sqlEscape (str (boost::format ("%s %d") % strIp % iPort));
@@ -246,6 +378,7 @@ bool PeersImp::savePeer (const std::string& strIp, int iPort, char code)
if (bNew) if (bNew)
scanRefresh (); scanRefresh ();
#endif
return bNew; return bNew;
} }
@@ -362,6 +495,7 @@ void PeersImp::policyLowWater ()
void PeersImp::policyEnforce () void PeersImp::policyEnforce ()
{ {
#if ! RIPPLE_USE_PEERFINDER
// Cancel any in progress timer. // Cancel any in progress timer.
(void) mPolicyTimer.cancel (); (void) mPolicyTimer.cancel ();
@@ -378,6 +512,7 @@ void PeersImp::policyEnforce ()
// Schedule next enforcement. // Schedule next enforcement.
mPolicyTimer.expires_at (boost::posix_time::second_clock::universal_time () + boost::posix_time::seconds (policyIntervalSeconds)); mPolicyTimer.expires_at (boost::posix_time::second_clock::universal_time () + boost::posix_time::seconds (policyIntervalSeconds));
mPolicyTimer.async_wait (BIND_TYPE (&PeersImp::policyHandler, this, P_1)); mPolicyTimer.async_wait (BIND_TYPE (&PeersImp::policyHandler, this, P_1));
#endif
} }
void PeersImp::policyHandler (const boost::system::error_code& ecResult) void PeersImp::policyHandler (const boost::system::error_code& ecResult)
@@ -829,6 +964,7 @@ void PeersImp::makeConfigured ()
// Scan ips as per db entries. // Scan ips as per db entries.
void PeersImp::scanRefresh () void PeersImp::scanRefresh ()
{ {
#if ! RIPPLE_USE_PEERFINDER
if (getConfig ().RUN_STANDALONE) if (getConfig ().RUN_STANDALONE)
{ {
nothing (); nothing ();
@@ -922,6 +1058,7 @@ void PeersImp::scanRefresh ()
mScanTimer.async_wait (BIND_TYPE (&PeersImp::scanHandler, this, P_1)); mScanTimer.async_wait (BIND_TYPE (&PeersImp::scanHandler, this, P_1));
} }
} }
#endif
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -17,12 +17,14 @@
*/ */
//============================================================================== //==============================================================================
#ifndef RIPPLE_PEERS_H_INCLUDED #ifndef RIPPLE_PEERS_H_INCLUDED
#define RIPPLE_PEERS_H_INCLUDED #define RIPPLE_PEERS_H_INCLUDED
/** Manages the set of connected peers. namespace PeerFinder {
*/ class Manager;
}
/** Manages the set of connected peers. */
class Peers class Peers
{ {
public: public:
@@ -32,6 +34,8 @@ public:
virtual ~Peers () { } virtual ~Peers () { }
virtual PeerFinder::Manager& getPeerFinder() = 0;
// Begin enforcing connection policy. // Begin enforcing connection policy.
virtual void start () = 0; virtual void start () = 0;

View File

@@ -23,6 +23,7 @@
#include "ripple_app.h" #include "ripple_app.h"
#include "../ripple_net/ripple_net.h" #include "../ripple_net/ripple_net.h"
#include "../ripple/peerfinder/ripple_peerfinder.h"
#include "../ripple/validators/ripple_validators.h" #include "../ripple/validators/ripple_validators.h"
namespace ripple namespace ripple
@@ -40,5 +41,6 @@ namespace ripple
# include "misc/ProofOfWorkFactory.h" # include "misc/ProofOfWorkFactory.h"
#include "peers/Peer.cpp" #include "peers/Peer.cpp"
#include "peers/PackedMessage.cpp" #include "peers/PackedMessage.cpp"
#include "peers/Peers.cpp"
} }

View File

@@ -29,7 +29,6 @@ namespace ripple
#include "ledger/LedgerHistory.cpp" #include "ledger/LedgerHistory.cpp"
#include "misc/SerializedLedger.cpp" #include "misc/SerializedLedger.cpp"
#include "tx/TransactionAcquire.cpp" #include "tx/TransactionAcquire.cpp"
#include "peers/Peers.cpp"
# include "tx/TxQueueEntry.h" # include "tx/TxQueueEntry.h"
# include "tx/TxQueue.h" # include "tx/TxQueue.h"

View File

@@ -1,159 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PEERFINDER_H_INCLUDED
#define RIPPLE_PEERFINDER_H_INCLUDED
/** The identifier we use to track peers in peerfinder
*/
typedef uint160 PeerId;
/** Maintains a set of IP addresses used for getting into the network.
*/
class PeerFinder : public Uncopyable
{
public:
//--------------------------------------------------------------------------
/** Describes the state of our currently connected peers
*/
struct Connections
{
int numberIncoming; // number of inbound Peers
int numberOutgoing; // number of outbound Peers
inline int numberTotal () const noexcept
{
return numberIncoming + numberOutgoing;
}
};
//--------------------------------------------------------------------------
/** An abstract address that can be turned into a socket endpoint. */
struct Address
{
virtual String asString () = 0;
};
/** An IPv4 address. */
#if 0
struct AddressIPv4 : Address
{
AddressIPv4 (InputParser::IPv4Address const& address, uint16 port)
: m_address (address)
, m_port (port)
{
}
String asString ()
{
return String () +
String (m_address.value [0]) + "." +
String (m_address.value [1]) + "." +
String (m_address.value [2]) + "." +
String (m_address.value [3]) + ":" +
String (m_port);
}
private:
InputParser::IPv4Address m_address;
uint16 m_port;
};
#endif
//--------------------------------------------------------------------------
/** The Callback receives Peerfinder notifications.
The notifications are sent on a thread owned by the PeerFinder,
so it is best not to do too much work in here. Just post functor
to another worker thread or job queue and return.
*/
struct Callback
{
/** Announces our listening ip/port combinations to the network.
@param address The address to broadcast.
*/
virtual void onAnnounceAddress () = 0;
/** Indicates whether or not incoming connections should be accepted.
When we are full on incoming connections, future incoming
connections from valid peers should be politely turned away,
after giving them a random sample of other addresses to try
from our cache.
*/
//virtual void onSetAcceptStatus (bool shouldAcceptIncoming) = 0;
/** Called periodically to update the callback's list of eligible addresses.
This is used for making new outgoing connections, for
handing out addresses to peers, and for periodically seeding the
network wth hop-limited broadcasts of IP addresses.
*/
//virtual void onNewAddressesAvailable (std::vector <Address> const& list) = 0;
};
//--------------------------------------------------------------------------
/** Create a new PeerFinder object.
*/
static PeerFinder* New (Callback& callback);
/** Destroy the object.
Any pending source fetch operations are aborted.
There may be some listener calls made before the
destructor returns.
*/
virtual ~PeerFinder () { }
/** Inform the PeerFinder of the status of our connections.
This call queues an asynchronous operation to the PeerFinder's thread
and returns immediately. Normally this is called by the Peer code
when the counts change.
Thread-safety:
Safe to call from any thread
@see Peer
*/
virtual void updateConnectionsStatus (Connections& connections) = 0;
/** Called when a new peer connection is established.
Internally, we add the peer to our tracking table, validate that
we can connect to it, and begin advertising it to others after
we are sure that its connection is stable.
*/
virtual void onPeerConnected(const PeerId& id) = 0;
/** Called when an existing peer connection drops for whatever reason.
Internally, we mark the peer as no longer connected, calculate
stability metrics, and consider whether we should try to reconnect
to it or drop it from our list.
*/
virtual void onPeerDisconnected(const PeerId& id) = 0;
};
#endif

View File

@@ -29,8 +29,6 @@
#include "beast/modules/beast_core/system/BeforeBoost.h" #include "beast/modules/beast_core/system/BeforeBoost.h"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include "nodestore/NodeStore.cpp" #include "nodestore/NodeStore.cpp"
@@ -47,6 +45,4 @@ namespace ripple
#include "functional/LoadEvent.cpp" #include "functional/LoadEvent.cpp"
#include "functional/LoadMonitor.cpp" #include "functional/LoadMonitor.cpp"
#include "peerfinder/PeerFinder.cpp"
} }

View File

@@ -44,8 +44,6 @@ namespace ripple
# include "functional/LoadType.h" # include "functional/LoadType.h"
#include "functional/LoadSource.h" #include "functional/LoadSource.h"
#include "peerfinder/PeerFinder.h"
} }
#endif #endif

View File

@@ -14,6 +14,7 @@ enum MessageType
mtCONTACT = 11; mtCONTACT = 11;
mtGET_PEERS = 12; mtGET_PEERS = 12;
mtPEERS = 13; mtPEERS = 13;
mtENDPOINTS = 14;
// operations for 'small' nodes // operations for 'small' nodes
mtSEARCH_TRANSACTION = 20; mtSEARCH_TRANSACTION = 20;
@@ -231,6 +232,23 @@ message TMPeers
repeated TMIPv4EndPoint nodes = 1; repeated TMIPv4EndPoint nodes = 1;
} }
// An Endpoint describes a network peer that can accept incoming connections
message TMEndpoint
{
required TMIPv4EndPoint ipv4 = 1;
required uint32 hops = 2;
required uint32 slots = 3; // the number of available incoming slots
required uint32 maxSlots = 4; // the maximum number of incoming slots
required uint32 uptimeMinutes = 5; // uptime in minutes
required string features = 6;
}
// An array of Endpoint messages
message TMEndpoints
{
repeated TMEndpoint endpoints = 1;
};
message TMSearchTransaction message TMSearchTransaction
{ {
required uint32 maxTrans = 1; required uint32 maxTrans = 1;