Merge pull request #8211

1137142 Change C-cast to static_cast in net_peerlist.h (Jeffrey)
175b411 Change C-style-casts to static_cast in time_helper.h (Jeffrey)
b49ed59 Remove the only 4 non-UTF8 characters in codebase (Jeffrey)
1f25aa2 Factor out move_it_backward from misc_language.h (Jeffrey)
7764d69 Move copyable_atomic into connection_context (Jeffrey)
801568d Refactor out to_nonconst_iterator.h (Jeffrey)
87ec36c Refactor out pragma_comp_defs (Jeffrey)
441c860 Merge functionality of misc_os_dependent into time_helper.h (Jeffrey)
40f02f9 Add Include statements (Jeffrey)
12b1b74 Trimming Fat (Jeffrey
 690ce56 Boring Old Deletes (Jeffrey)
This commit is contained in:
luigi1111 2022-04-18 12:13:32 -05:00
commit 53bf62d114
No known key found for this signature in database
GPG Key ID: F4ACA0183641E010
103 changed files with 98 additions and 10281 deletions

View File

@ -1 +0,0 @@
/build/*

View File

@ -1,49 +0,0 @@
cmake_minimum_required(VERSION 3.5)
set(Boost_USE_MULTITHREADED ON)
#set(Boost_DEBUG 1)
find_package(Boost COMPONENTS system filesystem thread date_time chrono regex )
include_directories( ${Boost_INCLUDE_DIRS} )
IF (MSVC)
add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /nologo /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /bigobj" )
ELSE()
# set stuff for other systems
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wno-reorder -D_GNU_SOURCE")
ENDIF()
include_directories(.)
include_directories(../include)
include_directories(iface)
# Add folders to filters
file(GLOB_RECURSE LEVIN_GENERAL_SECTION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.h
${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.inl
${CMAKE_CURRENT_SOURCE_DIR}/demo_levin_server/*.cpp)
file(GLOB_RECURSE HTTP_GENERAL_SECTION RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.h
${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.inl
${CMAKE_CURRENT_SOURCE_DIR}/demo_http_server/*.cpp)
source_group(general FILES ${LEVIN_GENERAL_SECTION} FILES ${HTTP_GENERAL_SECTION})
#source_group(general FILES ${HTTP_GENERAL_SECTION})
add_executable(demo_http_server ${HTTP_GENERAL_SECTION} )
add_executable(demo_levin_server ${LEVIN_GENERAL_SECTION} )
target_link_libraries( demo_http_server ${Boost_LIBRARIES} )
target_link_libraries( demo_levin_server ${Boost_LIBRARIES} )
IF (NOT WIN32)
target_link_libraries (demo_http_server rt)
target_link_libraries (demo_levin_server rt)
ENDIF()

View File

@ -1,8 +0,0 @@
// stdafx.cpp : source file that includes just the standard includes
// demo_http_server.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -1,40 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#define BOOST_FILESYSTEM_VERSION 3
#define ENABLE_RELEASE_LOGGING
#include "misc_log_ex.h"

View File

@ -1,13 +0,0 @@
#pragma once
// The following macros define the minimum required platform. The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified.
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
#endif

View File

@ -1,30 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "stdafx.h"

View File

@ -1,41 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#define BOOST_FILESYSTEM_VERSION 3
#define ENABLE_RELEASE_LOGGING
#include "log_opt_defs.h"
#include "misc_log_ex.h"

View File

@ -1,13 +0,0 @@
#pragma once
// The following macros define the minimum required platform. The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified.
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
#endif

View File

@ -1,4 +0,0 @@
mkdir build
cd build
cmake ..
#cmake -DBOOST_ROOT=/usr/local/proj/boost_1_49_0 -DBOOST_LIBRARYDIR=/usr/local/proj/boost_1_49_0/stage/lib ..

View File

@ -1,7 +0,0 @@
mkdir build
cd build
cmake "-DBoost_USE_STATIC_LIBS=TRUE" -G "Visual Studio 11 Win64" ..
cd ..
pause

View File

@ -1,225 +0,0 @@
#pragma once
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage_base.h"
namespace demo
{
struct some_test_subdata
{
std::string m_str;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_str)
END_KV_SERIALIZE_MAP()
};
struct some_test_data
{
std::string m_str;
uint64_t m_uint64;
uint32_t m_uint32;
uint16_t m_uint16;
uint8_t m_uint8;
int64_t m_int64;
int32_t m_int32;
int16_t m_int16;
int8_t m_int8;
double m_double;
bool m_bool;
std::list<std::string> m_list_of_str;
std::list<uint64_t> m_list_of_uint64_t;
std::list<uint32_t> m_list_of_uint32_t;
std::list<uint16_t> m_list_of_uint16_t;
std::list<uint8_t> m_list_of_uint8_t;
std::list<int64_t> m_list_of_int64_t;
std::list<int32_t> m_list_of_int32_t;
std::list<int16_t> m_list_of_int16_t;
std::list<int8_t> m_list_of_int8_t;
std::list<double> m_list_of_double;
std::list<bool> m_list_of_bool;
some_test_subdata m_subobj;
std::list<some_test_data> m_list_of_self;
epee::serialization::storage_entry m_storage_entry_int;
epee::serialization::storage_entry m_storage_entry_string;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_str)
KV_SERIALIZE(m_uint64)
KV_SERIALIZE(m_uint32)
KV_SERIALIZE(m_uint16)
KV_SERIALIZE(m_uint8)
KV_SERIALIZE(m_int64)
KV_SERIALIZE(m_int32)
KV_SERIALIZE(m_int16)
KV_SERIALIZE(m_int8)
KV_SERIALIZE(m_double)
KV_SERIALIZE(m_bool)
KV_SERIALIZE(m_subobj)
KV_SERIALIZE(m_list_of_str)
KV_SERIALIZE(m_list_of_uint64_t)
KV_SERIALIZE(m_list_of_uint32_t)
KV_SERIALIZE(m_list_of_uint16_t)
KV_SERIALIZE(m_list_of_uint8_t)
KV_SERIALIZE(m_list_of_int64_t)
KV_SERIALIZE(m_list_of_int32_t)
KV_SERIALIZE(m_list_of_int16_t)
KV_SERIALIZE(m_list_of_int8_t)
KV_SERIALIZE(m_list_of_double)
KV_SERIALIZE(m_list_of_bool)
KV_SERIALIZE(m_list_of_self)
KV_SERIALIZE(m_storage_entry_int)
KV_SERIALIZE(m_storage_entry_string)
END_KV_SERIALIZE_MAP()
};
/************************************************************************/
/* */
/************************************************************************/
struct COMMAND_EXAMPLE_1
{
const static int ID = 1000;
struct request_t
{
std::string example_string_data;
some_test_data sub;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(example_string_data)
KV_SERIALIZE(sub)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
bool m_success;
std::list<some_test_data> subs;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_success)
KV_SERIALIZE(subs)
END_KV_SERIALIZE_MAP()
};
};
typedef epee::misc_utils::struct_init<response_t> response;
struct COMMAND_EXAMPLE_2
{
const static int ID = 1001;
struct request_t
{
std::string example_string_data2;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(example_string_data2)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
bool m_success;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_success)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//in debug purpose
bool operator != (const some_test_subdata& a, const some_test_subdata& b)
{
return b.m_str != a.m_str;
}
bool operator == (const some_test_data& a, const some_test_data& b)
{
if( b.m_str != a.m_str
|| b.m_uint64 != a.m_uint64
|| b.m_uint32 != a.m_uint32
|| b.m_uint16 != a.m_uint16
|| b.m_uint8 != a.m_uint8
|| b.m_int64 != a.m_int64
|| b.m_int32 != a.m_int32
|| b.m_int16 != a.m_int16
|| b.m_int8 != a.m_int8
|| b.m_double != a.m_double
|| b.m_bool != a.m_bool
|| b.m_list_of_str != a.m_list_of_str
|| b.m_list_of_uint64_t != a.m_list_of_uint64_t
|| b.m_list_of_uint32_t != a.m_list_of_uint32_t
|| b.m_list_of_uint16_t != a.m_list_of_uint16_t
|| b.m_list_of_uint8_t != a.m_list_of_uint8_t
|| b.m_list_of_int64_t != a.m_list_of_int64_t
|| b.m_list_of_int32_t != a.m_list_of_int32_t
|| b.m_list_of_int16_t != a.m_list_of_int16_t
|| b.m_list_of_int8_t != a.m_list_of_int8_t
|| b.m_list_of_double != a.m_list_of_double
|| b.m_list_of_bool != a.m_list_of_bool
|| b.m_subobj != a.m_subobj
|| b.m_list_of_self != a.m_list_of_self
|| b.m_storage_entry_int.which() != a.m_storage_entry_int.which()
|| b.m_storage_entry_string.which() != a.m_storage_entry_string.which()
)
return false;
return true;
}
inline some_test_data get_test_data()
{
some_test_data s;
s.m_str = "zuzuzuzuzuz";
s.m_uint64 = 111111111111111;
s.m_uint32 = 2222222;
s.m_uint16 = 2222;
s.m_uint8 = 22;
s.m_int64 = -111111111111111;
s.m_int32 = -2222222;
s.m_int16 = -2222;
s.m_int8 = -24;
s.m_double = 0.11111;
s.m_bool = true;
s.m_list_of_str.push_back("1112121");
s.m_list_of_uint64_t.push_back(1111111111);
s.m_list_of_uint64_t.push_back(2222222222);
s.m_list_of_uint32_t.push_back(1111111);
s.m_list_of_uint32_t.push_back(2222222);
s.m_list_of_uint16_t.push_back(1111);
s.m_list_of_uint16_t.push_back(2222);
s.m_list_of_uint8_t.push_back(11);
s.m_list_of_uint8_t.push_back(22);
s.m_list_of_int64_t.push_back(-1111111111);
s.m_list_of_int64_t.push_back(-222222222);
s.m_list_of_int32_t.push_back(-1111111);
s.m_list_of_int32_t.push_back(-2222222);
s.m_list_of_int16_t.push_back(-1111);
s.m_list_of_int16_t.push_back(-2222);
s.m_list_of_int8_t.push_back(-11);
s.m_list_of_int8_t.push_back(-22);
s.m_list_of_double.push_back(0.11111);
s.m_list_of_double.push_back(0.22222);
s.m_list_of_bool.push_back(true);
s.m_list_of_bool.push_back(false);
s.m_subobj.m_str = "subszzzzzzzz";
s.m_list_of_self.push_back(s);
s.m_storage_entry_int = epee::serialization::storage_entry(uint64_t(22222));
s.m_storage_entry_string = epee::serialization::storage_entry(std::string("sdsvsdvs"));
return s;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,56 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include <atomic>
namespace epee
{
class copyable_atomic: public std::atomic<uint32_t>
{
public:
copyable_atomic()
{};
copyable_atomic(uint32_t value)
{ store(value); }
copyable_atomic(const copyable_atomic& a):std::atomic<uint32_t>(a.load())
{}
copyable_atomic& operator= (const copyable_atomic& a)
{
store(a.load());
return *this;
}
uint32_t operator++()
{
return std::atomic<uint32_t>::operator++();
}
uint32_t operator++(int fake)
{
return std::atomic<uint32_t>::operator++(fake);
}
};
}

View File

@ -36,10 +36,7 @@ namespace file_io_utils
{
bool is_file_exist(const std::string& path);
bool save_string_to_file(const std::string& path_to_file, const std::string& str);
bool get_file_time(const std::string& path_to_file, time_t& ft);
bool set_file_time(const std::string& path_to_file, const time_t& ft);
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000);
bool append_string_to_file(const std::string& path_to_file, const std::string& str);
bool get_file_size(const std::string& path_to_file, uint64_t &size);
}
}

View File

@ -1,35 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
std::stringstream& operator<<(std::stringstream& out, const std::wstring& ws)
{
std::string as = string_encoding::convert_to_ansii(ws);
out << as;
return out;
}

View File

@ -37,8 +37,8 @@
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/random_generator.hpp>
#include "misc_os_dependent.h"
#include "syncobj.h"
#include "time_helper.h"
namespace epee
{

View File

@ -30,73 +30,13 @@
#include <boost/utility/value_init.hpp>
#include <boost/shared_ptr.hpp>
#include <limits>
#include <functional>
#include <vector>
namespace epee
{
#define STD_TRY_BEGIN() try {
#define STD_TRY_CATCH(where_, ret_val) \
} \
catch (const std::exception &e) \
{ \
LOG_ERROR("EXCEPTION: " << where_ << ", mes: "<< e.what()); \
return ret_val; \
} \
catch (...) \
{ \
LOG_ERROR("EXCEPTION: " << where_ ); \
return ret_val; \
}
#define AUTO_VAL_INIT(v) boost::value_initialized<decltype(v)>()
namespace misc_utils
{
template<typename t_type>
t_type get_max_t_val(t_type t)
{
return (std::numeric_limits<t_type>::max)();
}
template<typename t_iterator>
t_iterator move_it_forward(t_iterator it, size_t count)
{
while(count--)
it++;
return it;
}
template<typename t_iterator>
t_iterator move_it_backward(t_iterator it, size_t count)
{
while(count--)
it--;
return it;
}
// TEMPLATE STRUCT less
template<class _Ty>
struct less_as_pod
: public std::binary_function<_Ty, _Ty, bool>
{ // functor for operator<
bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
}
};
template<class _Ty>
bool is_less_as_pod(const _Ty& _Left, const _Ty& _Right)
{ // apply operator< to operands
return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
}
bool sleep_no_w(long ms);
template <typename T>

View File

@ -1,129 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifdef _WIN32
#include <winsock2.h>
#endif
#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
//#ifdef _WIN32_WINNT
// #undef _WIN32_WINNT
// #define _WIN32_WINNT 0x0600
//#endif
#include <windows.h>
#endif
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#include <iostream>
#include <ctime>
#pragma once
namespace epee
{
namespace misc_utils
{
inline uint64_t get_ns_count()
{
#if defined(_MSC_VER)
return ::GetTickCount64() * 1000000;
#elif defined(WIN32)
static LARGE_INTEGER pcfreq = {0};
LARGE_INTEGER ticks;
if (!pcfreq.QuadPart)
QueryPerformanceFrequency(&pcfreq);
QueryPerformanceCounter(&ticks);
ticks.QuadPart *= 1000000000; /* we want nsec */
return ticks.QuadPart / pcfreq.QuadPart;
#elif defined(__MACH__)
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
return ((uint64_t)mts.tv_sec * 1000000000) + (mts.tv_nsec);
#else
struct timespec ts;
if(clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return ((uint64_t)ts.tv_sec * 1000000000) + (ts.tv_nsec);
#endif
}
inline uint64_t get_tick_count()
{
return get_ns_count() / 1000000;
}
inline int call_sys_cmd(const std::string& cmd)
{
std::cout << "# " << cmd << std::endl;
FILE * fp ;
//char tstCommand[] ="ls *";
char path[1000] = {0};
#if !defined(__GNUC__)
fp = _popen(cmd.c_str(), "r");
#else
fp = popen(cmd.c_str(), "r");
#endif
while ( fgets( path, 1000, fp ) != NULL )
std::cout << path;
#if !defined(__GNUC__)
_pclose(fp);
#else
pclose(fp);
#endif
return 0;
}
std::string get_thread_string_id();
inline bool get_gmt_time(time_t t, struct tm &tm)
{
#ifdef _WIN32
return gmtime_s(&tm, &t);
#else
return gmtime_r(&t, &tm);
#endif
}
}
}

View File

@ -1,318 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _ABSTRACT_TCP_SERVER_H_
#define _ABSTRACT_TCP_SERVER_H_
#include <process.h>
#include <list>
#include <winsock2.h>
#include "winobj.h"
//#include "threads_helper.h"
#include "net_utils_base.h"
#pragma comment(lib, "Ws2_32.lib")
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
namespace epee
{
namespace net_utils
{
/************************************************************************/
/* */
/************************************************************************/
class soket_sender: public i_service_endpoint
{
public:
soket_sender(SOCKET sock):m_sock(sock){}
private:
virtual bool handle_send(const void* ptr, size_t cb)
{
if(cb != send(m_sock, (char*)ptr, (int)cb, 0))
{
int sock_err = WSAGetLastError();
LOG_ERROR("soket_sender: Failed to send " << cb << " bytes, Error=" << sock_err);
return false;
}
return true;
}
SOCKET m_sock;
};
/************************************************************************/
/* */
/************************************************************************/
template<class THandler>
class abstract_tcp_server
{
public:
abstract_tcp_server();
bool init_server(int port_no);
bool deinit_server();
bool run_server();
bool send_stop_signal();
typename THandler::config_type& get_config_object(){return m_config;}
private:
bool invoke_connection(SOCKET hnew_sock, long ip_from, int post_from);
static unsigned __stdcall ConnectionHandlerProc(void* lpParameter);
class thread_context;
typedef std::list<thread_context> connections_container;
typedef typename connections_container::iterator connections_iterator;
struct thread_context
{
HANDLE m_htread;
SOCKET m_socket;
abstract_tcp_server* powner;
connection_context m_context;
typename connections_iterator m_self_it;
};
SOCKET m_listen_socket;
int m_port;
bool m_initialized;
volatile LONG m_stop_server;
volatile LONG m_threads_count;
typename THandler::config_type m_config;
connections_container m_connections;
critical_section m_connections_lock;
};
template<class THandler>
unsigned __stdcall abstract_tcp_server<THandler>::ConnectionHandlerProc(void* lpParameter)
{
thread_context* pthread_context = (thread_context*)lpParameter;
if(!pthread_context)
return 0;
abstract_tcp_server<THandler>* pthis = pthread_context->powner;
::InterlockedIncrement(&pthis->m_threads_count);
::CoInitialize(NULL);
LOG_PRINT("Handler thread STARTED with socket=" << pthread_context->m_socket, LOG_LEVEL_2);
int res = 0;
soket_sender sndr(pthread_context->m_socket);
THandler srv(&sndr, pthread_context->powner->m_config, pthread_context->m_context);
srv.after_init_connection();
char buff[1000] = {0};
std::string ansver;
while ( (res = recv(pthread_context->m_socket, (char*)buff, 1000, 0)) > 0)
{
LOG_PRINT("Data in, " << res << " bytes", LOG_LEVEL_3);
if(!srv.handle_recv(buff, res))
break;
}
shutdown(pthread_context->m_socket, SD_BOTH);
closesocket(pthread_context->m_socket);
abstract_tcp_server* powner = pthread_context->powner;
LOG_PRINT("Handler thread with socket=" << pthread_context->m_socket << " STOPPED", LOG_LEVEL_2);
powner->m_connections_lock.lock();
::CloseHandle(pthread_context->m_htread);
pthread_context->powner->m_connections.erase(pthread_context->m_self_it);
powner->m_connections_lock.unlock();
CoUninitialize();
::InterlockedDecrement(&pthis->m_threads_count);
return 1;
}
//----------------------------------------------------------------------------------------
template<class THandler>
abstract_tcp_server<THandler>::abstract_tcp_server():m_listen_socket(INVALID_SOCKET),
m_initialized(false),
m_stop_server(0), m_port(0), m_threads_count(0)
{
}
//----------------------------------------------------------------------------------------
template<class THandler>
bool abstract_tcp_server<THandler>::init_server(int port_no)
{
m_port = port_no;
WSADATA wsad = {0};
int err = ::WSAStartup(MAKEWORD(2,2), &wsad);
if ( err != 0 || LOBYTE( wsad.wVersion ) != 2 || HIBYTE( wsad.wVersion ) != 2 )
{
LOG_ERROR("Could not find a usable WinSock DLL, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
return false;
}
m_initialized = true;
m_listen_socket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
if(INVALID_SOCKET == m_listen_socket)
{
err = ::WSAGetLastError();
LOG_ERROR("Failed to create socket, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
return false;
}
int opt = 1;
setsockopt (m_listen_socket, SOL_SOCKET,SO_REUSEADDR, reinterpret_cast<char*>(&opt), sizeof(int));
sockaddr_in adr = {0};
adr.sin_family = AF_INET;
adr.sin_addr.s_addr = htonl(INADDR_ANY);
adr.sin_port = (u_short)htons(port_no);
err = bind(m_listen_socket, (const sockaddr*)&adr, sizeof(adr ));
if(SOCKET_ERROR == err )
{
err = ::WSAGetLastError();
LOG_PRINT("Failed to Bind, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_2);
deinit_server();
return false;
}
::InterlockedExchange(&m_stop_server, 0);
return true;
}
//----------------------------------------------------------------------------------------
template<class THandler>
bool abstract_tcp_server<THandler>::deinit_server()
{
if(!m_initialized)
return true;
if(INVALID_SOCKET != m_listen_socket)
{
shutdown(m_listen_socket, SD_BOTH);
int res = closesocket(m_listen_socket);
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to closesocket(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
}
m_listen_socket = INVALID_SOCKET;
}
int res = ::WSACleanup();
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to WSACleanup(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
}
m_initialized = false;
return true;
}
//----------------------------------------------------------------------------------------
template<class THandler>
bool abstract_tcp_server<THandler>::send_stop_signal()
{
InterlockedExchange(&m_stop_server, 1);
return true;
}
//----------------------------------------------------------------------------------------
template<class THandler>
bool abstract_tcp_server<THandler>::run_server()
{
int err = listen(m_listen_socket, 10000);
if(SOCKET_ERROR == err )
{
err = ::WSAGetLastError();
LOG_ERROR("Failed to listen, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
return false;
}
LOG_PRINT("Listening port "<< m_port << "...." , LOG_LEVEL_2);
while(!m_stop_server)
{
sockaddr_in adr_from = {0};
int adr_len = sizeof(adr_from);
fd_set read_fs = {0};
read_fs.fd_count = 1;
read_fs.fd_array[0] = m_listen_socket;
TIMEVAL tv = {0};
tv.tv_usec = 100;
int select_res = select(0, &read_fs, NULL, NULL, &tv);
if(!select_res)
continue;
SOCKET new_sock = WSAAccept(m_listen_socket, (sockaddr *)&adr_from, &adr_len, NULL, NULL);
LOG_PRINT("Accepted connection on socket=" << new_sock, LOG_LEVEL_2);
invoke_connection(new_sock, adr_from.sin_addr.s_addr, adr_from.sin_port);
}
deinit_server();
#define ABSTR_TCP_SRV_WAIT_COUNT_MAX 5000
#define ABSTR_TCP_SRV_WAIT_COUNT_INTERVAL 1000
int wait_count = 0;
while(m_threads_count && wait_count*1000 < ABSTR_TCP_SRV_WAIT_COUNT_MAX)
{
::Sleep(ABSTR_TCP_SRV_WAIT_COUNT_INTERVAL);
wait_count++;
}
LOG_PRINT("abstract_tcp_server exit with wait count=" << wait_count*ABSTR_TCP_SRV_WAIT_COUNT_INTERVAL << "(max=" << ABSTR_TCP_SRV_WAIT_COUNT_MAX <<")", LOG_LEVEL_0);
return true;
}
//----------------------------------------------------------------------------------------
template<class THandler>
bool abstract_tcp_server<THandler>::invoke_connection(SOCKET hnew_sock, const network_address &remote_address)
{
m_connections_lock.lock();
m_connections.push_back(thread_context());
m_connections_lock.unlock();
m_connections.back().m_socket = hnew_sock;
m_connections.back().powner = this;
m_connections.back().m_self_it = --m_connections.end();
m_connections.back().m_context.m_remote_address = remote_address;
m_connections.back().m_htread = threads_helper::create_thread(ConnectionHandlerProc, &m_connections.back()); // ugh, seems very risky
return true;
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
}
}
#endif //_ABSTRACT_TCP_SERVER_H_

View File

@ -44,8 +44,6 @@
#include "warnings.h"
#include "string_tools_lexical.h"
#include "misc_language.h"
#include "net/local_ip.h"
#include "pragma_comp_defs.h"
#include <sstream>
#include <iomanip>
@ -64,7 +62,6 @@
#define TIMEOUT_EXTRA_MS_PER_BYTE 0.2
PRAGMA_WARNING_PUSH
namespace epee
{
namespace net_utils
@ -79,8 +76,6 @@ namespace net_utils
/************************************************************************/
/* */
/************************************************************************/
PRAGMA_WARNING_DISABLE_VS(4355)
template<class t_protocol_handler>
connection<t_protocol_handler>::connection( boost::asio::io_service& io_service,
std::shared_ptr<shared_state> state,
@ -111,7 +106,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
MDEBUG("test, connection constructor set m_connection_type="<<m_connection_type);
}
PRAGMA_WARNING_DISABLE_VS(4355)
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
connection<t_protocol_handler>::~connection() noexcept(false)
@ -1092,8 +1086,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
}
}
//-----------------------------------------------------------------------------
PUSH_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
template<class t_protocol_handler>
bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port, const std::string& address,
const std::string port_ipv6, const std::string address_ipv6, bool use_ipv6, bool require_ipv4,
@ -1113,7 +1105,6 @@ DISABLE_GCC_WARNING(maybe-uninitialized)
}
return this->init_server(p, address, p_ipv6, address_ipv6, use_ipv6, require_ipv4, std::move(ssl_options));
}
POP_WARNINGS
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
bool boosted_tcp_server<t_protocol_handler>::worker_thread()
@ -1734,4 +1725,3 @@ POP_WARNINGS
} // namespace
} // namespace
PRAGMA_WARNING_POP

View File

@ -1,236 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _LEVIN_CP_SERVER_H_
#define _LEVIN_CP_SERVER_H_
#include <winsock2.h>
#include <rpc.h>
#include <string>
#include <map>
#include <boost/shared_ptr.hpp>
#include "misc_log_ex.h"
//#include "threads_helper.h"
#include "syncobj.h"
#define ENABLE_PROFILING
#include "profile_tools.h"
#include "net_utils_base.h"
#include "pragma_comp_defs.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
#define LEVIN_DEFAULT_DATA_BUFF_SIZE 2000
namespace epee
{
namespace net_utils
{
template<class TProtocol>
class cp_server_impl//: public abstract_handler
{
public:
cp_server_impl(/*abstract_handler* phandler = NULL*/);
virtual ~cp_server_impl();
bool init_server(int port_no);
bool deinit_server();
bool run_server(int threads_count = 0);
bool send_stop_signal();
bool is_stop_signal();
virtual bool on_net_idle(){return true;}
size_t get_active_connections_num();
typename TProtocol::config_type& get_config_object(){return m_config;}
private:
enum overlapped_operation_type
{
op_type_recv,
op_type_send,
op_type_stop
};
struct io_data_base
{
OVERLAPPED m_overlapped;
WSABUF DataBuf;
overlapped_operation_type m_op_type;
DWORD TotalBuffBytes;
volatile LONG m_is_in_use;
char Buffer[1];
};
PRAGMA_WARNING_PUSH
PRAGMA_WARNING_DISABLE_VS(4355)
template<class TProtocol>
struct connection: public net_utils::i_service_endpoint
{
connection(typename TProtocol::config_type& ref_config):m_sock(INVALID_SOCKET), m_tprotocol_handler(this, ref_config, context), m_psend_data(NULL), m_precv_data(NULL), m_asked_to_shutdown(0), m_connection_shutwoned(0)
{
}
//connection():m_sock(INVALID_SOCKET), m_tprotocol_handler(this, m_dummy_config, context), m_psend_data(NULL), m_precv_data(NULL), m_asked_to_shutdown(0), m_connection_shutwoned(0)
//{
//}
connection<TProtocol>& operator=(const connection<TProtocol>& obj)
{
return *this;
}
bool init_buffers()
{
m_psend_data = (io_data_base*)new char[sizeof(io_data_base) + LEVIN_DEFAULT_DATA_BUFF_SIZE-1];
m_psend_data->TotalBuffBytes = LEVIN_DEFAULT_DATA_BUFF_SIZE;
m_precv_data = (io_data_base*)new char[sizeof(io_data_base) + LEVIN_DEFAULT_DATA_BUFF_SIZE-1];
m_precv_data->TotalBuffBytes = LEVIN_DEFAULT_DATA_BUFF_SIZE;
return true;
}
bool query_shutdown()
{
if(!::InterlockedCompareExchange(&m_asked_to_shutdown, 1, 0))
{
m_psend_data->m_op_type = op_type_stop;
::PostQueuedCompletionStatus(m_completion_port, 0, (ULONG_PTR)this, &m_psend_data->m_overlapped);
}
return true;
}
//bool set_config(typename TProtocol::config_type& config)
//{
// this->~connection();
// new(this) connection<TProtocol>(config);
// return true;
//}
~connection()
{
if(m_psend_data)
delete m_psend_data;
if(m_precv_data)
delete m_precv_data;
}
virtual bool handle_send(const void* ptr, size_t cb)
{
PROFILE_FUNC("[handle_send]");
if(m_psend_data->TotalBuffBytes < cb)
resize_send_buff((DWORD)cb);
ZeroMemory(&m_psend_data->m_overlapped, sizeof(OVERLAPPED));
m_psend_data->DataBuf.len = (u_long)cb;//m_psend_data->TotalBuffBytes;
m_psend_data->DataBuf.buf = m_psend_data->Buffer;
memcpy(m_psend_data->DataBuf.buf, ptr, cb);
m_psend_data->m_op_type = op_type_send;
InterlockedExchange(&m_psend_data->m_is_in_use, 1);
DWORD bytes_sent = 0;
DWORD flags = 0;
int res = 0;
{
PROFILE_FUNC("[handle_send] ::WSASend");
res = ::WSASend(m_sock, &(m_psend_data->DataBuf), 1, &bytes_sent, flags, &(m_psend_data->m_overlapped), NULL);
}
if(res == SOCKET_ERROR )
{
int err = ::WSAGetLastError();
if(WSA_IO_PENDING == err )
return true;
}
LOG_ERROR("BIG FAIL: WSASend error code not correct, res=" << res << " last_err=" << err);
::InterlockedExchange(&m_psend_data->m_is_in_use, 0);
query_shutdown();
//closesocket(m_psend_data);
return false;
}else if(0 == res)
{
::InterlockedExchange(&m_psend_data->m_is_in_use, 0);
if(!bytes_sent || bytes_sent != cb)
{
int err = ::WSAGetLastError();
LOG_ERROR("BIG FAIL: WSASend immediatly complete? but bad results, res=" << res << " last_err=" << err);
query_shutdown();
return false;
}else
{
return true;
}
}
return true;
}
bool resize_send_buff(DWORD new_size)
{
if(m_psend_data->TotalBuffBytes >= new_size)
return true;
delete m_psend_data;
m_psend_data = (io_data_base*)new char[sizeof(io_data_base) + new_size-1];
m_psend_data->TotalBuffBytes = new_size;
LOG_PRINT("Connection buffer resized up to " << new_size, LOG_LEVEL_3);
return true;
}
SOCKET m_sock;
net_utils::connection_context_base context;
TProtocol m_tprotocol_handler;
typename TProtocol::config_type m_dummy_config;
io_data_base* m_precv_data;
io_data_base* m_psend_data;
HANDLE m_completion_port;
volatile LONG m_asked_to_shutdown;
volatile LONG m_connection_shutwoned;
};
PRAGMA_WARNING_POP
bool worker_thread_member();
static unsigned CALLBACK worker_thread(void* param);
bool add_new_connection(SOCKET new_sock, long ip_from, int port_from);
bool shutdown_connection(connection<TProtocol>* pconn);
typedef std::map<SOCKET, boost::shared_ptr<connection<TProtocol> > > connections_container;
SOCKET m_listen_socket;
HANDLE m_completion_port;
connections_container m_connections;
critical_section m_connections_lock;
int m_port;
volatile LONG m_stop;
//abstract_handler* m_phandler;
bool m_initialized;
volatile LONG m_worker_thread_counter;
typename TProtocol::config_type m_config;
};
}
}
#include "abstract_tcp_server_cp.inl"
#endif //_LEVIN_SERVER_H_

View File

@ -1,607 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma comment(lib, "Ws2_32.lib")
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
namespace epee
{
namespace net_utils
{
template<class TProtocol>
cp_server_impl<TProtocol>::cp_server_impl():
m_port(0), m_stop(false),
m_worker_thread_counter(0), m_listen_socket(INVALID_SOCKET)
{
}
//-------------------------------------------------------------
template<class TProtocol>
cp_server_impl<TProtocol>::~cp_server_impl()
{
deinit_server();
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::init_server(int port_no)
{
m_port = port_no;
WSADATA wsad = {0};
int err = ::WSAStartup(MAKEWORD(2,2), &wsad);
if ( err != 0 || LOBYTE( wsad.wVersion ) != 2 || HIBYTE( wsad.wVersion ) != 2 )
{
LOG_ERROR("Could not find a usable WinSock DLL, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
return false;
}
m_initialized = true;
m_listen_socket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
if(INVALID_SOCKET == m_listen_socket)
{
err = ::WSAGetLastError();
LOG_ERROR("Failed to create socket, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
return false;
}
int opt = 1;
err = setsockopt (m_listen_socket, SOL_SOCKET,SO_REUSEADDR, reinterpret_cast<char*>(&opt), sizeof(int));
if(SOCKET_ERROR == err )
{
err = ::WSAGetLastError();
LOG_PRINT("Failed to setsockopt(SO_REUSEADDR), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_1);
deinit_server();
return false;
}
sockaddr_in adr = {0};
adr.sin_family = AF_INET;
adr.sin_addr.s_addr = htonl(INADDR_ANY);
adr.sin_port = (u_short)htons(m_port);
//binding
err = bind(m_listen_socket, (const sockaddr*)&adr, sizeof(adr ));
if(SOCKET_ERROR == err )
{
err = ::WSAGetLastError();
LOG_PRINT("Failed to Bind, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_1);
deinit_server();
return false;
}
m_completion_port = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if(INVALID_HANDLE_VALUE == m_completion_port)
{
err = ::WSAGetLastError();
LOG_PRINT("Failed to CreateIoCompletionPort, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_1);
deinit_server();
return false;
}
return true;
}
//-------------------------------------------------------------
//-------------------------------------------------------------
static int CALLBACK CPConditionFunc(
IN LPWSABUF lpCallerId,
IN LPWSABUF lpCallerData,
IN OUT LPQOS lpSQOS,
IN OUT LPQOS lpGQOS,
IN LPWSABUF lpCalleeId,
OUT LPWSABUF lpCalleeData,
OUT GROUP FAR *g,
IN DWORD_PTR dwCallbackData
)
{
/*cp_server_impl* pthis = (cp_server_impl*)dwCallbackData;
if(!pthis)
return CF_REJECT;*/
/*if(pthis->get_active_connections_num()>=FD_SETSIZE-1)
{
LOG_PRINT("Maximum connections count overfull.", LOG_LEVEL_2);
return CF_REJECT;
}*/
return CF_ACCEPT;
}
//-------------------------------------------------------------
template<class TProtocol>
size_t cp_server_impl<TProtocol>::get_active_connections_num()
{
return m_connections.size();
}
//-------------------------------------------------------------
template<class TProtocol>
unsigned CALLBACK cp_server_impl<TProtocol>::worker_thread(void* param)
{
if(!param)
return 0;
cp_server_impl<TProtocol>* pthis = (cp_server_impl<TProtocol>*)param;
pthis->worker_thread_member();
return 1;
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::worker_thread_member()
{
LOG_PRINT("Worker thread STARTED", LOG_LEVEL_1);
bool stop_handling = false;
while(!stop_handling)
{
PROFILE_FUNC("[worker_thread]Worker Loop");
DWORD bytes_transfered = 0;
connection<TProtocol>* pconnection = 0;
io_data_base* pio_data = 0;
{
PROFILE_FUNC("[worker_thread]GetQueuedCompletionStatus");
BOOL res = ::GetQueuedCompletionStatus (m_completion_port, &bytes_transfered , (PULONG_PTR)&pconnection, (LPOVERLAPPED *)&pio_data, INFINITE);
if (res == 0)
{
// check return code for error
int err = GetLastError();
LOG_PRINT("GetQueuedCompletionStatus failed with error " << err << " " << log_space::get_win32_err_descr(err), LOG_LEVEL_1);
if(pio_data)
::InterlockedExchange(&pio_data->m_is_in_use, 0);
continue;
}
}
if(pio_data)
::InterlockedExchange(&pio_data->m_is_in_use, 0);
if(!bytes_transfered && !pconnection && !pio_data)
{
//signal to stop
break;
}
if(!pconnection || !pio_data)
{
LOG_PRINT("BIG FAIL: pconnection or pio_data is empty: pconnection=" << pconnection << " pio_data=" << pio_data, LOG_LEVEL_0);
break;
}
if(::InterlockedCompareExchange(&pconnection->m_connection_shutwoned, 0, 0))
{
LOG_ERROR("InterlockedCompareExchange(&pconnection->m_connection_shutwoned, 0, 0)");
//DebugBreak();
}
if(pio_data->m_op_type == op_type_stop)
{
if(!pconnection)
{
LOG_ERROR("op_type=op_type_stop, but pconnection is empty!!!");
continue;
}
shutdown_connection(pconnection);
continue;//
}
else if(pio_data->m_op_type == op_type_send)
{
continue;
//do nothing, just queuing request
}else if(pio_data->m_op_type == op_type_recv)
{
PROFILE_FUNC("[worker_thread]m_tprotocol_handler.handle_recv");
if(bytes_transfered)
{
bool res = pconnection->m_tprotocol_handler.handle_recv(pio_data->Buffer, bytes_transfered);
if(!res)
pconnection->query_shutdown();
}
else
{
pconnection->query_shutdown();
continue;
}
}
//preparing new request,
{
PROFILE_FUNC("[worker_thread]RECV Request small loop");
int res = 0;
while(true)
{
LOG_PRINT("Prepearing data for WSARecv....", LOG_LEVEL_3);
ZeroMemory(&pio_data->m_overlapped, sizeof(OVERLAPPED));
pio_data->DataBuf.len = pio_data->TotalBuffBytes;
pio_data->DataBuf.buf = pio_data->Buffer;
pio_data->m_op_type = op_type_recv;
//calling WSARecv() and go to completion waiting
DWORD bytes_recvd = 0;
DWORD flags = 0;
LOG_PRINT("Calling WSARecv....", LOG_LEVEL_3);
::InterlockedExchange(&pio_data->m_is_in_use, 1);
res = WSARecv(pconnection->m_sock, &(pio_data->DataBuf), 1, &bytes_recvd , &flags, &(pio_data->m_overlapped), NULL);
if(res == SOCKET_ERROR )
{
int err = ::WSAGetLastError();
if(WSA_IO_PENDING == err )
{//go pending, ok
LOG_PRINT("WSARecv return WSA_IO_PENDING", LOG_LEVEL_3);
break;
}
LOG_ERROR("BIG FAIL: WSARecv error code not correct, res=" << res << " last_err=" << err);
::InterlockedExchange(&pio_data->m_is_in_use, 0);
pconnection->query_shutdown();
break;
}
break;
/*else if(0 == res)
{
if(!bytes_recvd)
{
::InterlockedExchange(&pio_data->m_is_in_use, 0);
LOG_PRINT("WSARecv return 0, bytes_recvd=0, graceful close.", LOG_LEVEL_3);
int err = ::WSAGetLastError();
//LOG_ERROR("BIG FAIL: WSARecv error code not correct, res=" << res << " last_err=" << err);
//pconnection->query_shutdown();
break;
}else
{
LOG_PRINT("WSARecv return immediatily 0, bytes_recvd=" << bytes_recvd, LOG_LEVEL_3);
//pconnection->m_tprotocol_handler.handle_recv(pio_data->Buffer, bytes_recvd);
}
}*/
}
}
}
LOG_PRINT("Worker thread STOPED", LOG_LEVEL_1);
::InterlockedDecrement(&m_worker_thread_counter);
return true;
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::shutdown_connection(connection<TProtocol>* pconn)
{
PROFILE_FUNC("[shutdown_connection]");
if(!pconn)
{
LOG_ERROR("Attempt to remove null pptr connection!");
return false;
}
else
{
LOG_PRINT("Shutting down connection ("<< pconn << ")", LOG_LEVEL_3);
}
m_connections_lock.lock();
connections_container::iterator it = m_connections.find(pconn->m_sock);
m_connections_lock.unlock();
if(it == m_connections.end())
{
LOG_ERROR("Failed to find closing socket=" << pconn->m_sock);
return false;
}
SOCKET sock = it->second->m_sock;
{
PROFILE_FUNC("[shutdown_connection] shutdown, close");
::shutdown(it->second->m_sock, SD_SEND );
}
size_t close_sock_wait_count = 0;
{
LOG_PRINT("Entered to 'in_use wait zone'", LOG_LEVEL_3);
PROFILE_FUNC("[shutdown_connection] wait for in_use");
while(::InterlockedCompareExchange(&it->second->m_precv_data->m_is_in_use, 1, 1))
{
Sleep(100);
close_sock_wait_count++;
}
LOG_PRINT("First step to 'in_use wait zone'", LOG_LEVEL_3);
while(::InterlockedCompareExchange(&it->second->m_psend_data->m_is_in_use, 1, 1))
{
Sleep(100);
close_sock_wait_count++;
}
LOG_PRINT("Leaved 'in_use wait zone'", LOG_LEVEL_3);
}
::closesocket(it->second->m_sock);
::InterlockedExchange(&it->second->m_connection_shutwoned, 1);
m_connections_lock.lock();
m_connections.erase(it);
m_connections_lock.unlock();
LOG_PRINT("Socked " << sock << " closed, wait_count=" << close_sock_wait_count, LOG_LEVEL_2);
return true;
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::run_server(int threads_count = 0)
{
int err = listen(m_listen_socket, 100);
if(SOCKET_ERROR == err )
{
err = ::WSAGetLastError();
LOG_ERROR("Failed to listen, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
return false;
}
if(!threads_count)
{
SYSTEM_INFO si = {0};
::GetSystemInfo(&si);
threads_count = si.dwNumberOfProcessors + 2;
}
for(int i = 0; i != threads_count; i++)
{
boost::thread(boost::bind(&cp_server_impl::worker_thread_member, this));
//HANDLE h_thread = threads_helper::create_thread(worker_thread, this);
InterlockedIncrement(&m_worker_thread_counter);
//::CloseHandle(h_thread);
}
LOG_PRINT("Numbers of worker threads started: " << threads_count, LOG_LEVEL_1);
m_stop = false;
while(!m_stop)
{
PROFILE_FUNC("[run_server] main_loop");
TIMEVAL tv = {0};
tv.tv_sec = 0;
tv.tv_usec = 100;
fd_set sock_set;
sock_set.fd_count = 1;
sock_set.fd_array[0] = m_listen_socket;
int select_res = 0;
{
PROFILE_FUNC("[run_server] select");
select_res = select(0, &sock_set, &sock_set, NULL, &tv);
}
if(SOCKET_ERROR == select_res)
{
err = ::WSAGetLastError();
LOG_ERROR("Failed to select, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
return false;
}
if(!select_res)
{
on_net_idle();
continue;
}
else
{
sockaddr_in adr_from = {0};
int adr_len = sizeof(adr_from);
SOCKET new_sock = INVALID_SOCKET;
{
PROFILE_FUNC("[run_server] WSAAccept");
new_sock = ::WSAAccept(m_listen_socket, (sockaddr *)&adr_from, &adr_len, CPConditionFunc, (DWORD_PTR)this);
}
if(INVALID_SOCKET == new_sock)
{
if(m_stop)
break;
int err = ::WSAGetLastError();
LOG_PRINT("Failed to WSAAccept, err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_2);
continue;
}
LOG_PRINT("Accepted connection (new socket=" << new_sock << ")", LOG_LEVEL_2);
{
PROFILE_FUNC("[run_server] Add new connection");
add_new_connection(new_sock, adr_from.sin_addr.s_addr, adr_from.sin_port);
}
}
}
LOG_PRINT("Closing connections("<< m_connections.size() << ") and waiting...", LOG_LEVEL_2);
m_connections_lock.lock();
for(connections_container::iterator it = m_connections.begin(); it != m_connections.end(); it++)
{
::shutdown(it->second->m_sock, SD_BOTH);
::closesocket(it->second->m_sock);
}
m_connections_lock.unlock();
size_t wait_count = 0;
while(m_connections.size() && wait_count < 100)
{
::Sleep(100);
wait_count++;
}
LOG_PRINT("Connections closed OK (wait_count=" << wait_count << ")", LOG_LEVEL_2);
LOG_PRINT("Stopping worker threads("<< m_worker_thread_counter << ").", LOG_LEVEL_2);
for(int i = 0; i<m_worker_thread_counter; i++)
{
::PostQueuedCompletionStatus(m_completion_port, 0, 0, 0);
}
wait_count = 0;
while(InterlockedCompareExchange(&m_worker_thread_counter, 0, 0) && wait_count < 100)
{
Sleep(100);
wait_count++;
}
LOG_PRINT("Net Server STOPPED, wait_count = " << wait_count, LOG_LEVEL_1);
return true;
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::add_new_connection(SOCKET new_sock, const network_address &address_from)
{
PROFILE_FUNC("[add_new_connection]");
LOG_PRINT("Add new connection zone: entering lock", LOG_LEVEL_3);
m_connections_lock.lock();
boost::shared_ptr<connection<TProtocol> > ptr;
ptr.reset(new connection<TProtocol>(m_config));
connection<TProtocol>& conn = *ptr.get();
m_connections[new_sock] = ptr;
LOG_PRINT("Add new connection zone: leaving lock", LOG_LEVEL_3);
m_connections_lock.unlock();
conn.init_buffers();
conn.m_sock = new_sock;
conn.context.m_remote_address = address_from;
conn.m_completion_port = m_completion_port;
{
PROFILE_FUNC("[add_new_connection] CreateIoCompletionPort");
::CreateIoCompletionPort((HANDLE)new_sock, m_completion_port, (ULONG_PTR)&conn, 0);
}
//if(NULL == ::CreateIoCompletionPort((HANDLE)new_sock, m_completion_port, (ULONG_PTR)&conn, 0))
//{
// int err = ::GetLastError();
// LOG_PRINT("Failed to CreateIoCompletionPort(associate socket and completion port), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"", LOG_LEVEL_2);
// return false;
//}
conn.m_tprotocol_handler.after_init_connection();
{
PROFILE_FUNC("[add_new_connection] starting loop");
int res = 0;
while(true)//res!=SOCKET_ERROR)
{
PROFILE_FUNC("[add_new_connection] in loop time");
conn.m_precv_data->TotalBuffBytes = LEVIN_DEFAULT_DATA_BUFF_SIZE;
ZeroMemory(&conn.m_precv_data->m_overlapped, sizeof(OVERLAPPED));
conn.m_precv_data->DataBuf.len = conn.m_precv_data->TotalBuffBytes;
conn.m_precv_data->DataBuf.buf = conn.m_precv_data->Buffer;
conn.m_precv_data->m_op_type = op_type_recv;
InterlockedExchange(&conn.m_precv_data->m_is_in_use, 1);
DWORD bytes_recvd = 0;
DWORD flags = 0;
::InterlockedExchange(&conn.m_precv_data->m_is_in_use, 1);
{
PROFILE_FUNC("[add_new_connection] ::WSARecv");
res = ::WSARecv(conn.m_sock, &(conn.m_precv_data->DataBuf), 1, &bytes_recvd , &flags, &(conn.m_precv_data->m_overlapped), NULL);
}
if(res == SOCKET_ERROR )
{
int err = ::WSAGetLastError();
if(WSA_IO_PENDING == err )
{
break;
}
LOG_ERROR("BIG FAIL: WSARecv error code not correct, res=" << res << " last_err=" << err << " " << log_space::get_win32_err_descr(err));
::InterlockedExchange(&conn.m_precv_data->m_is_in_use, 0);
conn.query_shutdown();
//shutdown_connection(&conn);
break;
}
break;
/*else if(0 == res)
{
if(!bytes_recvd)
{
PROFILE_FUNC("[add_new_connection] shutdown_connection");
::InterlockedExchange(&conn.m_precv_data->m_is_in_use, 0);
conn.query_shutdown();
//shutdown_connection(&conn);
break;
}else
{
PROFILE_FUNC("[add_new_connection] handle_recv");
}
}*/
}
}
return true;
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::deinit_server()
{
if(!m_initialized)
return true;
if(INVALID_SOCKET != m_listen_socket)
{
shutdown(m_listen_socket, SD_BOTH);
int res = closesocket(m_listen_socket);
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to closesocket(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
}
m_listen_socket = INVALID_SOCKET;
}
int res = ::WSACleanup();
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to WSACleanup(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
}
m_initialized = false;
return true;
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::send_stop_signal()
{
::InterlockedExchange(&m_stop, 1);
return true;
}
//-------------------------------------------------------------
template<class TProtocol>
bool cp_server_impl<TProtocol>::is_stop_signal()
{
return m_stop?true:false;
}
//-------------------------------------------------------------
}
}

View File

@ -50,7 +50,6 @@
#include "abstract_http_client.h"
#include "http_base.h"
#include "http_auth.h"
#include "to_nonconst_iterator.h"
#include "net_parse_helpers.h"
#include "syncobj.h"

View File

@ -1,180 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include <wininet.h>
#include <atlutil.h>
#pragma comment(lib, "Wininet.lib")
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
namespace epee
{
namespace net_utils
{
inline
bool http_ssl_invoke(const std::string& url, const std::string usr, const std::string psw, std::string& http_response_body, bool use_post = false)
{
bool final_res = false;
ATL::CUrl url_obj;
BOOL crack_rss = url_obj.CrackUrl(string_encoding::convert_to_t<std::basic_string<TCHAR> >(url).c_str());
HINTERNET hinet = ::InternetOpenA(SHARED_JOBSCOMMON_HTTP_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(!hinet)
{
int err = ::GetLastError();
LOG_PRINT("Failed to call InternetOpenA, \nError: " << err << " " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
return false;
}
DWORD dwFlags = 0;
DWORD dwBuffLen = sizeof(dwFlags);
if(usr.size())
{
dwFlags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID|
INTERNET_FLAG_PRAGMA_NOCACHE | SECURITY_FLAG_IGNORE_UNKNOWN_CA|INTERNET_FLAG_SECURE;
}else
{
dwFlags |= INTERNET_FLAG_PRAGMA_NOCACHE;
}
int port = url_obj.GetPortNumber();
BOOL res = FALSE;
HINTERNET hsession = ::InternetConnectA(hinet, string_encoding::convert_to_ansii(url_obj.GetHostName()).c_str(), port/*INTERNET_DEFAULT_HTTPS_PORT*/, usr.c_str(), psw.c_str(), INTERNET_SERVICE_HTTP, dwFlags, NULL);
if(hsession)
{
const std::string uri = string_encoding::convert_to_ansii(url_obj.GetUrlPath()) + string_encoding::convert_to_ansii(url_obj.GetExtraInfo());
HINTERNET hrequest = ::HttpOpenRequestA(hsession, use_post?"POST":NULL, uri.c_str(), NULL, NULL,NULL, dwFlags, NULL);
if(hrequest)
{
while(true)
{
res = ::HttpSendRequestA(hrequest, NULL, 0, NULL, 0);
if(!res)
{
//ERROR_INTERNET_INVALID_CA 45
//ERROR_INTERNET_INVALID_URL (INTERNET_ERROR_BASE + 5)
int err = ::GetLastError();
LOG_PRINT("Failed to call HttpSendRequestA, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
break;
}
DWORD code = 0;
DWORD buf_len = sizeof(code);
DWORD index = 0;
res = ::HttpQueryInfo(hrequest, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, &code, &buf_len, &index);
if(!res)
{
//ERROR_INTERNET_INVALID_CA 45
//ERROR_INTERNET_INVALID_URL (INTERNET_ERROR_BASE + 5)
int err = ::GetLastError();
LOG_PRINT("Failed to call HttpQueryInfo, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
break;
}
if(code < 200 || code > 299)
{
LOG_PRINT("Wrong server response, HttpQueryInfo returned statuse code" << code , LOG_LEVEL_0);
break;
}
char buff[100000] = {0};
DWORD readed = 0;
while(true)
{
res = ::InternetReadFile(hrequest, buff, sizeof(buff), &readed);
if(!res)
{
int err = ::GetLastError();
LOG_PRINT("Failed to call InternetReadFile, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
break;
}
if(readed)
{
http_response_body.append(buff, readed);
}
else
break;
}
if(!res)
break;
//we success
final_res = true;
res = ::InternetCloseHandle(hrequest);
if(!res)
{
int err = ::GetLastError();
LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
}
break;
}
}
else
{
//ERROR_INTERNET_INVALID_CA
int err = ::GetLastError();
LOG_PRINT("Failed to call InternetOpenUrlA, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
return false;
}
res = ::InternetCloseHandle(hsession);
if(!res)
{
int err = ::GetLastError();
LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
}
}else
{
int err = ::GetLastError();
LOG_PRINT("Failed to call InternetConnectA(" << string_encoding::convert_to_ansii(url_obj.GetHostName()) << ", port " << port << " \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
}
res = ::InternetCloseHandle(hinet);
if(!res)
{
int err = ::GetLastError();
LOG_PRINT("Failed to call InternetCloseHandle, \nError: " << log_space::get_win32_err_descr(err), LOG_LEVEL_0);
}
return final_res;
}
}
}

View File

@ -33,7 +33,6 @@
#include <boost/optional/optional.hpp>
#include <string>
#include "net_utils_base.h"
#include "to_nonconst_iterator.h"
#include "http_auth.h"
#include "http_base.h"

View File

@ -376,7 +376,7 @@ namespace net_utils
m_query_info.m_http_method_str = result[2];
m_query_info.m_full_request_str = result[0];
m_cache.erase(m_cache.begin(), to_nonsonst_iterator(m_cache, result[0].second));
m_cache.erase(m_cache.begin(), result[0].second);
m_state = http_state_retriving_header;

View File

@ -1,52 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _HTTP_SERVER_CP_H_
#define _HTTP_SERVER_CP_H_
#include "abstract_tcp_server_cp.h"
#include "http_server.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
namespace epee
{
namespace net_utils
{
typedef cp_server_impl<http::simple_http_connection_handler> cp_http_server_file_system;
typedef cp_server_impl<http::http_custom_handler> cp_http_server_custum_handling;
}
}
#endif

View File

@ -1,51 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _HTTP_SERVER_CP2_H_
#define _HTTP_SERVER_CP2_H_
#include "abstract_tcp_server2.h"
#include "http_protocol_handler.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
namespace epee
{
namespace net_utils
{
typedef boosted_tcp_server<http::simple_http_connection_handler<> > boosted_http_server_file_system;
typedef boosted_tcp_server<http::http_custom_handler<> > boosted_http_server_custum_handling;
}
}
#endif

View File

@ -1,48 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _HTTP_SERVER_CP_H_
#define _HTTP_SERVER_CP_H_
#include "abstract_tcp_server.h"
#include "http_server.h"
namespace epee
{
namespace net_utils
{
typedef abstract_tcp_server<http::simple_http_connection_handler> mt_http_server_file_system;
typedef abstract_tcp_server<http::http_custom_handler> mt_http_server_custum_handling;
}
}
#endif

View File

@ -1,167 +0,0 @@
#ifndef JSONRPC_PROTOCOL_HANDLER_H
#define JSONRPC_PROTOCOL_HANDLER_H
#include <cstdint>
#include <string>
#include "net/net_utils_base.h"
#include "jsonrpc_structs.h"
#include "storages/portable_storage.h"
#include "storages/portable_storage_template_helper.h"
namespace epee
{
namespace net_utils
{
namespace jsonrpc2
{
inline
std::string& make_error_resp_json(int64_t code, const std::string& message,
std::string& response_data,
const epee::serialization::storage_entry& id = nullptr)
{
epee::json_rpc::error_response rsp;
rsp.id = id;
rsp.jsonrpc = "2.0";
rsp.error.code = code;
rsp.error.message = message;
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_data, 0, false);
response_data += "\n";
return response_data;
}
template<class t_connection_context>
struct i_jsonrpc2_server_handler
{
virtual ~i_jsonrpc2_server_handler()
{}
virtual bool handle_rpc_request(const std::string& req_data,
std::string& resp_data,
t_connection_context& conn_context) = 0;
virtual bool init_server_thread()
{ return true; }
virtual bool deinit_server_thread()
{ return true; }
};
template<class t_connection_context>
struct jsonrpc2_server_config
{
i_jsonrpc2_server_handler<t_connection_context>* m_phandler;
critical_section m_lock;
};
template<class t_connection_context = net_utils::connection_context_base>
class jsonrpc2_connection_handler
{
public:
typedef t_connection_context connection_context;
typedef jsonrpc2_server_config<t_connection_context> config_type;
jsonrpc2_connection_handler(i_service_endpoint* psnd_hndlr,
config_type& config,
t_connection_context& conn_context)
: m_psnd_hndlr(psnd_hndlr),
m_config(config),
m_conn_context(conn_context),
m_is_stop_handling(false)
{}
virtual ~jsonrpc2_connection_handler()
{}
bool release_protocol()
{
return true;
}
virtual bool thread_init()
{
return true;
}
virtual bool thread_deinit()
{
return true;
}
void handle_qued_callback()
{}
bool after_init_connection()
{
return true;
}
virtual bool handle_recv(const void* ptr, size_t cb)
{
std::string buf((const char*)ptr, cb);
LOG_PRINT_L0("JSONRPC2_RECV: " << ptr << "\r\n" << buf);
bool res = handle_buff_in(buf);
return res;
}
private:
bool handle_buff_in(std::string& buf)
{
if(m_cache.size())
m_cache += buf;
else
m_cache.swap(buf);
m_is_stop_handling = false;
while (!m_is_stop_handling) {
std::string::size_type pos = match_end_of_request(m_cache);
if (std::string::npos == pos) {
m_is_stop_handling = true;
if (m_cache.size() > 4096) {
LOG_ERROR("jsonrpc2_connection_handler::handle_buff_in: Too long request");
return false;
}
break;
} else {
extract_cached_request_and_handle(pos);
}
if (!m_cache.size()) {
m_is_stop_handling = true;
}
}
return true;
}
bool extract_cached_request_and_handle(std::string::size_type pos)
{
std::string request_data(m_cache.begin(), m_cache.begin() + pos);
m_cache.erase(0, pos);
return handle_request_and_send_response(request_data);
}
bool handle_request_and_send_response(const std::string& request_data)
{
CHECK_AND_ASSERT_MES(m_config.m_phandler, false, "m_config.m_phandler is NULL!!!!");
std::string response_data;
LOG_PRINT_L3("JSONRPC2_REQUEST: >> \r\n" << request_data);
bool rpc_result = m_config.m_phandler->handle_rpc_request(request_data, response_data, m_conn_context);
LOG_PRINT_L3("JSONRPC2_RESPONSE: << \r\n" << response_data);
m_psnd_hndlr->do_send((void*)response_data.data(), response_data.size());
return rpc_result;
}
std::string::size_type match_end_of_request(const std::string& buf)
{
std::string::size_type res = buf.find("\n");
if(std::string::npos != res) {
return res + 2;
}
return res;
}
protected:
i_service_endpoint* m_psnd_hndlr;
private:
config_type& m_config;
t_connection_context& m_conn_context;
std::string m_cache;
bool m_is_stop_handling;
};
}
}
}
#endif /* JSONRPC_PROTOCOL_HANDLER_H */

View File

@ -1,86 +0,0 @@
#ifndef JSONRPC_SERVER_HANDLERS_MAP_H
#define JSONRPC_SERVER_HANDLERS_MAP_H
#include <string>
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage_template_helper.h"
#include "storages/portable_storage_base.h"
#include "jsonrpc_structs.h"
#include "jsonrpc_protocol_handler.h"
#define BEGIN_JSONRPC2_MAP(t_connection_context) \
bool handle_rpc_request(const std::string& req_data, \
std::string& resp_data, \
t_connection_context& m_conn_context) \
{ \
bool handled = false; \
uint64_t ticks = epee::misc_utils::get_tick_count(); \
epee::serialization::portable_storage ps; \
if (!ps.load_from_json(req_data)) \
{ \
epee::net_utils::jsonrpc2::make_error_resp_json(-32700, "Parse error", resp_data); \
return true; \
} \
epee::serialization::storage_entry id_; \
id_ = epee::serialization::storage_entry(std::string()); \
if (!ps.get_value("id", id_, nullptr)) \
{ \
epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data); \
return true; \
} \
std::string callback_name; \
if (!ps.get_value("method", callback_name, nullptr)) \
{ \
epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data, id_); \
return true; \
} \
if (false) return true; //just a stub to have "else if"
#define PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
handled = true; \
boost::value_initialized<epee::json_rpc::request<command_type::request> > req_; \
epee::json_rpc::request<command_type::request>& req = static_cast<epee::json_rpc::request<command_type::request>&>(req_);\
if(!req.load(ps)) \
{ \
epee::net_utils::jsonrpc2::make_error_resp_json(-32602, "Invalid params", resp_data, req.id); \
return true; \
} \
uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
boost::value_initialized<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> > resp_; \
epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error>& resp = static_cast<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> &>(resp_); \
resp.jsonrpc = "2.0"; \
resp.id = req.id;
#define FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
uint64_t ticks2 = epee::misc_utils::get_tick_count(); \
epee::serialization::store_t_to_json(resp, resp_data, 0, false); \
resp_data += "\n"; \
uint64_t ticks3 = epee::misc_utils::get_tick_count(); \
LOG_PRINT("[" << method_name << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2);
#define MAP_JSONRPC2_WE(method_name, callback_f, command_type) \
else if (callback_name == method_name) \
{ \
PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
fail_resp.jsonrpc = "2.0"; \
fail_resp.id = req.id; \
if(!callback_f(req.params, resp.result, fail_resp.error, m_conn_context)) \
{ \
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), resp_data, 0, false); \
resp_data += "\n"; \
return true; \
} \
FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
return true; \
}
#define END_JSONRPC2_MAP() \
epee::net_utils::jsonrpc2::make_error_resp_json(-32601, "Method not found", resp_data, id_); \
return true; \
}
#endif /* JSONRPC_SERVER_HANDLERS_MAP_H */

View File

@ -1,84 +0,0 @@
#ifndef JSONRPC_SERVER_IMPL_BASE_H
#define JSONRPC_SERVER_IMPL_BASE_H
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "net/jsonrpc_protocol_handler.h"
#include "net/jsonrpc_server_handlers_map.h"
#include "net/abstract_tcp_server2.h"
namespace epee
{
template<class t_child_class, class t_connection_context = epee::net_utils::connection_context_base>
class jsonrpc_server_impl_base: public net_utils::jsonrpc2::i_jsonrpc2_server_handler<t_connection_context>
{
public:
jsonrpc_server_impl_base()
: m_net_server()
{}
explicit jsonrpc_server_impl_base(boost::asio::io_service& external_io_service)
: m_net_server(external_io_service)
{}
bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0")
{
//set self as callback handler
m_net_server.get_config_object().m_phandler = static_cast<t_child_class*>(this);
LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
bool res = m_net_server.init_server(bind_port, bind_ip);
if (!res)
{
LOG_ERROR("Failed to bind server");
return false;
}
return true;
}
bool run(size_t threads_count, bool wait = true)
{
//go to loop
LOG_PRINT("Run net_service loop( " << threads_count << " threads)...", LOG_LEVEL_0);
if(!m_net_server.run_server(threads_count, wait))
{
LOG_ERROR("Failed to run net tcp server!");
}
if(wait)
LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0);
return true;
}
bool deinit()
{
return m_net_server.deinit_server();
}
bool timed_wait_server_stop(uint64_t ms)
{
return m_net_server.timed_wait_server_stop(ms);
}
bool send_stop_signal()
{
m_net_server.send_stop_signal();
return true;
}
int get_binded_port()
{
return m_net_server.get_binded_port();
}
protected:
net_utils::boosted_tcp_server<net_utils::jsonrpc2::jsonrpc2_connection_handler<t_connection_context> > m_net_server;
};
}
#endif /* JSONRPC_SERVER_IMPL_BASE_H */

View File

@ -1,89 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _LEVIN_CLIENT_H_
#define _LEVIN_CLIENT_H_
#include "net_helper.h"
#include "levin_base.h"
#ifndef MAKE_IP
#define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24))
#endif
namespace epee
{
namespace levin
{
/************************************************************************/
/* */
/************************************************************************/
class levin_client_impl
{
public:
levin_client_impl();
virtual ~levin_client_impl();
bool connect(u_long ip, int port, unsigned int timeout, const std::string& bind_ip = "0.0.0.0");
bool connect(const std::string& addr, int port, unsigned int timeout, const std::string& bind_ip = "0.0.0.0");
bool is_connected();
bool disconnect();
virtual int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out);
virtual int notify(int command, const std::string& in_buff);
protected:
net_utils::blocked_mode_client m_transport;
};
/************************************************************************/
/* */
/************************************************************************/
class levin_client_impl2: public levin_client_impl
{
public:
int invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out);
int notify(int command, const std::string& in_buff);
};
}
namespace net_utils
{
typedef levin::levin_client_impl levin_client;
typedef levin::levin_client_impl2 levin_client2;
}
}
#include "levin_client.inl"
#endif //_LEVIN_CLIENT_H_

View File

@ -1,199 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#include "string_tools.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
namespace epee
{
namespace levin
{
inline
bool levin_client_impl::connect(u_long ip, int port, unsigned int timeout, const std::string& bind_ip)
{
return m_transport.connect(string_tools::get_ip_string_from_int32(ip), port, timeout, timeout, bind_ip);
}
//------------------------------------------------------------------------------
inline
bool levin_client_impl::connect(const std::string& addr, int port, unsigned int timeout, const std::string& bind_ip)
{
return m_transport.connect(addr, port, timeout, timeout, bind_ip);
}
//------------------------------------------------------------------------------
inline
bool levin_client_impl::is_connected()
{
return m_transport.is_connected();
}
//------------------------------------------------------------------------------
inline
bool levin_client_impl::disconnect()
{
return m_transport.disconnect();
}
//------------------------------------------------------------------------------
inline
levin_client_impl::levin_client_impl()
{
}
//------------------------------------------------------------------------------
inline
levin_client_impl::~levin_client_impl()
{
disconnect();
}
//------------------------------------------------------------------------------
inline
int levin_client_impl::invoke(int command, const epee::span<const uint8_t> in_buff, std::string& buff_out)
{
if(!is_connected())
return -1;
bucket_head head = {0};
head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
head.m_cb = SWAP64LE(in_buff.size());
head.m_have_to_return_data = 1;
head.m_command = SWAP32LE(command);
if(!m_transport.send(&head, sizeof(head)))
return -1;
if(!m_transport.send(in_buff))
return -1;
std::string local_buff;
if(!m_transport.recv_n(local_buff, sizeof(bucket_head)))
return -1;
head = *(bucket_head*)local_buff.data();
if(head.m_signature!=SWAP64LE(LEVIN_SIGNATURE))
{
LOG_PRINT_L1("Signature mismatch in response");
return -1;
}
if(!m_transport.recv_n(buff_out, head.m_cb))
return -1;
return head.m_return_code;
}
//------------------------------------------------------------------------------
inline
int levin_client_impl::notify(int command, const std::string& in_buff)
{
if(!is_connected())
return -1;
bucket_head head = {0};
head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
head.m_cb = SWAP64LE(in_buff.size());
head.m_have_to_return_data = 0;
head.m_command = SWAP32LE(command);
if(!m_transport.send((const char*)&head, sizeof(head)))
return -1;
if(!m_transport.send(in_buff))
return -1;
return 1;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
inline
int levin_client_impl2::invoke(int command, epee::span<const uint8_t>string& in_buff, std::string& buff_out)
{
if(!is_connected())
return -1;
bucket_head2 head = {0};
head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
head.m_cb = SWAP64LE(in_buff.size());
head.m_have_to_return_data = 1;
head.m_command = SWAP32LE(command);
head.m_return_code = SWAP32LE(0);
head.m_flags = SWAP32LE(LEVIN_PACKET_REQUEST);
head.m_protocol_version = SWAP32LE(LEVIN_PROTOCOL_VER_1);
if(!m_transport.send(&head, sizeof(head)))
return -1;
if(!m_transport.send(in_buff))
return -1;
std::string local_buff;
if(!m_transport.recv_n(local_buff, sizeof(bucket_head2)))
return -1;
head = *(bucket_head2*)local_buff.data();
if(head.m_signature != SWAP64LE(LEVIN_SIGNATURE))
{
LOG_PRINT_L1("Signature mismatch in response");
return -1;
}
if(!m_transport.recv_n(buff_out, SWAP64LE(head.m_cb)))
return -1;
return head.m_return_code;
}
//------------------------------------------------------------------------------
inline
int levin_client_impl2::notify(int command, const std::string& in_buff)
{
if(!is_connected())
return -1;
bucket_head2 head = {0};
head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
head.m_cb = SWAP64LE(in_buff.size());
head.m_have_to_return_data = 0;
head.m_command = SWAP32LE(command);
head.m_return_code = SWAP32LE(0);
head.m_flags = SWAP32LE(LEVIN_PACKET_REQUEST);
head.m_protocol_version = SWAP32LE(LEVIN_PROTOCOL_VER_1);
if(!m_transport.send((const char*)&head, sizeof(head)))
return -1;
if(!m_transport.send(in_buff))
return -1;
return 1;
}
}
}
//------------------------------------------------------------------------------

View File

@ -1,585 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include ""
#include "net_helper.h"
#include "levin_base.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
namespace epee
{
namespace levin
{
/************************************************************************
* levin_client_async - probably it is not really fast implementation,
* each handler thread could make up to 30 ms latency.
* But, handling events in reader thread will cause dead locks in
* case of recursive call (call invoke() to the same connection
* on reader thread on remote invoke() handler)
***********************************************************************/
class levin_client_async
{
levin_commands_handler* m_pcommands_handler;
void (*commands_handler_destroy)(levin_commands_handler*);
volatile uint32_t m_is_stop;
volatile uint32_t m_threads_count;
::critical_section m_send_lock;
std::string m_local_invoke_buff;
::critical_section m_local_invoke_buff_lock;
volatile int m_invoke_res;
volatile uint32_t m_invoke_data_ready;
volatile uint32_t m_invoke_is_active;
boost::mutex m_invoke_event;
boost::condition_variable m_invoke_cond;
size_t m_timeout;
::critical_section m_recieved_packets_lock;
struct packet_entry
{
bucket_head m_hd;
std::string m_body;
uint32_t m_connection_index;
};
std::list<packet_entry> m_recieved_packets;
/*
m_current_connection_index needed when some connection was broken and reconnected - in this
case we could have some received packets in que, which shoud not be handled
*/
volatile uint32_t m_current_connection_index;
::critical_section m_invoke_lock;
::critical_section m_reciev_packet_lock;
::critical_section m_connection_lock;
net_utils::blocked_mode_client m_transport;
public:
levin_client_async():m_pcommands_handler(NULL), commands_handler_destroy(NULL), m_is_stop(0), m_threads_count(0), m_invoke_data_ready(0), m_invoke_is_active(0)
{}
levin_client_async(const levin_client_async& /*v*/):m_pcommands_handler(NULL), commands_handler_destroy(NULL), m_is_stop(0), m_threads_count(0), m_invoke_data_ready(0), m_invoke_is_active(0)
{}
~levin_client_async()
{
boost::interprocess::ipcdetail::atomic_write32(&m_is_stop, 1);
disconnect();
while(boost::interprocess::ipcdetail::atomic_read32(&m_threads_count))
::Sleep(100);
set_handler(NULL);
}
void set_handler(levin_commands_handler* phandler, void (*destroy)(levin_commands_handler*) = NULL)
{
if (commands_handler_destroy && m_pcommands_handler)
(*commands_handler_destroy)(m_pcommands_handler);
m_pcommands_handler = phandler;
m_pcommands_handler_destroy = destroy;
}
bool connect(uint32_t ip, uint32_t port, uint32_t timeout)
{
loop_call_guard();
critical_region cr(m_connection_lock);
m_timeout = timeout;
bool res = false;
CRITICAL_REGION_BEGIN(m_reciev_packet_lock);
CRITICAL_REGION_BEGIN(m_send_lock);
res = levin_client_impl::connect(ip, port, timeout);
boost::interprocess::ipcdetail::atomic_inc32(&m_current_connection_index);
CRITICAL_REGION_END();
CRITICAL_REGION_END();
if(res && !boost::interprocess::ipcdetail::atomic_read32(&m_threads_count) )
{
//boost::interprocess::ipcdetail::atomic_write32(&m_is_stop, 0);//m_is_stop = false;
boost::thread( boost::bind(&levin_duplex_client::reciever_thread, this) );
boost::thread( boost::bind(&levin_duplex_client::handler_thread, this) );
boost::thread( boost::bind(&levin_duplex_client::handler_thread, this) );
}
return res;
}
bool is_connected()
{
loop_call_guard();
critical_region cr(m_cs);
return levin_client_impl::is_connected();
}
inline
bool check_connection()
{
loop_call_guard();
critical_region cr(m_cs);
if(!is_connected())
{
if( !reconnect() )
{
LOG_ERROR("Reconnect Failed. Failed to invoke() because not connected!");
return false;
}
}
return true;
}
//------------------------------------------------------------------------------
inline
bool recv_n(SOCKET s, char* pbuff, size_t cb)
{
while(cb)
{
int res = ::recv(m_socket, pbuff, (int)cb, 0);
if(SOCKET_ERROR == res)
{
if(!m_connected)
return false;
int err = ::WSAGetLastError();
LOG_ERROR("Failed to recv(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
disconnect();
//reconnect();
return false;
}else if(res == 0)
{
disconnect();
//reconnect();
return false;
}
LOG_PRINT_L4("[" << m_socket <<"] RECV " << res);
cb -= res;
pbuff += res;
}
return true;
}
//------------------------------------------------------------------------------
inline
bool recv_n(SOCKET s, std::string& buff)
{
size_t cb_remain = buff.size();
char* m_current_ptr = (char*)buff.data();
return recv_n(s, m_current_ptr, cb_remain);
}
bool disconnect()
{
//boost::interprocess::ipcdetail::atomic_write32(&m_is_stop, 1);//m_is_stop = true;
loop_call_guard();
critical_region cr(m_cs);
levin_client_impl::disconnect();
CRITICAL_REGION_BEGIN(m_local_invoke_buff_lock);
m_local_invoke_buff.clear();
m_invoke_res = LEVIN_ERROR_CONNECTION_DESTROYED;
CRITICAL_REGION_END();
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_data_ready, 1); //m_invoke_data_ready = true;
m_invoke_cond.notify_all();
return true;
}
void loop_call_guard()
{
}
void on_leave_invoke()
{
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_is_active, 0);
}
int invoke(const GUID& target, int command, const std::string& in_buff, std::string& buff_out)
{
critical_region cr_invoke(m_invoke_lock);
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_is_active, 1);
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_data_ready, 0);
misc_utils::destr_ptr hdlr = misc_utils::add_exit_scope_handler(boost::bind(&levin_duplex_client::on_leave_invoke, this));
loop_call_guard();
if(!check_connection())
return LEVIN_ERROR_CONNECTION_DESTROYED;
bucket_head head = {0};
head.m_signature = LEVIN_SIGNATURE;
head.m_cb = in_buff.size();
head.m_have_to_return_data = 1;
head.m_id = target;
#ifdef TRACE_LEVIN_PACKETS_BY_GUIDS
::UuidCreate(&head.m_id);
#endif
head.m_command = command;
head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
head.m_flags = LEVIN_PACKET_REQUEST;
LOG_PRINT("[" << m_socket <<"] Sending invoke data", LOG_LEVEL_4);
CRITICAL_REGION_BEGIN(m_send_lock);
LOG_PRINT_L4("[" << m_socket <<"] SEND " << sizeof(head));
int res = ::send(m_socket, (const char*)&head, sizeof(head), 0);
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
disconnect();
return LEVIN_ERROR_CONNECTION_DESTROYED;
}
LOG_PRINT_L4("[" << m_socket <<"] SEND " << (int)in_buff.size());
res = ::send(m_socket, in_buff.data(), (int)in_buff.size(), 0);
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
disconnect();
return LEVIN_ERROR_CONNECTION_DESTROYED;
}
CRITICAL_REGION_END();
LOG_PRINT_L4("LEVIN_PACKET_SENT. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
//hard coded timeout in 10 minutes for maximum invoke period. if it happens, it could mean only some real troubles.
boost::system_time timeout = boost::get_system_time()+ boost::posix_time::milliseconds(100);
size_t timeout_count = 0;
boost::unique_lock<boost::mutex> lock(m_invoke_event);
while(!boost::interprocess::ipcdetail::atomic_read32(&m_invoke_data_ready))
{
if(!m_invoke_cond.timed_wait(lock, timeout))
{
if(timeout_count < 10)
{
//workaround to avoid freezing at timed_wait called after notify_all.
timeout = boost::get_system_time()+ boost::posix_time::milliseconds(100);
++timeout_count;
continue;
}else if(timeout_count == 10)
{
//workaround to avoid freezing at timed_wait called after notify_all.
timeout = boost::get_system_time()+ boost::posix_time::minutes(10);
++timeout_count;
continue;
}else
{
LOG_PRINT("[" << m_socket <<"] Timeout on waiting invoke result. ", LOG_LEVEL_0);
//disconnect();
return LEVIN_ERROR_CONNECTION_TIMEDOUT;
}
}
}
CRITICAL_REGION_BEGIN(m_local_invoke_buff_lock);
buff_out.swap(m_local_invoke_buff);
m_local_invoke_buff.clear();
CRITICAL_REGION_END();
return m_invoke_res;
}
int notify(const GUID& target, int command, const std::string& in_buff)
{
if(!check_connection())
return LEVIN_ERROR_CONNECTION_DESTROYED;
bucket_head head = {0};
head.m_signature = LEVIN_SIGNATURE;
head.m_cb = in_buff.size();
head.m_have_to_return_data = 0;
head.m_id = target;
#ifdef TRACE_LEVIN_PACKETS_BY_GUIDS
::UuidCreate(&head.m_id);
#endif
head.m_command = command;
head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
head.m_flags = LEVIN_PACKET_REQUEST;
CRITICAL_REGION_BEGIN(m_send_lock);
LOG_PRINT_L4("[" << m_socket <<"] SEND " << sizeof(head));
int res = ::send(m_socket, (const char*)&head, sizeof(head), 0);
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
disconnect();
return LEVIN_ERROR_CONNECTION_DESTROYED;
}
LOG_PRINT_L4("[" << m_socket <<"] SEND " << (int)in_buff.size());
res = ::send(m_socket, in_buff.data(), (int)in_buff.size(), 0);
if(SOCKET_ERROR == res)
{
int err = ::WSAGetLastError();
LOG_ERROR("Failed to send(), err = " << err << " \"" << socket_errors::get_socket_error_text(err) <<"\"");
disconnect();
return LEVIN_ERROR_CONNECTION_DESTROYED;
}
CRITICAL_REGION_END();
LOG_PRINT_L4("LEVIN_PACKET_SENT. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
return 1;
}
private:
bool have_some_data(SOCKET sock, int interval = 1)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(sock, &fds);
fd_set fdse;
FD_ZERO(&fdse);
FD_SET(sock, &fdse);
timeval tv;
tv.tv_sec = interval;
tv.tv_usec = 0;
int sel_res = select(0, &fds, 0, &fdse, &tv);
if(0 == sel_res)
return false;
else if(sel_res == SOCKET_ERROR)
{
if(m_is_stop)
return false;
int err_code = ::WSAGetLastError();
LOG_ERROR("Filed to call select, err code = " << err_code);
disconnect();
}else
{
if(fds.fd_array[0])
{//some read operations was performed
return true;
}else if(fdse.fd_array[0])
{//some error was at the socket
return true;
}
}
return false;
}
bool reciev_and_process_incoming_data()
{
bucket_head head = {0};
uint32_t conn_index = 0;
bool is_request = false;
std::string local_buff;
CRITICAL_REGION_BEGIN(m_reciev_packet_lock);//to protect from socket reconnect between head and body
if(!recv_n(m_socket, (char*)&head, sizeof(head)))
{
if(m_is_stop)
return false;
LOG_ERROR("Failed to recv_n");
return false;
}
conn_index = boost::interprocess::ipcdetail::atomic_read32(&m_current_connection_index);
if(head.m_signature!=LEVIN_SIGNATURE)
{
LOG_ERROR("Signature mismatch in response");
return false;
}
is_request = (head.m_protocol_version == LEVIN_PROTOCOL_VER_1 && head.m_flags&LEVIN_PACKET_REQUEST);
local_buff.resize((size_t)head.m_cb);
if(!recv_n(m_socket, local_buff))
{
if(m_is_stop)
return false;
LOG_ERROR("Filed to reciev");
return false;
}
CRITICAL_REGION_END();
LOG_PRINT_L4("LEVIN_PACKET_RECEIVED. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
if(is_request)
{
CRITICAL_REGION_BEGIN(m_recieved_packets_lock);
m_recieved_packets.resize(m_recieved_packets.size() + 1);
m_recieved_packets.back().m_hd = head;
m_recieved_packets.back().m_body.swap(local_buff);
m_recieved_packets.back().m_connection_index = conn_index;
CRITICAL_REGION_END();
/*
*/
}else
{//this is some response
CRITICAL_REGION_BEGIN(m_local_invoke_buff_lock);
m_local_invoke_buff.swap(local_buff);
m_invoke_res = head.m_return_code;
CRITICAL_REGION_END();
boost::interprocess::ipcdetail::atomic_write32(&m_invoke_data_ready, 1); //m_invoke_data_ready = true;
m_invoke_cond.notify_all();
}
return true;
}
bool reciever_thread()
{
LOG_PRINT_L3("[" << m_socket <<"] Socket reciever thread started.[m_threads_count=" << m_threads_count << "]");
log_space::log_singletone::set_thread_log_prefix("RECIEVER_WORKER");
boost::interprocess::ipcdetail::atomic_inc32(&m_threads_count);
while(!m_is_stop)
{
if(!m_connected)
{
Sleep(100);
continue;
}
if(have_some_data(m_socket, 1))
{
if(!reciev_and_process_incoming_data())
{
if(m_is_stop)
{
break;//boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
//return true;
}
LOG_ERROR("Failed to reciev_and_process_incoming_data. shutting down");
//boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
//disconnect_no_wait();
//break;
}
}
}
boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
LOG_PRINT_L3("[" << m_socket <<"] Socket reciever thread stopped.[m_threads_count=" << m_threads_count << "]");
return true;
}
bool process_recieved_packet(bucket_head& head, const std::string& local_buff, uint32_t conn_index)
{
net_utils::connection_context_base conn_context;
conn_context.m_remote_address = m_address;
if(head.m_have_to_return_data)
{
std::string return_buff;
if(m_pcommands_handler)
head.m_return_code = m_pcommands_handler->invoke(head.m_id, head.m_command, local_buff, return_buff, conn_context);
else
head.m_return_code = LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED;
head.m_cb = return_buff.size();
head.m_have_to_return_data = 0;
head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
head.m_flags = LEVIN_PACKET_RESPONSE;
std::string send_buff((const char*)&head, sizeof(head));
send_buff += return_buff;
CRITICAL_REGION_BEGIN(m_send_lock);
if(conn_index != boost::interprocess::ipcdetail::atomic_read32(&m_current_connection_index))
{//there was reconnect, send response back is not allowed
return true;
}
int res = ::send(m_socket, (const char*)send_buff.data(), send_buff.size(), 0);
if(res == SOCKET_ERROR)
{
int err_code = ::WSAGetLastError();
LOG_ERROR("Failed to send, err = " << err_code);
return false;
}
CRITICAL_REGION_END();
LOG_PRINT_L4("LEVIN_PACKET_SENT. [len=" << head.m_cb << ", flags=" << head.m_flags << ", is_cmd=" << head.m_have_to_return_data <<", cmd_id = " << head.m_command << ", pr_v=" << head.m_protocol_version << ", uid=" << string_tools::get_str_from_guid_a(head.m_id) << "]");
}
else
{
if(m_pcommands_handler)
m_pcommands_handler->notify(head.m_id, head.m_command, local_buff, conn_context);
}
return true;
}
bool handler_thread()
{
LOG_PRINT_L3("[" << m_socket <<"] Socket handler thread started.[m_threads_count=" << m_threads_count << "]");
log_space::log_singletone::set_thread_log_prefix("HANDLER_WORKER");
boost::interprocess::ipcdetail::atomic_inc32(&m_threads_count);
while(!m_is_stop)
{
bool have_some_work = false;
std::string local_buff;
bucket_head bh = {0};
uint32_t conn_index = 0;
CRITICAL_REGION_BEGIN(m_recieved_packets_lock);
if(m_recieved_packets.size())
{
bh = m_recieved_packets.begin()->m_hd;
conn_index = m_recieved_packets.begin()->m_connection_index;
local_buff.swap(m_recieved_packets.begin()->m_body);
have_some_work = true;
m_recieved_packets.pop_front();
}
CRITICAL_REGION_END();
if(have_some_work)
{
process_recieved_packet(bh, local_buff, conn_index);
}else
{
//Idle when no work
Sleep(30);
}
}
boost::interprocess::ipcdetail::atomic_dec32(&m_threads_count);
LOG_PRINT_L3("[" << m_socket <<"] Socket handler thread stopped.[m_threads_count=" << m_threads_count << "]");
return true;
}
};
}
}

View File

@ -1,161 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "levin_base.h"
#include "serializeble_struct_helper.h"
#include "int-util.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
namespace epee
{
namespace levin
{
template<class t_struct>
bool pack_struct_to_levin_message(const t_struct& t, std::string& buff, int command_id)
{
buff.resize(sizeof(levin::bucket_head));
levin::bucket_head& head = *(levin::bucket_head*)(&buff[0]);
head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
head.m_cb = 0;
head.m_have_to_return_data = 1;
head.m_command = SWAP32LE(command_id);
head.m_return_code = SWAP32LE(1);
head.m_reservedA = rand(); //probably some flags in future
head.m_reservedB = rand(); //probably some check summ in future
std::string buff_strg;
if(!StorageNamed::save_struct_as_storage_to_buff_t<t_struct, StorageNamed::DefaultStorageType>(t, buff_strg))
return false;
head.m_cb = SWAP64LE(buff_strg.size());
buff.append(buff_strg);
return true;
}
bool pack_data_to_levin_message(const std::string& data, std::string& buff, int command_id)
{
buff.resize(sizeof(levin::bucket_head));
levin::bucket_head& head = *(levin::bucket_head*)(&buff[0]);
head.m_signature = SWAP64LE(LEVIN_SIGNATURE);
head.m_cb = 0;
head.m_have_to_return_data = 1;
head.m_command = SWAP32LE(command_id);
head.m_return_code = SWAP32LE(1);
head.m_reservedA = rand(); //probably some flags in future
head.m_reservedB = rand(); //probably some check summ in future
head.m_cb = SWAP64LE(data.size());
buff.append(data);
return true;
}
bool load_levin_data_from_levin_message(std::string& levin_data, const std::string& buff, int& command)
{
if(buff.size() < sizeof(levin::bucket_head) )
{
LOG_PRINT_L3("size of buff(" << buff.size() << ") is too small, at load_struct_from_levin_message");
return false;
}
#if BYTE_ORDER == LITTLE_ENDIAN
levin::bucket_head &head = *(levin::bucket_head*)(&buff[0]);
#else
levin::bucket_head head = *(levin::bucket_head*)(&buff[0]);
head.m_signature = SWAP64LE(head.m_signature);
head.m_cb = SWAP64LE(head.m_cb);
head.m_command = SWAP32LE(head.m_command);
head.m_return_code = SWAP32LE(head.m_return_code);
head.m_reservedA = SWAP32LE(head.m_reservedA);
head.m_reservedB = SWAP32LE(head.m_reservedB);
#endif
if(head.m_signature != LEVIN_SIGNATURE)
{
LOG_PRINT_L3("Failed to read signature in levin message, at load_struct_from_levin_message");
return false;
}
if(head.m_cb != buff.size()-sizeof(levin::bucket_head))
{
LOG_PRINT_L3("sizes mismatch, at load_struct_from_levin_message");
return false;
}
//std::string buff_strg;
levin_data.assign(&buff[sizeof(levin::bucket_head)], buff.size()-sizeof(levin::bucket_head));
command = head.m_command;
return true;
}
template<class t_struct>
bool load_struct_from_levin_message(t_struct& t, const std::string& buff, int& command)
{
if(buff.size() < sizeof(levin::bucket_head) )
{
LOG_ERROR("size of buff(" << buff.size() << ") is too small, at load_struct_from_levin_message");
return false;
}
#if BYTE_ORDER == LITTLE_ENDIAN
levin::bucket_head &head = *(levin::bucket_head*)(&buff[0]);
#else
levin::bucket_head head = *(levin::bucket_head*)(&buff[0]);
head.m_signature = SWAP64LE(head.m_signature);
head.m_cb = SWAP64LE(head.m_cb);
head.m_command = SWAP32LE(head.m_command);
head.m_return_code = SWAP32LE(head.m_return_code);
head.m_reservedA = SWAP32LE(head.m_reservedA);
head.m_reservedB = SWAP32LE(head.m_reservedB);
#endif
if(head.m_signature != LEVIN_SIGNATURE)
{
LOG_ERROR("Failed to read signature in levin message, at load_struct_from_levin_message");
return false;
}
if(head.m_cb != buff.size()-sizeof(levin::bucket_head))
{
LOG_ERROR("sizes mismatch, at load_struct_from_levin_message");
return false;
}
std::string buff_strg;
buff_strg.assign(&buff[sizeof(levin::bucket_head)], buff.size()-sizeof(levin::bucket_head));
if(!StorageNamed::load_struct_from_storage_buff_t<t_struct, StorageNamed::DefaultStorageType>(t, buff_strg))
{
LOG_ERROR("Failed to read storage, at load_struct_from_levin_message");
return false;
}
command = head.m_command;
return true;
}
}
}

View File

@ -37,7 +37,7 @@
#include "buffer.h"
#include "misc_language.h"
#include "syncobj.h"
#include "misc_os_dependent.h"
#include "time_helper.h"
#include "int-util.h"
#include <random>

View File

@ -1,47 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _HTTP_SERVER_CP_H_
#define _HTTP_SERVER_CP_H_
#include "abstract_tcp_server_cp.h"
#include "levin_protocol_handler.h"
namespace epee
{
namespace net_utils
{
typedef cp_server_impl<levin::protocol_handler> cp_levin_server;
}
}
#endif

View File

@ -1,49 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _HTTP_SERVER_CP_H_
#define _HTTP_SERVER_CP_H_
#include "abstract_tcp_server2.h"
#include "levin_protocol_handler.h"
#include "levin_protocol_handler_async.h"
namespace epee
{
namespace net_utils
{
typedef boosted_tcp_server<levin::protocol_handler<> > boosted_levin_server;
typedef boosted_tcp_server<levin::async_protocol_handler<> > boosted_levin_async_server;
}
}
#endif

View File

@ -27,7 +27,6 @@
#pragma once
#include <string>
#include "int-util.h"
// IP addresses are kept in network byte order
@ -44,9 +43,9 @@ namespace epee
ip = SWAP32LE(ip);
/*
local ip area
10.0.0.0 10.255.255.255
172.16.0.0 172.31.255.255
192.168.0.0 192.168.255.255
10.0.0.0 ... 10.255.255.255
172.16.0.0 ... 172.31.255.255
192.168.0.0 ... 192.168.255.255
*/
if( (ip | 0xffffff00) == 0xffffff0a)
return true;
@ -71,7 +70,7 @@ namespace epee
//MAKE_IP
/*
loopback ip
127.0.0.0 127.255.255.255
127.0.0.0 ... 127.255.255.255
*/
return false;
}

View File

@ -1,47 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _MULTIPROTOCOLS_SERVER_H_
#define _MULTIPROTOCOLS_SERVER_H_
//#include "abstract_tcp_server_cp.h"
#include "protocol_switcher.h"
#include "abstract_tcp_server2.h"
namespace epee
{
namespace net_utils
{
//typedef cp_server_impl<net_utils::protocol_switcher> multiprotocol_server;
typedef boosted_tcp_server<net_utils::protocol_switcher> boosted_multiprotocol_server;
}
}
#endif //_MULTIPROTOCOLS_SERVER_H_

View File

@ -1,376 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _MUNIN_CONNECTION_HANDLER_H_
#define _MUNIN_CONNECTION_HANDLER_H_
#include <string>
#include "net_utils_base.h"
#include "to_nonconst_iterator.h"
#include "http_base.h"
#include "reg_exp_definer.h"
#define MUNIN_ARGS_DEFAULT(vertial_lable_str) "graph_args --base 1000 -l 0 --vertical-label " vertial_lable_str " \n"
#define MUNIN_ARGS_FORCE_AUPPER_LIMIT(vertial_lable_str, limit) "graph_args --base 1000 -l 0 --vertical-label " vertial_lable_str " --rigid --upper-limit " limit " \n"
#define MUNIN_TITLE(title_str) "graph_title " title_str "\n"
#define MUNIN_CATEGORY(category_str) "graph_category " category_str "\n"
#define MUNIN_INFO(info_str) "graph_info " info_str "\n"
#define MUNIN_ENTRY(var_name) #var_name".label " #var_name "\n" #var_name".info "#var_name".\n"
#define MUNIN_ENTRY_AREA(var_name) #var_name".label " #var_name "\n" #var_name".info "#var_name".\n" #var_name".draw AREASTACK\n"
#define MUNIN_ENTRY_ALIAS(var_name, alias) #var_name".label " #alias"\n" #var_name".info "#alias".\n"
#define BEGIN_MUNIN_SERVICE(servivece_name_str) if(servivece_name_str == pservice->m_service_name) {
#define END_MUNIN_SERVICE() }
#define MUNIN_SERVICE_PARAM(munin_var_name_str, variable) paramters_text += std::string() + munin_var_name_str ".value " + boost::lexical_cast<std::string>(variable) + "\n"
namespace epee
{
namespace net_utils
{
namespace munin
{
/************************************************************************/
/* */
/************************************************************************/
struct munin_service;
struct munin_service_data_provider
{
virtual bool update_service_data(munin_service* pservice, std::string& paramters_text)=0;
};
struct munin_service
{
std::string m_service_name;
std::string m_service_config_string;
munin_service_data_provider* m_pdata_provider;
};
struct node_server_config
{
std::list<munin_service> m_services;
//TODO:
};
struct fake_send_handler: public i_service_endpoint
{
virtual bool do_send(const void* ptr, size_t cb)
{
m_cache += std::string((const char*)ptr, cb);
return true;
}
public:
std::string m_cache;
};
/************************************************************************/
/* */
/************************************************************************/
class munin_node_server_connection_handler
{
public:
typedef node_server_config config_type;
typedef connection_context_base connection_context;
munin_node_server_connection_handler(i_service_endpoint* psnd_hndlr, config_type& config, const connection_context_base& context):m_psnd_hndlr(psnd_hndlr),
m_machine_state(http_state_retriving_comand_line),
m_config(config)
{
init();
}
virtual ~munin_node_server_connection_handler()
{
}
bool release_protocol()
{
return true;
}
bool after_init_connection()
{
std::string hello_str = "# munin node at ";
hello_str += m_host_name + "\n";
send_hook(hello_str);
return true;
}
virtual bool thread_init()
{
return true;
}
virtual bool thread_deinit()
{
return true;
}
void handle_qued_callback()
{
}
virtual bool handle_recv(const void* ptr, size_t cb)
{
const char* pbuff = (const char*)ptr;
std::string recvd_buff(pbuff, cb);
LOG_PRINT("munin_recv: \n" << recvd_buff, LOG_LEVEL_3);
m_cache += recvd_buff;
bool stop_handling = false;
while(!stop_handling)
{
switch(m_machine_state)
{
case http_state_retriving_comand_line:
{
std::string::size_type fpos = m_cache.find('\n');
if(std::string::npos != fpos )
{
bool res = handle_command(m_cache);
if(!res)
return false;
m_cache.erase(0, fpos+1);
continue;
}
stop_handling = true;
}
break;
case http_state_error:
stop_handling = true;
return false;
default:
LOG_ERROR("Error in munin state machine! Unknown state=" << m_machine_state);
stop_handling = true;
m_machine_state = http_state_error;
return false;
}
}
return true;
}
private:
bool init()
{
char hostname[64] = {0};
int res = gethostname(hostname, 64);
hostname[63] = 0;//be happy
m_host_name = hostname;
return true;
}
bool handle_command(const std::string& command)
{
// list, nodes, config, fetch, version or quit
STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^((list)|(nodes)|(config)|(fetch)|(version)|(quit))(\\s+(\\S+))?", boost::regex::icase | boost::regex::normal);
// 12 3 4 5 6 7 8 9
size_t match_len = 0;
boost::smatch result;
if(boost::regex_search(command, result, rexp_match_command_line, boost::match_default) && result[0].matched)
{
if(result[2].matched)
{//list command
return handle_list_command();
}else if(result[3].matched)
{//nodes command
return handle_nodes_command();
}else if(result[4].matched)
{//config command
if(result[9].matched)
return handle_config_command(result[9]);
else
{
send_hook("Unknown service\n");
}
}else if(result[5].matched)
{//fetch command
if(result[9].matched)
return handle_fetch_command(result[9]);
else
{
send_hook("Unknown service\n");
}
}else if(result[6].matched)
{//version command
return handle_version_command();
}else if(result[7].matched)
{//quit command
return handle_quit_command();
}
else
return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");
}
return send_hook("Unknown command. Try list, nodes, config, fetch, version or quit\n");
}
bool handle_list_command()
{
std::string buff_to_send;
for(std::list<munin_service>::const_iterator it = m_config.m_services.begin(); it!=m_config.m_services.end();it++)
{
buff_to_send += it->m_service_name + " ";
}
buff_to_send+='\n';
return send_hook(buff_to_send);
}
bool handle_nodes_command()
{
//supports only one node - host name
send_hook(m_host_name + "\n.\n");
return true;
}
bool handle_config_command(const std::string& service_name)
{
munin_service* psrv = get_service_by_name(service_name);
if(!psrv)
return send_hook(std::string() + "Unknown service\n");
return send_hook(psrv->m_service_config_string + ".\n");
}
bool handle_fetch_command(const std::string& service_name)
{
munin_service* psrv = get_service_by_name(service_name);
if(!psrv)
return send_hook(std::string() + "Unknown service\n");
std::string buff;
psrv->m_pdata_provider->update_service_data(psrv, buff);
buff += ".\n";
return send_hook(buff);
}
bool handle_version_command()
{
return send_hook("Munin node component by Andrey Sabelnikov\n");
}
bool handle_quit_command()
{
return false;
}
bool send_hook(const std::string& buff)
{
LOG_PRINT("munin_send: \n" << buff, LOG_LEVEL_3);
if(m_psnd_hndlr)
return m_psnd_hndlr->do_send(buff.data(), buff.size());
else
return false;
}
munin_service* get_service_by_name(const std::string& srv_name)
{
std::list<munin_service>::iterator it = m_config.m_services.begin();
for(; it!=m_config.m_services.end(); it++)
if(it->m_service_name == srv_name)
break;
if(it==m_config.m_services.end())
return NULL;
return &(*it);
}
enum machine_state{
http_state_retriving_comand_line,
http_state_error
};
config_type& m_config;
machine_state m_machine_state;
std::string m_cache;
std::string m_host_name;
protected:
i_service_endpoint* m_psnd_hndlr;
};
inline bool test_self()
{
/*WSADATA w;
::WSAStartup(MAKEWORD(1, 1), &w);
node_server_config sc;
sc.m_services.push_back(munin_service());
sc.m_services.back().m_service_name = "test_service";
sc.m_services.back().m_service_config_string =
"graph_args --base 1000 -l 0 --vertical-label N --upper-limit 329342976\n"
"graph_title REPORTS STATICTICS\n"
"graph_category bind\n"
"graph_info This graph shows how many reports came in fixed time period.\n"
"graph_order apps free swap\n"
"apps.label apps\n"
"apps.draw AREA\n"
"apps.info Memory used by user-space applications.\n"
"swap.label swap\n"
"swap.draw STACK\n"
"swap.info Swap space used.\n"
"free.label unused\n"
"free.draw STACK\n"
"free.info Wasted memory. Memory that is not used for anything at all.\n"
"committed.label committed\n"
"committed.draw LINE2\n"
"committed.warn 625410048\n"
"committed.info The amount of memory that would be used if all the memory that's been allocated were to be used.\n";
sc.m_services.push_back(munin_service());
sc.m_services.back().m_service_name = "test_service1";
fake_send_handler fh;
munin_node_server_connection_handler mh(&fh, sc);
std::string buff = "list\n";
mh.handle_recv(buff.data(), buff.size());
buff = "nodes\n";
mh.handle_recv(buff.data(), buff.size());
*/
return true;
}
}
}
}
#endif//!_MUNIN_CONNECTION_HANDLER_H_

View File

@ -1,49 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _MUNIN_NODE_SERVER_H_
#define _MUNIN_NODE_SERVER_H_
#include <string>
//#include "net_utils_base.h"
#include "munin_connection_handler.h"
//#include "abstract_tcp_server.h"
//#include "abstract_tcp_server_cp.h"
#include "abstract_tcp_server2.h"
namespace epee
{
namespace net_utils
{
namespace munin
{
typedef boosted_tcp_server<munin_node_server_connection_handler> munin_node_server;
//typedef cp_server_impl<munin_node_server_connection_handler> munin_node_cp_server;
}
}
}
#endif//!_MUNIN_NODE_SERVER_H_

View File

@ -1,38 +0,0 @@
// Copyright (c) 2019-2022, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
namespace epee
{
namespace net_utils
{
struct ssl_authentication_t;
class ssl_options_t;
}
}

View File

@ -59,7 +59,6 @@
#include <boost/asio/deadline_timer.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "misc_language.h"
#include "pragma_comp_defs.h"
#include <sstream>
#include <iomanip>
#include <algorithm>

View File

@ -1,121 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _PROTOCOL_SWITCHER_H_
#define _PROTOCOL_SWITCHER_H_
#include "levin_base.h"
#include "http_server.h"
#include "levin_protocol_handler.h"
//#include "abstract_tcp_server.h"
namespace epee
{
namespace net_utils
{
struct protocl_switcher_config
{
http::http_custom_handler::config_type m_http_config;
levin::protocol_handler::config_type m_levin_config;
};
struct i_protocol_handler
{
virtual bool handle_recv(const void* ptr, size_t cb)=0;
};
template<class t>
class t_protocol_handler: public i_protocol_handler
{
public:
typedef t t_type;
t_protocol_handler(i_service_endpoint* psnd_hndlr, typename t_type::config_type& config, const connection_context& conn_context):m_hadler(psnd_hndlr, config, conn_context)
{}
private:
bool handle_recv(const void* ptr, size_t cb)
{
return m_hadler.handle_recv(ptr, cb);
}
t_type m_hadler;
};
class protocol_switcher
{
public:
typedef protocl_switcher_config config_type;
protocol_switcher(net_utils::i_service_endpoint* psnd_hndlr, config_type& config, const net_utils::connection_context_base& conn_context);
virtual ~protocol_switcher(){}
virtual bool handle_recv(const void* ptr, size_t cb);
bool after_init_connection(){return true;}
private:
t_protocol_handler<http::http_custom_handler> m_http_handler;
t_protocol_handler<levin::protocol_handler> m_levin_handler;
i_protocol_handler* pcurrent_handler;
std::string m_cached_buff;
};
protocol_switcher::protocol_switcher(net_utils::i_service_endpoint* psnd_hndlr, config_type& config, const net_utils::connection_context_base& conn_context):m_http_handler(psnd_hndlr, config.m_http_config, conn_context), m_levin_handler(psnd_hndlr, config.m_levin_config, conn_context), pcurrent_handler(NULL)
{}
bool protocol_switcher::handle_recv(const void* ptr, size_t cb)
{
if(pcurrent_handler)
return pcurrent_handler->handle_recv(ptr, cb);
else
{
m_cached_buff.append((const char*)ptr, cb);
if(m_cached_buff.size() < sizeof(uint64_t))
return true;
if(*((uint64_t*)&m_cached_buff[0]) == LEVIN_SIGNATURE)
{
pcurrent_handler = &m_levin_handler;
return pcurrent_handler->handle_recv(m_cached_buff.data(), m_cached_buff.size());
}
if(m_cached_buff.substr(0, 4) == "GET " || m_cached_buff.substr(0, 4) == "POST")
{
pcurrent_handler = &m_http_handler;
return pcurrent_handler->handle_recv(m_cached_buff.data(), m_cached_buff.size());
}else
{
LOG_ERROR("Wrong protocol accepted on port...");
return false;
}
}
return true;
}
}
}
#endif //_PROTOCOL_SWITCHER_H_

View File

@ -1,31 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#define RPC_METHOD_NAME(name) static inline const char* methodname(){return name;}

View File

@ -1,181 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>
namespace epee
{
namespace net_utils
{
namespace smtp
{
using boost::asio::ip::tcp;
using namespace boost::archive::iterators;
typedef base64_from_binary<transform_width<const char *,6,8> > base64_text;
/************************************************************************/
/* */
/************************************************************************/
class smtp_client
{
public:
smtp_client(std::string pServer,unsigned int pPort,std::string pUser,std::string pPassword):
mServer(pServer),mPort(pPort),mUserName(pUser),mPassword(pPassword),mSocket(mIOService),mResolver(mIOService)
{
tcp::resolver::query qry(mServer,boost::lexical_cast<std::string>( mPort ));
mResolver.async_resolve(qry,boost::bind(&smtp_client::handleResolve,this,boost::asio::placeholders::error,
boost::asio::placeholders::iterator));
}
bool Send(std::string pFrom,std::string pTo,std::string pSubject,std::string pMessage)
{
mHasError = true;
mFrom=pFrom;
mTo=pTo;
mSubject=pSubject;
mMessage=pMessage;
mIOService.run();
return !mHasError;
}
private:
std::string encodeBase64(std::string pData)
{
std::stringstream os;
size_t sz=pData.size();
std::copy(base64_text(pData.c_str()),base64_text(pData.c_str()+sz),std::ostream_iterator<char>(os));
return os.str();
}
void handleResolve(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
{
if(!err)
{
tcp::endpoint endpoint=*endpoint_iterator;
mSocket.async_connect(endpoint,
boost::bind(&smtp_client::handleConnect,this,boost::asio::placeholders::error,++endpoint_iterator));
}
else
{
mHasError=true;
mErrorMsg= err.message();
}
}
void writeLine(std::string pData)
{
std::ostream req_strm(&mRequest);
req_strm << pData << "\r\n";
boost::asio::write(mSocket,mRequest);
req_strm.clear();
}
void readLine(std::string& pData)
{
boost::asio::streambuf response;
boost::asio::read_until(mSocket, response, "\r\n");
std::istream response_stream(&response);
response_stream >> pData;
}
void handleConnect(const boost::system::error_code& err,tcp::resolver::iterator endpoint_iterator)
{
if (!err)
{
std::string read_buff;
// The connection was successful. Send the request.
std::ostream req_strm(&mRequest);
writeLine("EHLO "+mServer);
readLine(read_buff);//220
writeLine("AUTH LOGIN");
readLine(read_buff);//
writeLine(encodeBase64(mUserName));
readLine(read_buff);
writeLine(encodeBase64(mPassword));
readLine(read_buff);
writeLine( "MAIL FROM:<"+mFrom+">");
writeLine( "RCPT TO:<"+mTo+">");
writeLine( "DATA");
writeLine( "SUBJECT:"+mSubject);
writeLine( "From:"+mFrom);
writeLine( "To:"+mTo);
writeLine( "");
writeLine( mMessage );
writeLine( "\r\n.\r\n");
readLine(read_buff);
if(read_buff == "250")
mHasError = false;
writeLine( "QUIT");
}
else
{
mHasError=true;
mErrorMsg= err.message();
}
}
std::string mServer;
std::string mUserName;
std::string mPassword;
std::string mFrom;
std::string mTo;
std::string mSubject;
std::string mMessage;
unsigned int mPort;
boost::asio::io_service mIOService;
tcp::resolver mResolver;
tcp::socket mSocket;
boost::asio::streambuf mRequest;
boost::asio::streambuf mResponse;
bool mHasError;
std::string mErrorMsg;
};
bool send_mail(const std::string& server, int port, const std::string& login, const std::string& pass, const std::string& from_email, /*"STIL CRAWLER",*/
const std::string& maillist, const std::string& subject, const std::string& body)
{
STD_TRY_BEGIN();
//smtp_client mailc("yoursmtpserver.com",25,"user@yourdomain.com","password");
//mailc.Send("from@yourdomain.com","to@somewhere.com","subject","Hello from C++ SMTP Client!");
smtp_client mailc(server,port,login,pass);
return mailc.Send(from_email,maillist,subject,body);
STD_TRY_CATCH("at send_mail", false);
}
}
}
}
//#include "smtp.inl"

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "smtp.h"
namespace epee
{
namespace net_utils
{
namespace smtp
{
inline bool send_mail(const std::string& server, int port, const std::string& login, const std::string& pass, const std::string& from_addres, const std::string& from_name, const std::string& maillist, const std::string& subject, const std::string& mail_body)
{
net_utils::smtp::CSMTPClient smtp;
if ( !smtp.ServerConnect( server.c_str(), port ) )
{
LOG_PRINT("Reporting: Failed to connect to server " << server <<":"<< port, LOG_LEVEL_0);
return false;
}
if(login.size() && pass.size())
{
if ( !smtp.ServerLogin( login.c_str(), pass.c_str()) )
{
LOG_PRINT("Reporting: Failed to auth on server " << server <<":"<< port, LOG_LEVEL_0);
return false;
}
}
if ( !smtp.SendMessage( from_addres.c_str(),
from_name.c_str(),
maillist.c_str(),
subject.c_str(),
"bicycle-client",
(LPBYTE)mail_body.data(),
mail_body.size()))
{
char *szErrorText = smtp.GetLastErrorText();
if ( szErrorText )
{
LOG_PRINT("Failed to send message, error text: " << szErrorText, LOG_LEVEL_0);
}
else
{
LOG_PRINT("Failed to send message, error text: null", LOG_LEVEL_0);
}
return false;
}
smtp.ServerDisconnect();
return true;
}
}
}
}

View File

@ -1,14 +0,0 @@
#pragma once
#if defined(__GNUC__)
#define PRAGMA_WARNING_PUSH _Pragma("GCC diagnostic push")
#define PRAGMA_WARNING_POP _Pragma("GCC diagnostic pop")
#define PRAGMA_WARNING_DISABLE_VS(w)
#define PRAGMA_GCC(w) _Pragma(w)
#elif defined(_MSC_VER)
#define PRAGMA_WARNING_PUSH __pragma(warning( push ))
#define PRAGMA_WARNING_POP __pragma(warning( pop ))
#define PRAGMA_WARNING_DISABLE_VS(w) __pragma( warning ( disable: w ))
//#define PRAGMA_WARNING_DISABLE_GCC(w)
#define PRAGMA_GCC(w)
#endif

View File

@ -28,7 +28,7 @@
#ifndef _PROFILE_TOOLS_H_
#define _PROFILE_TOOLS_H_
#include "misc_os_dependent.h"
#include "time_helper.h"
namespace epee
{

View File

@ -1,249 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _MUSC_UTILS_EX_H_
#define _MUSC_UTILS_EX_H_
namespace epee
{
namespace reg_utils
{
//-----------------------------------------------------------------------------------------------------------------------------------
template<class T>
bool RegSetPODValue(HKEY hParentKey, const char* pSubKey, const char* pValName, const T& valToSave, bool force_create = true)
{
HKEY hRegKey = 0;
DWORD dw = 0;
if( ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey) != ERROR_SUCCESS )
if(force_create && (::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw) != ERROR_SUCCESS) )
return false;
DWORD val_type = (sizeof(valToSave) == sizeof(DWORD)) ? REG_DWORD:REG_BINARY;
BOOL res = ::RegSetValueExA( hRegKey, pValName, 0, val_type, (LPBYTE)&valToSave, sizeof(valToSave)) == ERROR_SUCCESS;
::RegCloseKey(hRegKey);
return ERROR_SUCCESS==res ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
template<class T>
bool RegGetPODValue(HKEY hParentKey, const char* pSubKey, const char* pValName, T& valToSave)
{
HKEY hRegKey = 0;
LONG res = 0;
if(::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey) == ERROR_SUCCESS )
{
DWORD dwType, lSize = 0;
res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, NULL, &lSize);
if(ERROR_SUCCESS!=res || (sizeof(valToSave) < lSize) )
{
::RegCloseKey(hRegKey);
return false;
}
res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, (LPBYTE)&valToSave, &lSize);
}
return ERROR_SUCCESS==res ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
inline
bool RegSetANSIString(HKEY hParentKey, const char* pSubKey, const char* pValName, const std::string& strToSave)
{
HKEY hRegKey = 0;
DWORD dw = 0;
DWORD res_ = 0;
if( (res_ = ::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw)) != ERROR_SUCCESS )
if( (res_= ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey)) != ERROR_SUCCESS )
return false;
DWORD valType = REG_SZ;
const char* pStr = strToSave.c_str();
DWORD sizeOfStr = (DWORD)strToSave.size()+1;
LSTATUS res = ::RegSetValueExA(hRegKey, pValName, 0, valType, (LPBYTE)pStr, sizeOfStr);
::RegCloseKey(hRegKey);
return ERROR_SUCCESS==res ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
inline
bool RegGetANSIString(HKEY hParentKey, const char* pSubKey, const char* pValName, std::string& strToSave)
{
HKEY hRegKey = 0;
LONG res = 0;
if((res = ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey)) == ERROR_SUCCESS )
{
DWORD dwType, lSize = 0;
res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, NULL, &lSize);
if(ERROR_SUCCESS!=res)
{
::RegCloseKey(hRegKey);
return false;
}
char* pTmpStr = new char[lSize+2];
memset(pTmpStr, 0, lSize+2);
res = ::RegQueryValueExA(hRegKey, pValName, 0, &dwType, (LPBYTE)pTmpStr, &lSize);
pTmpStr[lSize+1] = 0; //be happy ;)
strToSave = pTmpStr;
delete [] pTmpStr;
::RegCloseKey(hRegKey);
}
return ERROR_SUCCESS==res ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
template<class TMemoryObject>
bool RegSetRAWValue(HKEY hKey, const char* pValName, const TMemoryObject& valToSave, DWORD valType = REG_BINARY)
{
LONG res = ::RegSetValueExA( hKey, pValName, 0, valType, (CONST BYTE*)valToSave.get(0), (DWORD)valToSave.get_size());
return ERROR_SUCCESS==res ? true:false;
}
//----------------------------------------------------------------------------------------------------------------------------------
bool RegSetRAWValue(HKEY hKey, const char* pValName, const std::string & valToSave, DWORD valType = REG_BINARY)
{
LONG res = ::RegSetValueExA( hKey, pValName, 0, valType, (CONST BYTE*)valToSave.data(), (DWORD)valToSave.size());
return ERROR_SUCCESS==res ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
template<class TMemoryObject>
bool RegGetRAWValue(HKEY hKey, const char* pValName, TMemoryObject& valToSave, DWORD* pRegType)
{
DWORD dwType, lSize = 0;
LONG res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, NULL, &lSize);
if(ERROR_SUCCESS!=res || 0 >= lSize)
{
valToSave.release();
return false;
}
if(valToSave.get_size() < lSize)
valToSave.alloc_buff(lSize);
res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, (LPBYTE)valToSave.get(0), &lSize);
if(pRegType) *pRegType = dwType;
return ERROR_SUCCESS==res ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
bool RegGetRAWValue(HKEY hKey, const char* pValName, std::string& valToSave, DWORD* pRegType)
{
DWORD dwType, lSize = 0;
LONG res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, NULL, &lSize);
if(ERROR_SUCCESS!=res || 0 >= lSize)
{
return false;
}
valToSave.resize(lSize);
res = ::RegQueryValueExA(hKey, pValName, 0, &dwType, (LPBYTE)valToSave.data(), &lSize);
if(pRegType) *pRegType = dwType;
return ERROR_SUCCESS==res ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
template<class TMemoryObject>
bool RegSetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, const TMemoryObject& valToSave, DWORD valType = REG_BINARY)
{
HKEY hRegKey = 0;
DWORD dw = 0;
bool res = false;
if( ::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw) != ERROR_SUCCESS )
if( ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey) != ERROR_SUCCESS )
return false;
res = RegSetRAWValue(hRegKey, pValName, valToSave, valType);
::RegCloseKey(hRegKey);
return res;
}
//-----------------------------------------------------------------------------------------------------------------------------------
bool RegSetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, const std::string& valToSave, DWORD valType = REG_BINARY)
{
HKEY hRegKey = 0;
DWORD dw = 0;
bool res = false;
if( ::RegCreateKeyExA(hParentKey, pSubKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hRegKey, &dw) != ERROR_SUCCESS )
if( ::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_WRITE, &hRegKey) != ERROR_SUCCESS )
return false;
res = RegSetRAWValue(hRegKey, pValName, valToSave, valType);
::RegCloseKey(hRegKey);
return res;
}
//-----------------------------------------------------------------------------------------------------------------------------------
template<class TMemoryObject>
bool RegGetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, TMemoryObject& valToSave, DWORD* pRegType)
{
HKEY hRegKey = 0;
bool res = false;
if(::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey) == ERROR_SUCCESS )
{
res = RegGetRAWValue(hRegKey, pValName, valToSave, pRegType);
::RegCloseKey(hRegKey);
}
return res;
}
//-----------------------------------------------------------------------------------------------------------------------------------
inline
bool RegGetRAWValue(HKEY hParentKey, const char* pSubKey, const char* pValName, std::string& valToSave, DWORD* pRegType)
{
HKEY hRegKey = 0;
bool res = false;
if(::RegOpenKeyExA(hParentKey, pSubKey, 0, KEY_READ, &hRegKey) == ERROR_SUCCESS )
{
res = RegGetRAWValue(hRegKey, pValName, valToSave, pRegType);
::RegCloseKey(hRegKey);
}
return res;
}
//-----------------------------------------------------------------------------------------------------------------------------------
inline
bool RegRemoveValue(HKEY hParentKey, const char* pValName)
{
//CHECK_AND_ASSERT(hParentKey&&pValName, false);
return ::RegDeleteValueA(hParentKey, pValName)==ERROR_SUCCESS ? true:false;
}
//-----------------------------------------------------------------------------------------------------------------------------------
inline
bool RegRemoveKey(HKEY hParentKey, const char* pKeyName)
{
//CHECK_AND_ASSERT(hParentKey&&pKeyName, false);
return ::RegDeleteKeyA(hParentKey, pKeyName)==ERROR_SUCCESS ? true:false;
}
}
}
#endif //_MUSC_UTILS_EX_H_

View File

@ -1,2 +0,0 @@
#pragma once

View File

@ -1,323 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _SERVICE_IMPL_BASE_H_
#define _SERVICE_IMPL_BASE_H_
#pragma comment(lib, "advapi32.lib")
namespace epee
{
class service_impl_base {
public:
service_impl_base();
virtual ~service_impl_base();
virtual const char *get_name() = 0;
virtual const char *get_caption() = 0;
virtual const char *get_description() = 0;
bool run_service();
virtual bool install();
virtual bool remove();
virtual bool init();
void set_control_accepted(unsigned controls);
void set_status(unsigned state, unsigned pending = 0);
unsigned get_control_accepted();
private:
virtual void service_main() = 0;
virtual unsigned service_handler(unsigned control, unsigned event_code,
void *pdata) = 0;
//-------------------------------------------------------------------------
static service_impl_base*& instance();
//-------------------------------------------------------------------------
static DWORD __stdcall _service_handler(DWORD control, DWORD event,
void *pdata, void *pcontext);
static void __stdcall service_entry(DWORD argc, char **pargs);
virtual SERVICE_FAILURE_ACTIONSA* get_failure_actions();
private:
SC_HANDLE m_manager;
SC_HANDLE m_service;
SERVICE_STATUS_HANDLE m_status_handle;
DWORD m_accepted_control;
};
inline service_impl_base::service_impl_base() {
m_manager = 0;
m_service = 0;
m_status_handle = 0;
m_accepted_control = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN
| SERVICE_ACCEPT_PAUSE_CONTINUE;
instance() = this;
}
//-----------------------------------------------------------------------------
inline service_impl_base::~service_impl_base() {
if (m_service) {
::CloseServiceHandle(m_service);
}
m_service = 0;
if (m_manager) {
::CloseServiceHandle(m_manager);
}
m_manager = 0;
instance() = 0;
}
//-----------------------------------------------------------------------------
inline service_impl_base*& service_impl_base::instance() {
static service_impl_base *pservice = NULL;
return pservice;
}
//-----------------------------------------------------------------------------
inline
bool service_impl_base::install() {
CHECK_AND_ASSERT(!m_service, false);
const char *psz_descr = get_description();
SERVICE_FAILURE_ACTIONSA* fail_acts = get_failure_actions();
char sz_path[MAX_PATH];
::GetModuleFileNameA(0, sz_path, sizeof(sz_path));
::GetShortPathNameA(sz_path, sz_path, sizeof(sz_path));
while (TRUE) {
if (!m_manager) {
m_manager = ::OpenSCManager(NULL, NULL, GENERIC_ALL);
if (!m_manager) {
int err = GetLastError();
LOG_ERROR(
"Failed to OpenSCManager(), last err="
<< log_space::get_win32_err_descr(err));
break;
}
}
m_service = ::CreateServiceA(m_manager, get_name(), get_caption(),
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE, sz_path, 0, 0, 0, 0, 0);
if (!m_service) {
int err = GetLastError();
LOG_ERROR(
"Failed to CreateService(), last err="
<< log_space::get_win32_err_descr(err));
break;
}
if (psz_descr) {
SERVICE_DESCRIPTIONA sd = { (char*) psz_descr };
if (!::ChangeServiceConfig2A(m_service, SERVICE_CONFIG_DESCRIPTION,
&sd)) {
int err = GetLastError();
LOG_ERROR(
"Failed to ChangeServiceConfig2(SERVICE_CONFIG_DESCRIPTION), last err="
<< log_space::get_win32_err_descr(err));
break;
}
}
if (fail_acts) {
if (!::ChangeServiceConfig2A(m_service, SERVICE_CONFIG_FAILURE_ACTIONS,
fail_acts)) {
int err = GetLastError();
LOG_ERROR(
"Failed to ChangeServiceConfig2(SERVICE_CONFIG_FAILURE_ACTIONS), last err="
<< log_space::get_win32_err_descr(err));
break;
}
}
LOG_PRINT("Installed succesfully.", LOG_LEVEL_0);
return true;
}
LOG_PRINT("Failed to install.", LOG_LEVEL_0);
return false;
}
//-----------------------------------------------------------------------------
inline
bool service_impl_base::remove() {
CHECK_AND_ASSERT(!m_service, false);
while (TRUE) {
if (!m_manager) {
m_manager = ::OpenSCManager(0, 0, GENERIC_ALL);
if (!m_manager) {
int err = GetLastError();
LOG_ERROR(
"Failed to OpenSCManager(), last err="
<< log_space::get_win32_err_descr(err));
break;
}
}
if (!m_service) {
m_service = ::OpenServiceA(m_manager, get_name(), SERVICE_STOP | DELETE);
if (!m_service) {
int err = GetLastError();
LOG_ERROR(
"Failed to OpenService(), last err="
<< log_space::get_win32_err_descr(err));
break;
}
}
SERVICE_STATUS status = { };
if (!::ControlService(m_service, SERVICE_CONTROL_STOP, &status)) {
int err = ::GetLastError();
if (err == ERROR_SHUTDOWN_IN_PROGRESS)
continue;
else if (err != ERROR_SERVICE_NOT_ACTIVE) {
LOG_ERROR(
"Failed to ControlService(SERVICE_CONTROL_STOP), last err="
<< log_space::get_win32_err_descr(err));
break;
}
}
if (!::DeleteService(m_service)) {
int err = ::GetLastError();
LOG_ERROR(
"Failed to ControlService(SERVICE_CONTROL_STOP), last err="
<< log_space::get_win32_err_descr(err));
break;
}
LOG_PRINT("Removed successfully.", LOG_LEVEL_0);
break;
}
return true;
}
//-----------------------------------------------------------------------------
inline
bool service_impl_base::init() {
return true;
}
//-----------------------------------------------------------------------------
inline
bool service_impl_base::run_service() {
CHECK_AND_ASSERT(!m_service, false);
long error_code = 0;
SERVICE_TABLE_ENTRYA service_table[2];
ZeroMemory(&service_table, sizeof(service_table));
service_table->lpServiceName = (char*) get_name();
service_table->lpServiceProc = service_entry;
LOG_PRINT("[+] Start service control dispatcher for \"" << get_name() << "\"",
LOG_LEVEL_1);
error_code = 1;
BOOL res = ::StartServiceCtrlDispatcherA(service_table);
if (!res) {
int err = GetLastError();
LOG_PRINT(
"[+] Error starting service control dispatcher, err="
<< log_space::get_win32_err_descr(err), LOG_LEVEL_1);
return false;
} else {
LOG_PRINT("[+] End service control dispatcher for \"" << get_name() << "\"",
LOG_LEVEL_1);
}
return true;
}
//-----------------------------------------------------------------------------
inline DWORD __stdcall service_impl_base::_service_handler(DWORD control,
DWORD event, void *pdata, void *pcontext) {
CHECK_AND_ASSERT(pcontext, ERROR_CALL_NOT_IMPLEMENTED);
service_impl_base *pservice = (service_impl_base*) pcontext;
return pservice->service_handler(control, event, pdata);
}
//-----------------------------------------------------------------------------
inline
void __stdcall service_impl_base::service_entry(DWORD argc, char **pargs) {
service_impl_base *pme = instance();
LOG_PRINT("instance: " << pme, LOG_LEVEL_4);
if (!pme) {
LOG_ERROR("Error: at service_entry() pme = NULL");
return;
}
pme->m_status_handle = ::RegisterServiceCtrlHandlerExA(pme->get_name(),
_service_handler, pme);
pme->set_status(SERVICE_RUNNING);
pme->service_main();
pme->set_status(SERVICE_STOPPED);
}
//-----------------------------------------------------------------------------
inline
void service_impl_base::set_status(unsigned state, unsigned pending) {
if (!m_status_handle)
return;
SERVICE_STATUS status = { 0 };
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = state;
status.dwControlsAccepted = m_accepted_control;
/*status.dwWin32ExitCode = NO_ERROR;
status.dwServiceSpecificExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = state;*/
if (state == SERVICE_START_PENDING || state == SERVICE_STOP_PENDING
|| state == SERVICE_CONTINUE_PENDING || state == SERVICE_PAUSE_PENDING) {
status.dwWaitHint = 2000;
status.dwCheckPoint = pending;
}
::SetServiceStatus(m_status_handle, &status);
}
//-----------------------------------------------------------------------------------------
inline
void service_impl_base::set_control_accepted(unsigned controls) {
m_accepted_control = controls;
}
//-----------------------------------------------------------------------------------------
inline
unsigned service_impl_base::get_control_accepted() {
return m_accepted_control;
}
//-----------------------------------------------------------------------------------------
inline SERVICE_FAILURE_ACTIONSA* service_impl_base::get_failure_actions() {
// first 3 failures in 30 minutes. Service will be restarted.
// do nothing for next failures
static SC_ACTION sa[] = { { SC_ACTION_RESTART, 3 * 1000 }, {
SC_ACTION_RESTART, 3 * 1000 }, { SC_ACTION_RESTART, 3 * 1000 }, {
SC_ACTION_NONE, 0 } };
static SERVICE_FAILURE_ACTIONSA sfa = { 1800, // interval for failures counter - 30 min
"", NULL, 4, (SC_ACTION*) &sa };
// TODO: refactor this code, really unsafe!
return &sfa;
}
}
#endif //_SERVICE_IMPL_BASE_H_

View File

@ -1,51 +0,0 @@
/*
Copyright (c) 2011, Micael Hildenborg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Micael Hildenborg nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SHA1_DEFINED
#define SHA1_DEFINED
namespace sha1 {
/**
@param src points to any kind of data to be hashed.
@param bytelength the number of bytes to hash from the src pointer.
@param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in.
*/
void calc(const void* src, const int bytelength, unsigned char* hash);
/**
@param hash is 20 bytes of sha1 hash. This is the same data that is the result from the calc function.
@param hexstring should point to a buffer of at least 41 bytes of size for storing the hexadecimal representation of the hash. A zero will be written at position 40, so the buffer will be a valid zero ended string.
*/
void toHexString(const unsigned char* hash, char* hexstring);
} // namespace sha1
#include "sha1.inl"
#endif // SHA1_DEFINED

View File

@ -1,179 +0,0 @@
/*
Copyright (c) 2011, Micael Hildenborg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Micael Hildenborg nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Contributors:
Gustav
Several members in the gamedev.se forum.
Gregory Petrosyan
*/
#include "sha1.h"
namespace sha1 {
namespace {// local
// Rotate an integer value to left.
inline const unsigned int rol(const unsigned int value,
const unsigned int steps) {
return ((value << steps) | (value >> (32 - steps)));
}
// Sets the first 16 integers in the buffert to zero.
// Used for clearing the W buffert.
inline void clearWBuffert(unsigned int* buffert) {
for (int pos = 16; --pos >= 0;)
{
buffert[pos] = 0;
}
}
inline
void innerHash(unsigned int* result, unsigned int* w) {
unsigned int a = result[0];
unsigned int b = result[1];
unsigned int c = result[2];
unsigned int d = result[3];
unsigned int e = result[4];
int round = 0;
#define sha1macro(func,val) \
{ \
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
e = d; \
d = c; \
c = rol(b, 30); \
b = a; \
a = t; \
}
while (round < 16) {
sha1macro((b & c) | (~b & d), 0x5a827999)
++round;
}
while (round < 20) {
w[round] = rol(
(w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (~b & d), 0x5a827999)
++round;
}
while (round < 40) {
w[round] = rol(
(w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0x6ed9eba1)
++round;
}
while (round < 60) {
w[round] = rol(
(w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
++round;
}
while (round < 80) {
w[round] = rol(
(w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
sha1macro(b ^ c ^ d, 0xca62c1d6)
++round;
}
#undef sha1macro
result[0] += a;
result[1] += b;
result[2] += c;
result[3] += d;
result[4] += e;
}
} // namespace
inline
void calc(const void* src, const int bytelength, unsigned char* hash) {
// Init the result array.
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
0xc3d2e1f0 };
// Cast the void src pointer to be the byte array we can work with.
const unsigned char* sarray = (const unsigned char*) src;
// The reusable round buffer
unsigned int w[80];
// Loop through all complete 64byte blocks.
const int endOfFullBlocks = bytelength - 64;
int endCurrentBlock;
int currentBlock(0);
while (currentBlock <= endOfFullBlocks) {
endCurrentBlock = currentBlock + 64;
// Init the round buffer with the 64 byte block data.
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
{
// This line will swap endian on big endian and keep endian on little endian.
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
| (((unsigned int) sarray[currentBlock + 2]) << 8)
| (((unsigned int) sarray[currentBlock + 1]) << 16)
| (((unsigned int) sarray[currentBlock]) << 24);
}
innerHash(result, w);
}
// Handle the last and not full 64 byte block if existing.
endCurrentBlock = bytelength - currentBlock;
clearWBuffert(w);
int lastBlockBytes = 0;
for (; lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes
+ currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
}
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
if (endCurrentBlock >= 56) {
innerHash(result, w);
clearWBuffert(w);
}
w[15] = bytelength << 3;
innerHash(result, w);
// Store hash in result pointer, and make sure we get in in the correct order on both endian models.
for (int hashByte = 20; --hashByte >= 0;) {
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3))
& 0xff;
}
}
inline
void toHexString(const unsigned char* hash, char* hexstring) {
const char hexDigits[] = { "0123456789abcdef" };
for (int hashByte = 20; --hashByte >= 0;)
{
hexstring[hashByte << 1] = hexDigits[(hash[hashByte] >> 4) & 0xf];
hexstring[(hashByte << 1) + 1] = hexDigits[hash[hashByte] & 0xf];
}
hexstring[40] = 0;
}
} // namespace sha1

View File

@ -1,142 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "soci.h"
#include "soci-postgresql.h"
using namespace epee;
namespace soci
{
template <>
struct type_conversion<uint64_t>
{
typedef long long base_type;
static void from_base(base_type a_, indicator ind, uint64_t & mi)
{
if (ind == i_null)
{
mi = 0;
//throw soci_error("Null value not allowed for this type");
}
mi = (uint64_t)a_;
//mi.set(i);
}
static void to_base(const uint64_t & mi, base_type & i, indicator & ind)
{
i = (base_type)mi;
ind = i_ok;
}
};
template <>
struct type_conversion<bool>
{
typedef int base_type;
static void from_base(base_type a_, indicator ind, bool& mi)
{
if (ind == i_null)
{
mi = false;
//throw soci_error("Null value not allowed for this type");
}
mi = a_? true:false;
//mi.set(i);
}
static void to_base(const bool & mi, base_type & i, indicator & ind)
{
i = mi? 1:0;
ind = i_ok;
}
};
class per_thread_session
{
public:
bool init(const std::string& connection_string)
{
m_connection_string = connection_string;
return true;
}
soci::session& get()
{
//soci::session
m_db_connections_lock.lock();
boost::shared_ptr<soci::session>& conn_ptr = m_db_connections[epee::misc_utils::get_thread_string_id()];
m_db_connections_lock.unlock();
if(!conn_ptr.get())
{
conn_ptr.reset(new soci::session(soci::postgresql, m_connection_string));
}
//init new connection
return *conn_ptr.get();
}
bool reopen()
{
//soci::session
m_db_connections_lock.lock();
boost::shared_ptr<soci::session>& conn_ptr = m_db_connections[misc_utils::get_thread_string_id()];
m_db_connections_lock.unlock();
if(conn_ptr.get())
{
conn_ptr->close();
conn_ptr.reset(new soci::session(soci::postgresql, m_connection_string));
}
//init new connection
return true;
}
//----------------------------------------------------------------------------------------------
bool check_status()
{
return true;
}
protected:
private:
std::map<std::string, boost::shared_ptr<soci::session> > m_db_connections;
epee::critical_section m_db_connections_lock;
std::string m_connection_string;
};
}
/*}*/

View File

@ -1,82 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _STATIC_INITIALIZER_H_
#define _STATIC_INITIALIZER_H_
namespace epee
{
/***********************************************************************
class initializer - useful to initialize some static classes
which have init() and un_init() static members
************************************************************************/
template<class to_initialize>
class initializer
{
public:
initializer()
{
to_initialize::init();
//get_set_is_initialized(true, true);
}
~initializer()
{
to_initialize::un_init();
//get_set_is_uninitialized(true, true);
}
/*static inline bool is_initialized()
{
return get_set_is_initialized();
}
static inline bool is_uninitialized()
{
return get_set_is_uninitialized();
}
private:
static inline bool get_set_is_initialized(bool need_to_set = false, bool val_to_set= false)
{
static bool val_is_initialized = false;
if(need_to_set)
val_is_initialized = val_to_set;
return val_is_initialized;
}
static inline bool get_set_is_uninitialized(bool need_to_set = false, bool val_to_set = false)
{
static bool val_is_uninitialized = false;
if(need_to_set)
val_is_uninitialized = val_to_set;
return val_is_uninitialized;
}*/
};
}
#endif //_STATIC_INITIALIZER_H_

View File

@ -1,62 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _CRYPTED_STORAGE_H_
#define _CRYPTED_STORAGE_H_
#include "cryptopp_helper.h"
namespace epee
{
template<class t_base_storage, class crypt_provider, class t_key_provider>
class crypted_storage: public t_base_storage
{
public:
size_t PackToSolidBuffer(std::string& targetObj)
{
size_t res = t_base_storage::PackToSolidBuffer(targetObj);
if(res <= 0)
return res;
if(!crypt_provider::encrypt(targetObj, t_key_provider::get_storage_default_key()))
return 0;
return targetObj.size();
}
size_t LoadFromSolidBuffer(const std::string& pTargetObj)
{
std::string buff_to_decrypt = pTargetObj;
if(crypt_provider::decrypt(buff_to_decrypt, t_key_provider::get_storage_default_key()))
return t_base_storage::LoadFromSolidBuffer(buff_to_decrypt);
return 0;
}
};
}
#endif //_CRYPTED_STORAGE_H_

View File

@ -1,68 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _GZIPPED_INMEMSTORAGE_H_
#define _GZIPPED_INMEMSTORAGE_H_
#include "zlib_helper.h"
namespace epee
{
namespace StorageNamed
{
template<class t_base_storage>
class gziped_storage: public t_base_storage
{
public:
size_t PackToSolidBuffer(std::string& targetObj)
{
size_t res = t_base_storage::PackToSolidBuffer(targetObj);
if(res <= 0)
return res;
if(!zlib_helper::pack(targetObj))
return 0;
return targetObj.size();
}
size_t LoadFromSolidBuffer(const std::string& pTargetObj)
{
std::string buff_to_ungzip = pTargetObj;
if(zlib_helper::unpack(buff_to_ungzip))
return t_base_storage::LoadFromSolidBuffer(buff_to_ungzip);
return 0;
}
private:
};
}
}
#endif

View File

@ -56,54 +56,6 @@ namespace epee
{
namespace net_utils
{
#if 0
template<class t_arg, class t_result, class t_transport>
bool invoke_remote_command2(int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
{
if(!transport.is_connected())
return false;
serialization::portable_storage stg;
out_struct.store(stg);
std::string buff_to_send, buff_to_recv;
stg.store_to_binary(buff_to_send);
int res = transport.invoke(command, buff_to_send, buff_to_recv);
if( res <=0 )
{
MERROR("Failed to invoke command " << command << " return code " << res);
return false;
}
serialization::portable_storage stg_ret;
if(!stg_ret.load_from_binary(buff_to_recv, &default_levin_limits))
{
LOG_ERROR("Failed to load_from_binary on command " << command);
return false;
}
return result_struct.load(stg_ret);
}
template<class t_arg, class t_transport>
bool notify_remote_command2(int command, const t_arg& out_struct, t_transport& transport)
{
if(!transport.is_connected())
return false;
serialization::portable_storage stg;
out_struct.store(&stg);
std::string buff_to_send;
stg.store_to_binary(buff_to_send);
int res = transport.notify(command, buff_to_send);
if(res <=0 )
{
LOG_ERROR("Failed to notify command " << command << " return code " << res);
return false;
}
return true;
}
#endif
template<class t_arg, class t_result, class t_transport>
bool invoke_remote_command2(const epee::net_utils::connection_context_base context, int command, const t_arg& out_struct, t_result& result_struct, t_transport& transport)
{

View File

@ -28,7 +28,6 @@
#pragma once
#include "pragma_comp_defs.h"
#include "misc_language.h"
#include "portable_storage_base.h"
#include "portable_storage_bin_utils.h"
@ -49,11 +48,6 @@ namespace epee
return sizeof(pack_value);
}
PRAGMA_WARNING_PUSH
PRAGMA_GCC("GCC diagnostic ignored \"-Wstrict-aliasing\"")
#ifdef __clang__
PRAGMA_GCC("GCC diagnostic ignored \"-Wtautological-constant-out-of-range-compare\"")
#endif
template<class t_stream>
size_t pack_varint(t_stream& strm, size_t val)
{ //the first two bits always reserved for size information
@ -70,11 +64,11 @@ namespace epee
return pack_varint_t<uint32_t>(strm, PORTABLE_RAW_SIZE_MARK_DWORD, val);
}else
{
CHECK_AND_ASSERT_THROW_MES(val <= 4611686018427387903, "failed to pack varint - too big amount = " << val);
// Same as checking val <= 4611686018427387903 except that it's portable for 32-bit size_t
CHECK_AND_ASSERT_THROW_MES(!(val >> 31 >> 31), "failed to pack varint - too big amount = " << val);
return pack_varint_t<uint64_t>(strm, PORTABLE_RAW_SIZE_MARK_INT64, val);
}
}
PRAGMA_WARNING_POP
template<class t_stream>
bool put_string(t_stream& strm, const std::string& v)

View File

@ -28,132 +28,60 @@
#pragma once
//#include <atltime.h>
//#include <sqlext.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include "pragma_comp_defs.h"
#include <chrono>
#include <cstdio>
#include <ctime>
#include <string>
namespace epee
{
namespace misc_utils
{
#ifdef __ATLTIME_H__
inline
bool get_time_t_from_ole_date(DATE src, time_t& res)
inline bool get_gmt_time(time_t t, struct tm &tm)
{
SYSTEMTIME st = {0};
if(TRUE != ::VariantTimeToSystemTime(src, &st))
return false;
ATL::CTime ss(st);
res = ss.GetTime();
return true;
}
#ifdef _WIN32
return gmtime_s(&tm, &t);
#else
return gmtime_r(&t, &tm);
#endif
inline
std::string get_time_str(const time_t& time_)
{
char tmpbuf[200] = {0};
tm* pt = NULL;
PRAGMA_WARNING_PUSH
PRAGMA_WARNING_DISABLE_VS(4996)
pt = localtime(&time_);
PRAGMA_WARNING_POP
if(pt)
strftime( tmpbuf, 199, "%d.%m.%Y %H:%M:%S", pt );
else
{
std::stringstream strs;
strs << "[wrong_time: " << std::hex << time_ << "]";
return strs.str();
}
return tmpbuf;
}
inline
std::string get_time_str_v2(const time_t& time_)
{
char tmpbuf[200] = {0};
tm* pt = NULL;
PRAGMA_WARNING_PUSH
PRAGMA_WARNING_DISABLE_VS(4996)
pt = localtime(&time_);
PRAGMA_WARNING_POP
if(pt)
strftime( tmpbuf, 199, "%Y_%m_%d %H_%M_%S", pt );
else
{
std::stringstream strs;
strs << "[wrong_time: " << std::hex << time_ << "]";
return strs.str();
}
return tmpbuf;
}
inline
std::string get_time_str_v3(const boost::posix_time::ptime& time_)
{
return boost::posix_time::to_simple_string(time_);
}
inline std::string get_internet_time_str(const time_t& time_)
{
char tmpbuf[200] = {0};
tm* pt = NULL;
PRAGMA_WARNING_PUSH
PRAGMA_WARNING_DISABLE_VS(4996)
pt = gmtime(&time_);
PRAGMA_WARNING_POP
strftime( tmpbuf, 199, "%a, %d %b %Y %H:%M:%S GMT", pt );
struct tm pt;
get_gmt_time(time_, pt);
strftime(tmpbuf, 199, "%a, %d %b %Y %H:%M:%S GMT", &pt);
return tmpbuf;
}
inline std::string get_time_interval_string(const time_t& time_)
{
std::string res;
time_t tail = time_;
PRAGMA_WARNING_PUSH
PRAGMA_WARNING_DISABLE_VS(4244)
int days = tail/(60*60*24);
const int days = static_cast<int>(tail/(60*60*24));
tail = tail%(60*60*24);
int hours = tail/(60*60);
const int hours = static_cast<int>(tail/(60*60));
tail = tail%(60*60);
int minutes = tail/(60);
const int minutes = static_cast<int>(tail/60);
tail = tail%(60);
int seconds = tail;
PRAGMA_WARNING_POP
res = std::string() + "d" + boost::lexical_cast<std::string>(days) + ".h" + boost::lexical_cast<std::string>(hours) + ".m" + boost::lexical_cast<std::string>(minutes) + ".s" + boost::lexical_cast<std::string>(seconds);
return res;
const int seconds = static_cast<int>(tail);
char tmpbuf[64] = {0};
snprintf(tmpbuf, sizeof(tmpbuf) - 1, "d%d.h%d.m%d.s%d", days, hours, minutes, seconds);
return tmpbuf;
}
#ifdef __SQLEXT
inline
bool odbc_time_to_oledb_taime(const SQL_TIMESTAMP_STRUCT& odbc_timestamp, DATE& oledb_date)
inline uint64_t get_ns_count()
{
SYSTEMTIME st = {0};
st.wYear = odbc_timestamp.year;
st.wDay = odbc_timestamp.day;
st.wHour = odbc_timestamp.hour ;
st.wMilliseconds = (WORD)odbc_timestamp.fraction ;
st.wMinute = odbc_timestamp.minute ;
st.wMonth = odbc_timestamp.month ;
st.wSecond = odbc_timestamp.second ;
if(TRUE != ::SystemTimeToVariantTime(&st, &oledb_date))
return false;
return true;
typedef std::chrono::duration<uint64_t, std::nano> ns_duration;
const ns_duration ns_since_epoch = std::chrono::steady_clock::now().time_since_epoch();
return ns_since_epoch.count();
}
#endif
inline uint64_t get_tick_count()
{
return get_ns_count() / 1000000;
}
}
}

View File

@ -1,61 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _TINY_INI_H_
#define _TINY_INI_H_
#include "string_tools.h"
namespace epee
{
namespace tiny_ini
{
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res);
inline std::string get_param_value(const std::string& param_name, const std::string& ini_entry)
{
std::string buff;
get_param_value(param_name, ini_entry, buff);
return buff;
}
template<class T>
bool get_param_value_as_t(const std::string& param_name, const std::string& ini_entry, T& res)
{
std::string str_res = get_param_value(param_name, ini_entry);
string_tools::trim(str_res);
if(!str_res.size())
return false;
return string_tools::get_xtype_from_string(res, str_res);
}
}
}
#endif //_TINY_INI_H_

View File

@ -1,52 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _TO_NONCONST_ITERATOR_H_
#define _TO_NONCONST_ITERATOR_H_
namespace epee
{
template<class Type>
typename Type::iterator to_nonsonst_iterator(Type& obj, typename Type::const_iterator it)
{
typename Type::difference_type dist = std::distance(static_cast<typename Type::const_iterator>(obj.begin()), it);
typename Type::iterator res_it = obj.begin()+dist;
return res_it;
}
template<class Type>
typename Type::iterator to_nonsonst_iterator(typename Type::iterator base_it, typename Type::const_iterator it)
{
typename Type::difference_type dist = std::distance(static_cast<typename Type::const_iterator>(base_it), it);
typename Type::iterator res_it = base_it+dist;
return res_it;
}
}//namespace epee
#endif //_TO_NONCONST_ITERATOR_H_

View File

@ -1,227 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef __WINH_OBJ_H__
#define __WINH_OBJ_H__
#include <boost/thread/locks.hpp>
namespace epee
{
class critical_region;
class critical_section {
boost::mutex m_section;
public:
critical_section( const critical_section& section ) {
InitializeCriticalSection( &m_section );
}
critical_section() {
InitializeCriticalSection( &m_section );
}
~critical_section() {
DeleteCriticalSection( &m_section );
}
void lock() {
EnterCriticalSection( &m_section );
}
void unlock() {
LeaveCriticalSection( &m_section );
}
bool tryLock() {
return TryEnterCriticalSection( &m_section )? true:false;
}
critical_section& operator=( const critical_section& section )
{
return *this;
}
};
class critical_region {
::critical_section *m_locker;
critical_region( const critical_region& ){}
public:
critical_region(critical_section &cs ) {
m_locker = &cs;
cs.lock();
}
~critical_region()
{
m_locker->unlock();
}
};
class shared_critical_section
{
public:
shared_critical_section()
{
::InitializeSRWLock(&m_srw_lock);
}
~shared_critical_section()
{}
bool lock_shared()
{
AcquireSRWLockShared(&m_srw_lock);
return true;
}
bool unlock_shared()
{
ReleaseSRWLockShared(&m_srw_lock);
return true;
}
bool lock_exclusive()
{
::AcquireSRWLockExclusive(&m_srw_lock);
return true;
}
bool unlock_exclusive()
{
::ReleaseSRWLockExclusive(&m_srw_lock);
return true;
}
private:
SRWLOCK m_srw_lock;
};
class shared_guard
{
public:
shared_guard(shared_critical_section& ref_sec):m_ref_sec(ref_sec)
{
m_ref_sec.lock_shared();
}
~shared_guard()
{
m_ref_sec.unlock_shared();
}
private:
shared_critical_section& m_ref_sec;
};
class exclusive_guard
{
public:
exclusive_guard(shared_critical_section& ref_sec):m_ref_sec(ref_sec)
{
m_ref_sec.lock_exclusive();
}
~exclusive_guard()
{
m_ref_sec.unlock_exclusive();
}
private:
shared_critical_section& m_ref_sec;
};
class event
{
public:
event()
{
m_hevent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
}
~event()
{
::CloseHandle(m_hevent);
}
bool set()
{
return ::SetEvent(m_hevent) ? true:false;
}
bool reset()
{
return ::ResetEvent(m_hevent) ? true:false;
}
HANDLE get_handle()
{
return m_hevent;
}
private:
HANDLE m_hevent;
};
#define SHARED_CRITICAL_REGION_BEGIN(x) { shared_guard critical_region_var(x)
#define EXCLUSIVE_CRITICAL_REGION_BEGIN(x) { exclusive_guard critical_region_var(x)
#define CRITICAL_REGION_LOCAL(x) critical_region critical_region_var(x)
#define CRITICAL_REGION_BEGIN(x) { critical_region critical_region_var(x)
#define CRITICAL_REGION_END() }
inline const char* get_wait_for_result_as_text(DWORD res)
{
switch(res)
{
case WAIT_ABANDONED: return "WAIT_ABANDONED";
case WAIT_TIMEOUT: return "WAIT_TIMEOUT";
case WAIT_OBJECT_0: return "WAIT_OBJECT_0";
case WAIT_OBJECT_0+1: return "WAIT_OBJECT_1";
case WAIT_OBJECT_0+2: return "WAIT_OBJECT_2";
default:
return "UNKNOWN CODE";
}
}
}// namespace epee
#endif

View File

@ -1,139 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
extern "C" {
#include "zlib/zlib.h"
}
#pragma comment(lib, "zlibstat.lib")
namespace epee
{
namespace zlib_helper
{
inline
bool pack(std::string& target){
std::string result_packed_buff;
z_stream zstream = {0};
int ret = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
if(target.size())
{
result_packed_buff.resize(target.size()*2, 'X');
zstream.next_in = (Bytef*)target.data();
zstream.avail_in = (uInt)target.size();
zstream.next_out = (Bytef*)result_packed_buff.data();
zstream.avail_out = (uInt)result_packed_buff.size();
ret = deflate(&zstream, Z_FINISH);
CHECK_AND_ASSERT_MES(ret>=0, false, "Failed to deflate. err = " << ret);
if(result_packed_buff.size() != zstream.avail_out)
result_packed_buff.resize(result_packed_buff.size()-zstream.avail_out);
result_packed_buff.erase(0, 2);
target.swap(result_packed_buff);
}
deflateEnd(& zstream );
return true;
}
inline bool unpack(std::string& target)
{
z_stream zstream = {0};
int ret = inflateInit(&zstream);//
std::string decode_summary_buff;
size_t ungzip_buff_size = target.size() * 0x30;
std::string current_decode_buff(ungzip_buff_size, 'X');
while(target.size())
{
zstream.next_out = (Bytef*)current_decode_buff.data();
zstream.avail_out = (uInt)ungzip_buff_size;
int flag = Z_SYNC_FLUSH;
static char dummy_head[2] =
{
0x8 + 0x7 * 0x10,
(((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,
};
zstream.next_in = (Bytef*) dummy_head;
zstream.avail_in = sizeof(dummy_head);
ret = inflate(&zstream, Z_NO_FLUSH);
if (ret != Z_OK)
{
LOCAL_ASSERT(0);
return false;
}
zstream.next_in = (Bytef*)target.data();
zstream.avail_in = (uInt)target.size();
ret = inflate(&zstream, Z_SYNC_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
{
LOCAL_ASSERT(0);
return false;
}
target.erase(0, target.size()-zstream.avail_in);
if(ungzip_buff_size == zstream.avail_out)
{
LOG_ERROR("Can't unpack buffer");
return false;
}
current_decode_buff.resize(ungzip_buff_size - zstream.avail_out);
if(decode_summary_buff.size())
decode_summary_buff += current_decode_buff;
else
current_decode_buff.swap(decode_summary_buff);
current_decode_buff.resize(ungzip_buff_size);
}
inflateEnd(&zstream );
decode_summary_buff.swap(target);
return 1;
}
};
}//namespace epee

View File

@ -35,11 +35,9 @@ monero_add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_cli
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
int-util.cpp portable_storage.cpp
misc_language.cpp
misc_os_dependent.cpp
file_io_utils.cpp
net_parse_helpers.cpp
http_base.cpp
tiny_ini.cpp
${EPEE_HEADERS_PUBLIC}
)

View File

@ -39,7 +39,6 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include "misc_language.h"
#include "pragma_comp_defs.h"
#include <iomanip>
#include <boost/asio/basic_socket.hpp>

View File

@ -102,29 +102,6 @@ namespace file_io_utils
}
bool get_file_time(const std::string& path_to_file, time_t& ft)
{
boost::system::error_code ec;
ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
if(!ec)
return true;
else
return false;
}
bool set_file_time(const std::string& path_to_file, const time_t& ft)
{
boost::system::error_code ec;
boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
if(!ec)
return true;
else
return false;
}
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size)
{
#ifdef WIN32
@ -174,26 +151,6 @@ namespace file_io_utils
}
bool append_string_to_file(const std::string& path_to_file, const std::string& str)
{
// No special Windows implementation because so far not used in Monero code
try
{
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
fstream << str;
fstream.close();
return true;
}
catch(...)
{
return false;
}
}
bool get_file_size(const std::string& path_to_file, uint64_t &size)
{
#ifdef WIN32

View File

@ -1,44 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "misc_os_dependent.h"
#include <boost/lexical_cast.hpp>
namespace epee
{
namespace misc_utils
{
// TODO: (vtnerd) This function is weird since boost::this_thread::get_id() exists but returns a different value.
std::string get_thread_string_id()
{
#if defined(_WIN32)
return boost::lexical_cast<std::string>(GetCurrentThreadId());
#elif defined(__GNUC__)
return boost::lexical_cast<std::string>(pthread_self());
#endif
}
}
}

View File

@ -40,7 +40,7 @@
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "string_tools.h"
#include "misc_os_dependent.h"
#include "time_helper.h"
#include "misc_log_ex.h"
#undef MONERO_DEFAULT_LOG_CATEGORY

View File

@ -46,7 +46,6 @@
#include "misc_log_ex.h"
#include <boost/chrono.hpp>
#include "misc_language.h"
#include "pragma_comp_defs.h"
#include <sstream>
#include <iomanip>
#include <algorithm>

View File

@ -1,46 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "string_tools.h"
#include <boost/regex.hpp>
namespace epee
{
namespace tiny_ini
{
bool get_param_value(const std::string& param_name, const std::string& ini_entry, std::string& res)
{
std::string expr_str = std::string() + "^("+ param_name +") *=(.*?)$";
const boost::regex match_ini_entry( expr_str, boost::regex::icase | boost::regex::normal);
boost::smatch result;
if(!boost::regex_search(ini_entry, result, match_ini_entry, boost::match_default))
return false;
res = result[2];
string_tools::trim(res);
return true;
}
}
}

View File

@ -1 +0,0 @@
/build/*

View File

@ -1 +0,0 @@
¢IMóÙŸˆm_bo

View File

@ -1,5 +0,0 @@
mkdir build
cd build
cmake "-DBoost_USE_STATIC_LIBS=TRUE" -G "Visual Studio 11 Win64" ../src
cd ..
pause

View File

@ -1,40 +0,0 @@
cmake_minimum_required(VERSION 3.5)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(Boost_USE_MULTITHREADED ON)
include_directories(.)
include_directories(../../include)
find_package(Boost COMPONENTS system filesystem thread date_time chrono regex)
include_directories( ${Boost_INCLUDE_DIRS} )
IF (MSVC)
add_definitions( "/W3 /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /nologo /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /bigobj" )
include_directories(SYSTEM platform/msvc)
ELSE()
# set stuff for other systems
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-reorder")
ENDIF()
# Add folders to filters
file(GLOB_RECURSE SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/*.inl
${CMAKE_CURRENT_SOURCE_DIR}/*.h)
source_group(general FILES ${SRC})
add_executable(tests ${SRC} )
target_link_libraries( tests ${Boost_LIBRARIES} )

View File

@ -1,82 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "misc_language.h"
namespace epee
{
namespace tests
{
bool test_median()
{
LOG_PRINT_L0("Testing median");
std::vector<size_t> sz;
size_t m = misc_utils::median(sz);
CHECK_AND_ASSERT_MES(m == 0, false, "test failed");
sz.push_back(1);
m = misc_utils::median(sz);
CHECK_AND_ASSERT_MES(m == 1, false, "test failed");
sz.push_back(10);
m = misc_utils::median(sz);
CHECK_AND_ASSERT_MES(m == 5, false, "test failed");
sz.clear();
sz.resize(3);
sz[0] = 0;
sz[1] = 9;
sz[2] = 3;
m = misc_utils::median(sz);
CHECK_AND_ASSERT_MES(m == 3, false, "test failed");
sz.clear();
sz.resize(4);
sz[0] = 77;
sz[1] = 9;
sz[2] = 22;
sz[3] = 60;
m = misc_utils::median(sz);
CHECK_AND_ASSERT_MES(m == 41, false, "test failed");
sz.clear();
sz.resize(5);
sz[0] = 77;
sz[1] = 9;
sz[2] = 22;
sz[3] = 60;
sz[4] = 11;
m = misc_utils::median(sz);
CHECK_AND_ASSERT_MES(m == 22, false, "test failed");
return true;
}
}
}

View File

@ -1,408 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "net/abstract_tcp_server2.h"
#include "net/levin_protocol_handler.h"
#include "net/levin_protocol_handler_async.h"
#include "storages/abstract_invoke.h"
namespace epee
{
namespace StorageNamed
{
typedef CInMemStorage DefaultStorageType;
}
namespace tests
{
struct some_subdata
{
std::string str1;
std::list<uint64_t> array_of_id;
BEGIN_NAMED_SERIALIZE_MAP()
SERIALIZE_STL_ANSI_STRING(str1)
SERIALIZE_STL_CONTAINER_POD(array_of_id)
END_NAMED_SERIALIZE_MAP()
};
/************************************************************************/
/* */
/************************************************************************/
struct COMMAND_EXAMPLE_1
{
const static int ID = 1000;
struct request_t
{
std::string example_string_data;
uint64_t example_id_data;
some_subdata sub;
BEGIN_NAMED_SERIALIZE_MAP()
SERIALIZE_STL_ANSI_STRING(example_string_data)
SERIALIZE_POD(example_id_data)
SERIALIZE_T(sub)
END_NAMED_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
bool m_success;
uint64_t example_id_data;
std::list<some_subdata> subs;
BEGIN_NAMED_SERIALIZE_MAP()
SERIALIZE_POD(m_success)
SERIALIZE_POD(example_id_data)
SERIALIZE_STL_CONTAINER_T(subs)
END_NAMED_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
struct COMMAND_EXAMPLE_2
{
const static int ID = 1001;
struct request_t
{
std::string example_string_data2;
uint64_t example_id_data;
BEGIN_NAMED_SERIALIZE_MAP()
SERIALIZE_POD(example_id_data)
SERIALIZE_STL_ANSI_STRING(example_string_data2)
END_NAMED_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
bool m_success;
uint64_t example_id_data;
BEGIN_NAMED_SERIALIZE_MAP()
SERIALIZE_POD(example_id_data)
SERIALIZE_POD(m_success)
END_NAMED_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
typedef boost::uuids::uuid uuid;
class test_levin_server: public levin::levin_commands_handler<>
{
test_levin_server(const test_levin_server&){}
public:
test_levin_server(){}
void set_thread_prefix(const std::string& pref)
{
m_net_server.set_threads_prefix(pref);
}
template<class calback_t>
bool connect_async(const std::string adr, const std::string& port, uint32_t conn_timeot, calback_t cb, const std::string& bind_ip = "0.0.0.0")
{
return m_net_server.connect_async(adr, port, conn_timeot, cb, bind_ip);
}
bool connect(const std::string adr, const std::string& port, uint32_t conn_timeot, net_utils::connection_context_base& cn, const std::string& bind_ip = "0.0.0.0")
{
return m_net_server.connect(adr, port, conn_timeot, cn, bind_ip);
}
void close(net_utils::connection_context_base& cn)
{
m_net_server.get_config_object().close(cn.m_connection_id);
}
template<class t_request, class t_response>
bool invoke(uuid con_id, int command, t_request& req, t_response& resp)
{
return invoke_remote_command(con_id, command, req, resp, m_net_server.get_config_object());
}
template< class t_response, class t_request, class callback_t>
bool invoke_async(uuid con_id, int command, t_request& req, callback_t cb)
{
return async_invoke_remote_command<t_response>(con_id, command, req, m_net_server.get_config_object(), cb);
}
bool init(const std::string& bind_port = "", const std::string& bind_ip = "0.0.0.0")
{
m_net_server.get_config_object().set_handler(this);
m_net_server.get_config_object().m_invoke_timeout = 1000;
LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
return m_net_server.init_server(bind_port, bind_ip);
}
bool run()
{
//here you can set worker threads count
int thrds_count = 4;
//go to loop
LOG_PRINT("Run net_service loop( " << thrds_count << " threads)...", LOG_LEVEL_0);
if(!m_net_server.run_server(thrds_count))
{
LOG_ERROR("Failed to run net tcp server!");
}
LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0);
return true;
}
bool deinit()
{
return m_net_server.deinit_server();
}
bool send_stop_signal()
{
m_net_server.send_stop_signal();
return true;
}
uint32_t get_binded_port()
{
return m_net_server.get_binded_port();
}
private:
CHAIN_LEVIN_INVOKE_TO_MAP(); //move levin_commands_handler interface invoke(...) callbacks into invoke map
CHAIN_LEVIN_NOTIFY_TO_STUB(); //move levin_commands_handler interface notify(...) callbacks into nothing
BEGIN_INVOKE_MAP(test_levin_server)
HANDLE_INVOKE_T(COMMAND_EXAMPLE_1, &test_levin_server::handle_1)
HANDLE_INVOKE_T(COMMAND_EXAMPLE_2, &test_levin_server::handle_2)
END_INVOKE_MAP()
//----------------- commands handlers ----------------------------------------------
int handle_1(int command, COMMAND_EXAMPLE_1::request& arg, COMMAND_EXAMPLE_1::response& rsp, const net_utils::connection_context_base& context)
{
LOG_PRINT_L0("on_command_1: id " << arg.example_id_data << "---->>");
COMMAND_EXAMPLE_2::request arg_ = AUTO_VAL_INIT(arg_);
arg_.example_id_data = arg.example_id_data;
COMMAND_EXAMPLE_2::response rsp_ = AUTO_VAL_INIT(rsp_);
invoke_async<COMMAND_EXAMPLE_2::response>(context.m_connection_id, COMMAND_EXAMPLE_2::ID, arg_, [](int code, const COMMAND_EXAMPLE_2::response& rsp, const net_utils::connection_context_base& context)
{
if(code < 0)
{LOG_PRINT_RED_L0("on_command_1: command_2 failed to invoke");}
else
{LOG_PRINT_L0("on_command_1: command_2 response " << rsp.example_id_data);}
});
rsp.example_id_data = arg.example_id_data;
LOG_PRINT_L0("on_command_1: id " << arg.example_id_data << "<<----");
return true;
}
int handle_2(int command, COMMAND_EXAMPLE_2::request& arg, COMMAND_EXAMPLE_2::response& rsp, const net_utils::connection_context_base& context)
{
LOG_PRINT_L0("on_command_2: id "<< arg.example_id_data);
rsp.example_id_data = arg.example_id_data;
//misc_utils::sleep_no_w(6000);
return true;
}
//----------------------------------------------------------------------------------
net_utils::boosted_levin_async_server m_net_server;
};
inline
bool do_run_test_server()
{
test_levin_server srv1, srv2;
std::string bind_param = "0.0.0.0";
std::string port = "";
if(!srv1.init(port, bind_param))
{
LOG_ERROR("Failed to initialize srv!");
return 1;
}
if(!srv2.init(port, bind_param))
{
LOG_ERROR("Failed to initialize srv!");
return 1;
}
srv1.set_thread_prefix("SRV_A");
srv2.set_thread_prefix("SRV_B");
boost::thread th1( boost::bind(&test_levin_server::run, &srv1));
boost::thread th2( boost::bind(&test_levin_server::run, &srv2));
LOG_PRINT_L0("Initialized servers, waiting for worker threads started...");
misc_utils::sleep_no_w(1000);
LOG_PRINT_L0("Connecting to each other...");
uint32_t port1 = srv1.get_binded_port();
uint32_t port2 = srv2.get_binded_port();
COMMAND_EXAMPLE_1::request arg;
COMMAND_EXAMPLE_1::request resp;
net_utils::connection_context_base cntxt_1;
bool r = srv1.connect("127.0.0.1", string_tools::num_to_string_fast(port2), 5000, cntxt_1);
CHECK_AND_ASSERT_MES(r, false, "connect to server failed");
net_utils::connection_context_base cntxt_2;
r = srv2.connect("127.0.0.1", string_tools::num_to_string_fast(port1), 5000, cntxt_2);
CHECK_AND_ASSERT_MES(r, false, "connect to server failed");
while(true)
{
LOG_PRINT_L0("Invoking from A to B...");
int r = srv1.invoke(cntxt_1.m_connection_id, COMMAND_EXAMPLE_1::ID, arg, resp);
if(r<=0)
{
LOG_ERROR("Failed tp invoke A to B");
break;
}
LOG_PRINT_L0("Invoking from B to A...");
r = srv2.invoke(cntxt_2.m_connection_id, COMMAND_EXAMPLE_1::ID, arg, resp);
if(r<=0)
{
LOG_ERROR("Failed tp invoke B to A");
break;
}
}
srv1.send_stop_signal();
srv2.send_stop_signal();
th1.join();
th1.join();
return true;
}
inline bool do_test2_work_with_srv(test_levin_server& srv, int port)
{
uint64_t i = 0;
boost::mutex wait_event;
wait_event.lock();
while(true)
{
net_utils::connection_context_base cntxt_local = AUTO_VAL_INIT(cntxt_local);
bool r = srv.connect_async("127.0.0.1", string_tools::num_to_string_fast(port), 5000, [&srv, &port, &wait_event, &i, &cntxt_local](const net_utils::connection_context_base& cntxt, const boost::system::error_code& ec)
{
CHECK_AND_ASSERT_MES(!ec, void(), "Some problems at connect, message: " << ec.message() );
cntxt_local = cntxt;
LOG_PRINT_L0("Invoking command 1 to " << port);
COMMAND_EXAMPLE_1::request arg = AUTO_VAL_INIT(arg);
arg.example_id_data = i;
/*vc2010 workaround*/
int port_ = port;
boost::mutex& wait_event_ = wait_event;
int r = srv.invoke_async<COMMAND_EXAMPLE_1::request>(cntxt.m_connection_id, COMMAND_EXAMPLE_1::ID, arg, [port_, &wait_event_](int code, const COMMAND_EXAMPLE_1::request& rsp, const net_utils::connection_context_base& cntxt)
{
CHECK_AND_ASSERT_MES(code > 0, void(), "Failed to invoke");
LOG_PRINT_L0("command 1 invoke to " << port_ << " OK.");
wait_event_.unlock();
});
});
wait_event.lock();
srv.close(cntxt_local);
++i;
}
return true;
}
inline
bool do_run_test_server_async_connect()
{
test_levin_server srv1, srv2;
std::string bind_param = "0.0.0.0";
std::string port = "";
if(!srv1.init(port, bind_param))
{
LOG_ERROR("Failed to initialize srv!");
return 1;
}
if(!srv2.init(port, bind_param))
{
LOG_ERROR("Failed to initialize srv!");
return 1;
}
srv1.set_thread_prefix("SRV_A");
srv2.set_thread_prefix("SRV_B");
boost::thread thmain1( boost::bind(&test_levin_server::run, &srv1));
boost::thread thmain2( boost::bind(&test_levin_server::run, &srv2));
LOG_PRINT_L0("Initalized servers, waiting for worker threads started...");
misc_utils::sleep_no_w(1000);
LOG_PRINT_L0("Connecting to each other...");
uint32_t port1 = srv1.get_binded_port();
uint32_t port2 = srv2.get_binded_port();
COMMAND_EXAMPLE_1::request arg;
COMMAND_EXAMPLE_1::request resp;
boost::thread work_1( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
boost::thread work_2( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
boost::thread work_3( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
boost::thread work_4( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
boost::thread work_5( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
boost::thread work_6( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
boost::thread work_7( boost::bind(do_test2_work_with_srv, boost::ref(srv1), port2));
boost::thread work_8( boost::bind(do_test2_work_with_srv, boost::ref(srv2), port1));
work_1.join();
work_2.join();
srv1.send_stop_signal();
srv2.send_stop_signal();
thmain1.join();
thmain2.join();
return true;
}
}
}

View File

@ -1,232 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include <list>
#include <string>
#include "storages/serializeble_struct_helper.h"
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage.h"
#include "storages/portable_storage_template_helper.h"
namespace epee
{
namespace tests
{
struct port_test_struct_sub
{
std::string m_str;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_VAL(m_str)
END_KV_SERIALIZE_MAP()
};
#pragma pack (push, 1)
struct some_pod_struct
{
uint64_t a;
int32_t b;
};
#pragma pack(pop)
struct port_test_struct
{
std::string m_str;
uint64_t m_uint64;
uint32_t m_uint32;
uint16_t m_uint16;
uint8_t m_uint8;
int64_t m_int64;
int32_t m_int32;
int16_t m_int16;
int8_t m_int8;
double m_double;
bool m_bool;
some_pod_struct m_pod;
std::list<std::string> m_list_of_str;
std::list<uint64_t> m_list_of_uint64_t;
std::list<uint32_t> m_list_of_uint32_t;
std::list<uint16_t> m_list_of_uint16_t;
std::list<uint8_t> m_list_of_uint8_t;
std::list<int64_t> m_list_of_int64_t;
std::list<int32_t> m_list_of_int32_t;
std::list<int16_t> m_list_of_int16_t;
std::list<int8_t> m_list_of_int8_t;
std::list<double> m_list_of_double;
std::list<bool> m_list_of_bool;
port_test_struct_sub m_subobj;
std::list<port_test_struct> m_list_of_self;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_VAL(m_str)
KV_SERIALIZE_VAL(m_uint64)
KV_SERIALIZE_VAL(m_uint32)
KV_SERIALIZE_VAL(m_uint16)
KV_SERIALIZE_VAL(m_uint8)
KV_SERIALIZE_VAL(m_int64)
KV_SERIALIZE_VAL(m_int32)
KV_SERIALIZE_VAL(m_int16)
KV_SERIALIZE_VAL(m_int8)
KV_SERIALIZE_VAL(m_double)
KV_SERIALIZE_VAL(m_bool)
KV_SERIALIZE_VAL_POD_AS_BLOB(m_pod)
KV_SERIALIZE_OBJ(m_subobj)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_str)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint64_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint32_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint16_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_uint8_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_int64_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_int32_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_int16_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_int8_t)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_double)
KV_SERIALIZE_CONTAINER_VAL(m_list_of_bool)
KV_SERIALIZE_CONTAINER_OBJ(m_list_of_self)
END_KV_SERIALIZE_MAP()
};
bool operator != (const port_test_struct_sub& a, const port_test_struct_sub& b)
{
return b.m_str != a.m_str;
}
bool operator == (const port_test_struct& a, const port_test_struct& b)
{
if( b.m_str != a.m_str
|| b.m_uint64 != a.m_uint64
|| b.m_uint32 != a.m_uint32
|| b.m_uint16 != a.m_uint16
|| b.m_uint8 != a.m_uint8
|| b.m_int64 != a.m_int64
|| b.m_int32 != a.m_int32
|| b.m_int16 != a.m_int16
|| b.m_int8 != a.m_int8
|| b.m_double != a.m_double
|| b.m_bool != a.m_bool
|| b.m_pod.a != a.m_pod.a
|| b.m_pod.b != a.m_pod.b
|| b.m_list_of_str != a.m_list_of_str
|| b.m_list_of_uint64_t != a.m_list_of_uint64_t
|| b.m_list_of_uint32_t != a.m_list_of_uint32_t
|| b.m_list_of_uint16_t != a.m_list_of_uint16_t
|| b.m_list_of_uint8_t != a.m_list_of_uint8_t
|| b.m_list_of_int64_t != a.m_list_of_int64_t
|| b.m_list_of_int32_t != a.m_list_of_int32_t
|| b.m_list_of_int16_t != a.m_list_of_int16_t
|| b.m_list_of_int8_t != a.m_list_of_int8_t
|| b.m_list_of_double != a.m_list_of_double
|| b.m_list_of_bool != a.m_list_of_bool
|| b.m_subobj != a.m_subobj
|| b.m_list_of_self != a.m_list_of_self
)
return false;
return true;
}
void fill_struct_with_test_values(port_test_struct& s)
{
s.m_str = "zuzuzuzuzuz";
s.m_uint64 = 111111111111111;
s.m_uint32 = 2222222;
s.m_uint16 = 2222;
s.m_uint8 = 22;
s.m_int64 = -111111111111111;
s.m_int32 = -2222222;
s.m_int16 = -2222;
s.m_int8 = -24;
s.m_double = 0.11111;
s.m_bool = true;
s.m_pod.a = 32342342342342;
s.m_pod.b = -342342;
s.m_list_of_str.push_back("1112121");
s.m_list_of_uint64_t.push_back(1111111111);
s.m_list_of_uint64_t.push_back(2222222222);
s.m_list_of_uint32_t.push_back(1111111);
s.m_list_of_uint32_t.push_back(2222222);
s.m_list_of_uint16_t.push_back(1111);
s.m_list_of_uint16_t.push_back(2222);
s.m_list_of_uint8_t.push_back(11);
s.m_list_of_uint8_t.push_back(22);
s.m_list_of_int64_t.push_back(-1111111111);
s.m_list_of_int64_t.push_back(-222222222);
s.m_list_of_int32_t.push_back(-1111111);
s.m_list_of_int32_t.push_back(-2222222);
s.m_list_of_int16_t.push_back(-1111);
s.m_list_of_int16_t.push_back(-2222);
s.m_list_of_int8_t.push_back(-11);
s.m_list_of_int8_t.push_back(-22);
s.m_list_of_double.push_back(0.11111);
s.m_list_of_double.push_back(0.22222);
s.m_list_of_bool.push_back(true);
s.m_list_of_bool.push_back(false);
s.m_subobj.m_str = "subszzzzzzzz";
s.m_list_of_self.push_back(s);
}
bool test_portable_storages(const std::string& tests_folder)
{
serialization::portable_storage ps, ps2;
port_test_struct s1, s2;
fill_struct_with_test_values(s1);
s1.store(ps);
std::string binbuf;
bool r = ps.store_to_binary(binbuf);
ps2.load_from_binary(binbuf);
s2.load(ps2);
if(!(s1 == s2))
{
LOG_ERROR("Portable storage test failed!");
return false;
}
port_test_struct ss1, ss2;
fill_struct_with_test_values(ss1);
std::string json_buff = epee::serialization::store_t_to_json(ss1);
epee::serialization::load_t_from_json(ss2, json_buff);
if(!(ss1 == ss2))
{
LOG_ERROR("Portable storage test failed!");
return false;
}
return true;
}
}
}

View File

@ -1,142 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include "storages/serializeble_struct_helper.h"
#include "storages/portable_storage.h"
namespace epee
{
namespace tests
{
struct test_struct
{
std::string m_str;
unsigned int m_uint;
bool m_bool;
std::list<std::string> m_list_of_str;
std::list<int> m_list_of_int;
std::list<test_struct> m_list_of_self;
BEGIN_NAMED_SERIALIZE_MAP()
SERIALIZE_STL_ANSI_STRING(m_str)
SERIALIZE_POD(m_uint)
SERIALIZE_POD(m_bool)
SERIALIZE_STL_CONTAINER_ANSII_STRING(m_list_of_str)
SERIALIZE_STL_CONTAINER_POD(m_list_of_int)
SERIALIZE_STL_CONTAINER_T(m_list_of_self)
END_NAMED_SERIALIZE_MAP()
};
bool operator == (const test_struct& a, const test_struct& b)
{
if( b.m_str != a.m_str
|| b.m_uint != a.m_uint
|| b.m_bool != a.m_bool
|| b.m_list_of_str != a.m_list_of_str
|| b.m_list_of_int != a.m_list_of_int
|| b.m_list_of_self != a.m_list_of_self
)
return false;
return true;
}
inline test_struct get_test_struct()
{
test_struct t = boost::value_initialized<test_struct>();
t.m_bool = true;
t.m_str = "ackamdc'kmecemcececmacmecmcm[aicm[oeicm[oeicm[qaicm[qoe";
t.m_uint = 233242;
for(int i = 0; i!=500; i++)
t.m_list_of_int.push_back(i);
for(int i = 0; i!=500; i++)
t.m_list_of_str.push_back("ssccd");
for(int i = 0; i!=5; i++)
{
t.m_list_of_self.push_back(t);
}
return t;
}
bool test_storages(const std::string& tests_folder)
{
epee::serialization::portable_storage ps;
auto s = ps.open_section("zzz", nullptr);
uint64_t i = 0;
ps.get_value("afdsdf", i, s);
LOG_PRINT_L0("Generating test struct...");
boost::filesystem::path storage_folder = tests_folder;
storage_folder /= "storages";
test_struct t = get_test_struct();
LOG_PRINT_L0("Loading test struct from storage...");
test_struct t2;
bool res = epee::StorageNamed::load_struct_from_storage_file(t2, (storage_folder /+ "valid_storage.bin").string());
CHECK_AND_ASSERT_MES(res, false, "Failed to load valid_storage.bin");
LOG_PRINT_L0("Comparing generated and loaded test struct...");
if(!(t == t2))
return false;
LOG_PRINT_L0("Loading broken archive 1...");
test_struct t3;
res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_1.bin").string());
CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_1.bin loaded, but should not ");
LOG_PRINT_L0("Loading broken archive 2...");
res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_2.bin").string());
CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_2.bin loaded, but should not ");
LOG_PRINT_L0("Loading broken archive 3...");
res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_3.bin").string());
CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_3.bin loaded, but should not ");
LOG_PRINT_L0("Loading broken archive 4...");
res = epee::StorageNamed::load_struct_from_storage_file(t3, (storage_folder /+ "invalid_storage_4.bin").string());
CHECK_AND_ASSERT_MES(!res, false, "invalid_storage_3.bin loaded, but should not ");
return true;
}
}
}

View File

@ -1,59 +0,0 @@
#include "include_base_utils.h"
#include "storages/storage_tests.h"
#include "misc/test_math.h"
#include "storages/portable_storages_test.h"
#include "net/test_net.h"
using namespace epee;
int main(int argc, char* argv[])
{
string_tools::set_module_name_and_folder(argv[0]);
//set up logging options
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_2);
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
log_space::log_singletone::add_logger(LOGGER_FILE,
log_space::log_singletone::get_default_log_file().c_str(),
log_space::log_singletone::get_default_log_folder().c_str());
string_tools::command_line_params_a start_params;
string_tools::parse_commandline(start_params, argc, argv);
std::string tests_data_path;
string_tools::get_xparam_from_command_line(start_params, std::string("/tests_folder"), tests_data_path);
if(string_tools::have_in_command_line(start_params, std::string("/run_net_tests")))
{
if(!tests::do_run_test_server())
{
LOG_ERROR("net tests failed");
return 1;
}
if(!tests::do_run_test_server_async_connect() )
{
LOG_ERROR("net tests failed");
return 1;
}
}else if(string_tools::have_in_command_line(start_params, std::string("/run_unit_tests")))
{
if(!tests::test_median())
{
LOG_ERROR("median test failed");
return 1;
}
if(!tests::test_storages(tests_data_path))
{
LOG_ERROR("storage test failed");
return 1;
}
}else if(string_tools::have_in_command_line(start_params, std::string("/run_portable_storage_test")))
{
tests::test_portable_storages(tests_data_path);
}
return 1;
}

View File

@ -27,7 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include "misc_os_dependent.h"
#include "time_helper.h"
#include "perf_timer.h"
#undef MONERO_DEFAULT_LOG_CATEGORY

View File

@ -59,7 +59,7 @@
#include "include_base_utils.h"
#include "file_io_utils.h"
#include "wipeable_string.h"
#include "misc_os_dependent.h"
#include "time_helper.h"
using namespace epee;
#include "crypto/crypto.h"

View File

@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
// Parts of this file are originally copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
#pragma once
#include <unordered_set>
@ -34,7 +35,6 @@
#include <algorithm>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "net/net_utils_base.h"
#include "copyable_atomic.h"
#include "crypto/hash.h"
namespace cryptonote
@ -55,6 +55,37 @@ namespace cryptonote
state_normal
};
/*
This class was originally from the EPEE module. It is identical in function to std::atomic<uint32_t> except
that it has copy-construction and copy-assignment defined, which means that earliers devs didn't have to write
custom copy-contructors and copy-assingment operators for the outer class, cryptonote_connection_context.
cryptonote_connection_context should probably be refactored because it is both trying to be POD-like while
also (very loosely) controlling access to its atomic members.
*/
class copyable_atomic: public std::atomic<uint32_t>
{
public:
copyable_atomic()
{};
copyable_atomic(uint32_t value)
{ store(value); }
copyable_atomic(const copyable_atomic& a):std::atomic<uint32_t>(a.load())
{}
copyable_atomic& operator= (const copyable_atomic& a)
{
store(a.load());
return *this;
}
uint32_t operator++()
{
return std::atomic<uint32_t>::operator++();
}
uint32_t operator++(int fake)
{
return std::atomic<uint32_t>::operator++(fake);
}
};
static constexpr int handshake_command() noexcept { return 1001; }
bool handshake_complete() const noexcept { return m_state != state_before_handshake; }
@ -67,7 +98,7 @@ namespace cryptonote
uint64_t m_remote_blockchain_height;
uint64_t m_last_response_height;
boost::posix_time::ptime m_last_request_time;
epee::copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise
copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise
crypto::hash m_last_known_hash;
uint32_t m_pruning_seed;
uint16_t m_rpc_port;
@ -77,8 +108,8 @@ namespace cryptonote
int m_expect_response;
uint64_t m_expect_height;
size_t m_num_requested;
epee::copyable_atomic m_new_stripe_notification{0};
epee::copyable_atomic m_idle_peer_notification{0};
copyable_atomic m_new_stripe_notification{0};
copyable_atomic m_idle_peer_notification{0};
};
inline std::string get_protocol_state_string(cryptonote_connection_context::state s)

View File

@ -43,7 +43,6 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include "misc_language.h"
#include "pragma_comp_defs.h"
#include <algorithm>

View File

@ -40,7 +40,6 @@
#include "daemon/rpc_command_executor.h"
#include "common/common_fwd.h"
#include "net/net_fwd.h"
#include "rpc/core_rpc_server.h"
namespace daemonize {

View File

@ -43,7 +43,6 @@ Passing RPC commands:
#include "common/common_fwd.h"
#include "console_handler.h"
#include "daemon/command_parser_executor.h"
#include "net/net_fwd.h"
namespace daemonize {

View File

@ -43,7 +43,6 @@
#include "common/common_fwd.h"
#include "common/rpc_client.h"
#include "cryptonote_basic/cryptonote_basic.h"
#include "net/net_fwd.h"
#include "rpc/core_rpc_server.h"
#undef MONERO_DEFAULT_LOG_CATEGORY

View File

@ -55,7 +55,6 @@
#include "math_helper.h"
#include "misc_log_ex.h"
#include "p2p_protocol_defs.h"
#include "net/local_ip.h"
#include "crypto/crypto.h"
#include "storages/levin_abstract_invoke2.h"
#include "cryptonote_core/cryptonote_core.h"

View File

@ -31,6 +31,7 @@
#pragma once
#include <iosfwd>
#include <iterator>
#include <list>
#include <string>
#include <vector>
@ -46,7 +47,6 @@
#include "crypto/crypto.h"
#include "cryptonote_config.h"
#include "net/enums.h"
#include "net/local_ip.h"
#include "p2p_protocol_defs.h"
#include "syncobj.h"
@ -184,6 +184,7 @@ namespace nodetool
private:
void trim_white_peerlist();
void trim_gray_peerlist();
static peerlist_entry get_nth_latest_peer(peers_indexed& peerlist, size_t n);
friend class boost::serialization::access;
epee::critical_section m_peerlist_lock;
@ -215,6 +216,16 @@ namespace nodetool
}
//--------------------------------------------------------------------------------------------------
inline
peerlist_entry peerlist_manager::get_nth_latest_peer(peers_indexed& peerlist, const size_t n)
{
// Is not thread-safe nor does it check bounds. Do this before calling. Indexing starts at 0.
peers_indexed::index<by_time>::type& by_time_index = peerlist.get<by_time>();
auto by_time_it = --by_time_index.end();
std::advance(by_time_it, -static_cast<long long>(n));
return *by_time_it;
}
//--------------------------------------------------------------------------------------------------
inline
bool peerlist_manager::merge_peerlist(const std::vector<peerlist_entry>& outer_bs, const std::function<bool(const peerlist_entry&)> &f)
{
CRITICAL_REGION_LOCAL(m_peerlist_lock);
@ -235,8 +246,7 @@ namespace nodetool
if(i >= m_peers_white.size())
return false;
peers_indexed::index<by_time>::type& by_time_index = m_peers_white.get<by_time>();
p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
p = peerlist_manager::get_nth_latest_peer(m_peers_white, i);
return true;
}
//--------------------------------------------------------------------------------------------------
@ -247,8 +257,7 @@ namespace nodetool
if(i >= m_peers_gray.size())
return false;
peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
p = *epee::misc_utils::move_it_backward(--by_time_index.end(), i);
p = peerlist_manager::get_nth_latest_peer(m_peers_gray, i);
return true;
}
//--------------------------------------------------------------------------------------------------
@ -437,9 +446,7 @@ namespace nodetool
}
size_t random_index = crypto::rand_idx(m_peers_gray.size());
peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
pe = *epee::misc_utils::move_it_backward(--by_time_index.end(), random_index);
pe = peerlist_manager::get_nth_latest_peer(m_peers_gray, random_index);
return true;

View File

@ -30,6 +30,7 @@
#pragma once
#include <iomanip>
#include <boost/uuid/uuid.hpp>
#include <boost/serialization/version.hpp>
#include "serialization/keyvalue_serialization.h"

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