diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..349bf872
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "contrib/miniupnp"]
+ path = contrib/miniupnp
+ url = https://github.com/miniupnp/miniupnp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 911d69c1..c7060172 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,9 +45,14 @@ if (UNIX AND NOT APPLE)
find_package(Threads REQUIRED)
endif()
+# TODO(unassigned): expand on types and versions, and then refactor.
+if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ set(CLANG TRUE)
+endif()
if(MSVC)
- add_definitions("/bigobj /Zm1000 /Z7 /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4503 /wd4345 /wd4091 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__")
+ add_definitions("/D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /D__SSE4_1__")
+ add_compile_options(/bigobj /Zm1000 /Z7 /MP2 /W3 /GS- /wd4996 /wd4503 /wd4345 /wd4091 /FIinline_c.h)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:10485760 /DEBUG dbghelp.lib")
if(STATIC)
foreach(VAR CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE)
@@ -66,7 +71,6 @@ else()
# if(NOT APPLE)
# set(WARNINGS "${WARNINGS} -Werror")
# endif()
-
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(WARNINGS "${WARNINGS} -Wno-shift-count-overflow -Wno-error=mismatched-tags -Wno-error=null-conversion -Wno-overloaded-shift-op-parentheses -Wno-error=shift-count-overflow -Wno-error=tautological-constant-out-of-range-compare -Wno-error=unused-private-field -Wno-error=unneeded-internal-declaration")
else()
@@ -103,13 +107,15 @@ else()
else()
set(STATIC_ASSERT_FLAG "-Dstatic_assert=_Static_assert")
endif()
- set(LINUX_LD_GOLD "")
- set(LINUX_STATIC_ICU "")
- if((NOT APPLE) AND (NOT MSVC))
- set(LINUX_LD_GOLD "-fuse-ld=gold")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${ARCH_FLAG}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -ftemplate-depth-1024 -std=c++11 -D_GNU_SOURCE ${APPLE_FLAG} ${MINGW_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${ARCH_FLAG}")
+ if (NOT APPLE AND NOT MSVC)
+ if (CLANG)
+ set(LLVM_USE_LINKER "gold")
+ else()
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
+ endif()
endif()
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LINUX_LD_GOLD} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${ARCH_FLAG}")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LINUX_LD_GOLD} -fpermissive -ftemplate-depth-1024 -std=c++11 -D_GNU_SOURCE ${APPLE_FLAG} ${MINGW_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${ARCH_FLAG}")
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT (CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8))
set(DEBUG_FLAGS "-g3 -O0") #set(DEBUG_FLAGS "-g3 -Og")
else()
@@ -152,7 +158,7 @@ endif()
message(STATUS "Boost: ${Boost_VERSION} from ${Boost_LIBRARY_DIRS}")
-include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
+include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/contrib/ethereum/libethash)
if(MINGW)
set(Boost_LIBRARIES "${Boost_LIBRARIES};ws2_32;mswsock")
elseif(NOT MSVC)
@@ -196,8 +202,11 @@ else()
endif()
endif()
+set(BUILD_TESTS FALSE CACHE BOOL "Build Zano tests")
add_subdirectory(contrib)
add_subdirectory(src)
-add_subdirectory(tests)
+if (BUILD_TESTS)
+ add_subdirectory(tests)
+endif()
diff --git a/Makefile b/Makefile
index 451319b0..d0be5571 100644
--- a/Makefile
+++ b/Makefile
@@ -1,28 +1,77 @@
-all: all-release
+# Copyright (c) 2014-2019 Zano Project
+# Copyright (c) 2014 The Cryptonote developers
+# Distributed under the MIT/X11 software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-cmake-debug:
- mkdir -p build/debug
- cd build/debug && cmake -D CMAKE_BUILD_TYPE=Debug ../..
+# Define CMake generator
+system := $(shell uname)
+ifneq (, $(findstring MINGW, $(system)))
+ cmake_gen = -G 'MSYS Makefiles'
+endif
-build-debug: cmake-debug
- cd build/debug && $(MAKE)
+cmake = cmake $(cmake_gen)
-test-debug: build-debug
- cd build/debug && $(MAKE) test
+cmake_debug = $(cmake) -D CMAKE_BUILD_TYPE=Debug
+cmake_release = $(cmake) -D CMAKE_BUILD_TYPE=Release
-all-debug: build-debug
+cmake_gui = -D BUILD_GUI=ON
+cmake_static = -D STATIC=ON
+cmake_tests = -D BUILD_TESTS=ON
-cmake-release:
- mkdir -p build/release
- cd build/release && cmake -D CMAKE_BUILD_TYPE=Release ../..
+# Helper macro
+define CMAKE
+ mkdir -p $1 && cd $1 && $2 ../../
+endef
-build-release: cmake-release
- cd build/release && $(MAKE)
+build = build
+dir_debug = $(build)/debug
+dir_release = $(build)/release
-test-release: build-release
- cd build/release && $(MAKE) test
+all: release
-all-release: build-release
+release:
+ $(eval command += $(cmake_release))
+ $(call CMAKE,$(dir_release),$(command)) && $(MAKE)
+
+debug:
+ $(eval command += $(cmake_debug))
+ $(call CMAKE,$(dir_debug),$(command)) && $(MAKE)
+
+static: static-release
+static-release:
+ $(eval command += $(cmake_release) $(cmake_static))
+ $(call CMAKE,$(dir_release),$(command)) && $(MAKE)
+
+#
+# GUI
+#
+
+gui: gui-release
+gui-release:
+ $(eval command += $(cmake_release) $(cmake_gui))
+ $(call CMAKE,$(dir_release),$(command)) && $(MAKE)
+
+gui-debug:
+ $(eval command += $(cmake_debug) $(cmake_gui))
+ $(call CMAKE,$(dir_debug),$(command)) && $(MAKE)
+
+gui-static: gui-release-static
+gui-release-static:
+ $(eval command += $(cmake_release) $(cmake_gui) $(cmake_static))
+ $(call CMAKE,$(dir_release),$(command)) && $(MAKE)
+
+#
+# Tests
+#
+
+test: test-release
+test-release:
+ $(eval command += $(cmake_release) $(cmake_tests))
+ $(call CMAKE,$(dir_release),$(command)) && $(MAKE) && $(MAKE) test
+
+test-debug:
+ $(eval command += $(cmake_debug) $(cmake_tests))
+ $(call CMAKE,$(dir_debug),$(command)) && $(MAKE) && $(MAKE) test
clean:
rm -rf build
@@ -30,4 +79,4 @@ clean:
tags:
ctags -R --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ src contrib tests/gtest
-.PHONY: all cmake-debug build-debug test-debug all-debug cmake-release build-release test-release all-release clean tags
+.PHONY: all release debug static static-release gui gui-release gui-static gui-release-static gui-debug test test-release test-debug clean tags
diff --git a/README.md b/README.md
index ee524731..1804c829 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,21 @@
Building
--------
+### Cloning
+
+Be sure to properly clone the repository:
+
+`$ git clone --recursive https://github.com/hyle-team/zano.git`
+
+or, if already cloned:
+
+`$ cd zano/ && git submodule init && git submodule update`
+
### Dependencies
| component / version | minimum
(not recommended but may work) | recommended | most recent of what we have ever tested |
|--|--|--|--|
-| gcc (Linux) | 5.4.0 | 7.2.0 | 7.2.0 |
+| gcc (Linux) | 5.4.0 | 7.2.0 | 8.3.0 |
+| llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 |
| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2015 (14.0 update 3) | 2017 (15.5.7) |
| [XCode](https://developer.apple.com/downloads/) (macOS) | 7.3.1 | 9.2 | 9.2 |
| [CMake](https://cmake.org/download/) | 2.8.6 | 3.4.1 | 3.11.0 |
@@ -12,12 +23,16 @@ Building
| [Qt](https://download.qt.io/archive/qt/) (only for GUI) | 5.8.0 | 5.9.1 | 5.10.1 |
### Linux
+
Recommended OS version: Ubuntu 17.04 LTS.
- 1. Install dependencies: `sudo apt-get install build-essential git cmake unzip libicu-dev ocl-icd-opencl-dev mesa-common-dev libglu1-mesa-dev`
- 2. Install Qt and Boost
- 3. Set `BOOST_ROOT` and `QT_PREFIX_PATH` environment variables
- 4. `mkdir build`
`cd build`
`cmake -DBUILD_GUI=FALSE -DSTATIC=TRUE ..`
`make`
-5. In order to build GUI, revise and run script at `/utils/build_script_linux.sh`
+
+1. For server version: \
+`$ sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git libboost-all-dev screen`\
+For GUI version:\
+`$ sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git libboost-all-dev screen mesa-common-dev libglu1-mesa-dev qt5-default qtwebengine5-dev`
+
+2. `$ cd zano/ && make -j$(nproc) gui`
+3. Look for the binaries, including the `Zano` GUI, in the build directory
### Windows
Recommended OS version: Windows 7 x64.
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
index 46ed7497..c1ea6bdd 100644
--- a/contrib/CMakeLists.txt
+++ b/contrib/CMakeLists.txt
@@ -1,18 +1,19 @@
set(UPNPC_BUILD_STATIC ON CACHE BOOL "Build static library")
set(UPNPC_BUILD_SHARED OFF CACHE BOOL "Build shared library")
set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Build test executables")
-add_subdirectory(miniupnpc)
+add_subdirectory(miniupnp/miniupnpc)
add_subdirectory(zlib)
add_subdirectory(db)
+add_subdirectory(ethereum)
-
-set_property(TARGET upnpc-static PROPERTY FOLDER "contrib")
+set_property(TARGET upnpc-static PROPERTY FOLDER "contrib/miniupnp")
set_property(TARGET zlibstatic PROPERTY FOLDER "contrib")
set_property(TARGET lmdb PROPERTY FOLDER "contrib")
+
if(MSVC)
set_property(TARGET upnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
else()
diff --git a/contrib/db/CMakeLists.txt b/contrib/db/CMakeLists.txt
index bdd4381b..eb5c8415 100644
--- a/contrib/db/CMakeLists.txt
+++ b/contrib/db/CMakeLists.txt
@@ -2,6 +2,6 @@ add_subdirectory(liblmdb)
if(MSVC)
target_compile_options(lmdb PRIVATE /wd4996 /wd4503 /wd4345 /wd4267 /wd4244 /wd4146 /wd4333 /wd4172)
else()
- target_compile_options(lmdb PRIVATE -Wno-discarded-qualifiers -Wno-empty-body -Wno-unused-but-set-variable)
+ # Warnings as used by LMDB itself (LMDB_0.9.23)
+ target_compile_options(lmdb PRIVATE -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized)
endif()
-
diff --git a/contrib/eos_portable_archive/eos/portable_archive_exception.hpp b/contrib/eos_portable_archive/eos/portable_archive_exception.hpp
index fad9ed5f..719fc004 100644
--- a/contrib/eos_portable_archive/eos/portable_archive_exception.hpp
+++ b/contrib/eos_portable_archive/eos/portable_archive_exception.hpp
@@ -35,12 +35,11 @@ namespace eos {
// version of the linked boost archive library
const archive_version_type archive_version(
- 11
-// #if BOOST_VERSION < 103700
-// boost::archive::ARCHIVE_VERSION()
-// #else
-// boost::archive::BOOST_ARCHIVE_VERSION()
-// #endif
+ #if BOOST_VERSION < 103700
+ boost::archive::ARCHIVE_VERSION()
+ #else
+ boost::archive::BOOST_ARCHIVE_VERSION()
+ #endif
);
/**
diff --git a/contrib/eos_portable_archive/eos/portable_iarchive.hpp b/contrib/eos_portable_archive/eos/portable_iarchive.hpp
index 54540989..6f60c93d 100644
--- a/contrib/eos_portable_archive/eos/portable_iarchive.hpp
+++ b/contrib/eos_portable_archive/eos/portable_iarchive.hpp
@@ -3,7 +3,7 @@
* \file portable_iarchive.hpp
* \brief Provides an archive to read from portable binary files.
* \author christian.pfligersdorffer@gmx.at
- * \version 5.0
+ * \version 5.1
*
* This pair of archives brings the advantages of binary streams to the cross
* platform boost::serialization user. While being almost as fast as the native
@@ -23,6 +23,9 @@
* chance it will instantly work for your specific setup. If you encounter
* problems or have suggestions please contact the author.
*
+ * \note Version 5.1 is now compatible with boost up to version 1.59. Thanks to
+ * ecotax for pointing to the issue with shared_ptr_helper.
+ *
* \note Version 5.0 is now compatible with boost up to version 1.49 and enables
* serialization of std::wstring by converting it to/from utf8 (thanks to
* Arash Abghari for this suggestion). With that all unit tests from the
@@ -89,9 +92,7 @@
#include
#include
-#if BOOST_VERSION >= 105600
-#include
-#elif BOOST_VERSION >= 103500
+#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
#include
#endif
@@ -115,14 +116,16 @@
#include
#elif BOOST_VERSION < 104800
#include
+// Boost 1.69 (Spirit.X2/X3) has dropped their own FP routines in favor of boost::math
+#elif BOOST_VERSION < 106900
#include
+#include
#else
#include
-#include
#endif
// namespace alias
-#if BOOST_VERSION < 103800
+#if BOOST_VERSION < 103800 || BOOST_VERSION >= 106900
namespace fp = boost::math;
#else
namespace fp = boost::spirit::math;
@@ -135,7 +138,7 @@ namespace endian = boost::detail;
namespace endian = boost::spirit::detail;
#endif
-#ifndef BOOST_NO_STD_WSTRING
+#if BOOST_VERSION >= 104500 && !defined BOOST_NO_STD_WSTRING
// used for wstring to utf8 conversion
#include
#include
@@ -190,9 +193,7 @@ namespace eos {
// load_override functions so we chose to stay one level higher
, public boost::archive::basic_binary_iarchive
- #if BOOST_VERSION >= 105600
- // mix-in helper class for serializing shared_ptr does not exist anymore
- #elif BOOST_VERSION >= 103500
+ #if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
// mix-in helper class for serializing shared_ptr
, public boost::archive::detail::shared_ptr_helper
#endif
@@ -349,7 +350,7 @@ namespace eos {
T temp = size < 0 ? -1 : 0;
load_binary(&temp, abs(size));
- // load the value from little endian - is is then converted
+ // load the value from little endian - it is then converted
// to the target type T and fits it because size <= sizeof(T)
t = endian::load_little_endian(&temp);
}
diff --git a/contrib/eos_portable_archive/eos/portable_oarchive.hpp b/contrib/eos_portable_archive/eos/portable_oarchive.hpp
index 67f3a695..20d4c29c 100644
--- a/contrib/eos_portable_archive/eos/portable_oarchive.hpp
+++ b/contrib/eos_portable_archive/eos/portable_oarchive.hpp
@@ -3,7 +3,7 @@
* \file portable_oarchive.hpp
* \brief Provides an archive to create portable binary files.
* \author christian.pfligersdorffer@gmx.at
- * \version 5.0
+ * \version 5.1
*
* This pair of archives brings the advantages of binary streams to the cross
* platform boost::serialization user. While being almost as fast as the native
@@ -23,6 +23,9 @@
* chance it will instantly work for your specific setup. If you encounter
* problems or have suggestions please contact the author.
*
+ * \note Version 5.1 is now compatible with boost up to version 1.59. Thanks to
+ * ecotax for pointing to the issue with shared_ptr_helper.
+ *
* \note Version 5.0 is now compatible with boost up to version 1.49 and enables
* serialization of std::wstring by converting it to/from utf8 (thanks to
* Arash Abghari for this suggestion). With that all unit tests from the
@@ -91,15 +94,9 @@
#include
#include
#include
-#if BOOST_VERSION >= 105600
-#include
-#elif BOOST_VERSION >= 103500
-#include
-#endif
-#if BOOST_VERSION >= 104500
-#include
-#include
+#if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
+#include
#endif
// funny polymorphics
@@ -122,14 +119,16 @@
#include
#elif BOOST_VERSION < 104800
#include
+// Boost 1.69 (Spirit.X2/X3) has dropped their own FP routines in favor of boost::math
+#elif BOOST_VERSION < 106900
#include
+#include
#else
#include
-#include
#endif
// namespace alias fp_classify
-#if BOOST_VERSION < 103800
+#if BOOST_VERSION < 103800 || BOOST_VERSION >= 106900
namespace fp = boost::math;
#else
namespace fp = boost::spirit::math;
@@ -142,7 +141,7 @@ namespace endian = boost::detail;
namespace endian = boost::spirit::detail;
#endif
-#ifndef BOOST_NO_STD_WSTRING
+#if BOOST_VERSION >= 104500 && !defined BOOST_NO_STD_WSTRING
// used for wstring to utf8 conversion
#include
#include
@@ -195,9 +194,7 @@ namespace eos {
// save_override functions so we chose to stay one level higher
, public boost::archive::basic_binary_oarchive
- #if BOOST_VERSION >= 105600
- // mix-in helper class for serializing shared_ptr does not exist anymore
- #elif BOOST_VERSION >= 103500
+ #if BOOST_VERSION >= 103500 && BOOST_VERSION < 105600
// mix-in helper class for serializing shared_ptr
, public boost::archive::detail::shared_ptr_helper
#endif
diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h
index ef131696..2dbec160 100644
--- a/contrib/epee/include/console_handler.h
+++ b/contrib/epee/include/console_handler.h
@@ -422,7 +422,6 @@ namespace epee
std::string get_usage()
{
std::stringstream ss;
- ss << "Commands: " << ENDL;
size_t max_command_len = 0;
for(auto& x:m_command_handlers)
if(x.first.size() > max_command_len)
@@ -430,8 +429,7 @@ namespace epee
for(auto& x:m_command_handlers)
{
- ss.width(max_command_len + 3);
- ss << " " << std::left << x.first << " " << x.second.second << ENDL;
+ ss << " " << std::left << std::setw(max_command_len + 3) << x.first << " " << x.second.second << ENDL;
}
return ss.str();
}
diff --git a/contrib/epee/include/math_helper.h b/contrib/epee/include/math_helper.h
index 3646d050..dc7d74dc 100644
--- a/contrib/epee/include/math_helper.h
+++ b/contrib/epee/include/math_helper.h
@@ -51,6 +51,7 @@ namespace math_helper
average()
{
m_base = default_base;
+ m_count = 0;
}
bool set_base()
@@ -71,6 +72,7 @@ namespace math_helper
CRITICAL_REGION_LOCAL(m_lock);
//#ifndef DEBUG_STUB
+ m_count++;
m_list.push_back(vl);
if(m_list.size() > m_base )
m_list.pop_front();
@@ -106,9 +108,20 @@ namespace math_helper
return 0;
}
+ uint64_t& get_count()
+ {
+ return m_count;
+ }
+
+ void reset()
+ {
+ m_count = 0;
+ m_list.clear();
+ }
private:
- unsigned int m_base;
+ unsigned int m_base;
+ uint64_t m_count;
std::list m_list;
mutable critical_section m_lock;
};
diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h
index b70052c7..225b8c1e 100644
--- a/contrib/epee/include/misc_language.h
+++ b/contrib/epee/include/misc_language.h
@@ -389,22 +389,27 @@ namespace misc_utils
auto res = container.insert(typename t_container_type::value_type(key, AUTO_VAL_INIT(typename t_container_type::mapped_type())));
return res.first->second;
}
-}
-}
+} // namespace misc_utils
+} // namespace epee
template
std::ostream& print_container_content(std::ostream& out, const T& v);
-template
-std::ostream& operator<< (std::ostream& out, const std::vector& v)
+namespace std
{
- return print_container_content(out, v);
-}
-template
-std::ostream& operator<< (std::ostream& out, const std::list& v)
-{
- return print_container_content(out, v);
-}
+ template
+ std::ostream& operator<< (std::ostream& out, const std::vector& v)
+ {
+ return print_container_content(out, v);
+ }
+
+ template
+ std::ostream& operator<< (std::ostream& out, const std::list& v)
+ {
+ return print_container_content(out, v);
+ }
+
+} // namespace std
template
std::ostream& print_container_content(std::ostream& out, const T& v)
diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h
index c74378fc..412cb504 100644
--- a/contrib/epee/include/misc_log_ex.h
+++ b/contrib/epee/include/misc_log_ex.h
@@ -893,12 +893,10 @@ namespace log_space
FAST_CRITICAL_REGION_END();
return true;
}
-
std::string get_thread_prefix()
{
FAST_CRITICAL_REGION_LOCAL(m_critical_sec);
return m_thr_prefix_strings[misc_utils::get_thread_string_id()];
-
}
std::string get_default_log_file()
@@ -1160,7 +1158,6 @@ namespace log_space
}
-
static bool add_logger( ibase_log_stream* pstream, int log_level_limit = LOG_LEVEL_4 )
{
logger* plogger = get_or_create_instance();
@@ -1234,8 +1231,6 @@ POP_WARNINGS
}
-
-
#ifdef _MSC_VER
@@ -1290,8 +1285,6 @@ POP_WARNINGS
return plogger->get_thread_prefix();
}
-
-
static std::string get_prefix_entry()
{
std::stringstream str_prefix;
@@ -1587,8 +1580,6 @@ POP_WARNINGS
#endif
-
-
#define LOG_PRINT_NO_POSTFIX(mess, level) LOG_PRINT_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_PRINT_NO_PREFIX(mess, level) LOG_PRINT_NO_PREFIX2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_PRINT_NO_PREFIX_NO_POSTFIX(mess, level) LOG_PRINT_NO_PREFIX_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
@@ -1694,7 +1685,6 @@ POP_WARNINGS
#define CHECK_AND_ASSERT_MES2(expr, message) do{if(!(expr)) {LOG_ERROR(message); };}while(0)
#endif
-
}
POP_WARNINGS
diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/misc_os_dependent.h
index 4fe89b9f..116826ce 100644
--- a/contrib/epee/include/misc_os_dependent.h
+++ b/contrib/epee/include/misc_os_dependent.h
@@ -111,6 +111,7 @@ namespace misc_utils
#if defined(__GNUC__)
#include
+#include
#endif
inline std::string print_trace()
{
@@ -125,9 +126,9 @@ namespace misc_utils
stack_depth = backtrace(stack_addrs, max_depth);
stack_strings = backtrace_symbols(stack_addrs, stack_depth);
-
- for (size_t i = 1; i < stack_depth; i++) {
- ss << stack_strings[i] << std::endl;
+ for (size_t i = 1; i < stack_depth; i++)
+ {
+ ss << boost::core::demangle(stack_strings[i]) << std::endl;
}
free(stack_strings); // malloc()ed by backtrace_symbols
#endif
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index 15ce8441..c59c60e0 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -316,6 +316,7 @@ DISABLE_VS_WARNINGS(4355)
send_guard.unlock();//manual unlock
LOG_ERROR("send to [" << print_connection_context_short(context) << ", (" << (void*)this << ")] que size is more than ABSTRACT_SERVER_SEND_QUE_MAX_COUNT(" << ABSTRACT_SERVER_SEND_QUE_MAX_COUNT << "), shutting down connection");
close();
+ shutdown();
return false;
}
@@ -351,6 +352,8 @@ DISABLE_VS_WARNINGS(4355)
template
bool connection::shutdown()
{
+ if (m_was_shutdown)
+ return true;
// Initiate graceful connection closure.
boost::system::error_code ignored_ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
diff --git a/contrib/epee/include/net/http_protocol_handler.h b/contrib/epee/include/net/http_protocol_handler.h
index 569b6128..aa4dfa9a 100644
--- a/contrib/epee/include/net/http_protocol_handler.h
+++ b/contrib/epee/include/net/http_protocol_handler.h
@@ -137,6 +137,7 @@ namespace net_utils
bool m_is_stop_handling;
http::http_request_info m_query_info;
size_t m_len_summary, m_len_remain;
+ size_t m_precommand_line_chars;
config_type& m_config;
bool m_want_close;
protected:
diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl
index d981cdc8..b84bf47c 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -33,8 +33,9 @@
#include "file_io_utils.h"
#include "net_parse_helpers.h"
-#define HTTP_MAX_URI_LEN 9000
-#define HTTP_MAX_HEADER_LEN 100000
+#define HTTP_MAX_URI_LEN 9000
+#define HTTP_MAX_PRE_COMMAND_LINE_CHARS 20
+#define HTTP_MAX_HEADER_LEN 100000
PUSH_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
@@ -204,7 +205,8 @@ namespace net_utils
m_len_remain(0),
m_config(config),
m_want_close(false),
- m_psnd_hndlr(psnd_hndlr)
+ m_psnd_hndlr(psnd_hndlr),
+ m_precommand_line_chars(0)
{
}
@@ -217,6 +219,7 @@ namespace net_utils
m_body_transfer_type = http_body_transfer_undefined;
m_query_info.clear();
m_len_summary = 0;
+ m_precommand_line_chars = 0;
return true;
}
//--------------------------------------------------------------------------------------------
@@ -257,11 +260,19 @@ namespace net_utils
if((m_cache[0] == '\r' || m_cache[0] == '\n'))
{
//some times it could be that before query line cold be few line breaks
- //so we have to be calm without panic with assers
+ //so we have to be calm down without panic and asserts
m_cache.erase(0, 1);
+
+ //fixed bug with possible '\r\n' chars flood, thanks to @anonimal (https://github.com/anonimal) for pointing this
+ ++m_precommand_line_chars;
+ if (m_precommand_line_chars > HTTP_MAX_PRE_COMMAND_LINE_CHARS)
+ {
+ LOG_ERROR("simple_http_connection_handler::handle_buff_in: Too long URI line");
+ m_state = http_state_error;
+ return false;
+ }
break;
}
-
if(std::string::npos != m_cache.find('\n', 0))
handle_invoke_query_line();
else
@@ -269,7 +280,7 @@ namespace net_utils
m_is_stop_handling = true;
if(m_cache.size() > HTTP_MAX_URI_LEN)
{
- LOG_ERROR("simple_http_connection_handler::handle_buff_out: Too long URI line");
+ LOG_ERROR("simple_http_connection_handler::handle_buff_in: Too long URI line");
m_state = http_state_error;
return false;
}
@@ -297,10 +308,10 @@ namespace net_utils
case http_state_connection_close:
return false;
default:
- LOG_ERROR("simple_http_connection_handler::handle_char_out: Wrong state: " << m_state);
+ LOG_ERROR("simple_http_connection_handler::handle_buff_in: Wrong state: " << m_state);
return false;
case http_state_error:
- LOG_ERROR("simple_http_connection_handler::handle_char_out: Error state!!!");
+ LOG_ERROR("simple_http_connection_handler::handle_buff_in: Error state!!!");
return false;
}
@@ -334,10 +345,10 @@ namespace net_utils
template
bool simple_http_connection_handler::handle_invoke_query_line()
{
- LOG_FRAME("simple_http_connection_handler::handle_recognize_protocol_out(*)", LOG_LEVEL_3);
+ LOG_FRAME("simple_http_connection_handler::handle_invoke_query_line(*)", LOG_LEVEL_3);
STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+).(\\d+))\r?\n", boost::regex::icase | boost::regex::normal);
- // 123 4 5 6 7 8 9 10 11 12
+ // 123 4 5 6 7 8 9 10 11 12
//size_t match_len = 0;
boost::smatch result;
if(boost::regex_search(m_cache, result, rexp_match_command_line, boost::match_default) && result[0].matched)
@@ -682,4 +693,4 @@ namespace net_utils
POP_WARNINGS
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
-//--------------------------------------------------------------------------------------------
\ No newline at end of file
+//--------------------------------------------------------------------------------------------
diff --git a/contrib/epee/include/print_fixed_point_helper.h b/contrib/epee/include/print_fixed_point_helper.h
index 43843618..c652f601 100644
--- a/contrib/epee/include/print_fixed_point_helper.h
+++ b/contrib/epee/include/print_fixed_point_helper.h
@@ -31,9 +31,10 @@ namespace epee
{
namespace string_tools
{
- inline std::string print_fixed_decimal_point(uint64_t amount, size_t decimal_point)
+ template
+ inline std::string print_fixed_decimal_point(t_number amount, size_t decimal_point)
{
- std::string s = std::to_string(amount);
+ std::string s = boost::lexical_cast(amount);
if (s.size() < decimal_point + 1)
{
s.insert(0, decimal_point + 1 - s.size(), '0');
diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
index 073fd441..05c235d8 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
@@ -125,6 +125,7 @@ namespace epee
template
static bool serialize_stl_container_pod_val_as_blob(const stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
{
+ static_assert(std::is_trivial::value, "Item supposed to be 'trivial'(trivially copyable)");
if(!container.size()) return true;
std::string mb;
mb.resize(sizeof(typename stl_container::value_type)*container.size());
@@ -140,6 +141,7 @@ namespace epee
template
static bool unserialize_stl_container_pod_val_as_blob(stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
{
+ static_assert(std::is_trivial::value, "Item supposed to be 'trivial'(trivially copyable)");
container.clear();
std::string buff;
bool res = stg.get_value(pname, buff, hparent_section);
diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h
index b9b7aba9..92fbeece 100644
--- a/contrib/epee/include/storages/portable_storage.h
+++ b/contrib/epee/include/storages/portable_storage.h
@@ -83,7 +83,7 @@ namespace epee
bool load_from_binary(const binarybuffer& target);
template
bool dump_as_xml(std::string& targetObj, const std::string& root_name = "");
- bool dump_as_json(std::string& targetObj, size_t indent = 0);
+ bool dump_as_json(std::string& targetObj, size_t indent = 0, end_of_line_t eol = eol_crlf);
bool load_from_json(const std::string& source);
private:
@@ -106,11 +106,11 @@ namespace epee
#pragma pack(pop)
};
inline
- bool portable_storage::dump_as_json(std::string& buff, size_t indent)
+ bool portable_storage::dump_as_json(std::string& buff, size_t indent /* = 0 */, end_of_line_t eol /* = eol_crlf */)
{
TRY_ENTRY();
std::stringstream ss;
- epee::serialization::dump_as_json(ss, m_root, indent);
+ epee::serialization::dump_as_json(ss, m_root, indent, eol);
buff = ss.str();
return true;
CATCH_ENTRY("portable_storage::dump_as_json", false)
diff --git a/contrib/epee/include/storages/portable_storage_base.h b/contrib/epee/include/storages/portable_storage_base.h
index 3f163753..3620dbcc 100644
--- a/contrib/epee/include/storages/portable_storage_base.h
+++ b/contrib/epee/include/storages/portable_storage_base.h
@@ -69,6 +69,8 @@ namespace epee
{
namespace serialization
{
+ enum end_of_line_t { eol_crlf = 0, eol_lf = 1, eol_cr = 2, eol_space = 3 };
+
struct section;
/************************************************************************/
diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/storages/portable_storage_template_helper.h
index 4f91e081..d7471a51 100644
--- a/contrib/epee/include/storages/portable_storage_template_helper.h
+++ b/contrib/epee/include/storages/portable_storage_template_helper.h
@@ -56,16 +56,16 @@ namespace epee
}
//-----------------------------------------------------------------------------------------------------------
template
- bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0)
+ bool store_t_to_json(const t_struct& str_in, std::string& json_buff, size_t indent = 0, end_of_line_t eol = eol_crlf)
{
portable_storage ps;
str_in.store(ps);
- ps.dump_as_json(json_buff, indent);
+ ps.dump_as_json(json_buff, indent, eol);
return true;
}
//-----------------------------------------------------------------------------------------------------------
template
- std::string store_t_to_json(const t_struct& str_in, size_t indent = 0)
+ std::string store_t_to_json(const t_struct& str_in, size_t indent = 0, end_of_line_t eol = eol_crlf)
{
std::string json_buff;
store_t_to_json(str_in, json_buff, indent);
diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/storages/portable_storage_to_json.h
index 7c22f30c..9cfd9c0a 100644
--- a/contrib/epee/include/storages/portable_storage_to_json.h
+++ b/contrib/epee/include/storages/portable_storage_to_json.h
@@ -37,23 +37,23 @@ namespace epee
{
template
- void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent);
+ void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent);
+ void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const std::string& v, size_t indent);
+ void dump_as_json(t_stream& strm, const std::string& v, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const int8_t& v, size_t indent);
+ void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent);
+ void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const bool& v, size_t indent);
+ void dump_as_json(t_stream& strm, const bool& v, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const double& v, size_t indent);
+ void dump_as_json(t_stream& strm, const double& v, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const t_type& v, size_t indent);
+ void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol = eol_crlf);
template
- void dump_as_json(t_stream& strm, const section& sec, size_t indent);
+ void dump_as_json(t_stream& strm, const section& sec, size_t indent, end_of_line_t eol = eol_crlf);
inline std::string make_indent(size_t indent)
@@ -66,7 +66,13 @@ namespace epee
{
t_stream& m_strm;
size_t m_indent;
- array_entry_store_to_json_visitor(t_stream& strm, size_t indent):m_strm(strm), m_indent(indent){}
+ end_of_line_t m_eol;
+
+ array_entry_store_to_json_visitor(t_stream& strm, size_t indent, end_of_line_t eol)
+ : m_strm(strm)
+ , m_indent(indent)
+ , m_eol(eol)
+ {}
template
void operator()(const array_entry_t& a)
@@ -77,7 +83,7 @@ namespace epee
auto last_it = --a.m_array.end();
for(auto it = a.m_array.begin(); it != a.m_array.end(); it++)
{
- dump_as_json(m_strm, *it, m_indent);
+ dump_as_json(m_strm, *it, m_indent, m_eol);
if(it != last_it)
m_strm << ",";
}
@@ -91,50 +97,56 @@ namespace epee
{
t_stream& m_strm;
size_t m_indent;
- storage_entry_store_to_json_visitor(t_stream& strm, size_t indent):m_strm(strm), m_indent(indent)
+ end_of_line_t m_eol;
+
+ storage_entry_store_to_json_visitor(t_stream& strm, size_t indent, end_of_line_t eol)
+ : m_strm(strm)
+ , m_indent(indent)
+ , m_eol(eol)
{}
+
//section, array_entry
template
void operator()(const visited_type& v)
{
- dump_as_json(m_strm, v, m_indent);
+ dump_as_json(m_strm, v, m_indent, m_eol);
}
};
template
- void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent)
+ void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, end_of_line_t eol)
{
- array_entry_store_to_json_visitor aesv(strm, indent);
+ array_entry_store_to_json_visitor aesv(strm, indent, eol);
boost::apply_visitor(aesv, ae);
}
template
- void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent)
+ void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, end_of_line_t eol)
{
- storage_entry_store_to_json_visitor sv(strm, indent);
+ storage_entry_store_to_json_visitor sv(strm, indent, eol);
boost::apply_visitor(sv, se);
}
template
- void dump_as_json(t_stream& strm, const std::string& v, size_t indent)
+ void dump_as_json(t_stream& strm, const std::string& v, size_t indent, end_of_line_t eol)
{
strm << "\"" << misc_utils::parse::transform_to_json_escape_sequence(v) << "\"";
}
template
- void dump_as_json(t_stream& strm, const int8_t& v, size_t indent)
+ void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, end_of_line_t eol)
{
strm << static_cast(v);
}
template
- void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent)
+ void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, end_of_line_t eol)
{
strm << static_cast(v);
}
template
- void dump_as_json(t_stream& strm, const bool& v, size_t indent)
+ void dump_as_json(t_stream& strm, const bool& v, size_t indent, end_of_line_t eol)
{
if(v)
strm << "true";
@@ -143,23 +155,34 @@ namespace epee
}
template
- void dump_as_json(t_stream& strm, const double& v, size_t indent)
+ void dump_as_json(t_stream& strm, const double& v, size_t indent, end_of_line_t eol)
{
strm.precision(8);
strm << std::fixed << v;
}
template
- void dump_as_json(t_stream& strm, const t_type& v, size_t /*indent*/)
+ void dump_as_json(t_stream& strm, const t_type& v, size_t indent, end_of_line_t eol)
{
strm << v;
}
template
- void dump_as_json(t_stream& strm, const section& sec, size_t indent)
+ void dump_as_json(t_stream& strm, const section& sec, size_t indent, end_of_line_t eol)
{
+ auto put_eol = [&]() {
+ switch (eol)
+ {
+ case eol_lf: strm << "\n"; break;
+ case eol_cr: strm << "\r"; break;
+ case eol_space: strm << " "; break;
+ default: strm << "\r\n"; break;
+ }
+ };
+
size_t local_indent = indent + 1;
- strm << "{\r\n";
+ strm << "{";
+ put_eol();
std::string indent_str = make_indent(local_indent);
if(sec.m_entries.size())
{
@@ -167,10 +190,10 @@ namespace epee
for(auto it = sec.m_entries.begin(); it!= sec.m_entries.end();it++)
{
strm << indent_str << "\"" << misc_utils::parse::transform_to_json_escape_sequence(it->first) << "\"" << ": ";
- dump_as_json(strm, it->second, local_indent);
+ dump_as_json(strm, it->second, local_indent, eol);
if(it_last != it)
strm << ",";
- strm << "\r\n";
+ put_eol();
}
}
strm << make_indent(indent) << "}";
diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h
index f66abfcf..e1cb977f 100644
--- a/contrib/epee/include/string_tools.h
+++ b/contrib/epee/include/string_tools.h
@@ -648,9 +648,6 @@ POP_WARNINGS
return res;
}
//----------------------------------------------------------------------------
-
-
-
inline std::string cut_off_extension(const std::string& str)
{
std::string res;
@@ -661,7 +658,17 @@ POP_WARNINGS
res = str.substr(0, pos);
return res;
}
+ //----------------------------------------------------------------------------
+ inline std::wstring cut_off_extension(const std::wstring& str)
+ {
+ std::wstring res;
+ std::wstring::size_type pos = str.rfind('.');
+ if (std::wstring::npos == pos)
+ return str;
+ res = str.substr(0, pos);
+ return res;
+ }
//----------------------------------------------------------------------------
// replaces all non-ascii characters with mask_character
inline std::string mask_non_ascii_chars(const std::string& str, const char mask_character = '?')
diff --git a/contrib/epee/include/sync_locked_object.h b/contrib/epee/include/sync_locked_object.h
index 1a60b7dc..09e85178 100644
--- a/contrib/epee/include/sync_locked_object.h
+++ b/contrib/epee/include/sync_locked_object.h
@@ -78,7 +78,7 @@ namespace epee
{
t_object t;
- std::recursive_mutex m;
+ mutable std::recursive_mutex m;
template
friend class locked_object_proxy;
public:
@@ -106,6 +106,16 @@ namespace epee
return locked_object_proxy(t, m);
}
+ locked_object_proxy operator->() const
+ {
+ return locked_object_proxy(t, m);
+ }
+
+ locked_object_proxy operator*() const
+ {
+ return locked_object_proxy(t, m);
+ }
+
/*locked_object_proxy operator()()
{
return locked_object_proxy(t, m);
diff --git a/contrib/epee/include/syncobj.h b/contrib/epee/include/syncobj.h
index f20bff07..c31b5e0c 100644
--- a/contrib/epee/include/syncobj.h
+++ b/contrib/epee/include/syncobj.h
@@ -701,6 +701,11 @@ namespace epee
#define CRITICAL_REGION_BEGIN1(x) CRITICAL_REGION_BEGIN_VAR(x, critical_region_var1)
#define CRITICAL_REGION_END() }
+#define SHARED_CRITICAL_REGION_LOCAL(x) boost::shared_lock< boost::shared_mutex > critical_region_var(x)
+#define EXCLUSIVE_CRITICAL_REGION_LOCAL(x) boost::unique_lock< boost::shared_mutex > critical_region_var(x)
+
+#define SHARED_CRITICAL_REGION_BEGIN(x) { SHARED_CRITICAL_REGION_LOCAL(x)
+#define EXCLUSIVE_CRITICAL_REGION_BEGIN(x) { EXCLUSIVE_CRITICAL_REGION_LOCAL(x)
}
diff --git a/contrib/ethereum/CMakeLists.txt b/contrib/ethereum/CMakeLists.txt
new file mode 100644
index 00000000..359ad19e
--- /dev/null
+++ b/contrib/ethereum/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_subdirectory(libethash)
+
+set_property(TARGET ethash PROPERTY FOLDER "contrib")
+
+if(MSVC)
+ target_compile_options(ethash PRIVATE /wd4477 /wd4267)
+else()
+ target_compile_options(ethash PRIVATE -Wno-format -Wno-aggregate-return -Wno-empty-body)
+endif()
+
diff --git a/contrib/ethereum/libethash/CMakeLists.txt b/contrib/ethereum/libethash/CMakeLists.txt
new file mode 100644
index 00000000..8205079d
--- /dev/null
+++ b/contrib/ethereum/libethash/CMakeLists.txt
@@ -0,0 +1,33 @@
+# ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+# Copyright 2018 Pawel Bylica.
+# Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+# set(include_dir ${PROJECT_SOURCE_DIR}/include)
+
+
+add_library(
+ ethash
+ bit_manipulation.h
+ builtins.h
+ endianness.hpp
+ ethash/ethash.h
+ ethash/ethash.hpp
+ ethash-internal.hpp
+ ethash.cpp
+ ethash/hash_types.h
+ managed.cpp
+ ethash/keccak.h
+ ethash/keccak.hpp
+ keccak.c
+ keccakf800.c
+ keccakf1600.c
+ kiss99.hpp
+ primes.h
+ primes.c
+ ethash/progpow.hpp
+ progpow.cpp
+)
+
+
+
+
diff --git a/contrib/ethereum/libethash/bit_manipulation.h b/contrib/ethereum/libethash/bit_manipulation.h
new file mode 100644
index 00000000..3fa22948
--- /dev/null
+++ b/contrib/ethereum/libethash/bit_manipulation.h
@@ -0,0 +1,81 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#pragma once
+
+#include "builtins.h"
+#include "support/attributes.h"
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline uint32_t rotl32(uint32_t n, unsigned int c)
+{
+ const unsigned int mask = 31;
+
+ c &= mask;
+ unsigned int neg_c = (unsigned int)(-(int)c);
+ return (n << c) | (n >> (neg_c & mask));
+}
+
+static inline uint32_t rotr32(uint32_t n, unsigned int c)
+{
+ const unsigned int mask = 31;
+
+ c &= mask;
+ unsigned int neg_c = (unsigned int)(-(int)c);
+ return (n >> c) | (n << (neg_c & mask));
+}
+
+static inline uint32_t clz32(uint32_t x)
+{
+ return x ? (uint32_t)__builtin_clz(x) : 32;
+}
+
+static inline uint32_t popcount32(uint32_t x)
+{
+ return (uint32_t)__builtin_popcount(x);
+}
+
+static inline uint32_t mul_hi32(uint32_t x, uint32_t y)
+{
+ return (uint32_t)(((uint64_t)x * (uint64_t)y) >> 32);
+}
+
+
+/** FNV 32-bit prime. */
+static const uint32_t fnv_prime = 0x01000193;
+
+/** FNV 32-bit offset basis. */
+static const uint32_t fnv_offset_basis = 0x811c9dc5;
+
+/**
+ * The implementation of FNV-1 hash.
+ *
+ * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1_hash.
+ */
+NO_SANITIZE("unsigned-integer-overflow")
+static inline uint32_t fnv1(uint32_t u, uint32_t v) noexcept
+{
+ return (u * fnv_prime) ^ v;
+}
+
+/**
+ * The implementation of FNV-1a hash.
+ *
+ * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash.
+ */
+NO_SANITIZE("unsigned-integer-overflow")
+static inline uint32_t fnv1a(uint32_t u, uint32_t v) noexcept
+{
+ return (u ^ v) * fnv_prime;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/ethereum/libethash/builtins.h b/contrib/ethereum/libethash/builtins.h
new file mode 100644
index 00000000..6cf6a285
--- /dev/null
+++ b/contrib/ethereum/libethash/builtins.h
@@ -0,0 +1,43 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+/**
+ * @file
+ * Implementation of GCC/clang builtins for MSVC compiler.
+ */
+
+#pragma once
+
+#ifdef _MSC_VER
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns the number of leading 0-bits in `x`, starting at the most significant bit position.
+ * If `x` is 0, the result is undefined.
+ */
+static inline int __builtin_clz(unsigned int x)
+{
+ unsigned long most_significant_bit;
+ _BitScanReverse(&most_significant_bit, x);
+ return 31 - (int)most_significant_bit;
+}
+
+/**
+ * Returns the number of 1-bits in `x`.
+ */
+static inline int __builtin_popcount(unsigned int x)
+{
+ return (int)__popcnt(x);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/ethereum/libethash/endianness.hpp b/contrib/ethereum/libethash/endianness.hpp
new file mode 100644
index 00000000..34724778
--- /dev/null
+++ b/contrib/ethereum/libethash/endianness.hpp
@@ -0,0 +1,98 @@
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+/// @file
+/// This file contains helper functions to handle big-endian architectures.
+/// The Ethash algorithm is naturally defined for little-endian architectures
+/// so for those the helpers are just no-op empty functions.
+/// For big-endian architectures we need 32-bit and 64-bit byte swapping in
+/// some places.
+
+#pragma once
+
+#include
+
+#if _WIN32
+
+#include
+
+#define bswap32 _byteswap_ulong
+#define bswap64 _byteswap_uint64
+
+// On Windows assume little endian.
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+#elif __APPLE__
+
+#include
+
+#define bswap32 __builtin_bswap32
+#define bswap64 __builtin_bswap64
+
+#else
+
+#include
+
+#define bswap32 __builtin_bswap32
+#define bswap64 __builtin_bswap64
+
+#endif
+
+namespace ethash
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+struct le
+{
+ static uint32_t uint32(uint32_t x) noexcept { return x; }
+ static uint64_t uint64(uint64_t x) noexcept { return x; }
+
+ static const hash1024& uint32s(const hash1024& h) noexcept { return h; }
+ static const hash512& uint32s(const hash512& h) noexcept { return h; }
+ static const hash256& uint32s(const hash256& h) noexcept { return h; }
+};
+
+struct be
+{
+ static uint64_t uint64(uint64_t x) noexcept { return bswap64(x); }
+};
+
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+struct le
+{
+ static uint32_t uint32(uint32_t x) noexcept { return bswap32(x); }
+ static uint64_t uint64(uint64_t x) noexcept { return bswap64(x); }
+
+ static hash1024 uint32s(hash1024 h) noexcept
+ {
+ for (auto& w : h.word32s)
+ w = uint32(w);
+ return h;
+ }
+
+ static hash512 uint32s(hash512 h) noexcept
+ {
+ for (auto& w : h.word32s)
+ w = uint32(w);
+ return h;
+ }
+
+ static hash256 uint32s(hash256 h) noexcept
+ {
+ for (auto& w : h.word32s)
+ w = uint32(w);
+ return h;
+ }
+};
+
+struct be
+{
+ static uint64_t uint64(uint64_t x) noexcept { return x; }
+};
+
+#endif
+} // namespace ethash
\ No newline at end of file
diff --git a/contrib/ethereum/libethash/ethash-internal.hpp b/contrib/ethereum/libethash/ethash-internal.hpp
new file mode 100644
index 00000000..96209bd1
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash-internal.hpp
@@ -0,0 +1,69 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+/// @file
+/// Contains declarations of internal ethash functions to allow them to be
+/// unit-tested.
+
+#pragma once
+
+#include
+
+#include "endianness.hpp"
+
+#include
+#include
+
+extern "C" struct ethash_epoch_context_full : ethash_epoch_context
+{
+ ethash_hash1024* full_dataset;
+
+ constexpr ethash_epoch_context_full(int epoch_number, int light_cache_num_items,
+ const ethash_hash512* light_cache, const uint32_t* l1_cache, int full_dataset_num_items,
+ ethash_hash1024* full_dataset) noexcept
+ : ethash_epoch_context{epoch_number, light_cache_num_items, light_cache, l1_cache,
+ full_dataset_num_items},
+ full_dataset{full_dataset}
+ {}
+};
+
+namespace ethash
+{
+inline bool is_less_or_equal(const hash256& a, const hash256& b) noexcept
+{
+ for (size_t i = 0; i < (sizeof(a) / sizeof(a.word64s[0])); ++i)
+ {
+ if (be::uint64(a.word64s[i]) > be::uint64(b.word64s[i]))
+ return false;
+ if (be::uint64(a.word64s[i]) < be::uint64(b.word64s[i]))
+ return true;
+ }
+ return true;
+}
+
+inline bool is_equal(const hash256& a, const hash256& b) noexcept
+{
+ return std::memcmp(a.bytes, b.bytes, sizeof(a)) == 0;
+}
+
+void build_light_cache(hash512 cache[], int num_items, const hash256& seed) noexcept;
+
+hash512 calculate_dataset_item_512(const epoch_context& context, int64_t index) noexcept;
+hash1024 calculate_dataset_item_1024(const epoch_context& context, uint32_t index) noexcept;
+hash2048 calculate_dataset_item_2048(const epoch_context& context, uint32_t index) noexcept;
+
+namespace generic
+{
+using hash_fn_512 = hash512 (*)(const uint8_t* data, size_t size);
+using build_light_cache_fn = void (*)(hash512 cache[], int num_items, const hash256& seed);
+
+void build_light_cache(
+ hash_fn_512 hash_fn, hash512 cache[], int num_items, const hash256& seed) noexcept;
+
+epoch_context_full* create_epoch_context(
+ build_light_cache_fn build_fn, int epoch_number, bool full) noexcept;
+
+} // namespace generic
+
+} // namespace ethash
diff --git a/contrib/ethereum/libethash/ethash.cpp b/contrib/ethereum/libethash/ethash.cpp
new file mode 100644
index 00000000..f12faab7
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash.cpp
@@ -0,0 +1,441 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+#include "ethash-internal.hpp"
+
+#include "bit_manipulation.h"
+#include "endianness.hpp"
+#include "primes.h"
+#include "support/attributes.h"
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace ethash
+{
+// Internal constants:
+constexpr static int light_cache_init_size = 1 << 24;
+constexpr static int light_cache_growth = 1 << 17;
+constexpr static int light_cache_rounds = 3;
+constexpr static int full_dataset_init_size = 1 << 30;
+constexpr static int full_dataset_growth = 1 << 23;
+constexpr static int full_dataset_item_parents = 256;
+
+// Verify constants:
+static_assert(sizeof(hash512) == ETHASH_LIGHT_CACHE_ITEM_SIZE, "");
+static_assert(sizeof(hash1024) == ETHASH_FULL_DATASET_ITEM_SIZE, "");
+static_assert(light_cache_item_size == ETHASH_LIGHT_CACHE_ITEM_SIZE, "");
+static_assert(full_dataset_item_size == ETHASH_FULL_DATASET_ITEM_SIZE, "");
+
+
+namespace
+{
+using ::fnv1;
+
+inline hash512 fnv1(const hash512& u, const hash512& v) noexcept
+{
+ hash512 r;
+ for (size_t i = 0; i < sizeof(r) / sizeof(r.word32s[0]); ++i)
+ r.word32s[i] = fnv1(u.word32s[i], v.word32s[i]);
+ return r;
+}
+
+inline hash512 bitwise_xor(const hash512& x, const hash512& y) noexcept
+{
+ hash512 z;
+ for (size_t i = 0; i < sizeof(z) / sizeof(z.word64s[0]); ++i)
+ z.word64s[i] = x.word64s[i] ^ y.word64s[i];
+ return z;
+}
+} // namespace
+
+int find_epoch_number(const hash256& seed) noexcept
+{
+ static constexpr int num_tries = 30000; // Divisible by 16.
+
+ // Thread-local cache of the last search.
+ static thread_local int cached_epoch_number = 0;
+ static thread_local hash256 cached_seed = {};
+
+ // Load from memory once (memory will be clobbered by keccak256()).
+ const uint32_t seed_part = seed.word32s[0];
+ const int e = cached_epoch_number;
+ hash256 s = cached_seed;
+
+ if (s.word32s[0] == seed_part)
+ return e;
+
+ // Try the next seed, will match for sequential epoch access.
+ s = keccak256(s);
+ if (s.word32s[0] == seed_part)
+ {
+ cached_seed = s;
+ cached_epoch_number = e + 1;
+ return e + 1;
+ }
+
+ // Search for matching seed starting from epoch 0.
+ s = {};
+ for (int i = 0; i < num_tries; ++i)
+ {
+ if (s.word32s[0] == seed_part)
+ {
+ cached_seed = s;
+ cached_epoch_number = i;
+ return i;
+ }
+
+ s = keccak256(s);
+ }
+
+ return -1;
+}
+
+namespace generic
+{
+void build_light_cache(
+ hash_fn_512 hash_fn, hash512 cache[], int num_items, const hash256& seed) noexcept
+{
+ hash512 item = hash_fn(seed.bytes, sizeof(seed));
+ cache[0] = item;
+ for (int i = 1; i < num_items; ++i)
+ {
+ item = hash_fn(item.bytes, sizeof(item));
+ cache[i] = item;
+ }
+
+ for (int q = 0; q < light_cache_rounds; ++q)
+ {
+ for (int i = 0; i < num_items; ++i)
+ {
+ const uint32_t index_limit = static_cast(num_items);
+
+ // Fist index: 4 first bytes of the item as little-endian integer.
+ const uint32_t t = le::uint32(cache[i].word32s[0]);
+ const uint32_t v = t % index_limit;
+
+ // Second index.
+ const uint32_t w = static_cast(num_items + (i - 1)) % index_limit;
+
+ const hash512 x = bitwise_xor(cache[v], cache[w]);
+ cache[i] = hash_fn(x.bytes, sizeof(x));
+ }
+ }
+}
+
+epoch_context_full* create_epoch_context(
+ build_light_cache_fn build_fn, int epoch_number, bool full) noexcept
+{
+ static_assert(sizeof(epoch_context_full) < sizeof(hash512), "epoch_context too big");
+ static constexpr size_t context_alloc_size = sizeof(hash512);
+
+ const int light_cache_num_items = calculate_light_cache_num_items(epoch_number);
+ const int full_dataset_num_items = calculate_full_dataset_num_items(epoch_number);
+ const size_t light_cache_size = get_light_cache_size(light_cache_num_items);
+ const size_t full_dataset_size =
+ full ? static_cast(full_dataset_num_items) * sizeof(hash1024) :
+ progpow::l1_cache_size;
+
+ const size_t alloc_size = context_alloc_size + light_cache_size + full_dataset_size;
+
+ char* const alloc_data = static_cast(std::calloc(1, alloc_size));
+ if (!alloc_data)
+ return nullptr; // Signal out-of-memory by returning null pointer.
+
+ hash512* const light_cache = reinterpret_cast(alloc_data + context_alloc_size);
+ const hash256 epoch_seed = calculate_epoch_seed(epoch_number);
+ build_fn(light_cache, light_cache_num_items, epoch_seed);
+
+ uint32_t* const l1_cache =
+ reinterpret_cast(alloc_data + context_alloc_size + light_cache_size);
+
+ hash1024* full_dataset = full ? reinterpret_cast(l1_cache) : nullptr;
+
+ epoch_context_full* const context = new (alloc_data) epoch_context_full{
+ epoch_number,
+ light_cache_num_items,
+ light_cache,
+ l1_cache,
+ full_dataset_num_items,
+ full_dataset,
+ };
+
+ auto* full_dataset_2048 = reinterpret_cast(l1_cache);
+ for (uint32_t i = 0; i < progpow::l1_cache_size / sizeof(full_dataset_2048[0]); ++i)
+ full_dataset_2048[i] = calculate_dataset_item_2048(*context, i);
+ return context;
+}
+} // namespace generic
+
+void build_light_cache(hash512 cache[], int num_items, const hash256& seed) noexcept
+{
+ return generic::build_light_cache(keccak512, cache, num_items, seed);
+}
+
+struct item_state
+{
+ const hash512* const cache;
+ const int64_t num_cache_items;
+ const uint32_t seed;
+
+ hash512 mix;
+
+ ALWAYS_INLINE item_state(const epoch_context& context, int64_t index) noexcept
+ : cache{context.light_cache},
+ num_cache_items{context.light_cache_num_items},
+ seed{static_cast(index)}
+ {
+ mix = cache[index % num_cache_items];
+ mix.word32s[0] ^= le::uint32(seed);
+ mix = le::uint32s(keccak512(mix));
+ }
+
+ ALWAYS_INLINE void update(uint32_t round) noexcept
+ {
+ static constexpr size_t num_words = sizeof(mix) / sizeof(uint32_t);
+ const uint32_t t = fnv1(seed ^ round, mix.word32s[round % num_words]);
+ const int64_t parent_index = t % num_cache_items;
+ mix = fnv1(mix, le::uint32s(cache[parent_index]));
+ }
+
+ ALWAYS_INLINE hash512 final() noexcept { return keccak512(le::uint32s(mix)); }
+};
+
+hash512 calculate_dataset_item_512(const epoch_context& context, int64_t index) noexcept
+{
+ item_state item0{context, index};
+ for (uint32_t j = 0; j < full_dataset_item_parents; ++j)
+ item0.update(j);
+ return item0.final();
+}
+
+/// Calculates a full dataset item
+///
+/// This consist of two 512-bit items produced by calculate_dataset_item_partial().
+/// Here the computation is done interleaved for better performance.
+hash1024 calculate_dataset_item_1024(const epoch_context& context, uint32_t index) noexcept
+{
+ item_state item0{context, int64_t(index) * 2};
+ item_state item1{context, int64_t(index) * 2 + 1};
+
+ for (uint32_t j = 0; j < full_dataset_item_parents; ++j)
+ {
+ item0.update(j);
+ item1.update(j);
+ }
+
+ return hash1024{{item0.final(), item1.final()}};
+}
+
+hash2048 calculate_dataset_item_2048(const epoch_context& context, uint32_t index) noexcept
+{
+ item_state item0{context, int64_t(index) * 4};
+ item_state item1{context, int64_t(index) * 4 + 1};
+ item_state item2{context, int64_t(index) * 4 + 2};
+ item_state item3{context, int64_t(index) * 4 + 3};
+
+ for (uint32_t j = 0; j < full_dataset_item_parents; ++j)
+ {
+ item0.update(j);
+ item1.update(j);
+ item2.update(j);
+ item3.update(j);
+ }
+
+ return hash2048{{item0.final(), item1.final(), item2.final(), item3.final()}};
+}
+
+namespace
+{
+using lookup_fn = hash1024 (*)(const epoch_context&, uint32_t);
+
+inline hash512 hash_seed(const hash256& header_hash, uint64_t nonce) noexcept
+{
+ nonce = le::uint64(nonce);
+ uint8_t init_data[sizeof(header_hash) + sizeof(nonce)];
+ std::memcpy(&init_data[0], &header_hash, sizeof(header_hash));
+ std::memcpy(&init_data[sizeof(header_hash)], &nonce, sizeof(nonce));
+
+ return keccak512(init_data, sizeof(init_data));
+}
+
+inline hash256 hash_final(const hash512& seed, const hash256& mix_hash)
+{
+ uint8_t final_data[sizeof(seed) + sizeof(mix_hash)];
+ std::memcpy(&final_data[0], seed.bytes, sizeof(seed));
+ std::memcpy(&final_data[sizeof(seed)], mix_hash.bytes, sizeof(mix_hash));
+ return keccak256(final_data, sizeof(final_data));
+}
+
+inline hash256 hash_kernel(
+ const epoch_context& context, const hash512& seed, lookup_fn lookup) noexcept
+{
+ static constexpr size_t num_words = sizeof(hash1024) / sizeof(uint32_t);
+ const uint32_t index_limit = static_cast(context.full_dataset_num_items);
+ const uint32_t seed_init = le::uint32(seed.word32s[0]);
+
+ hash1024 mix{{le::uint32s(seed), le::uint32s(seed)}};
+
+ for (uint32_t i = 0; i < num_dataset_accesses; ++i)
+ {
+ const uint32_t p = fnv1(i ^ seed_init, mix.word32s[i % num_words]) % index_limit;
+ const hash1024 newdata = le::uint32s(lookup(context, p));
+
+ for (size_t j = 0; j < num_words; ++j)
+ mix.word32s[j] = fnv1(mix.word32s[j], newdata.word32s[j]);
+ }
+
+ hash256 mix_hash;
+ for (size_t i = 0; i < num_words; i += 4)
+ {
+ const uint32_t h1 = fnv1(mix.word32s[i], mix.word32s[i + 1]);
+ const uint32_t h2 = fnv1(h1, mix.word32s[i + 2]);
+ const uint32_t h3 = fnv1(h2, mix.word32s[i + 3]);
+ mix_hash.word32s[i / 4] = h3;
+ }
+
+ return le::uint32s(mix_hash);
+}
+} // namespace
+
+result hash(const epoch_context& context, const hash256& header_hash, uint64_t nonce) noexcept
+{
+ const hash512 seed = hash_seed(header_hash, nonce);
+ const hash256 mix_hash = hash_kernel(context, seed, calculate_dataset_item_1024);
+ return {hash_final(seed, mix_hash), mix_hash};
+}
+
+result hash(const epoch_context_full& context, const hash256& header_hash, uint64_t nonce) noexcept
+{
+ static const auto lazy_lookup = [](const epoch_context& context, uint32_t index) noexcept
+ {
+ auto full_dataset = static_cast(context).full_dataset;
+ hash1024& item = full_dataset[index];
+ if (item.word64s[0] == 0)
+ {
+ // TODO: Copy elision here makes it thread-safe?
+ item = calculate_dataset_item_1024(context, index);
+ }
+
+ return item;
+ };
+
+ const hash512 seed = hash_seed(header_hash, nonce);
+ const hash256 mix_hash = hash_kernel(context, seed, lazy_lookup);
+ return {hash_final(seed, mix_hash), mix_hash};
+}
+
+bool verify_final_hash(const hash256& header_hash, const hash256& mix_hash, uint64_t nonce,
+ const hash256& boundary) noexcept
+{
+ const hash512 seed = hash_seed(header_hash, nonce);
+ return is_less_or_equal(hash_final(seed, mix_hash), boundary);
+}
+
+bool verify(const epoch_context& context, const hash256& header_hash, const hash256& mix_hash,
+ uint64_t nonce, const hash256& boundary) noexcept
+{
+ const hash512 seed = hash_seed(header_hash, nonce);
+ if (!is_less_or_equal(hash_final(seed, mix_hash), boundary))
+ return false;
+
+ const hash256 expected_mix_hash = hash_kernel(context, seed, calculate_dataset_item_1024);
+ return is_equal(expected_mix_hash, mix_hash);
+}
+
+search_result search_light(const epoch_context& context, const hash256& header_hash,
+ const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept
+{
+ const uint64_t end_nonce = start_nonce + iterations;
+ for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce)
+ {
+ result r = hash(context, header_hash, nonce);
+ if (is_less_or_equal(r.final_hash, boundary))
+ return {r, nonce};
+ }
+ return {};
+}
+
+search_result search(const epoch_context_full& context, const hash256& header_hash,
+ const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept
+{
+ const uint64_t end_nonce = start_nonce + iterations;
+ for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce)
+ {
+ result r = hash(context, header_hash, nonce);
+ if (is_less_or_equal(r.final_hash, boundary))
+ return {r, nonce};
+ }
+ return {};
+}
+} // namespace ethash
+
+using namespace ethash;
+
+extern "C" {
+
+ethash_hash256 ethash_calculate_epoch_seed(int epoch_number) noexcept
+{
+ ethash_hash256 epoch_seed = {};
+ for (int i = 0; i < epoch_number; ++i)
+ epoch_seed = ethash_keccak256_32(epoch_seed.bytes);
+ return epoch_seed;
+}
+
+int ethash_calculate_light_cache_num_items(int epoch_number) noexcept
+{
+ static constexpr int item_size = sizeof(hash512);
+ static constexpr int num_items_init = light_cache_init_size / item_size;
+ static constexpr int num_items_growth = light_cache_growth / item_size;
+ static_assert(
+ light_cache_init_size % item_size == 0, "light_cache_init_size not multiple of item size");
+ static_assert(
+ light_cache_growth % item_size == 0, "light_cache_growth not multiple of item size");
+
+ int num_items_upper_bound = num_items_init + epoch_number * num_items_growth;
+ int num_items = ethash_find_largest_prime(num_items_upper_bound);
+ return num_items;
+}
+
+int ethash_calculate_full_dataset_num_items(int epoch_number) noexcept
+{
+ static constexpr int item_size = sizeof(hash1024);
+ static constexpr int num_items_init = full_dataset_init_size / item_size;
+ static constexpr int num_items_growth = full_dataset_growth / item_size;
+ static_assert(full_dataset_init_size % item_size == 0,
+ "full_dataset_init_size not multiple of item size");
+ static_assert(
+ full_dataset_growth % item_size == 0, "full_dataset_growth not multiple of item size");
+
+ int num_items_upper_bound = num_items_init + epoch_number * num_items_growth;
+ int num_items = ethash_find_largest_prime(num_items_upper_bound);
+ return num_items;
+}
+
+epoch_context* ethash_create_epoch_context(int epoch_number) noexcept
+{
+ return generic::create_epoch_context(build_light_cache, epoch_number, false);
+}
+
+epoch_context_full* ethash_create_epoch_context_full(int epoch_number) noexcept
+{
+ return generic::create_epoch_context(build_light_cache, epoch_number, true);
+}
+
+void ethash_destroy_epoch_context_full(epoch_context_full* context) noexcept
+{
+ ethash_destroy_epoch_context(context);
+}
+
+void ethash_destroy_epoch_context(epoch_context* context) noexcept
+{
+ context->~epoch_context();
+ std::free(context);
+}
+
+} // extern "C"
diff --git a/contrib/ethereum/libethash/ethash/ethash.h b/contrib/ethereum/libethash/ethash/ethash.h
new file mode 100644
index 00000000..b12f1aa9
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/ethash.h
@@ -0,0 +1,99 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#pragma once
+
+#include
+
+#include
+
+#ifdef __cplusplus
+#define NOEXCEPT noexcept
+#else
+#define NOEXCEPT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The Ethash algorithm revision implemented as specified in the Ethash spec
+ * https://github.com/ethereum/wiki/wiki/Ethash.
+ */
+#define ETHASH_REVISION "23"
+
+#define ETHASH_EPOCH_LENGTH 30000
+#define ETHASH_LIGHT_CACHE_ITEM_SIZE 64
+#define ETHASH_FULL_DATASET_ITEM_SIZE 128
+#define ETHASH_NUM_DATASET_ACCESSES 64
+
+
+struct ethash_epoch_context
+{
+ const int epoch_number;
+ const int light_cache_num_items;
+ const union ethash_hash512* const light_cache;
+ const uint32_t* const l1_cache;
+ const int full_dataset_num_items;
+};
+
+
+struct ethash_epoch_context_full;
+
+
+/**
+ * Calculates the number of items in the light cache for given epoch.
+ *
+ * This function will search for a prime number matching the criteria given
+ * by the Ethash so the execution time is not constant. It takes ~ 0.01 ms.
+ *
+ * @param epoch_number The epoch number.
+ * @return The number items in the light cache.
+ */
+int ethash_calculate_light_cache_num_items(int epoch_number) NOEXCEPT;
+
+
+/**
+ * Calculates the number of items in the full dataset for given epoch.
+ *
+ * This function will search for a prime number matching the criteria given
+ * by the Ethash so the execution time is not constant. It takes ~ 0.05 ms.
+ *
+ * @param epoch_number The epoch number.
+ * @return The number items in the full dataset.
+ */
+int ethash_calculate_full_dataset_num_items(int epoch_number) NOEXCEPT;
+
+/**
+ * Calculates the epoch seed hash.
+ * @param epoch_number The epoch number.
+ * @return The epoch seed hash.
+ */
+union ethash_hash256 ethash_calculate_epoch_seed(int epoch_number) NOEXCEPT;
+
+
+struct ethash_epoch_context* ethash_create_epoch_context(int epoch_number) NOEXCEPT;
+
+/**
+ * Creates the epoch context with the full dataset initialized.
+ *
+ * The memory for the full dataset is only allocated and marked as "not-generated".
+ * The items of the full dataset are generated on the fly when hit for the first time.
+ *
+ * The memory allocated in the context MUST be freed with ethash_destroy_epoch_context_full().
+ *
+ * @param epoch_number The epoch number.
+ * @return Pointer to the context or null in case of memory allocation failure.
+ */
+struct ethash_epoch_context_full* ethash_create_epoch_context_full(int epoch_number) NOEXCEPT;
+
+void ethash_destroy_epoch_context(struct ethash_epoch_context* context) NOEXCEPT;
+
+void ethash_destroy_epoch_context_full(struct ethash_epoch_context_full* context) NOEXCEPT;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/ethereum/libethash/ethash/ethash.hpp b/contrib/ethereum/libethash/ethash/ethash.hpp
new file mode 100644
index 00000000..03f29afd
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/ethash.hpp
@@ -0,0 +1,160 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+/// @file
+///
+/// API design decisions:
+///
+/// 1. Signed integer type is used whenever the size of the type is not
+/// restricted by the Ethash specification.
+/// See http://www.aristeia.com/Papers/C++ReportColumns/sep95.pdf.
+/// See https://stackoverflow.com/questions/10168079/why-is-size-t-unsigned/.
+/// See https://github.com/Microsoft/GSL/issues/171.
+
+#pragma once
+
+#include
+#include
+
+#include
+#include
+#include
+
+namespace ethash
+{
+constexpr auto revision = ETHASH_REVISION;
+
+static constexpr int epoch_length = ETHASH_EPOCH_LENGTH;
+static constexpr int light_cache_item_size = ETHASH_LIGHT_CACHE_ITEM_SIZE;
+static constexpr int full_dataset_item_size = ETHASH_FULL_DATASET_ITEM_SIZE;
+static constexpr int num_dataset_accesses = ETHASH_NUM_DATASET_ACCESSES;
+
+using epoch_context = ethash_epoch_context;
+using epoch_context_full = ethash_epoch_context_full;
+
+/// Constructs a 256-bit hash from an array of bytes.
+///
+/// @param bytes A pointer to array of at least 32 bytes.
+/// @return The constructed hash.
+inline hash256 hash256_from_bytes(const uint8_t bytes[32]) noexcept
+{
+ hash256 h;
+ std::memcpy(&h, bytes, sizeof(h));
+ return h;
+}
+
+struct result
+{
+ hash256 final_hash;
+ hash256 mix_hash;
+};
+
+struct search_result
+{
+ bool solution_found = false;
+ uint64_t nonce = 0;
+ hash256 final_hash = {};
+ hash256 mix_hash = {};
+
+ search_result() noexcept = default;
+
+ search_result(result res, uint64_t nonce) noexcept
+ : solution_found(true), nonce(nonce), final_hash(res.final_hash), mix_hash(res.mix_hash)
+ {}
+};
+
+
+/// Alias for ethash_calculate_light_cache_num_items().
+static constexpr auto calculate_light_cache_num_items = ethash_calculate_light_cache_num_items;
+
+/// Alias for ethash_calculate_full_dataset_num_items().
+static constexpr auto calculate_full_dataset_num_items = ethash_calculate_full_dataset_num_items;
+
+/// Alias for ethash_calculate_epoch_seed().
+static constexpr auto calculate_epoch_seed = ethash_calculate_epoch_seed;
+
+
+/// Calculates the epoch number out of the block number.
+inline constexpr int get_epoch_number(int block_number) noexcept
+{
+ return block_number / epoch_length;
+}
+
+/**
+ * Coverts the number of items of a light cache to size in bytes.
+ *
+ * @param num_items The number of items in the light cache.
+ * @return The size of the light cache in bytes.
+ */
+inline constexpr size_t get_light_cache_size(int num_items) noexcept
+{
+ return static_cast(num_items) * light_cache_item_size;
+}
+
+/**
+ * Coverts the number of items of a full dataset to size in bytes.
+ *
+ * @param num_items The number of items in the full dataset.
+ * @return The size of the full dataset in bytes.
+ */
+inline constexpr uint64_t get_full_dataset_size(int num_items) noexcept
+{
+ return static_cast(num_items) * full_dataset_item_size;
+}
+
+/// Owned unique pointer to an epoch context.
+using epoch_context_ptr = std::unique_ptr;
+
+using epoch_context_full_ptr =
+ std::unique_ptr;
+
+/// Creates Ethash epoch context.
+///
+/// This is a wrapper for ethash_create_epoch_number C function that returns
+/// the context as a smart pointer which handles the destruction of the context.
+inline epoch_context_ptr create_epoch_context(int epoch_number) noexcept
+{
+ return {ethash_create_epoch_context(epoch_number), ethash_destroy_epoch_context};
+}
+
+inline epoch_context_full_ptr create_epoch_context_full(int epoch_number) noexcept
+{
+ return {ethash_create_epoch_context_full(epoch_number), ethash_destroy_epoch_context_full};
+}
+
+
+result hash(const epoch_context& context, const hash256& header_hash, uint64_t nonce) noexcept;
+
+result hash(const epoch_context_full& context, const hash256& header_hash, uint64_t nonce) noexcept;
+
+bool verify_final_hash(const hash256& header_hash, const hash256& mix_hash, uint64_t nonce,
+ const hash256& boundary) noexcept;
+
+bool verify(const epoch_context& context, const hash256& header_hash, const hash256& mix_hash,
+ uint64_t nonce, const hash256& boundary) noexcept;
+
+search_result search_light(const epoch_context& context, const hash256& header_hash,
+ const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept;
+
+search_result search(const epoch_context_full& context, const hash256& header_hash,
+ const hash256& boundary, uint64_t start_nonce, size_t iterations) noexcept;
+
+
+/// Tries to find the epoch number matching the given seed hash.
+///
+/// Mining pool protocols (many variants of stratum and "getwork") send out
+/// seed hash instead of epoch number to workers. This function tries to recover
+/// the epoch number from this seed hash.
+///
+/// @param seed Ethash seed hash.
+/// @return The epoch number or -1 if not found.
+int find_epoch_number(const hash256& seed) noexcept;
+
+
+/// Get global shared epoch context.
+const epoch_context& get_global_epoch_context(int epoch_number);
+
+/// Get global shared epoch context with full dataset initialized.
+const epoch_context_full& get_global_epoch_context_full(int epoch_number);
+} // namespace ethash
diff --git a/contrib/ethereum/libethash/ethash/hash_types.h b/contrib/ethereum/libethash/ethash/hash_types.h
new file mode 100644
index 00000000..108e141c
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/hash_types.h
@@ -0,0 +1,46 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#pragma once
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+union ethash_hash256
+{
+ uint64_t word64s[4];
+ uint32_t word32s[8];
+ uint8_t bytes[32];
+};
+
+union ethash_hash512
+{
+ uint64_t word64s[8];
+ uint32_t word32s[16];
+ uint8_t bytes[64];
+};
+
+union ethash_hash1024
+{
+ union ethash_hash512 hash512s[2];
+ uint64_t word64s[16];
+ uint32_t word32s[32];
+ uint8_t bytes[128];
+};
+
+union ethash_hash2048
+{
+ union ethash_hash512 hash512s[4];
+ uint64_t word64s[32];
+ uint32_t word32s[64];
+ uint8_t bytes[256];
+};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/ethereum/libethash/ethash/hash_types.hpp b/contrib/ethereum/libethash/ethash/hash_types.hpp
new file mode 100644
index 00000000..cb9c3f10
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/hash_types.hpp
@@ -0,0 +1,15 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+#pragma once
+
+#include
+
+namespace ethash
+{
+using hash256 = ethash_hash256;
+using hash512 = ethash_hash512;
+using hash1024 = ethash_hash1024;
+using hash2048 = ethash_hash2048;
+} // namespace ethash
diff --git a/contrib/ethereum/libethash/ethash/keccak.h b/contrib/ethereum/libethash/ethash/keccak.h
new file mode 100644
index 00000000..e1414b84
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/keccak.h
@@ -0,0 +1,49 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#pragma once
+
+#include
+
+#include
+
+#ifdef __cplusplus
+#define NOEXCEPT noexcept
+#else
+#define NOEXCEPT
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The Keccak-f[1600] function.
+ *
+ * The implementation of the Keccak-f function with 1600-bit width of the permutation (b).
+ * The size of the state is also 1600 bit what gives 25 64-bit words.
+ *
+ * @param state The state of 25 64-bit words on which the permutation is to be performed.
+ */
+void ethash_keccakf1600(uint64_t state[25]) NOEXCEPT;
+
+/**
+ * The Keccak-f[800] function.
+ *
+ * The implementation of the Keccak-f function with 800-bit width of the permutation (b).
+ * The size of the state is also 800 bit what gives 25 32-bit words.
+ *
+ * @param state The state of 25 32-bit words on which the permutation is to be performed.
+ */
+void ethash_keccakf800(uint32_t state[25]) NOEXCEPT;
+
+union ethash_hash256 ethash_keccak256(const uint8_t* data, size_t size) NOEXCEPT;
+union ethash_hash256 ethash_keccak256_32(const uint8_t data[32]) NOEXCEPT;
+union ethash_hash512 ethash_keccak512(const uint8_t* data, size_t size) NOEXCEPT;
+union ethash_hash512 ethash_keccak512_64(const uint8_t data[64]) NOEXCEPT;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/ethereum/libethash/ethash/keccak.hpp b/contrib/ethereum/libethash/ethash/keccak.hpp
new file mode 100644
index 00000000..9dbc6aaa
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/keccak.hpp
@@ -0,0 +1,35 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+#pragma once
+
+#include
+#include
+
+namespace ethash
+{
+inline hash256 keccak256(const uint8_t* data, size_t size) noexcept
+{
+ return ethash_keccak256(data, size);
+}
+
+inline hash256 keccak256(const hash256& input) noexcept
+{
+ return ethash_keccak256_32(input.bytes);
+}
+
+inline hash512 keccak512(const uint8_t* data, size_t size) noexcept
+{
+ return ethash_keccak512(data, size);
+}
+
+inline hash512 keccak512(const hash512& input) noexcept
+{
+ return ethash_keccak512_64(input.bytes);
+}
+
+static constexpr auto keccak256_32 = ethash_keccak256_32;
+static constexpr auto keccak512_64 = ethash_keccak512_64;
+
+} // namespace ethash
diff --git a/contrib/ethereum/libethash/ethash/progpow.hpp b/contrib/ethereum/libethash/ethash/progpow.hpp
new file mode 100644
index 00000000..81e6dbaa
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/progpow.hpp
@@ -0,0 +1,47 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+/// @file
+///
+/// ProgPoW API
+///
+/// This file provides the public API for ProgPoW as the Ethash API extension.
+
+#include
+
+namespace progpow
+{
+using namespace ethash; // Include ethash namespace.
+
+
+/// The ProgPoW algorithm revision implemented as specified in the spec
+/// https://github.com/ifdefelse/ProgPOW#change-history.
+constexpr auto revision = "0.9.2";
+
+constexpr int period_length = 50;
+constexpr uint32_t num_regs = 32;
+constexpr size_t num_lanes = 16;
+constexpr int num_cache_accesses = 12;
+constexpr int num_math_operations = 20;
+constexpr size_t l1_cache_size = 16 * 1024;
+constexpr size_t l1_cache_num_items = l1_cache_size / sizeof(uint32_t);
+
+result hash(const epoch_context& context, int block_number, const hash256& header_hash,
+ uint64_t nonce) noexcept;
+
+result hash(const epoch_context_full& context, int block_number, const hash256& header_hash,
+ uint64_t nonce) noexcept;
+
+bool verify(const epoch_context& context, int block_number, const hash256& header_hash,
+ const hash256& mix_hash, uint64_t nonce, const hash256& boundary) noexcept;
+
+search_result search_light(const epoch_context& context, int block_number,
+ const hash256& header_hash, const hash256& boundary, uint64_t start_nonce,
+ size_t iterations) noexcept;
+
+search_result search(const epoch_context_full& context, int block_number,
+ const hash256& header_hash, const hash256& boundary, uint64_t start_nonce,
+ size_t iterations) noexcept;
+
+} // namespace progpow
diff --git a/contrib/ethereum/libethash/ethash/version.h b/contrib/ethereum/libethash/ethash/version.h
new file mode 100644
index 00000000..f0372b0d
--- /dev/null
+++ b/contrib/ethereum/libethash/ethash/version.h
@@ -0,0 +1,18 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2019 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+#pragma once
+
+/** The ethash library version. */
+#define ETHASH_VERSION "0.4.3"
+
+#ifdef __cplusplus
+namespace ethash
+{
+/// The ethash library version.
+constexpr auto version = ETHASH_VERSION;
+
+} // namespace ethash
+#endif
diff --git a/contrib/ethereum/libethash/keccak.c b/contrib/ethereum/libethash/keccak.c
new file mode 100644
index 00000000..4c0b4caa
--- /dev/null
+++ b/contrib/ethereum/libethash/keccak.c
@@ -0,0 +1,123 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#include
+
+#include "support/attributes.h"
+#include
+
+#if _WIN32
+/* On Windows assume little endian. */
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#elif __APPLE__
+#include
+#else
+#include
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define to_le64(X) X
+#else
+#define to_le64(X) __builtin_bswap64(X)
+#endif
+
+
+/** Loads 64-bit integer from given memory location as little-endian number. */
+static INLINE ALWAYS_INLINE uint64_t load_le(const uint8_t* data)
+{
+ /* memcpy is the best way of expressing the intention. Every compiler will
+ optimize is to single load instruction if the target architecture
+ supports unaligned memory access (GCC and clang even in O0).
+ This is great trick because we are violating C/C++ memory alignment
+ restrictions with no performance penalty. */
+ uint64_t word;
+ memcpy(&word, data, sizeof(word));
+ return to_le64(word);
+}
+
+static INLINE ALWAYS_INLINE void keccak(
+ uint64_t* out, size_t bits, const uint8_t* data, size_t size)
+{
+ static const size_t word_size = sizeof(uint64_t);
+ const size_t hash_size = bits / 8;
+ const size_t block_size = (1600 - bits * 2) / 8;
+
+ size_t i;
+ uint64_t* state_iter;
+ uint64_t last_word = 0;
+ uint8_t* last_word_iter = (uint8_t*)&last_word;
+
+ uint64_t state[25] = {0};
+
+ while (size >= block_size)
+ {
+ for (i = 0; i < (block_size / word_size); ++i)
+ {
+ state[i] ^= load_le(data);
+ data += word_size;
+ }
+
+ ethash_keccakf1600(state);
+
+ size -= block_size;
+ }
+
+ state_iter = state;
+
+ while (size >= word_size)
+ {
+ *state_iter ^= load_le(data);
+ ++state_iter;
+ data += word_size;
+ size -= word_size;
+ }
+
+ while (size > 0)
+ {
+ *last_word_iter = *data;
+ ++last_word_iter;
+ ++data;
+ --size;
+ }
+ *last_word_iter = 0x01;
+ *state_iter ^= to_le64(last_word);
+
+ state[(block_size / word_size) - 1] ^= 0x8000000000000000;
+
+ ethash_keccakf1600(state);
+
+ for (i = 0; i < (hash_size / word_size); ++i)
+ out[i] = to_le64(state[i]);
+}
+
+union ethash_hash256 ethash_keccak256(const uint8_t* data, size_t size)
+{
+ union ethash_hash256 hash;
+ keccak(hash.word64s, 256, data, size);
+ return hash;
+}
+
+union ethash_hash256 ethash_keccak256_32(const uint8_t data[32])
+{
+ union ethash_hash256 hash;
+ keccak(hash.word64s, 256, data, 32);
+ return hash;
+}
+
+union ethash_hash512 ethash_keccak512(const uint8_t* data, size_t size)
+{
+ union ethash_hash512 hash;
+ keccak(hash.word64s, 512, data, size);
+ return hash;
+}
+
+union ethash_hash512 ethash_keccak512_64(const uint8_t data[64])
+{
+ union ethash_hash512 hash;
+ keccak(hash.word64s, 512, data, 64);
+ return hash;
+}
diff --git a/contrib/ethereum/libethash/keccakf1600.c b/contrib/ethereum/libethash/keccakf1600.c
new file mode 100644
index 00000000..271fe76d
--- /dev/null
+++ b/contrib/ethereum/libethash/keccakf1600.c
@@ -0,0 +1,255 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#include
+
+static uint64_t rol(uint64_t x, unsigned s)
+{
+ return (x << s) | (x >> (64 - s));
+}
+
+static const uint64_t round_constants[24] = {
+ 0x0000000000000001,
+ 0x0000000000008082,
+ 0x800000000000808a,
+ 0x8000000080008000,
+ 0x000000000000808b,
+ 0x0000000080000001,
+ 0x8000000080008081,
+ 0x8000000000008009,
+ 0x000000000000008a,
+ 0x0000000000000088,
+ 0x0000000080008009,
+ 0x000000008000000a,
+ 0x000000008000808b,
+ 0x800000000000008b,
+ 0x8000000000008089,
+ 0x8000000000008003,
+ 0x8000000000008002,
+ 0x8000000000000080,
+ 0x000000000000800a,
+ 0x800000008000000a,
+ 0x8000000080008081,
+ 0x8000000000008080,
+ 0x0000000080000001,
+ 0x8000000080008008,
+};
+
+void ethash_keccakf1600(uint64_t state[25])
+{
+ /* The implementation based on the "simple" implementation by Ronny Van Keer. */
+
+ int round;
+
+ uint64_t Aba, Abe, Abi, Abo, Abu;
+ uint64_t Aga, Age, Agi, Ago, Agu;
+ uint64_t Aka, Ake, Aki, Ako, Aku;
+ uint64_t Ama, Ame, Ami, Amo, Amu;
+ uint64_t Asa, Ase, Asi, Aso, Asu;
+
+ uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
+ uint64_t Ega, Ege, Egi, Ego, Egu;
+ uint64_t Eka, Eke, Eki, Eko, Eku;
+ uint64_t Ema, Eme, Emi, Emo, Emu;
+ uint64_t Esa, Ese, Esi, Eso, Esu;
+
+ uint64_t Ba, Be, Bi, Bo, Bu;
+
+ uint64_t Da, De, Di, Do, Du;
+
+ Aba = state[0];
+ Abe = state[1];
+ Abi = state[2];
+ Abo = state[3];
+ Abu = state[4];
+ Aga = state[5];
+ Age = state[6];
+ Agi = state[7];
+ Ago = state[8];
+ Agu = state[9];
+ Aka = state[10];
+ Ake = state[11];
+ Aki = state[12];
+ Ako = state[13];
+ Aku = state[14];
+ Ama = state[15];
+ Ame = state[16];
+ Ami = state[17];
+ Amo = state[18];
+ Amu = state[19];
+ Asa = state[20];
+ Ase = state[21];
+ Asi = state[22];
+ Aso = state[23];
+ Asu = state[24];
+
+ for (round = 0; round < 24; round += 2)
+ {
+ /* Round (round + 0): Axx -> Exx */
+
+ Ba = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
+ Be = Abe ^ Age ^ Ake ^ Ame ^ Ase;
+ Bi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
+ Bo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
+ Bu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
+
+ Da = Bu ^ rol(Be, 1);
+ De = Ba ^ rol(Bi, 1);
+ Di = Be ^ rol(Bo, 1);
+ Do = Bi ^ rol(Bu, 1);
+ Du = Bo ^ rol(Ba, 1);
+
+ Ba = Aba ^ Da;
+ Be = rol(Age ^ De, 44);
+ Bi = rol(Aki ^ Di, 43);
+ Bo = rol(Amo ^ Do, 21);
+ Bu = rol(Asu ^ Du, 14);
+ Eba = Ba ^ (~Be & Bi) ^ round_constants[round];
+ Ebe = Be ^ (~Bi & Bo);
+ Ebi = Bi ^ (~Bo & Bu);
+ Ebo = Bo ^ (~Bu & Ba);
+ Ebu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abo ^ Do, 28);
+ Be = rol(Agu ^ Du, 20);
+ Bi = rol(Aka ^ Da, 3);
+ Bo = rol(Ame ^ De, 45);
+ Bu = rol(Asi ^ Di, 61);
+ Ega = Ba ^ (~Be & Bi);
+ Ege = Be ^ (~Bi & Bo);
+ Egi = Bi ^ (~Bo & Bu);
+ Ego = Bo ^ (~Bu & Ba);
+ Egu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abe ^ De, 1);
+ Be = rol(Agi ^ Di, 6);
+ Bi = rol(Ako ^ Do, 25);
+ Bo = rol(Amu ^ Du, 8);
+ Bu = rol(Asa ^ Da, 18);
+ Eka = Ba ^ (~Be & Bi);
+ Eke = Be ^ (~Bi & Bo);
+ Eki = Bi ^ (~Bo & Bu);
+ Eko = Bo ^ (~Bu & Ba);
+ Eku = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abu ^ Du, 27);
+ Be = rol(Aga ^ Da, 36);
+ Bi = rol(Ake ^ De, 10);
+ Bo = rol(Ami ^ Di, 15);
+ Bu = rol(Aso ^ Do, 56);
+ Ema = Ba ^ (~Be & Bi);
+ Eme = Be ^ (~Bi & Bo);
+ Emi = Bi ^ (~Bo & Bu);
+ Emo = Bo ^ (~Bu & Ba);
+ Emu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abi ^ Di, 62);
+ Be = rol(Ago ^ Do, 55);
+ Bi = rol(Aku ^ Du, 39);
+ Bo = rol(Ama ^ Da, 41);
+ Bu = rol(Ase ^ De, 2);
+ Esa = Ba ^ (~Be & Bi);
+ Ese = Be ^ (~Bi & Bo);
+ Esi = Bi ^ (~Bo & Bu);
+ Eso = Bo ^ (~Bu & Ba);
+ Esu = Bu ^ (~Ba & Be);
+
+
+ /* Round (round + 1): Exx -> Axx */
+
+ Ba = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
+ Be = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
+ Bi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
+ Bo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
+ Bu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
+
+ Da = Bu ^ rol(Be, 1);
+ De = Ba ^ rol(Bi, 1);
+ Di = Be ^ rol(Bo, 1);
+ Do = Bi ^ rol(Bu, 1);
+ Du = Bo ^ rol(Ba, 1);
+
+ Ba = Eba ^ Da;
+ Be = rol(Ege ^ De, 44);
+ Bi = rol(Eki ^ Di, 43);
+ Bo = rol(Emo ^ Do, 21);
+ Bu = rol(Esu ^ Du, 14);
+ Aba = Ba ^ (~Be & Bi) ^ round_constants[round + 1];
+ Abe = Be ^ (~Bi & Bo);
+ Abi = Bi ^ (~Bo & Bu);
+ Abo = Bo ^ (~Bu & Ba);
+ Abu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebo ^ Do, 28);
+ Be = rol(Egu ^ Du, 20);
+ Bi = rol(Eka ^ Da, 3);
+ Bo = rol(Eme ^ De, 45);
+ Bu = rol(Esi ^ Di, 61);
+ Aga = Ba ^ (~Be & Bi);
+ Age = Be ^ (~Bi & Bo);
+ Agi = Bi ^ (~Bo & Bu);
+ Ago = Bo ^ (~Bu & Ba);
+ Agu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebe ^ De, 1);
+ Be = rol(Egi ^ Di, 6);
+ Bi = rol(Eko ^ Do, 25);
+ Bo = rol(Emu ^ Du, 8);
+ Bu = rol(Esa ^ Da, 18);
+ Aka = Ba ^ (~Be & Bi);
+ Ake = Be ^ (~Bi & Bo);
+ Aki = Bi ^ (~Bo & Bu);
+ Ako = Bo ^ (~Bu & Ba);
+ Aku = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebu ^ Du, 27);
+ Be = rol(Ega ^ Da, 36);
+ Bi = rol(Eke ^ De, 10);
+ Bo = rol(Emi ^ Di, 15);
+ Bu = rol(Eso ^ Do, 56);
+ Ama = Ba ^ (~Be & Bi);
+ Ame = Be ^ (~Bi & Bo);
+ Ami = Bi ^ (~Bo & Bu);
+ Amo = Bo ^ (~Bu & Ba);
+ Amu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebi ^ Di, 62);
+ Be = rol(Ego ^ Do, 55);
+ Bi = rol(Eku ^ Du, 39);
+ Bo = rol(Ema ^ Da, 41);
+ Bu = rol(Ese ^ De, 2);
+ Asa = Ba ^ (~Be & Bi);
+ Ase = Be ^ (~Bi & Bo);
+ Asi = Bi ^ (~Bo & Bu);
+ Aso = Bo ^ (~Bu & Ba);
+ Asu = Bu ^ (~Ba & Be);
+ }
+
+ state[0] = Aba;
+ state[1] = Abe;
+ state[2] = Abi;
+ state[3] = Abo;
+ state[4] = Abu;
+ state[5] = Aga;
+ state[6] = Age;
+ state[7] = Agi;
+ state[8] = Ago;
+ state[9] = Agu;
+ state[10] = Aka;
+ state[11] = Ake;
+ state[12] = Aki;
+ state[13] = Ako;
+ state[14] = Aku;
+ state[15] = Ama;
+ state[16] = Ame;
+ state[17] = Ami;
+ state[18] = Amo;
+ state[19] = Amu;
+ state[20] = Asa;
+ state[21] = Ase;
+ state[22] = Asi;
+ state[23] = Aso;
+ state[24] = Asu;
+}
diff --git a/contrib/ethereum/libethash/keccakf800.c b/contrib/ethereum/libethash/keccakf800.c
new file mode 100644
index 00000000..aa7cceef
--- /dev/null
+++ b/contrib/ethereum/libethash/keccakf800.c
@@ -0,0 +1,253 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#include
+
+static uint32_t rol(uint32_t x, unsigned s)
+{
+ return (x << s) | (x >> (32 - s));
+}
+
+static const uint32_t round_constants[22] = {
+ 0x00000001,
+ 0x00008082,
+ 0x0000808A,
+ 0x80008000,
+ 0x0000808B,
+ 0x80000001,
+ 0x80008081,
+ 0x00008009,
+ 0x0000008A,
+ 0x00000088,
+ 0x80008009,
+ 0x8000000A,
+ 0x8000808B,
+ 0x0000008B,
+ 0x00008089,
+ 0x00008003,
+ 0x00008002,
+ 0x00000080,
+ 0x0000800A,
+ 0x8000000A,
+ 0x80008081,
+ 0x00008080,
+};
+
+void ethash_keccakf800(uint32_t state[25])
+{
+ /* The implementation directly translated from ethash_keccakf1600. */
+
+ int round;
+
+ uint32_t Aba, Abe, Abi, Abo, Abu;
+ uint32_t Aga, Age, Agi, Ago, Agu;
+ uint32_t Aka, Ake, Aki, Ako, Aku;
+ uint32_t Ama, Ame, Ami, Amo, Amu;
+ uint32_t Asa, Ase, Asi, Aso, Asu;
+
+ uint32_t Eba, Ebe, Ebi, Ebo, Ebu;
+ uint32_t Ega, Ege, Egi, Ego, Egu;
+ uint32_t Eka, Eke, Eki, Eko, Eku;
+ uint32_t Ema, Eme, Emi, Emo, Emu;
+ uint32_t Esa, Ese, Esi, Eso, Esu;
+
+ uint32_t Ba, Be, Bi, Bo, Bu;
+
+ uint32_t Da, De, Di, Do, Du;
+
+ Aba = state[0];
+ Abe = state[1];
+ Abi = state[2];
+ Abo = state[3];
+ Abu = state[4];
+ Aga = state[5];
+ Age = state[6];
+ Agi = state[7];
+ Ago = state[8];
+ Agu = state[9];
+ Aka = state[10];
+ Ake = state[11];
+ Aki = state[12];
+ Ako = state[13];
+ Aku = state[14];
+ Ama = state[15];
+ Ame = state[16];
+ Ami = state[17];
+ Amo = state[18];
+ Amu = state[19];
+ Asa = state[20];
+ Ase = state[21];
+ Asi = state[22];
+ Aso = state[23];
+ Asu = state[24];
+
+ for (round = 0; round < 22; round += 2)
+ {
+ /* Round (round + 0): Axx -> Exx */
+
+ Ba = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
+ Be = Abe ^ Age ^ Ake ^ Ame ^ Ase;
+ Bi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
+ Bo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
+ Bu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
+
+ Da = Bu ^ rol(Be, 1);
+ De = Ba ^ rol(Bi, 1);
+ Di = Be ^ rol(Bo, 1);
+ Do = Bi ^ rol(Bu, 1);
+ Du = Bo ^ rol(Ba, 1);
+
+ Ba = Aba ^ Da;
+ Be = rol(Age ^ De, 12);
+ Bi = rol(Aki ^ Di, 11);
+ Bo = rol(Amo ^ Do, 21);
+ Bu = rol(Asu ^ Du, 14);
+ Eba = Ba ^ (~Be & Bi) ^ round_constants[round];
+ Ebe = Be ^ (~Bi & Bo);
+ Ebi = Bi ^ (~Bo & Bu);
+ Ebo = Bo ^ (~Bu & Ba);
+ Ebu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abo ^ Do, 28);
+ Be = rol(Agu ^ Du, 20);
+ Bi = rol(Aka ^ Da, 3);
+ Bo = rol(Ame ^ De, 13);
+ Bu = rol(Asi ^ Di, 29);
+ Ega = Ba ^ (~Be & Bi);
+ Ege = Be ^ (~Bi & Bo);
+ Egi = Bi ^ (~Bo & Bu);
+ Ego = Bo ^ (~Bu & Ba);
+ Egu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abe ^ De, 1);
+ Be = rol(Agi ^ Di, 6);
+ Bi = rol(Ako ^ Do, 25);
+ Bo = rol(Amu ^ Du, 8);
+ Bu = rol(Asa ^ Da, 18);
+ Eka = Ba ^ (~Be & Bi);
+ Eke = Be ^ (~Bi & Bo);
+ Eki = Bi ^ (~Bo & Bu);
+ Eko = Bo ^ (~Bu & Ba);
+ Eku = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abu ^ Du, 27);
+ Be = rol(Aga ^ Da, 4);
+ Bi = rol(Ake ^ De, 10);
+ Bo = rol(Ami ^ Di, 15);
+ Bu = rol(Aso ^ Do, 24);
+ Ema = Ba ^ (~Be & Bi);
+ Eme = Be ^ (~Bi & Bo);
+ Emi = Bi ^ (~Bo & Bu);
+ Emo = Bo ^ (~Bu & Ba);
+ Emu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Abi ^ Di, 30);
+ Be = rol(Ago ^ Do, 23);
+ Bi = rol(Aku ^ Du, 7);
+ Bo = rol(Ama ^ Da, 9);
+ Bu = rol(Ase ^ De, 2);
+ Esa = Ba ^ (~Be & Bi);
+ Ese = Be ^ (~Bi & Bo);
+ Esi = Bi ^ (~Bo & Bu);
+ Eso = Bo ^ (~Bu & Ba);
+ Esu = Bu ^ (~Ba & Be);
+
+
+ /* Round (round + 1): Exx -> Axx */
+
+ Ba = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
+ Be = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
+ Bi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
+ Bo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
+ Bu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
+
+ Da = Bu ^ rol(Be, 1);
+ De = Ba ^ rol(Bi, 1);
+ Di = Be ^ rol(Bo, 1);
+ Do = Bi ^ rol(Bu, 1);
+ Du = Bo ^ rol(Ba, 1);
+
+ Ba = Eba ^ Da;
+ Be = rol(Ege ^ De, 12);
+ Bi = rol(Eki ^ Di, 11);
+ Bo = rol(Emo ^ Do, 21);
+ Bu = rol(Esu ^ Du, 14);
+ Aba = Ba ^ (~Be & Bi) ^ round_constants[round + 1];
+ Abe = Be ^ (~Bi & Bo);
+ Abi = Bi ^ (~Bo & Bu);
+ Abo = Bo ^ (~Bu & Ba);
+ Abu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebo ^ Do, 28);
+ Be = rol(Egu ^ Du, 20);
+ Bi = rol(Eka ^ Da, 3);
+ Bo = rol(Eme ^ De, 13);
+ Bu = rol(Esi ^ Di, 29);
+ Aga = Ba ^ (~Be & Bi);
+ Age = Be ^ (~Bi & Bo);
+ Agi = Bi ^ (~Bo & Bu);
+ Ago = Bo ^ (~Bu & Ba);
+ Agu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebe ^ De, 1);
+ Be = rol(Egi ^ Di, 6);
+ Bi = rol(Eko ^ Do, 25);
+ Bo = rol(Emu ^ Du, 8);
+ Bu = rol(Esa ^ Da, 18);
+ Aka = Ba ^ (~Be & Bi);
+ Ake = Be ^ (~Bi & Bo);
+ Aki = Bi ^ (~Bo & Bu);
+ Ako = Bo ^ (~Bu & Ba);
+ Aku = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebu ^ Du, 27);
+ Be = rol(Ega ^ Da, 4);
+ Bi = rol(Eke ^ De, 10);
+ Bo = rol(Emi ^ Di, 15);
+ Bu = rol(Eso ^ Do, 24);
+ Ama = Ba ^ (~Be & Bi);
+ Ame = Be ^ (~Bi & Bo);
+ Ami = Bi ^ (~Bo & Bu);
+ Amo = Bo ^ (~Bu & Ba);
+ Amu = Bu ^ (~Ba & Be);
+
+ Ba = rol(Ebi ^ Di, 30);
+ Be = rol(Ego ^ Do, 23);
+ Bi = rol(Eku ^ Du, 7);
+ Bo = rol(Ema ^ Da, 9);
+ Bu = rol(Ese ^ De, 2);
+ Asa = Ba ^ (~Be & Bi);
+ Ase = Be ^ (~Bi & Bo);
+ Asi = Bi ^ (~Bo & Bu);
+ Aso = Bo ^ (~Bu & Ba);
+ Asu = Bu ^ (~Ba & Be);
+ }
+
+ state[0] = Aba;
+ state[1] = Abe;
+ state[2] = Abi;
+ state[3] = Abo;
+ state[4] = Abu;
+ state[5] = Aga;
+ state[6] = Age;
+ state[7] = Agi;
+ state[8] = Ago;
+ state[9] = Agu;
+ state[10] = Aka;
+ state[11] = Ake;
+ state[12] = Aki;
+ state[13] = Ako;
+ state[14] = Aku;
+ state[15] = Ama;
+ state[16] = Ame;
+ state[17] = Ami;
+ state[18] = Amo;
+ state[19] = Amu;
+ state[20] = Asa;
+ state[21] = Ase;
+ state[22] = Asi;
+ state[23] = Aso;
+ state[24] = Asu;
+}
diff --git a/contrib/ethereum/libethash/kiss99.hpp b/contrib/ethereum/libethash/kiss99.hpp
new file mode 100644
index 00000000..8550b82e
--- /dev/null
+++ b/contrib/ethereum/libethash/kiss99.hpp
@@ -0,0 +1,64 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#pragma once
+
+#include "support/attributes.h"
+#include
+
+/**
+ * KISS PRNG by the spec from 1999.
+ *
+ * The implementation of KISS pseudo-random number generator
+ * by the specification published on 21 Jan 1999 in
+ * http://www.cse.yorku.ca/~oz/marsaglia-rng.html.
+ * The KISS is not versioned so here we are using `kiss99` prefix to indicate
+ * the version from 1999.
+ *
+ * The specification uses `unsigned long` type with the intention for 32-bit
+ * values. Because in GCC/clang for 64-bit architectures `unsigned long` is
+ * 64-bit size type, here the explicit `uint32_t` type is used.
+ *
+ * @defgroup kiss99 KISS99
+ * @{
+ */
+
+/**
+ * The KISS generator.
+ */
+class kiss99
+{
+ uint32_t z = 362436069;
+ uint32_t w = 521288629;
+ uint32_t jsr = 123456789;
+ uint32_t jcong = 380116160;
+
+public:
+ /** Creates KISS generator state with default values provided by the specification. */
+ kiss99() noexcept = default;
+
+ /** Creates KISS generator state with provided init values.*/
+ kiss99(uint32_t z, uint32_t w, uint32_t jsr, uint32_t jcong) noexcept
+ : z{z}, w{w}, jsr{jsr}, jcong{jcong}
+ {}
+
+ /** Generates next number from the KISS generator. */
+ NO_SANITIZE("unsigned-integer-overflow")
+ uint32_t operator()() noexcept
+ {
+ z = 36969 * (z & 0xffff) + (z >> 16);
+ w = 18000 * (w & 0xffff) + (w >> 16);
+
+ jcong = 69069 * jcong + 1234567;
+
+ jsr ^= (jsr << 17);
+ jsr ^= (jsr >> 13);
+ jsr ^= (jsr << 5);
+
+ return (((z << 16) + w) ^ jcong) + jsr;
+ }
+};
+
+/** @} */
diff --git a/contrib/ethereum/libethash/managed.cpp b/contrib/ethereum/libethash/managed.cpp
new file mode 100644
index 00000000..900da7e7
--- /dev/null
+++ b/contrib/ethereum/libethash/managed.cpp
@@ -0,0 +1,100 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+#include "ethash-internal.hpp"
+
+#include
+#include
+
+#if !defined(__has_cpp_attribute)
+#define __has_cpp_attribute(x) 0
+#endif
+
+#if __has_cpp_attribute(gnu::noinline)
+#define ATTRIBUTE_NOINLINE [[gnu::noinline]]
+#elif _MSC_VER
+#define ATTRIBUTE_NOINLINE __declspec(noinline)
+#else
+#define ATTRIBUTE_NOINLINE
+#endif
+
+namespace ethash
+{
+namespace
+{
+std::mutex shared_context_mutex;
+std::shared_ptr shared_context;
+thread_local std::shared_ptr thread_local_context;
+
+std::mutex shared_context_full_mutex;
+std::shared_ptr shared_context_full;
+thread_local std::shared_ptr thread_local_context_full;
+
+/// Update thread local epoch context.
+///
+/// This function is on the slow path. It's separated to allow inlining the fast
+/// path.
+///
+/// @todo: Redesign to guarantee deallocation before new allocation.
+ATTRIBUTE_NOINLINE
+void update_local_context(int epoch_number)
+{
+ // Release the shared pointer of the obsoleted context.
+ thread_local_context.reset();
+
+ // Local context invalid, check the shared context.
+ std::lock_guard lock{shared_context_mutex};
+
+ if (!shared_context || shared_context->epoch_number != epoch_number)
+ {
+ // Release the shared pointer of the obsoleted context.
+ shared_context.reset();
+
+ // Build new context.
+ shared_context = create_epoch_context(epoch_number);
+ }
+
+ thread_local_context = shared_context;
+}
+
+ATTRIBUTE_NOINLINE
+void update_local_context_full(int epoch_number)
+{
+ // Release the shared pointer of the obsoleted context.
+ thread_local_context_full.reset();
+
+ // Local context invalid, check the shared context.
+ std::lock_guard lock{shared_context_full_mutex};
+
+ if (!shared_context_full || shared_context_full->epoch_number != epoch_number)
+ {
+ // Release the shared pointer of the obsoleted context.
+ shared_context_full.reset();
+
+ // Build new context.
+ shared_context_full = create_epoch_context_full(epoch_number);
+ }
+
+ thread_local_context_full = shared_context_full;
+}
+} // namespace
+
+const epoch_context& get_global_epoch_context(int epoch_number)
+{
+ // Check if local context matches epoch number.
+ if (!thread_local_context || thread_local_context->epoch_number != epoch_number)
+ update_local_context(epoch_number);
+
+ return *thread_local_context;
+}
+
+const epoch_context_full& get_global_epoch_context_full(int epoch_number)
+{
+ // Check if local context matches epoch number.
+ if (!thread_local_context_full || thread_local_context_full->epoch_number != epoch_number)
+ update_local_context_full(epoch_number);
+
+ return *thread_local_context_full;
+}
+} // namespace ethash
diff --git a/contrib/ethereum/libethash/primes.c b/contrib/ethereum/libethash/primes.c
new file mode 100644
index 00000000..2d58874b
--- /dev/null
+++ b/contrib/ethereum/libethash/primes.c
@@ -0,0 +1,43 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#include "primes.h"
+
+/** Checks if the number is prime. Requires the number to be > 2 and odd. */
+static int is_odd_prime(int number)
+{
+ int d;
+
+ /* Check factors up to sqrt(number).
+ To avoid computing sqrt, compare d*d <= number with 64-bit precision. */
+ for (d = 3; (int64_t)d * (int64_t)d <= (int64_t)number; d += 2)
+ {
+ if (number % d == 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+int ethash_find_largest_prime(int upper_bound)
+{
+ int n = upper_bound;
+
+ if (n < 2)
+ return 0;
+
+ if (n == 2)
+ return 2;
+
+ /* If even number, skip it. */
+ if (n % 2 == 0)
+ --n;
+
+ /* Test descending odd numbers. */
+ while (!is_odd_prime(n))
+ n -= 2;
+
+ return n;
+}
diff --git a/contrib/ethereum/libethash/primes.h b/contrib/ethereum/libethash/primes.h
new file mode 100644
index 00000000..cf923b01
--- /dev/null
+++ b/contrib/ethereum/libethash/primes.h
@@ -0,0 +1,25 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#pragma once
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Finds the largest prime number not greater than the provided upper bound.
+ *
+ * @param upper_bound The upper bound. SHOULD be greater than 1.
+ * @return The largest prime number `p` such `p <= upper_bound`.
+ * In case `upper_bound <= 1`, returns 0.
+ */
+int ethash_find_largest_prime(int upper_bound) NOEXCEPT;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/ethereum/libethash/progpow.cpp b/contrib/ethereum/libethash/progpow.cpp
new file mode 100644
index 00000000..d74c8747
--- /dev/null
+++ b/contrib/ethereum/libethash/progpow.cpp
@@ -0,0 +1,360 @@
+// ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+// Copyright 2018 Pawel Bylica.
+// Licensed under the Apache License, Version 2.0. See the LICENSE file.
+
+#include
+
+#include "bit_manipulation.h"
+#include "endianness.hpp"
+#include "ethash-internal.hpp"
+#include "kiss99.hpp"
+#include
+
+#include
+
+namespace progpow
+{
+namespace
+{
+/// A variant of Keccak hash function for ProgPoW.
+///
+/// This Keccak hash function uses 800-bit permutation (Keccak-f[800]) with 576 bitrate.
+/// It take exactly 576 bits of input (split across 3 arguments) and adds no padding.
+///
+/// @param header_hash The 256-bit header hash.
+/// @param nonce The 64-bit nonce.
+/// @param mix_hash Additional 256-bits of data.
+/// @return The 256-bit output of the hash function.
+hash256 keccak_progpow_256(
+ const hash256& header_hash, uint64_t nonce, const hash256& mix_hash) noexcept
+{
+ static constexpr size_t num_words =
+ sizeof(header_hash.word32s) / sizeof(header_hash.word32s[0]);
+
+ uint32_t state[25] = {};
+
+ size_t i;
+ for (i = 0; i < num_words; ++i)
+ state[i] = le::uint32(header_hash.word32s[i]);
+
+ state[i++] = static_cast(nonce);
+ state[i++] = static_cast(nonce >> 32);
+
+ for (uint32_t mix_word : mix_hash.word32s)
+ state[i++] = le::uint32(mix_word);
+
+ ethash_keccakf800(state);
+
+ hash256 output;
+ for (i = 0; i < num_words; ++i)
+ output.word32s[i] = le::uint32(state[i]);
+ return output;
+}
+
+/// The same as keccak_progpow_256() but uses null mix
+/// and returns top 64 bits of the output being a big-endian prefix of the 256-bit hash.
+inline uint64_t keccak_progpow_64(const hash256& header_hash, uint64_t nonce) noexcept
+{
+ const hash256 h = keccak_progpow_256(header_hash, nonce, {});
+ return be::uint64(h.word64s[0]);
+}
+
+
+/// ProgPoW mix RNG state.
+///
+/// Encapsulates the state of the random number generator used in computing ProgPoW mix.
+/// This includes the state of the KISS99 RNG and the precomputed random permutation of the
+/// sequence of mix item indexes.
+class mix_rng_state
+{
+public:
+ inline explicit mix_rng_state(uint64_t seed) noexcept;
+
+ uint32_t next_dst() noexcept { return dst_seq[(dst_counter++) % num_regs]; }
+ uint32_t next_src() noexcept { return src_seq[(src_counter++) % num_regs]; }
+
+ kiss99 rng;
+
+private:
+ size_t dst_counter = 0;
+ std::array dst_seq;
+ size_t src_counter = 0;
+ std::array src_seq;
+};
+
+mix_rng_state::mix_rng_state(uint64_t seed) noexcept
+{
+ const auto seed_lo = static_cast(seed);
+ const auto seed_hi = static_cast(seed >> 32);
+
+ const auto z = fnv1a(fnv_offset_basis, seed_lo);
+ const auto w = fnv1a(z, seed_hi);
+ const auto jsr = fnv1a(w, seed_lo);
+ const auto jcong = fnv1a(jsr, seed_hi);
+
+ rng = kiss99{z, w, jsr, jcong};
+
+ // Create random permutations of mix destinations / sources.
+ // Uses Fisher-Yates shuffle.
+ for (uint32_t i = 0; i < num_regs; ++i)
+ {
+ dst_seq[i] = i;
+ src_seq[i] = i;
+ }
+
+ for (uint32_t i = num_regs; i > 1; --i)
+ {
+ std::swap(dst_seq[i - 1], dst_seq[rng() % i]);
+ std::swap(src_seq[i - 1], src_seq[rng() % i]);
+ }
+}
+
+
+NO_SANITIZE("unsigned-integer-overflow")
+inline uint32_t random_math(uint32_t a, uint32_t b, uint32_t selector) noexcept
+{
+ switch (selector % 11)
+ {
+ default:
+ case 2:
+ return a + b;
+ case 3:
+ return a * b;
+ case 4:
+ return mul_hi32(a, b);
+ case 5:
+ return std::min(a, b);
+ case 6:
+ return rotl32(a, b);
+ case 7:
+ return rotr32(a, b);
+ case 8:
+ return a & b;
+ case 9:
+ return a | b;
+ case 10:
+ return a ^ b;
+ case 0:
+ return clz32(a) + clz32(b);
+ case 1:
+ return popcount32(a) + popcount32(b);
+ }
+}
+
+/// Merge data from `b` and `a`.
+/// Assuming `a` has high entropy, only do ops that retain entropy even if `b`
+/// has low entropy (i.e. do not do `a & b`).
+NO_SANITIZE("unsigned-integer-overflow")
+inline void random_merge(uint32_t& a, uint32_t b, uint32_t selector) noexcept
+{
+ const auto x = (selector >> 16) % 31 + 1; // Additional non-zero selector from higher bits.
+ switch (selector % 4)
+ {
+ case 0:
+ a = (a * 33) + b;
+ break;
+ case 1:
+ a = (a ^ b) * 33;
+ break;
+ case 2:
+ a = rotl32(a, x) ^ b;
+ break;
+ case 3:
+ a = rotr32(a, x) ^ b;
+ break;
+ }
+}
+
+using lookup_fn = hash2048 (*)(const epoch_context&, uint32_t);
+
+using mix_array = std::array, num_lanes>;
+
+void round(
+ const epoch_context& context, uint32_t r, mix_array& mix, mix_rng_state state, lookup_fn lookup)
+{
+ const uint32_t num_items = static_cast(context.full_dataset_num_items / 2);
+ const uint32_t item_index = mix[r % num_lanes][0] % num_items;
+ const hash2048 item = lookup(context, item_index);
+
+ constexpr size_t num_words_per_lane = sizeof(item) / (sizeof(uint32_t) * num_lanes);
+ constexpr int max_operations =
+ num_cache_accesses > num_math_operations ? num_cache_accesses : num_math_operations;
+
+ // Process lanes.
+ for (int i = 0; i < max_operations; ++i)
+ {
+ if (i < num_cache_accesses) // Random access to cached memory.
+ {
+ const auto src = state.next_src();
+ const auto dst = state.next_dst();
+ const auto sel = state.rng();
+
+ for (size_t l = 0; l < num_lanes; ++l)
+ {
+ const size_t offset = mix[l][src] % l1_cache_num_items;
+ random_merge(mix[l][dst], le::uint32(context.l1_cache[offset]), sel);
+ }
+ }
+ if (i < num_math_operations) // Random math.
+ {
+ // Generate 2 unique source indexes.
+ const auto src_rnd = state.rng() % (num_regs * (num_regs - 1));
+ const auto src1 = src_rnd % num_regs; // O <= src1 < num_regs
+ auto src2 = src_rnd / num_regs; // 0 <= src2 < num_regs - 1
+ if (src2 >= src1)
+ ++src2;
+
+ const auto sel1 = state.rng();
+ const auto dst = state.next_dst();
+ const auto sel2 = state.rng();
+
+ for (size_t l = 0; l < num_lanes; ++l)
+ {
+ const uint32_t data = random_math(mix[l][src1], mix[l][src2], sel1);
+ random_merge(mix[l][dst], data, sel2);
+ }
+ }
+ }
+
+ // DAG access pattern.
+ uint32_t dsts[num_words_per_lane];
+ uint32_t sels[num_words_per_lane];
+ for (size_t i = 0; i < num_words_per_lane; ++i)
+ {
+ dsts[i] = i == 0 ? 0 : state.next_dst();
+ sels[i] = state.rng();
+ }
+
+ // DAG access.
+ for (size_t l = 0; l < num_lanes; ++l)
+ {
+ const auto offset = ((l ^ r) % num_lanes) * num_words_per_lane;
+ for (size_t i = 0; i < num_words_per_lane; ++i)
+ {
+ const auto word = le::uint32(item.word32s[offset + i]);
+ random_merge(mix[l][dsts[i]], word, sels[i]);
+ }
+ }
+}
+
+mix_array init_mix(uint64_t seed)
+{
+ const uint32_t z = fnv1a(fnv_offset_basis, static_cast(seed));
+ const uint32_t w = fnv1a(z, static_cast(seed >> 32));
+
+ mix_array mix;
+ for (uint32_t l = 0; l < mix.size(); ++l)
+ {
+ const uint32_t jsr = fnv1a(w, l);
+ const uint32_t jcong = fnv1a(jsr, l);
+ kiss99 rng{z, w, jsr, jcong};
+
+ for (auto& row : mix[l])
+ row = rng();
+ }
+ return mix;
+}
+
+hash256 hash_mix(
+ const epoch_context& context, int block_number, uint64_t seed, lookup_fn lookup) noexcept
+{
+ auto mix = init_mix(seed);
+ mix_rng_state state{uint64_t(block_number / period_length)};
+
+ for (uint32_t i = 0; i < 64; ++i)
+ round(context, i, mix, state, lookup);
+
+ // Reduce mix data to a single per-lane result.
+ uint32_t lane_hash[num_lanes];
+ for (size_t l = 0; l < num_lanes; ++l)
+ {
+ lane_hash[l] = fnv_offset_basis;
+ for (uint32_t i = 0; i < num_regs; ++i)
+ lane_hash[l] = fnv1a(lane_hash[l], mix[l][i]);
+ }
+
+ // Reduce all lanes to a single 256-bit result.
+ static constexpr size_t num_words = sizeof(hash256) / sizeof(uint32_t);
+ hash256 mix_hash;
+ for (uint32_t& w : mix_hash.word32s)
+ w = fnv_offset_basis;
+ for (size_t l = 0; l < num_lanes; ++l)
+ mix_hash.word32s[l % num_words] = fnv1a(mix_hash.word32s[l % num_words], lane_hash[l]);
+ return le::uint32s(mix_hash);
+}
+} // namespace
+
+result hash(const epoch_context& context, int block_number, const hash256& header_hash,
+ uint64_t nonce) noexcept
+{
+ const uint64_t seed = keccak_progpow_64(header_hash, nonce);
+ const hash256 mix_hash = hash_mix(context, block_number, seed, calculate_dataset_item_2048);
+ const hash256 final_hash = keccak_progpow_256(header_hash, seed, mix_hash);
+ return {final_hash, mix_hash};
+}
+
+result hash(const epoch_context_full& context, int block_number, const hash256& header_hash,
+ uint64_t nonce) noexcept
+{
+ static const auto lazy_lookup = [](const epoch_context& context, uint32_t index) noexcept
+ {
+ auto* full_dataset_1024 = static_cast(context).full_dataset;
+ auto* full_dataset_2048 = reinterpret_cast(full_dataset_1024);
+ hash2048& item = full_dataset_2048[index];
+ if (item.word64s[0] == 0)
+ {
+ // TODO: Copy elision here makes it thread-safe?
+ item = calculate_dataset_item_2048(context, index);
+ }
+
+ return item;
+ };
+
+ const uint64_t seed = keccak_progpow_64(header_hash, nonce);
+ const hash256 mix_hash = hash_mix(context, block_number, seed, lazy_lookup);
+ const hash256 final_hash = keccak_progpow_256(header_hash, seed, mix_hash);
+ return {final_hash, mix_hash};
+}
+
+bool verify(const epoch_context& context, int block_number, const hash256& header_hash,
+ const hash256& mix_hash, uint64_t nonce, const hash256& boundary) noexcept
+{
+ const uint64_t seed = keccak_progpow_64(header_hash, nonce);
+ const hash256 final_hash = keccak_progpow_256(header_hash, seed, mix_hash);
+ if (!is_less_or_equal(final_hash, boundary))
+ return false;
+
+ const hash256 expected_mix_hash =
+ hash_mix(context, block_number, seed, calculate_dataset_item_2048);
+ return is_equal(expected_mix_hash, mix_hash);
+}
+
+search_result search_light(const epoch_context& context, int block_number,
+ const hash256& header_hash, const hash256& boundary, uint64_t start_nonce,
+ size_t iterations) noexcept
+{
+ const uint64_t end_nonce = start_nonce + iterations;
+ for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce)
+ {
+ result r = hash(context, block_number, header_hash, nonce);
+ if (is_less_or_equal(r.final_hash, boundary))
+ return {r, nonce};
+ }
+ return {};
+}
+
+search_result search(const epoch_context_full& context, int block_number,
+ const hash256& header_hash, const hash256& boundary, uint64_t start_nonce,
+ size_t iterations) noexcept
+{
+ const uint64_t end_nonce = start_nonce + iterations;
+ for (uint64_t nonce = start_nonce; nonce < end_nonce; ++nonce)
+ {
+ result r = hash(context, block_number, header_hash, nonce);
+ if (is_less_or_equal(r.final_hash, boundary))
+ return {r, nonce};
+ }
+ return {};
+}
+
+} // namespace progpow
diff --git a/contrib/ethereum/libethash/support/attributes.h b/contrib/ethereum/libethash/support/attributes.h
new file mode 100644
index 00000000..bb62b8d4
--- /dev/null
+++ b/contrib/ethereum/libethash/support/attributes.h
@@ -0,0 +1,33 @@
+/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
+ * Copyright 2018 Pawel Bylica.
+ * Licensed under the Apache License, Version 2.0. See the LICENSE file.
+ */
+
+#pragma once
+
+/** inline */
+#if _MSC_VER || __STDC_VERSION__
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+/** [[always_inline]] */
+#if _MSC_VER
+#define ALWAYS_INLINE __forceinline
+#elif defined(__has_attribute) && __STDC_VERSION__
+#if __has_attribute(always_inline)
+#define ALWAYS_INLINE __attribute__((always_inline))
+#endif
+#endif
+#if !defined(ALWAYS_INLINE)
+#define ALWAYS_INLINE
+#endif
+
+/** [[no_sanitize()]] */
+#if __clang__
+#define NO_SANITIZE(sanitizer) \
+ __attribute__((no_sanitize(sanitizer)))
+#else
+#define NO_SANITIZE(sanitizer)
+#endif
diff --git a/contrib/miniupnp b/contrib/miniupnp
new file mode 160000
index 00000000..bd836936
--- /dev/null
+++ b/contrib/miniupnp
@@ -0,0 +1 @@
+Subproject commit bd836936f7ed7e697f36dff709d00a907644172a
diff --git a/contrib/miniupnpc/CMakeLists.txt b/contrib/miniupnpc/CMakeLists.txt
deleted file mode 100644
index 464ae74b..00000000
--- a/contrib/miniupnpc/CMakeLists.txt
+++ /dev/null
@@ -1,176 +0,0 @@
-cmake_minimum_required (VERSION 2.6)
-
-project (miniupnpc C)
-set (MINIUPNPC_VERSION 1.9)
-set (MINIUPNPC_API_VERSION 10)
-
-if (NOT CMAKE_BUILD_TYPE)
- if (WIN32)
- set (DEFAULT_BUILD_TYPE MinSizeRel)
- else (WIN32)
- set (DEFAULT_BUILD_TYPE RelWithDebInfo)
- endif(WIN32)
- set (CMAKE_BUILD_TYPE ${DEFAULT_BUILD_TYPE} CACHE STRING
- "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
- FORCE)
-endif()
-
-option (UPNPC_BUILD_STATIC "Build static library" TRUE)
-option (UPNPC_BUILD_SHARED "Build shared library" TRUE)
-if (NOT WIN32)
- option (UPNPC_BUILD_TESTS "Build test executables" TRUE)
-endif (NOT WIN32)
-option (NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE)
-
-mark_as_advanced (NO_GETADDRINFO)
-
-if (NO_GETADDRINFO)
- add_definitions (-DNO_GETADDRINFO)
-endif (NO_GETADDRINFO)
-
-if (NOT WIN32)
- add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT)
- add_definitions (-D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=1)
-else (NOT WIN32)
- add_definitions (-D_WIN32_WINNT=0x0501) # XP or higher for getnameinfo and friends
-endif (NOT WIN32)
-
-if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
- add_definitions (-DMACOSX -D_DARWIN_C_SOURCE)
-endif ()
-
-# Set compiler specific build flags
-if (CMAKE_COMPILER_IS_GNUC)
- # Set our own default flags at first run.
- if (NOT CONFIGURED)
-
- if (NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
- set (_PIC -fPIC)
- endif (CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
-
- set (CMAKE_C_FLAGS "${_PIC} -Wall $ENV{CFLAGS}" # CMAKE_C_FLAGS gets appended to the other C flags
- CACHE STRING "Flags used by the C compiler during normal builds." FORCE)
- set (CMAKE_C_FLAGS_DEBUG "-g -DDDEBUG"
- CACHE STRING "Flags used by the C compiler during debug builds." FORCE)
- set (CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG"
- CACHE STRING "Flags used by the C compiler during release builds." FORCE)
- set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG"
- CACHE STRING "Flags used by the C compiler during release builds." FORCE)
- set (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG"
- CACHE STRING "Flags used by the C compiler during release builds." FORCE)
-
- endif (NOT CONFIGURED)
-endif ()
-
-configure_file (miniupnpcstrings.h.cmake ${CMAKE_BINARY_DIR}/miniupnpcstrings.h)
-include_directories (${CMAKE_BINARY_DIR})
-
-set (MINIUPNPC_SOURCES
- igd_desc_parse.c
- miniupnpc.c
- minixml.c
- minisoap.c
- miniwget.c
- upnpc.c
- upnpcommands.c
- upnpreplyparse.c
- upnperrors.c
- connecthostport.c
- portlistingparse.c
- receivedata.c
-)
-
-if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
- set (MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c)
-endif (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS")
-
-if (WIN32)
- set_source_files_properties (${MINIUPNPC_SOURCES} PROPERTIES
- COMPILE_DEFINITIONS STATICLIB
- COMPILE_DEFINITIONS MINIUPNP_EXPORTS
- )
-endif (WIN32)
-
-if (WIN32)
-# find_library (WINSOCK2_LIBRARY NAMES ws2_32 WS2_32 Ws2_32)
-# find_library (IPHLPAPI_LIBRARY NAMES iphlpapi)
- set(WINSOCK2_LIBRARY ws2_32)
- set(IPHLPAPI_LIBRARY iphlpapi)
- set (LDLIBS ${WINSOCK2_LIBRARY} ${IPHLPAPI_LIBRARY} ${LDLIBS})
-#elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris")
-# find_library (SOCKET_LIBRARY NAMES socket)
-# find_library (NSL_LIBRARY NAMES nsl)
-# find_library (RESOLV_LIBRARY NAMES resolv)
-# set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS})
-endif (WIN32)
-
-if (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED)
- message (FATAL "Both shared and static libraries are disabled!")
-endif (NOT UPNPC_BUILD_STATIC AND NOT UPNPC_BUILD_SHARED)
-
-if (UPNPC_BUILD_STATIC)
- add_library (upnpc-static STATIC ${MINIUPNPC_SOURCES})
- set_target_properties (upnpc-static PROPERTIES OUTPUT_NAME "miniupnpc")
- target_link_libraries (upnpc-static ${LDLIBS})
- set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-static)
- set (UPNPC_LIBRARY_TARGET upnpc-static)
-endif (UPNPC_BUILD_STATIC)
-
-if (UPNPC_BUILD_SHARED)
- add_library (upnpc-shared SHARED ${MINIUPNPC_SOURCES})
- set_target_properties (upnpc-shared PROPERTIES OUTPUT_NAME "miniupnpc")
- set_target_properties (upnpc-shared PROPERTIES VERSION ${MINIUPNPC_VERSION})
- set_target_properties (upnpc-shared PROPERTIES SOVERSION ${MINIUPNPC_API_VERSION})
- target_link_libraries (upnpc-shared ${LDLIBS})
- set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} upnpc-shared)
- set (UPNPC_LIBRARY_TARGET upnpc-shared)
-endif (UPNPC_BUILD_SHARED)
-
-if (UPNPC_BUILD_TESTS)
- add_executable (testminixml testminixml.c minixml.c igd_desc_parse.c)
- target_link_libraries (testminixml ${LDLIBS})
-
- add_executable (minixmlvalid minixmlvalid.c minixml.c)
- target_link_libraries (minixmlvalid ${LDLIBS})
-
- add_executable (testupnpreplyparse testupnpreplyparse.c
- minixml.c upnpreplyparse.c)
- target_link_libraries (testupnpreplyparse ${LDLIBS})
-
- add_executable (testigddescparse testigddescparse.c
- igd_desc_parse.c minixml.c miniupnpc.c miniwget.c minissdpc.c
- upnpcommands.c upnpreplyparse.c minisoap.c connecthostport.c
- portlistingparse.c receivedata.c
- )
- target_link_libraries (testigddescparse ${LDLIBS})
-
- add_executable (testminiwget testminiwget.c
- miniwget.c miniupnpc.c minisoap.c upnpcommands.c minissdpc.c
- upnpreplyparse.c minixml.c igd_desc_parse.c connecthostport.c
- portlistingparse.c receivedata.c
- )
- target_link_libraries (testminiwget ${LDLIBS})
-
-# set (UPNPC_INSTALL_TARGETS ${UPNPC_INSTALL_TARGETS} testminixml minixmlvalid testupnpreplyparse testigddescparse testminiwget)
-endif (UPNPC_BUILD_TESTS)
-
-
-install (TARGETS ${UPNPC_INSTALL_TARGETS}
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib${LIB_SUFFIX}
- ARCHIVE DESTINATION lib${LIB_SUFFIX}
-)
-install (FILES
- miniupnpc.h
- miniwget.h
- upnpcommands.h
- igd_desc_parse.h
- upnpreplyparse.h
- upnperrors.h
- declspec.h
- DESTINATION include/miniupnpc
-)
-
-set (CONFIGURED YES CACHE INTERNAL "")
-
-# vim: ts=2:sw=2
diff --git a/contrib/miniupnpc/Changelog.txt b/contrib/miniupnpc/Changelog.txt
deleted file mode 100644
index 53e9a112..00000000
--- a/contrib/miniupnpc/Changelog.txt
+++ /dev/null
@@ -1,585 +0,0 @@
-$Id: Changelog.txt,v 1.193 2014/02/05 17:26:45 nanard Exp $
-miniUPnP client Changelog.
-
-2014/02/05:
- handle EINPROGRESS after connect()
-
-2014/02/03:
- minixml now handle XML comments
-
-VERSION 1.9 : released 2014/01/31
-
-2014/01/31:
- added argument remoteHost to UPNP_GetSpecificPortMappingEntry()
- increment API_VERSION to 10
-
-2013/12/09:
- --help and -h arguments in upnpc.c
-
-2013/10/07:
- fixed potential buffer overrun in miniwget.c
- Modified UPNP_GetValidIGD() to check for ExternalIpAddress
-
-2013/08/01:
- define MAXHOSTNAMELEN if not already done
-
-2013/06/06:
- update upnpreplyparse to allow larger values (128 chars instead of 64)
-
-2013/05/14:
- Update upnpreplyparse to take into account "empty" elements
- validate upnpreplyparse.c code with "make check"
-
-2013/05/03:
- Fix Solaris build thanks to Maciej Małecki
-
-2013/04/27:
- Fix testminiwget.sh for BSD
-
-2013/03/23:
- Fixed Makefile for *BSD
-
-2013/03/11:
- Update Makefile to use JNAerator version 0.11
-
-2013/02/11:
- Fix testminiwget.sh for use with dash
- Use $(DESTDIR) in Makefile
-
-VERSION 1.8 : released 2013/02/06
-
-2012/10/16:
- fix testminiwget with no IPv6 support
-
-2012/09/27:
- Rename all include guards to not clash with C99
- (7.1.3 Reserved identifiers).
-
-2012/08/30:
- Added -e option to upnpc program (set description for port mappings)
-
-2012/08/29:
- Python 3 support (thanks to Christopher Foo)
-
-2012/08/11:
- Fix a memory link in UPNP_GetValidIGD()
- Try to handle scope id in link local IPv6 URL under MS Windows
-
-2012/07/20:
- Disable HAS_IP_MREQN on DragonFly BSD
-
-2012/06/28:
- GetUPNPUrls() now inserts scope into link-local IPv6 addresses
-
-2012/06/23:
- More error return checks in upnpc.c
- #define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
- parseURL() now parses IPv6 addresses scope
- new parameter for miniwget() : IPv6 address scope
- increment API_VERSION to 9
-
-2012/06/20:
- fixed CMakeLists.txt
-
-2012/05/29
- Improvements in testminiwget.sh
-
-VERSION 1.7 : released 2012/05/24
-
-2012/05/01:
- Cleanup settings of CFLAGS in Makefile
- Fix signed/unsigned integer comparaisons
-
-2012/04/20:
- Allow to specify protocol with TCP or UDP for -A option
-
-2012/04/09:
- Only try to fetch XML description once in UPNP_GetValidIGD()
- Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments.
-
-2012/04/05:
- minor improvements to minihttptestserver.c
-
-2012/03/15:
- upnperrors.c returns valid error string for unrecognized error codes
-
-2012/03/08:
- make minihttptestserver listen on loopback interface instead of 0.0.0.0
-
-2012/01/25:
- Maven installation thanks to Alexey Kuznetsov
-
-2012/01/21:
- Replace WIN32 macro by _WIN32
-
-2012/01/19:
- Fixes in java wrappers thanks to Alexey Kuznetsov :
- https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc
- Make and install .deb packages (python) thanks to Alexey Kuznetsov :
- https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc
-
-2012/01/07:
- The multicast interface can now be specified by name with IPv4.
-
-2012/01/02:
- Install man page
-
-2011/11/25:
- added header to Port Mappings list in upnpc.c
-
-2011/10/09:
- Makefile : make clean now removes jnaerator generated files.
- MINIUPNPC_VERSION in miniupnpc.h (updated by make)
-
-2011/09/12:
- added rootdescURL to UPNPUrls structure.
-
-VERSION 1.6 : released 2011/07/25
-
-2011/07/25:
- Update doc for version 1.6 release
-
-2011/06/18:
- Fix for windows in miniwget.c
-
-2011/06/04:
- display remote host in port mapping listing
-
-2011/06/03:
- Fix in make install : there were missing headers
-
-2011/05/26:
- Fix the socket leak in miniwget thanks to Richard Marsh.
- Permit to add leaseduration in -a command. Display lease duration.
-
-2011/05/15:
- Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6
-
-2011/05/09:
- add a test in testminiwget.sh.
- more error checking in miniwget.c
-
-2011/05/06:
- Adding some tool to test and validate miniwget.c
- simplified and debugged miniwget.c
-
-2011/04/11:
- moving ReceiveData() to a receivedata.c file.
- parsing presentation url
- adding IGD v2 WANIPv6FirewallControl commands
-
-2011/04/10:
- update of miniupnpcmodule.c
- comments in miniwget.c, update in testminiwget
- Adding errors codes from IGD v2
- new functions in upnpc.c for IGD v2
-
-2011/04/09:
- Support for litteral ip v6 address in miniwget
-
-2011/04/08:
- Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
- Updating APIVERSION
- Supporting IPV6 in upnpDiscover()
- Adding a -6 option to upnpc command line tool
-
-2011/03/18:
- miniwget/parseURL() : return an error when url param is null.
- fixing GetListOfPortMappings()
-
-2011/03/14:
- upnpDiscover() now reporting an error code.
- improvements in comments.
-
-2011/03/11:
- adding miniupnpcstrings.h.cmake and CMakeLists.txt files.
-
-2011/02/15:
- Implementation of GetListOfPortMappings()
-
-2011/02/07:
- updates to minixml to support character data starting with spaces
- minixml now support CDATA
- upnpreplyparse treats specificaly
- change in simpleUPnPcommand to return the buffer (simplification)
-
-2011/02/06:
- Added leaseDuration argument to AddPortMapping()
- Starting to implement GetListOfPortMappings()
-
-2011/01/11:
- updating wingenminiupnpcstrings.c
-
-2011/01/04:
- improving updateminiupnpcstrings.sh
-
-VERSION 1.5 : released 2011/01/01
-
-2010/12/21:
- use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
-
-2010/12/11:
- Improvements on getHTTPResponse() code.
-
-2010/12/09:
- new code for miniwget that handle Chunked transfer encoding
- using getHTTPResponse() in SOAP call code
- Adding MANIFEST.in for 'python setup.py bdist_rpm'
-
-2010/11/25:
- changes to minissdpc.c to compile under Win32.
- see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729
-
-2010/09/17:
- Various improvement to Makefile from Michał Górny
-
-2010/08/05:
- Adding the script "external-ip.sh" from Reuben Hawkins
-
-2010/06/09:
- update to python module to match modification made on 2010/04/05
- update to Java test code to match modification made on 2010/04/05
- all UPNP_* function now return an error if the SOAP request failed
- at HTTP level.
-
-2010/04/17:
- Using GetBestRoute() under win32 in order to find the
- right interface to use.
-
-2010/04/12:
- Retrying with HTTP/1.1 if HTTP/1.0 failed. see
- http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703
-
-2010/04/07:
- avoid returning duplicates in upnpDiscover()
-
-2010/04/05:
- Create a connecthostport.h/.c with connecthostport() function
- and use it in miniwget and miniupnpc.
- Use getnameinfo() instead of inet_ntop or inet_ntoa
- Work to make miniupnpc IPV6 compatible...
- Add java test code.
- Big changes in order to support device having both WANIPConnection
- and WANPPPConnection.
-
-2010/04/04:
- Use getaddrinfo() instead of gethostbyname() in miniwget.
-
-2010/01/06:
- #define _DARWIN_C_SOURCE for Mac OS X
-
-2009/12/19:
- Improve MinGW32 build
-
-2009/12/11:
- adding a MSVC9 project to build the static library and executable
-
-2009/12/10:
- Fixing some compilation stuff for Windows/MinGW
-
-2009/12/07:
- adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS
- some fixes for Windows when using virtual ethernet adapters (it is the
- case with VMWare installed).
-
-2009/12/04:
- some fixes for AmigaOS compilation
- Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked
- transfer encoding)
-
-2009/12/03:
- updating printIDG and testigddescparse.c for debug.
- modifications to compile under AmigaOS
- adding a testminiwget program
- Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked
- transfer encoding
-
-2009/11/26:
- fixing updateminiupnpcstrings.sh to take into account
- which command that does not return an error code.
-
-VERSION 1.4 : released 2009/10/30
-
-2009/10/16:
- using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module.
-
-2009/10/10:
- Some fixes for compilation under Solaris
- compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464
-
-2009/09/21:
- fixing the code to ignore EINTR during connect() calls.
-
-2009/08/07:
- Set socket timeout for connect()
- Some cleanup in miniwget.c
-
-2009/08/04:
- remove multiple redirections with -d in upnpc.c
- Print textual error code in upnpc.c
- Ignore EINTR during the connect() and poll() calls.
-
-2009/07/29:
- fix in updateminiupnpcstrings.sh if OS name contains "/"
- Sending a correct value for MX: field in SSDP request
-
-2009/07/20:
- Change the Makefile to compile under Mac OS X
- Fixed a stackoverflow in getDevicesFromMiniSSDPD()
-
-2009/07/09:
- Compile under Haiku
- generate miniupnpcstrings.h.in from miniupnpcstrings.h
-
-2009/06/04:
- patching to compile under CygWin and cross compile for minGW
-
-VERSION 1.3 :
-
-2009/04/17:
- updating python module
- Use strtoull() when using C99
-
-2009/02/28:
- Fixed miniwget.c for compiling under sun
-
-2008/12/18:
- cleanup in Makefile (thanks to Paul de Weerd)
- minissdpc.c : win32 compatibility
- miniupnpc.c : changed xmlns prefix from 'm' to 'u'
- Removed NDEBUG (using DEBUG)
-
-2008/10/14:
- Added the ExternalHost argument to DeletePortMapping()
-
-2008/10/11:
- Added the ExternalHost argument to AddPortMapping()
- Put a correct User-Agent: header in HTTP requests.
-
-VERSION 1.2 :
-
-2008/10/07:
- Update docs
-
-2008/09/25:
- Integrated sameport patch from Dario Meloni : Added a "sameport"
- argument to upnpDiscover().
-
-2008/07/18:
- small modif to make Clang happy :)
-
-2008/07/17:
- #define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
-
-2008/07/14:
- include declspec.h in installation (to /usr/include/miniupnpc)
-
-VERSION 1.1 :
-
-2008/07/04:
- standard options for install/ln instead of gnu-specific stuff.
-
-2008/07/03:
- now builds a .dll and .lib with win32. (mingw32)
-
-2008/04/28:
- make install now install the binary of the upnpc tool
-
-2008/04/27:
- added testupnpigd.py
- added error strings for miniupnpc "internal" errors
- improved python module error/exception reporting.
-
-2008/04/23:
- Completely rewrite igd_desc_parse.c in order to be compatible with
- Linksys WAG200G
- Added testigddescparse
- updated python module
-
-VERSION 1.0 :
-
-2008/02/21:
- put some #ifdef DEBUG around DisplayNameValueList()
-
-2008/02/18:
- Improved error reporting in upnpcommands.c
- UPNP_GetStatusInfo() returns LastConnectionError
-
-2008/02/16:
- better error handling in minisoap.c
- improving display of "valid IGD found" in upnpc.c
-
-2008/02/03:
- Fixing UPNP_GetValidIGD()
- improved make install :)
-
-2007/12/22:
- Adding upnperrors.c/h to provide a strupnperror() function
- used to translate UPnP error codes to string.
-
-2007/12/19:
- Fixing getDevicesFromMiniSSDPD()
- improved error reporting of UPnP functions
-
-2007/12/18:
- It is now possible to specify a different location for MiniSSDPd socket.
- working with MiniSSDPd is now more efficient.
- python module improved.
-
-2007/12/16:
- improving error reporting
-
-2007/12/13:
- Try to improve compatibility by using HTTP/1.0 instead of 1.1 and
- XML a bit different for SOAP.
-
-2007/11/25:
- fixed select() call for linux
-
-2007/11/15:
- Added -fPIC to CFLAG for better shared library code.
-
-2007/11/02:
- Fixed a potential socket leak in miniwget2()
-
-2007/10/16:
- added a parameter to upnpDiscover() in order to allow the use of another
- interface than the default multicast interface.
-
-2007/10/12:
- Fixed the creation of symbolic link in Makefile
-
-2007/10/08:
- Added man page
-
-2007/10/02:
- fixed memory bug in GetUPNPUrls()
-
-2007/10/01:
- fixes in the Makefile
- Added UPNP_GetIGDFromUrl() and adapted the sample program accordingly.
- Added SONAME in the shared library to please debian :)
- fixed MS Windows compilation (minissdpd is not available under MS Windows).
-
-2007/09/25:
- small change to Makefile to be able to install in a different location
- (default is /usr)
-
-2007/09/24:
- now compiling both shared and static library
-
-2007/09/19:
- Cosmetic changes on upnpc.c
-
-2007/09/02:
- adapting to new miniSSDPd (release version ?)
-
-2007/08/31:
- Usage of miniSSDPd to skip discovery process.
-
-2007/08/27:
- fixed python module to allow compilation with Python older than Python 2.4
-
-2007/06/12:
- Added a python module.
-
-2007/05/19:
- Fixed compilation under MinGW
-
-2007/05/15:
- fixed a memory leak in AddPortMapping()
- Added testupnpreplyparse executable to check the parsing of
- upnp soap messages
- minixml now ignore namespace prefixes.
-
-2007/04/26:
- upnpc now displays external ip address with -s or -l
-
-2007/04/11:
- changed MINIUPNPC_URL_MAXSIZE to 128 to accomodate the "BT Voyager 210"
-
-2007/03/19:
- cleanup in miniwget.c
-
-2007/03/01:
- Small typo fix...
-
-2007/01/30:
- Now parsing the HTTP header from SOAP responses in order to
- get content-length value.
-
-2007/01/29:
- Fixed the Soap Query to speedup the HTTP request.
- added some Win32 DLL stuff...
-
-2007/01/27:
- Fixed some WIN32 compatibility issues
-
-2006/12/14:
- Added UPNPIGD_IsConnected() function in miniupnp.c/.h
- Added UPNP_GetValidIGD() in miniupnp.c/.h
- cleaned upnpc.c main(). now using UPNP_GetValidIGD()
-
-2006/12/07:
- Version 1.0-RC1 released
-
-2006/12/03:
- Minor changes to compile under SunOS/Solaris
-
-2006/11/30:
- made a minixml parser validator program
- updated minixml to handle attributes correctly
-
-2006/11/22:
- Added a -r option to the upnpc sample thanks to Alexander Hubmann.
-
-2006/11/19:
- Cleanup code to make it more ANSI C compliant
-
-2006/11/10:
- detect and display local lan address.
-
-2006/11/04:
- Packets and Bytes Sent/Received are now unsigned int.
-
-2006/11/01:
- Bug fix thanks to Giuseppe D'Angelo
-
-2006/10/31:
- C++ compatibility for .h files.
- Added a way to get ip Address on the LAN used to reach the IGD.
-
-2006/10/25:
- Added M-SEARCH to the services in the discovery process.
-
-2006/10/22:
- updated the Makefile to use makedepend, added a "make install"
- update Makefile
-
-2006/10/20:
- fixing the description url parsing thanks to patch sent by
- Wayne Dawe.
- Fixed/translated some comments.
- Implemented a better discover process, first looking
- for IGD then for root devices (as some devices only reply to
- M-SEARCH for root devices).
-
-2006/09/02:
- added freeUPNPDevlist() function.
-
-2006/08/04:
- More command line arguments checking
-
-2006/08/01:
- Added the .bat file to compile under Win32 with minGW32
-
-2006/07/31:
- Fixed the rootdesc parser (igd_desc_parse.c)
-
-2006/07/20:
- parseMSEARCHReply() is now returning the ST: line as well
- starting changes to detect several UPnP devices on the network
-
-2006/07/19:
- using GetCommonLinkProperties to get down/upload bitrate
-
diff --git a/contrib/miniupnpc/LICENSE b/contrib/miniupnpc/LICENSE
deleted file mode 100644
index ac89a751..00000000
--- a/contrib/miniupnpc/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-MiniUPnPc
-Copyright (c) 2005-2011, Thomas BERNARD
-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.
- * The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/contrib/miniupnpc/MANIFEST.in b/contrib/miniupnpc/MANIFEST.in
deleted file mode 100644
index 54b86f95..00000000
--- a/contrib/miniupnpc/MANIFEST.in
+++ /dev/null
@@ -1,5 +0,0 @@
-include README
-include miniupnpcmodule.c
-include setup.py
-include *.h
-include libminiupnpc.a
diff --git a/contrib/miniupnpc/Makefile b/contrib/miniupnpc/Makefile
deleted file mode 100644
index eaf42f05..00000000
--- a/contrib/miniupnpc/Makefile
+++ /dev/null
@@ -1,319 +0,0 @@
-# $Id: Makefile,v 1.107 2014/01/31 14:19:12 nanard Exp $
-# MiniUPnP Project
-# http://miniupnp.free.fr/
-# http://miniupnp.tuxfamily.org/
-# https://github.com/miniupnp/miniupnp
-# (c) 2005-2014 Thomas Bernard
-# to install use :
-# $ make DESTDIR=/tmp/dummylocation install
-# or
-# $ INSTALLPREFIX=/usr/local make install
-# or
-# $ make install (default INSTALLPREFIX is /usr)
-OS = $(shell uname -s)
-VERSION = $(shell cat VERSION)
-
-ifeq ($(OS), Darwin)
-JARSUFFIX=mac
-endif
-ifeq ($(OS), Linux)
-JARSUFFIX=linux
-endif
-ifneq (,$(findstring NT-5.1,$(OS)))
-JARSUFFIX=win32
-endif
-
-HAVE_IPV6 ?= yes
-export HAVE_IPV6
-
-CC ?= gcc
-#AR = gar
-#CFLAGS = -O -g -DDEBUG
-CFLAGS ?= -O
-CFLAGS += -Wall
-CFLAGS += -W -Wstrict-prototypes
-CFLAGS += -fno-common
-CFLAGS += -DMINIUPNPC_SET_SOCKET_TIMEOUT
-CFLAGS += -DMINIUPNPC_GET_SRC_ADDR
-CFLAGS += -D_BSD_SOURCE -D_POSIX_C_SOURCE=1
-CFLAGS += -ansi
-# -DNO_GETADDRINFO
-INSTALL = install
-SH = /bin/sh
-JAVA = java
-# see http://code.google.com/p/jnaerator/
-#JNAERATOR = jnaerator-0.9.7.jar
-#JNAERATOR = jnaerator-0.9.8-shaded.jar
-#JNAERATORARGS = -library miniupnpc
-#JNAERATOR = jnaerator-0.10-shaded.jar
-JNAERATOR = jnaerator-0.11-shaded.jar
-JNAERATORARGS = -mode StandaloneJar -runtime JNAerator -library miniupnpc
-JNAERATORBASEURL = http://jnaerator.googlecode.com/files/
-
-ifeq (SunOS, $(OS))
- LDFLAGS=-lsocket -lnsl -lresolv
-endif
-
-# APIVERSION is used to build SONAME
-APIVERSION = 10
-
-SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \
- upnpc.c upnpcommands.c upnpreplyparse.c testminixml.c \
- minixmlvalid.c testupnpreplyparse.c minissdpc.c \
- upnperrors.c testigddescparse.c testminiwget.c \
- connecthostport.c portlistingparse.c receivedata.c
-
-LIBOBJS = miniwget.o minixml.o igd_desc_parse.o minisoap.o \
- miniupnpc.o upnpreplyparse.o upnpcommands.o upnperrors.o \
- connecthostport.o portlistingparse.o receivedata.o
-
-ifneq ($(OS), AmigaOS)
-CFLAGS := -fPIC $(CFLAGS)
-LIBOBJS := $(LIBOBJS) minissdpc.o
-endif
-
-OBJS = $(patsubst %.c,%.o,$(SRCS))
-
-# HEADERS to install
-HEADERS = miniupnpc.h miniwget.h upnpcommands.h igd_desc_parse.h \
- upnpreplyparse.h upnperrors.h miniupnpctypes.h \
- portlistingparse.h \
- declspec.h
-
-# library names
-LIBRARY = libminiupnpc.a
-ifeq ($(OS), Darwin)
- SHAREDLIBRARY = libminiupnpc.dylib
- SONAME = $(basename $(SHAREDLIBRARY)).$(APIVERSION).dylib
- CFLAGS := -DMACOSX -D_DARWIN_C_SOURCE $(CFLAGS)
-else
-ifeq ($(JARSUFFIX), win32)
- SHAREDLIBRARY = miniupnpc.dll
-else
- # Linux/BSD/etc.
- SHAREDLIBRARY = libminiupnpc.so
- SONAME = $(SHAREDLIBRARY).$(APIVERSION)
-endif
-endif
-
-EXECUTABLES = upnpc-static
-EXECUTABLES_ADDTESTS = testminixml minixmlvalid testupnpreplyparse \
- testigddescparse testminiwget
-
-TESTMINIXMLOBJS = minixml.o igd_desc_parse.o testminixml.o
-
-TESTMINIWGETOBJS = miniwget.o testminiwget.o connecthostport.o receivedata.o
-
-TESTUPNPREPLYPARSE = testupnpreplyparse.o minixml.o upnpreplyparse.o
-
-TESTIGDDESCPARSE = testigddescparse.o igd_desc_parse.o minixml.o \
- miniupnpc.o miniwget.o upnpcommands.o upnpreplyparse.o \
- minisoap.o connecthostport.o receivedata.o \
- portlistingparse.o
-
-ifneq ($(OS), AmigaOS)
-EXECUTABLES := $(EXECUTABLES) upnpc-shared
-TESTMINIWGETOBJS := $(TESTMINIWGETOBJS) minissdpc.o
-TESTIGDDESCPARSE := $(TESTIGDDESCPARSE) minissdpc.o
-endif
-
-LIBDIR ?= lib
-# install directories
-INSTALLPREFIX ?= $(PREFIX)/usr
-INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc
-INSTALLDIRLIB = $(INSTALLPREFIX)/$(LIBDIR)
-INSTALLDIRBIN = $(INSTALLPREFIX)/bin
-INSTALLDIRMAN = $(INSTALLPREFIX)/share/man
-
-FILESTOINSTALL = $(LIBRARY) $(EXECUTABLES)
-ifneq ($(OS), AmigaOS)
-FILESTOINSTALL := $(FILESTOINSTALL) $(SHAREDLIBRARY)
-endif
-
-
-.PHONY: install clean depend all check test everything \
- installpythonmodule updateversion
-# validateminixml validateminiwget
-
-all: $(LIBRARY) $(EXECUTABLES)
-
-test: check
-
-check: validateminixml validateminiwget validateupnpreplyparse
-
-everything: all $(EXECUTABLES_ADDTESTS)
-
-pythonmodule: $(LIBRARY) miniupnpcmodule.c setup.py
- python setup.py build
- touch $@
-
-installpythonmodule: pythonmodule
- python setup.py install
-
-pythonmodule3: $(LIBRARY) miniupnpcmodule.c setup.py
- python3 setup.py build
- touch $@
-
-installpythonmodule3: pythonmodule3
- python3 setup.py install
-
-validateminixml: minixmlvalid
- @echo "minixml validation test"
- ./minixmlvalid
- touch $@
-
-validateminiwget: testminiwget minihttptestserver testminiwget.sh
- @echo "miniwget validation test"
- ./testminiwget.sh
- touch $@
-
-validateupnpreplyparse: testupnpreplyparse testupnpreplyparse.sh
- @echo "upnpreplyparse validation test"
- ./testupnpreplyparse.sh
- touch $@
-
-clean:
- $(RM) $(LIBRARY) $(SHAREDLIBRARY) $(EXECUTABLES) $(OBJS) miniupnpcstrings.h
- # clean python stuff
- $(RM) pythonmodule pythonmodule3
- $(RM) validateminixml validateminiwget validateupnpreplyparse
- $(RM) -r build/ dist/
- #python setup.py clean
- # clean jnaerator stuff
- $(RM) _jnaerator.* java/miniupnpc_$(OS).jar
-
-distclean: clean
- $(RM) $(JNAERATOR) java/*.jar java/*.class out.errors.txt
-
-updateversion: miniupnpc.h
- cp miniupnpc.h miniupnpc.h.bak
- sed 's/\(.*MINIUPNPC_API_VERSION\s\+\)[0-9]\+/\1$(APIVERSION)/' < miniupnpc.h.bak > miniupnpc.h
-
-install: updateversion $(FILESTOINSTALL)
- $(INSTALL) -d $(DESTDIR)$(INSTALLDIRINC)
- $(INSTALL) -m 644 $(HEADERS) $(DESTDIR)$(INSTALLDIRINC)
- $(INSTALL) -d $(DESTDIR)$(INSTALLDIRLIB)
- $(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(INSTALLDIRLIB)
-ifneq ($(OS), AmigaOS)
- $(INSTALL) -m 644 $(SHAREDLIBRARY) $(DESTDIR)$(INSTALLDIRLIB)/$(SONAME)
- ln -fs $(SONAME) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY)
-endif
- $(INSTALL) -d $(DESTDIR)$(INSTALLDIRBIN)
-ifeq ($(OS), AmigaOS)
- $(INSTALL) -m 755 upnpc-static $(DESTDIR)$(INSTALLDIRBIN)/upnpc
-else
- $(INSTALL) -m 755 upnpc-shared $(DESTDIR)$(INSTALLDIRBIN)/upnpc
-endif
- $(INSTALL) -m 755 external-ip.sh $(DESTDIR)$(INSTALLDIRBIN)/external-ip
-ifneq ($(OS), AmigaOS)
- $(INSTALL) -d $(DESTDIR)$(INSTALLDIRMAN)/man3
- $(INSTALL) man3/miniupnpc.3 $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3
-ifeq ($(OS), Linux)
- gzip $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3
-endif
-endif
-
-
-cleaninstall:
- $(RM) -r $(DESTDIR)$(INSTALLDIRINC)
- $(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(LIBRARY)
- $(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY)
-
-depend:
- makedepend -Y -- $(CFLAGS) -- $(SRCS) 2>/dev/null
-
-$(LIBRARY): $(LIBOBJS)
- $(AR) crs $@ $?
-
-$(SHAREDLIBRARY): $(LIBOBJS)
-ifeq ($(OS), Darwin)
-# $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(SONAME) -o $@ $^
- $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(INSTALLDIRLIB)/$(SONAME) -o $@ $^
-else
- $(CC) -shared $(LDFLAGS) -Wl,-soname,$(SONAME) -o $@ $^
-endif
-
-upnpc-static: upnpc.o $(LIBRARY)
- $(CC) $(LDFLAGS) -o $@ $^
-
-upnpc-shared: upnpc.o $(SHAREDLIBRARY)
- $(CC) $(LDFLAGS) -o $@ $^
-
-testminixml: $(TESTMINIXMLOBJS)
-
-testminiwget: $(TESTMINIWGETOBJS)
-
-minixmlvalid: minixml.o minixmlvalid.o
-
-testupnpreplyparse: $(TESTUPNPREPLYPARSE)
-
-testigddescparse: $(TESTIGDDESCPARSE)
-
-miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh VERSION
- $(SH) updateminiupnpcstrings.sh
-
-# ftp tool supplied with OpenBSD can download files from http.
-jnaerator-%.jar:
- wget $(JNAERATORBASEURL)/$@ || \
- curl -o $@ $(JNAERATORBASEURL)/$@ || \
- ftp $(JNAERATORBASEURL)/$@
-
-jar: $(SHAREDLIBRARY) $(JNAERATOR)
- $(JAVA) -jar $(JNAERATOR) $(JNAERATORARGS) \
- miniupnpc.h declspec.h upnpcommands.h upnpreplyparse.h \
- igd_desc_parse.h miniwget.h upnperrors.h $(SHAREDLIBRARY) \
- -package fr.free.miniupnp -o . -jar java/miniupnpc_$(JARSUFFIX).jar -v
-
-mvn_install:
- mvn install:install-file -Dfile=java/miniupnpc_$(JARSUFFIX).jar \
- -DgroupId=com.github \
- -DartifactId=miniupnp \
- -Dversion=$(VERSION) \
- -Dpackaging=jar \
- -Dclassifier=$(JARSUFFIX) \
- -DgeneratePom=true \
- -DcreateChecksum=true
-
-# make .deb packages
-deb: /usr/share/pyshared/stdeb all
- (python setup.py --command-packages=stdeb.command bdist_deb)
-
-# install .deb packages
-ideb:
- (sudo dpkg -i deb_dist/*.deb)
-
-/usr/share/pyshared/stdeb: /usr/share/doc/python-all-dev
- (sudo apt-get install python-stdeb)
-
-/usr/share/doc/python-all-dev:
- (sudo apt-get install python-all-dev)
-
-minihttptestserver: minihttptestserver.o
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-igd_desc_parse.o: igd_desc_parse.h
-miniupnpc.o: miniupnpc.h declspec.h igd_desc_parse.h minissdpc.h miniwget.h
-miniupnpc.o: minisoap.h minixml.h upnpcommands.h upnpreplyparse.h
-miniupnpc.o: portlistingparse.h miniupnpctypes.h connecthostport.h
-miniupnpc.o: receivedata.h
-minixml.o: minixml.h
-minisoap.o: minisoap.h miniupnpcstrings.h
-miniwget.o: miniupnpcstrings.h miniwget.h declspec.h connecthostport.h
-miniwget.o: receivedata.h
-upnpc.o: miniwget.h declspec.h miniupnpc.h igd_desc_parse.h upnpcommands.h
-upnpc.o: upnpreplyparse.h portlistingparse.h miniupnpctypes.h upnperrors.h
-upnpcommands.o: upnpcommands.h upnpreplyparse.h portlistingparse.h declspec.h
-upnpcommands.o: miniupnpctypes.h miniupnpc.h igd_desc_parse.h
-upnpreplyparse.o: upnpreplyparse.h minixml.h
-testminixml.o: minixml.h igd_desc_parse.h
-minixmlvalid.o: minixml.h
-testupnpreplyparse.o: upnpreplyparse.h
-minissdpc.o: minissdpc.h miniupnpc.h declspec.h igd_desc_parse.h codelength.h
-upnperrors.o: upnperrors.h declspec.h upnpcommands.h upnpreplyparse.h
-upnperrors.o: portlistingparse.h miniupnpctypes.h miniupnpc.h
-upnperrors.o: igd_desc_parse.h
-testigddescparse.o: igd_desc_parse.h minixml.h miniupnpc.h declspec.h
-testminiwget.o: miniwget.h declspec.h
-connecthostport.o: connecthostport.h
-receivedata.o: receivedata.h
diff --git a/contrib/miniupnpc/Makefile.mingw b/contrib/miniupnpc/Makefile.mingw
deleted file mode 100644
index 60b3f1b1..00000000
--- a/contrib/miniupnpc/Makefile.mingw
+++ /dev/null
@@ -1,91 +0,0 @@
-# $Id: Makefile.mingw,v 1.18 2014/01/17 09:04:01 nanard Exp $
-# Miniupnp project.
-# http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
-# (c) 2005-2014 Thomas Bernard
-# This Makefile is made for MinGW
-#
-CC = gcc
-#CFLAGS = -Wall -g -DDEBUG -D_WIN32_WINNT=0X501
-CFLAGS = -Wall -Os -DNDEBUG -D_WIN32_WINNT=0X501
-LDLIBS = -lws2_32 -liphlpapi
-# -lwsock32
-# -liphlpapi is needed for GetBestRoute() and GetIpAddrTable()
-PYTHON=\utils\python25\python
-OBJS=miniwget.o minixml.o igd_desc_parse.o minisoap.o \
- miniupnpc.o upnpreplyparse.o upnpcommands.o upnperrors.o \
- connecthostport.o portlistingparse.o receivedata.o
-OBJSDLL=$(addprefix dll/, $(OBJS))
-
-all: init upnpc-static upnpc-shared testminixml libminiupnpc.a miniupnpc.dll
-
-init:
- mkdir dll
- echo init > init
-
-clean:
- del upnpc testminixml *.o
- del dll\*.o
- del *.exe
- del miniupnpc.dll
- del libminiupnpc.a
-
-libminiupnpc.a: $(OBJS)
- $(AR) cr $@ $?
-
-pythonmodule: libminiupnpc.a
- $(PYTHON) setupmingw32.py build --compiler=mingw32
- $(PYTHON) setupmingw32.py install --skip-build
-
-miniupnpc.dll: libminiupnpc.a $(OBJSDLL)
- dllwrap -k --driver-name gcc \
- --def miniupnpc.def \
- --output-def miniupnpc.dll.def \
- --implib miniupnpc.lib -o $@ \
- $(OBJSDLL) $(LDLIBS)
-
-miniupnpc.lib: miniupnpc.dll
- echo $@ generated with $<
-
-dll/upnpc.o: upnpc.o
- echo $@ generated with $<
-
-.c.o:
- $(CC) $(CFLAGS) -DSTATICLIB -c -o $@ $<
- $(CC) $(CFLAGS) -DMINIUPNP_EXPORTS -c -o dll/$@ $<
-
-upnpc.o:
- $(CC) $(CFLAGS) -DSTATICLIB -c -o $@ $<
- $(CC) $(CFLAGS) -c -o dll/$@ $<
-
-# --enable-stdcall-fixup
-upnpc-static: upnpc.o libminiupnpc.a
- $(CC) -o $@ $^ $(LDLIBS)
-
-upnpc-shared: dll/upnpc.o miniupnpc.lib
- $(CC) -o $@ $^ $(LDLIBS)
-
-wingenminiupnpcstrings: wingenminiupnpcstrings.o
-
-wingenminiupnpcstrings.o: wingenminiupnpcstrings.c
-
-miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings
- wingenminiupnpcstrings $< $@
-
-minixml.o: minixml.c minixml.h miniupnpcstrings.h
-
-upnpc.o: upnpc.c miniwget.h minisoap.h miniupnpc.h igd_desc_parse.h upnpreplyparse.h upnpcommands.h upnperrors.h
-
-miniwget.o: miniwget.c miniwget.h miniupnpcstrings.h connecthostport.h
-
-minisoap.o: minisoap.c minisoap.h miniupnpcstrings.h
-
-miniupnpc.o: miniupnpc.c miniupnpc.h minisoap.h miniwget.h minixml.h
-
-igd_desc_parse.o: igd_desc_parse.c igd_desc_parse.h
-
-testminixml: minixml.o igd_desc_parse.o testminixml.c
-
-upnpreplyparse.o: upnpreplyparse.c upnpreplyparse.h minixml.h
-
-upnpcommands.o: upnpcommands.c upnpcommands.h upnpreplyparse.h miniupnpc.h portlistingparse.h
-
diff --git a/contrib/miniupnpc/README b/contrib/miniupnpc/README
deleted file mode 100644
index b23478de..00000000
--- a/contrib/miniupnpc/README
+++ /dev/null
@@ -1,66 +0,0 @@
-Project: miniupnp
-Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
-github: https://github.com/miniupnp/miniupnp
-freecode: http://freecode.com/projects/miniupnp
-Author: Thomas Bernard
-Copyright (c) 2005-2012 Thomas Bernard
-This software is subject to the conditions detailed in the
-LICENSE file provided within this distribution.
-
-
-For the comfort of Win32 users, bsdqueue.h is included in the distribution.
-Its licence is included in the header of the file.
-bsdqueue.h is a copy of the sys/queue.h of an OpenBSD system.
-
-
-* miniUPnP Client - miniUPnPc *
-
-To compile, simply run 'gmake' (could be 'make' on your system).
-Under win32, to compile with MinGW, type "mingw32make.bat".
-MS Visual C solution and project files are supplied in the msvc/ subdirectory.
-
-The compilation is known to work under linux, FreeBSD,
-OpenBSD, MacOS X, AmigaOS and cygwin.
-The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
-upx (http://upx.sourceforge.net) is used to compress the win32 .exe files.
-
-To install the library and headers on the system use :
-> su
-> make install
-> exit
-
-alternatively, to install into a specific location, use :
-> INSTALLPREFIX=/usr/local make install
-
-upnpc.c is a sample client using the libminiupnpc.
-To use the libminiupnpc in your application, link it with
-libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h,
-upnpcommands.h and miniwget.h :
-- upnpDiscover()
-- miniwget()
-- parserootdesc()
-- GetUPNPUrls()
-- UPNP_* (calling UPNP methods)
-
-Note : use #include etc... for the includes
-and -lminiupnpc for the link
-
-Discovery process is speeded up when MiniSSDPd is running on the machine.
-
-
-* Python module *
-
-you can build a python module with 'make pythonmodule'
-and install it with 'make installpythonmodule'.
-setup.py (and setupmingw32.py) are included in the distribution.
-
-
-Feel free to contact me if you have any problem :
-e-mail : miniupnp@free.fr
-
-If you are using libminiupnpc in your application, please
-send me an email !
-
-For any question, you can use the web forum :
-http://miniupnp.tuxfamily.org/forum/
-
diff --git a/contrib/miniupnpc/VERSION b/contrib/miniupnpc/VERSION
deleted file mode 100644
index 2e0e38c6..00000000
--- a/contrib/miniupnpc/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.9
diff --git a/contrib/miniupnpc/apiversions.txt b/contrib/miniupnpc/apiversions.txt
deleted file mode 100644
index 69f61c79..00000000
--- a/contrib/miniupnpc/apiversions.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-$Id: apiversions.txt,v 1.3 2014/01/31 13:14:32 nanard Exp $
-
-Differences in API between miniUPnPc versions
-
-====================== miniUPnPc version 1.9 ======================
-API version 10
-
-upnpcommands.h:
- added argument remoteHost to UPNP_GetSpecificPortMappingEntry()
-
-miniupnpc.h:
- updated macros :
- #define MINIUPNPC_VERSION "1.9"
- #define MINIUPNPC_API_VERSION 10
-
-====================== miniUPnPc version 1.8 ======================
-API version 9
-
-miniupnpc.h:
- updated macros :
- #define MINIUPNPC_VERSION "1.8"
- #define MINIUPNPC_API_VERSION 9
- added "unsigned int scope_id;" to struct UPNPDev
- added scope_id argument to GetUPNPUrls()
-
-
-
-====================== miniUPnPc version 1.7 ======================
-API version 8
-
-miniupnpc.h :
- add new macros :
- #define MINIUPNPC_VERSION "1.7"
- #define MINIUPNPC_API_VERSION 8
- add rootdescURL to struct UPNPUrls
-
-
-
-====================== miniUPnPc version 1.6 ======================
-API version 8
-
-Adding support for IPv6.
-igd_desc_parse.h :
- struct IGDdatas_service :
- add char presentationurl[MINIUPNPC_URL_MAXSIZE];
- struct IGDdatas :
- add struct IGDdatas_service IPv6FC;
-miniupnpc.h :
- new macros :
- #define UPNPDISCOVER_SUCCESS (0)
- #define UPNPDISCOVER_UNKNOWN_ERROR (-1)
- #define UPNPDISCOVER_SOCKET_ERROR (-101)
- #define UPNPDISCOVER_MEMORY_ERROR (-102)
- simpleUPnPcommand() prototype changed (but is normaly not used by API users)
- add arguments ipv6 and error to upnpDiscover() :
- struct UPNPDev *
- upnpDiscover(int delay, const char * multicastif,
- const char * minissdpdsock, int sameport,
- int ipv6,
- int * error);
- add controlURL_6FC member to struct UPNPUrls :
- struct UPNPUrls {
- char * controlURL;
- char * ipcondescURL;
- char * controlURL_CIF;
- char * controlURL_6FC;
- };
-
-upnpcommands.h :
- add leaseDuration argument to UPNP_AddPortMapping()
- add desc, enabled and leaseDuration arguments to UPNP_GetSpecificPortMappingEntry()
- add UPNP_GetListOfPortMappings() function (IGDv2)
- add IGDv2 IPv6 related functions :
- UPNP_GetFirewallStatus()
- UPNP_GetOutboundPinholeTimeout()
- UPNP_AddPinhole()
- UPNP_UpdatePinhole()
- UPNP_DeletePinhole()
- UPNP_CheckPinholeWorking()
- UPNP_GetPinholePackets()
-
-
-
-====================== miniUPnPc version 1.5 ======================
-API version 5
-
-new function :
-int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
-new macro in upnpcommands.h :
-#define UPNPCOMMAND_HTTP_ERROR
-
-====================== miniUPnPc version 1.4 ======================
-Same API as version 1.3
-
-====================== miniUPnPc version 1.3 ======================
-API version 4
-
-Use UNSIGNED_INTEGER type for
-UPNP_GetTotalBytesSent(), UPNP_GetTotalBytesReceived(),
-UPNP_GetTotalPacketsSent(), UPNP_GetTotalPacketsReceived()
-Add remoteHost argument to UPNP_AddPortMapping() and UPNP_DeletePortMapping()
-
-====================== miniUPnPc version 1.2 ======================
-API version 3
-
-added sameport argument to upnpDiscover()
-struct UPNPDev *
-upnpDiscover(int delay, const char * multicastif,
- const char * minissdpdsock, int sameport);
-
-====================== miniUPnPc Version 1.1 ======================
-Same API as 1.0
-
-
-====================== miniUPnPc Version 1.0 ======================
-API version 2
-
-
-struct UPNPDev {
- struct UPNPDev * pNext;
- char * descURL;
- char * st;
- char buffer[2];
-};
-struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
- const char * minissdpdsock);
-
diff --git a/contrib/miniupnpc/bsdqueue.h b/contrib/miniupnpc/bsdqueue.h
deleted file mode 100644
index c6afe1f7..00000000
--- a/contrib/miniupnpc/bsdqueue.h
+++ /dev/null
@@ -1,531 +0,0 @@
-/* $OpenBSD: queue.h,v 1.31 2005/11/25 08:06:25 otto Exp $ */
-/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
-
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)queue.h 8.5 (Berkeley) 8/20/94
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * lists, simple queues, tail queues, and circular queues.
- *
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction. Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A simple queue is headed by a pair of pointers, one the head of the
- * list and the other to the tail of the list. The elements are singly
- * linked to save space, so elements can only be removed from the
- * head of the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the
- * list. A simple queue may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-#ifdef QUEUE_MACRO_DEBUG
-#define _Q_INVALIDATE(a) (a) = ((void *)-1)
-#else
-#define _Q_INVALIDATE(a)
-#endif
-
-/*
- * Singly-linked List definitions.
- */
-#define SLIST_HEAD(name, type) \
-struct name { \
- struct type *slh_first; /* first element */ \
-}
-
-#define SLIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#ifdef SLIST_ENTRY
-#undef SLIST_ENTRY
-#endif
-
-#define SLIST_ENTRY(type) \
-struct { \
- struct type *sle_next; /* next element */ \
-}
-
-/*
- * Singly-linked List access methods.
- */
-#define SLIST_FIRST(head) ((head)->slh_first)
-#define SLIST_END(head) NULL
-#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
-#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
-
-#define SLIST_FOREACH(var, head, field) \
- for((var) = SLIST_FIRST(head); \
- (var) != SLIST_END(head); \
- (var) = SLIST_NEXT(var, field))
-
-#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
- for ((varp) = &SLIST_FIRST((head)); \
- ((var) = *(varp)) != SLIST_END(head); \
- (varp) = &SLIST_NEXT((var), field))
-
-/*
- * Singly-linked List functions.
- */
-#define SLIST_INIT(head) { \
- SLIST_FIRST(head) = SLIST_END(head); \
-}
-
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
- (elm)->field.sle_next = (slistelm)->field.sle_next; \
- (slistelm)->field.sle_next = (elm); \
-} while (0)
-
-#define SLIST_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.sle_next = (head)->slh_first; \
- (head)->slh_first = (elm); \
-} while (0)
-
-#define SLIST_REMOVE_NEXT(head, elm, field) do { \
- (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
-} while (0)
-
-#define SLIST_REMOVE_HEAD(head, field) do { \
- (head)->slh_first = (head)->slh_first->field.sle_next; \
-} while (0)
-
-#define SLIST_REMOVE(head, elm, type, field) do { \
- if ((head)->slh_first == (elm)) { \
- SLIST_REMOVE_HEAD((head), field); \
- } else { \
- struct type *curelm = (head)->slh_first; \
- \
- while (curelm->field.sle_next != (elm)) \
- curelm = curelm->field.sle_next; \
- curelm->field.sle_next = \
- curelm->field.sle_next->field.sle_next; \
- _Q_INVALIDATE((elm)->field.sle_next); \
- } \
-} while (0)
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type) \
-struct name { \
- struct type *lh_first; /* first element */ \
-}
-
-#define LIST_HEAD_INITIALIZER(head) \
- { NULL }
-
-#define LIST_ENTRY(type) \
-struct { \
- struct type *le_next; /* next element */ \
- struct type **le_prev; /* address of previous next element */ \
-}
-
-/*
- * List access methods
- */
-#define LIST_FIRST(head) ((head)->lh_first)
-#define LIST_END(head) NULL
-#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-#define LIST_FOREACH(var, head, field) \
- for((var) = LIST_FIRST(head); \
- (var)!= LIST_END(head); \
- (var) = LIST_NEXT(var, field))
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) do { \
- LIST_FIRST(head) = LIST_END(head); \
-} while (0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
- if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- (listelm)->field.le_next->field.le_prev = \
- &(elm)->field.le_next; \
- (listelm)->field.le_next = (elm); \
- (elm)->field.le_prev = &(listelm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.le_prev = (listelm)->field.le_prev; \
- (elm)->field.le_next = (listelm); \
- *(listelm)->field.le_prev = (elm); \
- (listelm)->field.le_prev = &(elm)->field.le_next; \
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- (head)->lh_first = (elm); \
- (elm)->field.le_prev = &(head)->lh_first; \
-} while (0)
-
-#define LIST_REMOVE(elm, field) do { \
- if ((elm)->field.le_next != NULL) \
- (elm)->field.le_next->field.le_prev = \
- (elm)->field.le_prev; \
- *(elm)->field.le_prev = (elm)->field.le_next; \
- _Q_INVALIDATE((elm)->field.le_prev); \
- _Q_INVALIDATE((elm)->field.le_next); \
-} while (0)
-
-#define LIST_REPLACE(elm, elm2, field) do { \
- if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
- (elm2)->field.le_next->field.le_prev = \
- &(elm2)->field.le_next; \
- (elm2)->field.le_prev = (elm)->field.le_prev; \
- *(elm2)->field.le_prev = (elm2); \
- _Q_INVALIDATE((elm)->field.le_prev); \
- _Q_INVALIDATE((elm)->field.le_next); \
-} while (0)
-
-/*
- * Simple queue definitions.
- */
-#define SIMPLEQ_HEAD(name, type) \
-struct name { \
- struct type *sqh_first; /* first element */ \
- struct type **sqh_last; /* addr of last next element */ \
-}
-
-#define SIMPLEQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).sqh_first }
-
-#define SIMPLEQ_ENTRY(type) \
-struct { \
- struct type *sqe_next; /* next element */ \
-}
-
-/*
- * Simple queue access methods.
- */
-#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
-#define SIMPLEQ_END(head) NULL
-#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
-#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
-
-#define SIMPLEQ_FOREACH(var, head, field) \
- for((var) = SIMPLEQ_FIRST(head); \
- (var) != SIMPLEQ_END(head); \
- (var) = SIMPLEQ_NEXT(var, field))
-
-/*
- * Simple queue functions.
- */
-#define SIMPLEQ_INIT(head) do { \
- (head)->sqh_first = NULL; \
- (head)->sqh_last = &(head)->sqh_first; \
-} while (0)
-
-#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
- (head)->sqh_last = &(elm)->field.sqe_next; \
- (head)->sqh_first = (elm); \
-} while (0)
-
-#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.sqe_next = NULL; \
- *(head)->sqh_last = (elm); \
- (head)->sqh_last = &(elm)->field.sqe_next; \
-} while (0)
-
-#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
- (head)->sqh_last = &(elm)->field.sqe_next; \
- (listelm)->field.sqe_next = (elm); \
-} while (0)
-
-#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
- if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
- (head)->sqh_last = &(head)->sqh_first; \
-} while (0)
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type) \
-struct name { \
- struct type *tqh_first; /* first element */ \
- struct type **tqh_last; /* addr of last next element */ \
-}
-
-#define TAILQ_HEAD_INITIALIZER(head) \
- { NULL, &(head).tqh_first }
-
-#define TAILQ_ENTRY(type) \
-struct { \
- struct type *tqe_next; /* next element */ \
- struct type **tqe_prev; /* address of previous next element */ \
-}
-
-/*
- * tail queue access methods
- */
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-#define TAILQ_END(head) NULL
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-#define TAILQ_LAST(head, headname) \
- (*(((struct headname *)((head)->tqh_last))->tqh_last))
-/* XXX */
-#define TAILQ_PREV(elm, headname, field) \
- (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-#define TAILQ_EMPTY(head) \
- (TAILQ_FIRST(head) == TAILQ_END(head))
-
-#define TAILQ_FOREACH(var, head, field) \
- for((var) = TAILQ_FIRST(head); \
- (var) != TAILQ_END(head); \
- (var) = TAILQ_NEXT(var, field))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for((var) = TAILQ_LAST(head, headname); \
- (var) != TAILQ_END(head); \
- (var) = TAILQ_PREV(var, headname, field))
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) do { \
- (head)->tqh_first = NULL; \
- (head)->tqh_last = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
- if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- (head)->tqh_first->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (head)->tqh_first = (elm); \
- (elm)->field.tqe_prev = &(head)->tqh_first; \
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.tqe_next = NULL; \
- (elm)->field.tqe_prev = (head)->tqh_last; \
- *(head)->tqh_last = (elm); \
- (head)->tqh_last = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
- if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- (elm)->field.tqe_next->field.tqe_prev = \
- &(elm)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm)->field.tqe_next; \
- (listelm)->field.tqe_next = (elm); \
- (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
- (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
- (elm)->field.tqe_next = (listelm); \
- *(listelm)->field.tqe_prev = (elm); \
- (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
-} while (0)
-
-#define TAILQ_REMOVE(head, elm, field) do { \
- if (((elm)->field.tqe_next) != NULL) \
- (elm)->field.tqe_next->field.tqe_prev = \
- (elm)->field.tqe_prev; \
- else \
- (head)->tqh_last = (elm)->field.tqe_prev; \
- *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
- _Q_INVALIDATE((elm)->field.tqe_prev); \
- _Q_INVALIDATE((elm)->field.tqe_next); \
-} while (0)
-
-#define TAILQ_REPLACE(head, elm, elm2, field) do { \
- if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
- (elm2)->field.tqe_next->field.tqe_prev = \
- &(elm2)->field.tqe_next; \
- else \
- (head)->tqh_last = &(elm2)->field.tqe_next; \
- (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
- *(elm2)->field.tqe_prev = (elm2); \
- _Q_INVALIDATE((elm)->field.tqe_prev); \
- _Q_INVALIDATE((elm)->field.tqe_next); \
-} while (0)
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type) \
-struct name { \
- struct type *cqh_first; /* first element */ \
- struct type *cqh_last; /* last element */ \
-}
-
-#define CIRCLEQ_HEAD_INITIALIZER(head) \
- { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
-
-#define CIRCLEQ_ENTRY(type) \
-struct { \
- struct type *cqe_next; /* next element */ \
- struct type *cqe_prev; /* previous element */ \
-}
-
-/*
- * Circular queue access methods
- */
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-#define CIRCLEQ_END(head) ((void *)(head))
-#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
-#define CIRCLEQ_EMPTY(head) \
- (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
-
-#define CIRCLEQ_FOREACH(var, head, field) \
- for((var) = CIRCLEQ_FIRST(head); \
- (var) != CIRCLEQ_END(head); \
- (var) = CIRCLEQ_NEXT(var, field))
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
- for((var) = CIRCLEQ_LAST(head); \
- (var) != CIRCLEQ_END(head); \
- (var) = CIRCLEQ_PREV(var, field))
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = CIRCLEQ_END(head); \
- (head)->cqh_last = CIRCLEQ_END(head); \
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- (elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
- (head)->cqh_last = (elm); \
- else \
- (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- (listelm)->field.cqe_next = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
- (elm)->field.cqe_next = (listelm); \
- (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
- (head)->cqh_first = (elm); \
- else \
- (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- (listelm)->field.cqe_prev = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
- (elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = CIRCLEQ_END(head); \
- if ((head)->cqh_last == CIRCLEQ_END(head)) \
- (head)->cqh_last = (elm); \
- else \
- (head)->cqh_first->field.cqe_prev = (elm); \
- (head)->cqh_first = (elm); \
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = CIRCLEQ_END(head); \
- (elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == CIRCLEQ_END(head)) \
- (head)->cqh_first = (elm); \
- else \
- (head)->cqh_last->field.cqe_next = (elm); \
- (head)->cqh_last = (elm); \
-} while (0)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
- (head)->cqh_last = (elm)->field.cqe_prev; \
- else \
- (elm)->field.cqe_next->field.cqe_prev = \
- (elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
- (head)->cqh_first = (elm)->field.cqe_next; \
- else \
- (elm)->field.cqe_prev->field.cqe_next = \
- (elm)->field.cqe_next; \
- _Q_INVALIDATE((elm)->field.cqe_prev); \
- _Q_INVALIDATE((elm)->field.cqe_next); \
-} while (0)
-
-#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
- if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
- CIRCLEQ_END(head)) \
- (head).cqh_last = (elm2); \
- else \
- (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
- if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
- CIRCLEQ_END(head)) \
- (head).cqh_first = (elm2); \
- else \
- (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
- _Q_INVALIDATE((elm)->field.cqe_prev); \
- _Q_INVALIDATE((elm)->field.cqe_next); \
-} while (0)
-
-#endif /* !_SYS_QUEUE_H_ */
diff --git a/contrib/miniupnpc/codelength.h b/contrib/miniupnpc/codelength.h
deleted file mode 100644
index d342bd14..00000000
--- a/contrib/miniupnpc/codelength.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id: codelength.h,v 1.4 2012/09/27 15:40:29 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas BERNARD
- * copyright (c) 2005-2011 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#ifndef CODELENGTH_H_INCLUDED
-#define CODELENGTH_H_INCLUDED
-
-/* Encode length by using 7bit per Byte :
- * Most significant bit of each byte specifies that the
- * following byte is part of the code */
-#define DECODELENGTH(n, p) n = 0; \
- do { n = (n << 7) | (*p & 0x7f); } \
- while((*(p++)&0x80) && (n<(1<<25)));
-
-#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \
- n = 0; \
- do { \
- if((p) >= (p_limit)) break; \
- n = (n << 7) | (*(p) & 0x7f); \
- } while((*((p)++)&0x80) && (n<(1<<25)));
-
-#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
- if(n>=2097152) *(p++) = (n >> 21) | 0x80; \
- if(n>=16384) *(p++) = (n >> 14) | 0x80; \
- if(n>=128) *(p++) = (n >> 7) | 0x80; \
- *(p++) = n & 0x7f;
-
-#endif
-
diff --git a/contrib/miniupnpc/connecthostport.c b/contrib/miniupnpc/connecthostport.c
deleted file mode 100644
index d66ae315..00000000
--- a/contrib/miniupnpc/connecthostport.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/* $Id: connecthostport.c,v 1.13 2014/03/31 12:36:36 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2010-2014 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-/* use getaddrinfo() or gethostbyname()
- * uncomment the following line in order to use gethostbyname() */
-#ifdef NO_GETADDRINFO
-#define USE_GETHOSTBYNAME
-#endif
-
-#include
-#include
-#ifdef _WIN32
-#include
-#include
-#include
-#define MAXHOSTNAMELEN 64
-#define snprintf _snprintf
-#define herror
-#define socklen_t int
-#else /* #ifdef _WIN32 */
-#include
-#include
-#include
-#include
-#define closesocket close
-#include
-#include
-/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
- * during the connect() call */
-#define MINIUPNPC_IGNORE_EINTR
-#ifndef USE_GETHOSTBYNAME
-#include
-#include
-#include
-#endif /* #ifndef USE_GETHOSTBYNAME */
-#endif /* #else _WIN32 */
-
-/* definition of PRINT_SOCKET_ERROR */
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#if defined(__amigaos__) || defined(__amigaos4__)
-#define herror(A) printf("%s\n", A)
-#endif
-
-#include "connecthostport.h"
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-/* connecthostport()
- * return a socket connected (TCP) to the host and port
- * or -1 in case of error */
-int connecthostport(const char * host, unsigned short port,
- unsigned int scope_id)
-{
- int s, n;
-#ifdef USE_GETHOSTBYNAME
- struct sockaddr_in dest;
- struct hostent *hp;
-#else /* #ifdef USE_GETHOSTBYNAME */
- char tmp_host[MAXHOSTNAMELEN+1];
- char port_str[8];
- struct addrinfo *ai, *p;
- struct addrinfo hints;
-#endif /* #ifdef USE_GETHOSTBYNAME */
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
- struct timeval timeout;
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-
-#ifdef USE_GETHOSTBYNAME
- hp = gethostbyname(host);
- if(hp == NULL)
- {
- herror(host);
- return -1;
- }
- memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
- memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
- s = socket(PF_INET, SOCK_STREAM, 0);
- if(s < 0)
- {
- PRINT_SOCKET_ERROR("socket");
- return -1;
- }
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
- /* setting a 3 seconds timeout for the connect() call */
- timeout.tv_sec = 3;
- timeout.tv_usec = 0;
- if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
- {
- PRINT_SOCKET_ERROR("setsockopt");
- }
- timeout.tv_sec = 3;
- timeout.tv_usec = 0;
- if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
- {
- PRINT_SOCKET_ERROR("setsockopt");
- }
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
- dest.sin_family = AF_INET;
- dest.sin_port = htons(port);
- n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
-#ifdef MINIUPNPC_IGNORE_EINTR
- /* EINTR The system call was interrupted by a signal that was caught
- * EINPROGRESS The socket is nonblocking and the connection cannot
- * be completed immediately. */
- while(n < 0 && (errno == EINTR || errno = EINPROGRESS))
- {
- socklen_t len;
- fd_set wset;
- int err;
- FD_ZERO(&wset);
- FD_SET(s, &wset);
- if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
- continue;
- /*len = 0;*/
- /*n = getpeername(s, NULL, &len);*/
- len = sizeof(err);
- if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
- PRINT_SOCKET_ERROR("getsockopt");
- closesocket(s);
- return -1;
- }
- if(err != 0) {
- errno = err;
- n = -1;
- }
- }
-#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
- if(n<0)
- {
- PRINT_SOCKET_ERROR("connect");
- closesocket(s);
- return -1;
- }
-#else /* #ifdef USE_GETHOSTBYNAME */
- /* use getaddrinfo() instead of gethostbyname() */
- memset(&hints, 0, sizeof(hints));
- /* hints.ai_flags = AI_ADDRCONFIG; */
-#ifdef AI_NUMERICSERV
- hints.ai_flags = AI_NUMERICSERV;
-#endif
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
- /* hints.ai_protocol = IPPROTO_TCP; */
- snprintf(port_str, sizeof(port_str), "%hu", port);
- if(host[0] == '[')
- {
- /* literal ip v6 address */
- int i, j;
- for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
- {
- tmp_host[i] = host[j];
- if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */
- j+=2; /* skip "25" */
- }
- tmp_host[i] = '\0';
- }
- else
- {
- strncpy(tmp_host, host, MAXHOSTNAMELEN);
- }
- tmp_host[MAXHOSTNAMELEN] = '\0';
- n = getaddrinfo(tmp_host, port_str, &hints, &ai);
- if(n != 0)
- {
-#ifdef _WIN32
- fprintf(stderr, "getaddrinfo() error : %d\n", n);
-#else
- fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
-#endif
- return -1;
- }
- s = -1;
- for(p = ai; p; p = p->ai_next)
- {
- s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
- if(s < 0)
- continue;
- if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) {
- struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr;
- addr6->sin6_scope_id = scope_id;
- }
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
- /* setting a 3 seconds timeout for the connect() call */
- timeout.tv_sec = 3;
- timeout.tv_usec = 0;
- if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
- {
- PRINT_SOCKET_ERROR("setsockopt");
- }
- timeout.tv_sec = 3;
- timeout.tv_usec = 0;
- if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
- {
- PRINT_SOCKET_ERROR("setsockopt");
- }
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
- n = connect(s, p->ai_addr, p->ai_addrlen);
-#ifdef MINIUPNPC_IGNORE_EINTR
- /* EINTR The system call was interrupted by a signal that was caught
- * EINPROGRESS The socket is nonblocking and the connection cannot
- * be completed immediately. */
- while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
- {
- socklen_t len;
- fd_set wset;
- int err;
- FD_ZERO(&wset);
- FD_SET(s, &wset);
- if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
- continue;
- /*len = 0;*/
- /*n = getpeername(s, NULL, &len);*/
- len = sizeof(err);
- if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
- PRINT_SOCKET_ERROR("getsockopt");
- closesocket(s);
- freeaddrinfo(ai);
- return -1;
- }
- if(err != 0) {
- errno = err;
- n = -1;
- }
- }
-#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
- if(n < 0)
- {
- closesocket(s);
- continue;
- }
- else
- {
- break;
- }
- }
- freeaddrinfo(ai);
- if(s < 0)
- {
- PRINT_SOCKET_ERROR("socket");
- return -1;
- }
- if(n < 0)
- {
- PRINT_SOCKET_ERROR("connect");
- return -1;
- }
-#endif /* #ifdef USE_GETHOSTBYNAME */
- return s;
-}
-
diff --git a/contrib/miniupnpc/connecthostport.h b/contrib/miniupnpc/connecthostport.h
deleted file mode 100644
index 56941d6f..00000000
--- a/contrib/miniupnpc/connecthostport.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* $Id: connecthostport.h,v 1.3 2012/09/27 15:42:10 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/
- * Author: Thomas Bernard
- * Copyright (c) 2010-2012 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef CONNECTHOSTPORT_H_INCLUDED
-#define CONNECTHOSTPORT_H_INCLUDED
-
-/* connecthostport()
- * return a socket connected (TCP) to the host and port
- * or -1 in case of error */
-int connecthostport(const char * host, unsigned short port,
- unsigned int scope_id);
-
-#endif
-
diff --git a/contrib/miniupnpc/declspec.h b/contrib/miniupnpc/declspec.h
deleted file mode 100644
index 77299693..00000000
--- a/contrib/miniupnpc/declspec.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef DECLSPEC_H_INCLUDED
-#define DECLSPEC_H_INCLUDED
-
-#if defined(_WIN32) && !defined(STATICLIB)
- /* for windows dll */
- #ifdef MINIUPNP_EXPORTS
- #define LIBSPEC __declspec(dllexport)
- #else
- #define LIBSPEC __declspec(dllimport)
- #endif
-#else
- #if defined(__GNUC__) && __GNUC__ >= 4
- /* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */
- #define LIBSPEC __attribute__ ((visibility ("default")))
- #else
- #define LIBSPEC
- #endif
-#endif
-
-#endif
-
diff --git a/contrib/miniupnpc/external-ip.sh b/contrib/miniupnpc/external-ip.sh
deleted file mode 100644
index 965d86b2..00000000
--- a/contrib/miniupnpc/external-ip.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-# $Id: external-ip.sh,v 1.1 2010/08/05 12:57:41 nanard Exp $
-# (c) 2010 Reuben Hawkins
-upnpc -s | grep ExternalIPAddress | sed 's/[^0-9\.]//g'
diff --git a/contrib/miniupnpc/igd_desc_parse.c b/contrib/miniupnpc/igd_desc_parse.c
deleted file mode 100644
index 6c3e6567..00000000
--- a/contrib/miniupnpc/igd_desc_parse.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* $Id: igd_desc_parse.c,v 1.14 2011/04/11 09:19:24 nanard Exp $ */
-/* Project : miniupnp
- * http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2010 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include "igd_desc_parse.h"
-#include
-#include
-
-/* Start element handler :
- * update nesting level counter and copy element name */
-void IGDstartelt(void * d, const char * name, int l)
-{
- struct IGDdatas * datas = (struct IGDdatas *)d;
- memcpy( datas->cureltname, name, l);
- datas->cureltname[l] = '\0';
- datas->level++;
- if( (l==7) && !memcmp(name, "service", l) ) {
- datas->tmp.controlurl[0] = '\0';
- datas->tmp.eventsuburl[0] = '\0';
- datas->tmp.scpdurl[0] = '\0';
- datas->tmp.servicetype[0] = '\0';
- }
-}
-
-/* End element handler :
- * update nesting level counter and update parser state if
- * service element is parsed */
-void IGDendelt(void * d, const char * name, int l)
-{
- struct IGDdatas * datas = (struct IGDdatas *)d;
- datas->level--;
- /*printf("endelt %2d %.*s\n", datas->level, l, name);*/
- if( (l==7) && !memcmp(name, "service", l) )
- {
- /*
- if( datas->state < 1
- && !strcmp(datas->servicetype,
- // "urn:schemas-upnp-org:service:WANIPConnection:1") )
- "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
- datas->state ++;
- */
- if(0==strcmp(datas->tmp.servicetype,
- "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
- memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
- } else if(0==strcmp(datas->tmp.servicetype,
- "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1")) {
- memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service));
- } else if(0==strcmp(datas->tmp.servicetype,
- "urn:schemas-upnp-org:service:WANIPConnection:1")
- || 0==strcmp(datas->tmp.servicetype,
- "urn:schemas-upnp-org:service:WANPPPConnection:1") ) {
- if(datas->first.servicetype[0] == '\0') {
- memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service));
- } else {
- memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service));
- }
- }
- }
-}
-
-/* Data handler :
- * copy data depending on the current element name and state */
-void IGDdata(void * d, const char * data, int l)
-{
- struct IGDdatas * datas = (struct IGDdatas *)d;
- char * dstmember = 0;
- /*printf("%2d %s : %.*s\n",
- datas->level, datas->cureltname, l, data); */
- if( !strcmp(datas->cureltname, "URLBase") )
- dstmember = datas->urlbase;
- else if( !strcmp(datas->cureltname, "presentationURL") )
- dstmember = datas->presentationurl;
- else if( !strcmp(datas->cureltname, "serviceType") )
- dstmember = datas->tmp.servicetype;
- else if( !strcmp(datas->cureltname, "controlURL") )
- dstmember = datas->tmp.controlurl;
- else if( !strcmp(datas->cureltname, "eventSubURL") )
- dstmember = datas->tmp.eventsuburl;
- else if( !strcmp(datas->cureltname, "SCPDURL") )
- dstmember = datas->tmp.scpdurl;
-/* else if( !strcmp(datas->cureltname, "deviceType") )
- dstmember = datas->devicetype_tmp;*/
- if(dstmember)
- {
- if(l>=MINIUPNPC_URL_MAXSIZE)
- l = MINIUPNPC_URL_MAXSIZE-1;
- memcpy(dstmember, data, l);
- dstmember[l] = '\0';
- }
-}
-
-void printIGD(struct IGDdatas * d)
-{
- printf("urlbase = '%s'\n", d->urlbase);
- printf("WAN Device (Common interface config) :\n");
- /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/
- printf(" serviceType = '%s'\n", d->CIF.servicetype);
- printf(" controlURL = '%s'\n", d->CIF.controlurl);
- printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
- printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
- printf("primary WAN Connection Device (IP or PPP Connection):\n");
- /*printf(" deviceType = '%s'\n", d->first.devicetype);*/
- printf(" servicetype = '%s'\n", d->first.servicetype);
- printf(" controlURL = '%s'\n", d->first.controlurl);
- printf(" eventSubURL = '%s'\n", d->first.eventsuburl);
- printf(" SCPDURL = '%s'\n", d->first.scpdurl);
- printf("secondary WAN Connection Device (IP or PPP Connection):\n");
- /*printf(" deviceType = '%s'\n", d->second.devicetype);*/
- printf(" servicetype = '%s'\n", d->second.servicetype);
- printf(" controlURL = '%s'\n", d->second.controlurl);
- printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
- printf(" SCPDURL = '%s'\n", d->second.scpdurl);
- printf("WAN IPv6 Firewall Control :\n");
- /*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/
- printf(" servicetype = '%s'\n", d->IPv6FC.servicetype);
- printf(" controlURL = '%s'\n", d->IPv6FC.controlurl);
- printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl);
- printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl);
-}
-
-
diff --git a/contrib/miniupnpc/igd_desc_parse.h b/contrib/miniupnpc/igd_desc_parse.h
deleted file mode 100644
index 0a49b019..00000000
--- a/contrib/miniupnpc/igd_desc_parse.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $Id: igd_desc_parse.h,v 1.11 2012/10/16 16:49:02 nanard Exp $ */
-/* Project : miniupnp
- * http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2010 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#ifndef IGD_DESC_PARSE_H_INCLUDED
-#define IGD_DESC_PARSE_H_INCLUDED
-
-/* Structure to store the result of the parsing of UPnP
- * descriptions of Internet Gateway Devices */
-#define MINIUPNPC_URL_MAXSIZE (128)
-struct IGDdatas_service {
- char controlurl[MINIUPNPC_URL_MAXSIZE];
- char eventsuburl[MINIUPNPC_URL_MAXSIZE];
- char scpdurl[MINIUPNPC_URL_MAXSIZE];
- char servicetype[MINIUPNPC_URL_MAXSIZE];
- /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
-};
-
-struct IGDdatas {
- char cureltname[MINIUPNPC_URL_MAXSIZE];
- char urlbase[MINIUPNPC_URL_MAXSIZE];
- char presentationurl[MINIUPNPC_URL_MAXSIZE];
- int level;
- /*int state;*/
- /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
- struct IGDdatas_service CIF;
- /* "urn:schemas-upnp-org:service:WANIPConnection:1"
- * "urn:schemas-upnp-org:service:WANPPPConnection:1" */
- struct IGDdatas_service first;
- /* if both WANIPConnection and WANPPPConnection are present */
- struct IGDdatas_service second;
- /* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
- struct IGDdatas_service IPv6FC;
- /* tmp */
- struct IGDdatas_service tmp;
-};
-
-void IGDstartelt(void *, const char *, int);
-void IGDendelt(void *, const char *, int);
-void IGDdata(void *, const char *, int);
-void printIGD(struct IGDdatas *);
-
-#endif
-
diff --git a/contrib/miniupnpc/java/JavaBridgeTest.java b/contrib/miniupnpc/java/JavaBridgeTest.java
deleted file mode 100644
index a7fa56d8..00000000
--- a/contrib/miniupnpc/java/JavaBridgeTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-
-import fr.free.miniupnp.*;
-
-/**
- *
- * @author syuu
- */
-public class JavaBridgeTest {
- public static void main(String[] args) {
- int UPNP_DELAY = 2000;
- MiniupnpcLibrary miniupnpc = MiniupnpcLibrary.INSTANCE;
- UPNPDev devlist = null;
- UPNPUrls urls = new UPNPUrls();
- IGDdatas data = new IGDdatas();
- ByteBuffer lanaddr = ByteBuffer.allocate(16);
- ByteBuffer intClient = ByteBuffer.allocate(16);
- ByteBuffer intPort = ByteBuffer.allocate(6);
- ByteBuffer desc = ByteBuffer.allocate(80);
- ByteBuffer enabled = ByteBuffer.allocate(4);
- ByteBuffer leaseDuration = ByteBuffer.allocate(16);
- int ret;
- int i;
-
- if(args.length < 2) {
- System.err.println("Usage : java [...] JavaBridgeTest port protocol");
- System.out.println(" port is numeric, protocol is TCP or UDP");
- return;
- }
-
- devlist = miniupnpc.upnpDiscover(UPNP_DELAY, (String) null, (String) null, 0, 0, IntBuffer.allocate(1));
- if (devlist != null) {
- System.out.println("List of UPNP devices found on the network :");
- for (UPNPDev device = devlist; device != null; device = device.pNext) {
- System.out.println("desc: " + device.descURL.getString(0) + " st: " + device.st.getString(0));
- }
- if ((i = miniupnpc.UPNP_GetValidIGD(devlist, urls, data, lanaddr, 16)) != 0) {
- switch (i) {
- case 1:
- System.out.println("Found valid IGD : " + urls.controlURL.getString(0));
- break;
- case 2:
- System.out.println("Found a (not connected?) IGD : " + urls.controlURL.getString(0));
- System.out.println("Trying to continue anyway");
- break;
- case 3:
- System.out.println("UPnP device found. Is it an IGD ? : " + urls.controlURL.getString(0));
- System.out.println("Trying to continue anyway");
- break;
- default:
- System.out.println("Found device (igd ?) : " + urls.controlURL.getString(0));
- System.out.println("Trying to continue anyway");
-
- }
- System.out.println("Local LAN ip address : " + new String(lanaddr.array()));
- ByteBuffer externalAddress = ByteBuffer.allocate(16);
- miniupnpc.UPNP_GetExternalIPAddress(urls.controlURL.getString(0),
- new String(data.first.servicetype), externalAddress);
- System.out.println("ExternalIPAddress = " + new String(externalAddress.array()));
- ret = miniupnpc.UPNP_AddPortMapping(
- urls.controlURL.getString(0), // controlURL
- new String(data.first.servicetype), // servicetype
- args[0], // external Port
- args[0], // internal Port
- new String(lanaddr.array()), // internal client
- "added via miniupnpc/JAVA !", // description
- args[1], // protocol UDP or TCP
- null, // remote host (useless)
- "0"); // leaseDuration
- if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
- System.out.println("AddPortMapping() failed with code " + ret);
- ret = miniupnpc.UPNP_GetSpecificPortMappingEntry(
- urls.controlURL.getString(0), new String(data.first.servicetype),
- args[0], args[1], null, intClient, intPort,
- desc, enabled, leaseDuration);
- if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
- System.out.println("GetSpecificPortMappingEntry() failed with code " + ret);
- System.out.println("InternalIP:Port = " +
- new String(intClient.array()) + ":" + new String(intPort.array()) +
- " (" + new String(desc.array()) + ")");
- ret = miniupnpc.UPNP_DeletePortMapping(
- urls.controlURL.getString(0),
- new String(data.first.servicetype),
- args[0], args[1], null);
- if (ret != MiniupnpcLibrary.UPNPCOMMAND_SUCCESS)
- System.out.println("DelPortMapping() failed with code " + ret);
- miniupnpc.FreeUPNPUrls(urls);
- } else {
- System.out.println("No valid UPNP Internet Gateway Device found.");
- }
- miniupnpc.freeUPNPDevlist(devlist);
- } else {
- System.out.println("No IGD UPnP Device found on the network !\n");
- }
- }
-}
diff --git a/contrib/miniupnpc/java/testjava.bat b/contrib/miniupnpc/java/testjava.bat
deleted file mode 100644
index b836da14..00000000
--- a/contrib/miniupnpc/java/testjava.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-@echo off
-set JAVA=java
-set JAVAC=javac
-REM notice the semicolon for Windows. Write once, run ... oh nevermind
-set CP=miniupnpc_win32.jar;.
-
-%JAVAC% -cp "%CP%" JavaBridgeTest.java || exit 1
-%JAVA% -cp "%CP%" JavaBridgeTest 12345 UDP || exit 1
diff --git a/contrib/miniupnpc/java/testjava.sh b/contrib/miniupnpc/java/testjava.sh
deleted file mode 100644
index 9880523a..00000000
--- a/contrib/miniupnpc/java/testjava.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-JAVA=java
-JAVAC=javac
-CP=$(for i in *.jar; do echo -n $i:; done).
-
-$JAVAC -cp $CP JavaBridgeTest.java || exit 1
-$JAVA -cp $CP JavaBridgeTest 12345 UDP || exit 1
diff --git a/contrib/miniupnpc/man3/miniupnpc.3 b/contrib/miniupnpc/man3/miniupnpc.3
deleted file mode 100644
index 1b166474..00000000
--- a/contrib/miniupnpc/man3/miniupnpc.3
+++ /dev/null
@@ -1,52 +0,0 @@
-.TH MINIUPNPC 3
-.SH NAME
-miniupnpc \- UPnP client library
-.SH SYNOPSIS
-.SH DESCRIPTION
-The miniupnpc library implement the UPnP protocol defined
-to dialog with Internet Gateway Devices. It also has
-the ability to use data gathered by minissdpd(1) about
-UPnP devices up on the network in order to skip the
-long UPnP device discovery process.
-.PP
-At first, upnpDiscover(3) has to be used to discover UPnP IGD present
-on the network. Then UPNP_GetValidIGD(3) to select the right one.
-Alternatively, UPNP_GetIGDFromUrl(3) could be used to bypass discovery
-process if the root description url of the device to use is known.
-Then all the UPNP_* functions can be used, such as
-UPNP_GetConnectionTypeInfo(3), UPNP_AddPortMapping(3), etc...
-.SH "HEADER FILES"
-.IP miniupnpc.h
-That's the main header file for the miniupnpc library API.
-It contains all the functions and structures related to device discovery.
-.IP upnpcommands.h
-This header file contain the UPnP IGD methods that are accessible
-through the miniupnpc API. The name of the C functions are matching
-the UPnP methods names. ie: GetGenericPortMappingEntry is
-UPNP_GetGenericPortMappingEntry.
-.SH "API FUNCTIONS"
-.IP "struct UPNPDev * upnpDiscover(int delay, const char * multicastif, const char * minissdpdsock, int sameport, int ipv6, int * error);"
-execute the discovery process.
-delay (in millisecond) is the maximum time for waiting any device response.
-If available, device list will be obtained from MiniSSDPd.
-Default path for minissdpd socket will be used if minissdpdsock argument is NULL.
-If multicastif is not NULL, it will be used instead of the default multicast interface for sending SSDP discover packets.
-If sameport is not null, SSDP packets will be sent from the source port 1900 (same as destination port) otherwise system assign a source port.
-If ipv6 is not 0, IPv6 is used instead of IPv4 for the discovery process.
-.IP "void freeUPNPDevlist(struct UPNPDev * devlist);"
-free the list returned by upnpDiscover().
-.IP "int UPNP_GetValidIGD(struct UPNPDev * devlist, struct UPNPUrls * urls, struct IGDdatas * data, char * lanaddr, int lanaddrlen);"
-browse the list of device returned by upnpDiscover(), find
-a live UPnP internet gateway device and fill structures passed as arguments
-with data used for UPNP methods invokation.
-.IP "int UPNP_GetIGDFromUrl(const char * rootdescurl, struct UPNPUrls * urls, struct IGDdatas * data, char * lanaddr, int lanaddrlen);"
-permit to bypass the upnpDiscover() call if the xml root description
-URL of the UPnP IGD is known.
-Fill structures passed as arguments
-with data used for UPNP methods invokation.
-.IP "void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);"
-.IP "void FreeUPNPUrls(struct UPNPUrls *);"
-
-.SH "SEE ALSO"
-minissdpd(1)
-.SH BUGS
diff --git a/contrib/miniupnpc/mingw32make.bat b/contrib/miniupnpc/mingw32make.bat
deleted file mode 100644
index c5d3cc4f..00000000
--- a/contrib/miniupnpc/mingw32make.bat
+++ /dev/null
@@ -1,8 +0,0 @@
-@mingw32-make -f Makefile.mingw %1
-@if errorlevel 1 goto end
-@if not exist upnpc-static.exe goto end
-@strip upnpc-static.exe
-@upx --best upnpc-static.exe
-@strip upnpc-shared.exe
-@upx --best upnpc-shared.exe
-:end
diff --git a/contrib/miniupnpc/minihttptestserver.c b/contrib/miniupnpc/minihttptestserver.c
deleted file mode 100644
index b7193611..00000000
--- a/contrib/miniupnpc/minihttptestserver.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/* $Id: minihttptestserver.c,v 1.13 2012/05/29 13:03:07 nanard Exp $ */
-/* Project : miniUPnP
- * Author : Thomas Bernard
- * Copyright (c) 2011-2012 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define CRAP_LENGTH (2048)
-
-volatile sig_atomic_t quit = 0;
-volatile sig_atomic_t child_to_wait_for = 0;
-
-/**
- * signal handler for SIGCHLD (child status has changed)
- */
-void handle_signal_chld(int sig)
-{
- printf("handle_signal_chld(%d)\n", sig);
- ++child_to_wait_for;
-}
-
-/**
- * signal handler for SIGINT (CRTL C)
- */
-#if 0
-void handle_signal_int(int sig)
-{
- printf("handle_signal_int(%d)\n", sig);
- quit = 1;
-}
-#endif
-
-/**
- * build a text/plain content of the specified length
- */
-void build_content(char * p, int n)
-{
- char line_buffer[80];
- int k;
- int i = 0;
-
- while(n > 0) {
- k = snprintf(line_buffer, sizeof(line_buffer),
- "%04d_ABCDEFGHIJKL_This_line_is_64_bytes_long_ABCDEFGHIJKL_%04d\r\n",
- i, i);
- if(k != 64) {
- fprintf(stderr, "snprintf() returned %d in build_content()\n", k);
- }
- ++i;
- if(n >= 64) {
- memcpy(p, line_buffer, 64);
- p += 64;
- n -= 64;
- } else {
- memcpy(p, line_buffer, n);
- p += n;
- n = 0;
- }
- }
-}
-
-/**
- * build crappy content
- */
-void build_crap(char * p, int n)
-{
- static const char crap[] = "_CRAP_\r\n";
- int i;
-
- while(n > 0) {
- i = sizeof(crap) - 1;
- if(i > n)
- i = n;
- memcpy(p, crap, i);
- p += i;
- n -= i;
- }
-}
-
-/**
- * build chunked response.
- * return a malloc'ed buffer
- */
-char * build_chunked_response(int content_length, int * response_len) {
- char * response_buffer;
- char * content_buffer;
- int buffer_length;
- int i, n;
-
- /* allocate to have some margin */
- buffer_length = 256 + content_length + (content_length >> 4);
- response_buffer = malloc(buffer_length);
- *response_len = snprintf(response_buffer, buffer_length,
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/plain\r\n"
- "Transfer-Encoding: chunked\r\n"
- "\r\n");
-
- /* build the content */
- content_buffer = malloc(content_length);
- build_content(content_buffer, content_length);
-
- /* chunk it */
- i = 0;
- while(i < content_length) {
- n = (rand() % 199) + 1;
- if(i + n > content_length) {
- n = content_length - i;
- }
- /* TODO : check buffer size ! */
- *response_len += snprintf(response_buffer + *response_len,
- buffer_length - *response_len,
- "%x\r\n", n);
- memcpy(response_buffer + *response_len, content_buffer + i, n);
- *response_len += n;
- i += n;
- response_buffer[(*response_len)++] = '\r';
- response_buffer[(*response_len)++] = '\n';
- }
- /* the last chunk : "0\r\n" a empty body and then
- * the final "\r\n" */
- memcpy(response_buffer + *response_len, "0\r\n\r\n", 5);
- *response_len += 5;
- free(content_buffer);
-
- printf("resp_length=%d buffer_length=%d content_length=%d\n",
- *response_len, buffer_length, content_length);
- return response_buffer;
-}
-
-enum modes { MODE_INVALID, MODE_CHUNKED, MODE_ADDCRAP, MODE_NORMAL };
-const struct {
- const enum modes mode;
- const char * text;
-} modes_array[] = {
- {MODE_CHUNKED, "chunked"},
- {MODE_ADDCRAP, "addcrap"},
- {MODE_NORMAL, "normal"},
- {MODE_INVALID, NULL}
-};
-
-/**
- * write the response with random behaviour !
- */
-void send_response(int c, const char * buffer, int len)
-{
- int n;
- while(len > 0) {
- n = (rand() % 99) + 1;
- if(n > len)
- n = len;
- n = write(c, buffer, n);
- if(n < 0) {
- if(errno != EINTR) {
- perror("write");
- return;
- }
- /* if errno == EINTR, try again */
- } else {
- len -= n;
- buffer += n;
- }
- usleep(10000); /* 10ms */
- }
-}
-
-/**
- * handle the HTTP connection
- */
-void handle_http_connection(int c)
-{
- char request_buffer[2048];
- int request_len = 0;
- int headers_found = 0;
- int n, i;
- char request_method[16];
- char request_uri[256];
- char http_version[16];
- char * p;
- char * response_buffer;
- int response_len;
- enum modes mode;
- int content_length = 16*1024;
-
- /* read the request */
- while(request_len < (int)sizeof(request_buffer) && !headers_found) {
- n = read(c,
- request_buffer + request_len,
- sizeof(request_buffer) - request_len);
- if(n < 0) {
- perror("read");
- return;
- } else if(n==0) {
- /* remote host closed the connection */
- break;
- } else {
- request_len += n;
- for(i = 0; i < request_len - 3; i++) {
- if(0 == memcmp(request_buffer + i, "\r\n\r\n", 4)) {
- /* found the end of headers */
- headers_found = 1;
- break;
- }
- }
- }
- }
- if(!headers_found) {
- /* error */
- return;
- }
- printf("headers :\n%.*s", request_len, request_buffer);
- /* the request have been received, now parse the request line */
- p = request_buffer;
- for(i = 0; i < (int)sizeof(request_method) - 1; i++) {
- if(*p == ' ' || *p == '\r')
- break;
- request_method[i] = *p;
- ++p;
- }
- request_method[i] = '\0';
- while(*p == ' ')
- p++;
- for(i = 0; i < (int)sizeof(request_uri) - 1; i++) {
- if(*p == ' ' || *p == '\r')
- break;
- request_uri[i] = *p;
- ++p;
- }
- request_uri[i] = '\0';
- while(*p == ' ')
- p++;
- for(i = 0; i < (int)sizeof(http_version) - 1; i++) {
- if(*p == ' ' || *p == '\r')
- break;
- http_version[i] = *p;
- ++p;
- }
- http_version[i] = '\0';
- printf("Method = %s, URI = %s, %s\n",
- request_method, request_uri, http_version);
- /* check if the request method is allowed */
- if(0 != strcmp(request_method, "GET")) {
- const char response405[] = "HTTP/1.1 405 Method Not Allowed\r\n"
- "Allow: GET\r\n\r\n";
- const char * pc;
- /* 405 Method Not Allowed */
- /* The response MUST include an Allow header containing a list
- * of valid methods for the requested resource. */
- n = sizeof(response405) - 1;
- pc = response405;
- while(n > 0) {
- i = write(c, pc, n);
- if(i<0) {
- if(errno != EINTR) {
- perror("write");
- return;
- }
- } else {
- n -= i;
- pc += i;
- }
- }
- return;
- }
-
- mode = MODE_INVALID;
- /* use the request URI to know what to do */
- for(i = 0; modes_array[i].mode != MODE_INVALID; i++) {
- if(strstr(request_uri, modes_array[i].text)) {
- mode = modes_array[i].mode; /* found */
- break;
- }
- }
-
- switch(mode) {
- case MODE_CHUNKED:
- response_buffer = build_chunked_response(content_length, &response_len);
- break;
- case MODE_ADDCRAP:
- response_len = content_length+256;
- response_buffer = malloc(response_len);
- n = snprintf(response_buffer, response_len,
- "HTTP/1.1 200 OK\r\n"
- "Server: minihttptestserver\r\n"
- "Content-Type: text/plain\r\n"
- "Content-Length: %d\r\n"
- "\r\n", content_length);
- response_len = content_length+n+CRAP_LENGTH;
- response_buffer = realloc(response_buffer, response_len);
- build_content(response_buffer + n, content_length);
- build_crap(response_buffer + n + content_length, CRAP_LENGTH);
- break;
- default:
- response_len = content_length+256;
- response_buffer = malloc(response_len);
- n = snprintf(response_buffer, response_len,
- "HTTP/1.1 200 OK\r\n"
- "Server: minihttptestserver\r\n"
- "Content-Type: text/plain\r\n"
- "\r\n");
- response_len = content_length+n;
- response_buffer = realloc(response_buffer, response_len);
- build_content(response_buffer + n, response_len - n);
- }
-
- if(response_buffer) {
- send_response(c, response_buffer, response_len);
- free(response_buffer);
- } else {
- /* Error 500 */
- }
-}
-
-/**
- */
-int main(int argc, char * * argv) {
- int ipv6 = 0;
- int s, c, i;
- unsigned short port = 0;
- struct sockaddr_storage server_addr;
- socklen_t server_addrlen;
- struct sockaddr_storage client_addr;
- socklen_t client_addrlen;
- pid_t pid;
- int child = 0;
- int status;
- const char * expected_file_name = NULL;
-
- for(i = 1; i < argc; i++) {
- if(argv[i][0] == '-') {
- switch(argv[i][1]) {
- case '6':
- ipv6 = 1;
- break;
- case 'e':
- /* write expected file ! */
- expected_file_name = argv[++i];
- break;
- case 'p':
- /* port */
- if(++i < argc) {
- port = (unsigned short)atoi(argv[i]);
- }
- break;
- default:
- fprintf(stderr, "unknown command line switch '%s'\n", argv[i]);
- }
- } else {
- fprintf(stderr, "unkown command line argument '%s'\n", argv[i]);
- }
- }
-
- srand(time(NULL));
- signal(SIGCHLD, handle_signal_chld);
-#if 0
- signal(SIGINT, handle_signal_int);
-#endif
-
- s = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
- if(s < 0) {
- perror("socket");
- return 1;
- }
- memset(&server_addr, 0, sizeof(struct sockaddr_storage));
- memset(&client_addr, 0, sizeof(struct sockaddr_storage));
- if(ipv6) {
- struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr;
- addr->sin6_family = AF_INET6;
- addr->sin6_port = htons(port);
- addr->sin6_addr = in6addr_loopback;
- } else {
- struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr;
- addr->sin_family = AF_INET;
- addr->sin_port = htons(port);
- addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- }
- if(bind(s, (struct sockaddr *)&server_addr,
- ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) < 0) {
- perror("bind");
- return 1;
- }
- if(listen(s, 5) < 0) {
- perror("listen");
- }
- if(port == 0) {
- server_addrlen = sizeof(struct sockaddr_storage);
- if(getsockname(s, (struct sockaddr *)&server_addr, &server_addrlen) < 0) {
- perror("getsockname");
- return 1;
- }
- if(ipv6) {
- struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr;
- port = ntohs(addr->sin6_port);
- } else {
- struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr;
- port = ntohs(addr->sin_port);
- }
- printf("Listening on port %hu\n", port);
- fflush(stdout);
- }
-
- /* write expected file */
- if(expected_file_name) {
- FILE * f;
- f = fopen(expected_file_name, "wb");
- if(f) {
- char * buffer;
- buffer = malloc(16*1024);
- build_content(buffer, 16*1024);
- i = fwrite(buffer, 1, 16*1024, f);
- if(i != 16*1024) {
- fprintf(stderr, "error writing to file %s : %dbytes written (out of %d)\n", expected_file_name, i, 16*1024);
- }
- free(buffer);
- fclose(f);
- } else {
- fprintf(stderr, "error opening file %s for writing\n", expected_file_name);
- }
- }
-
- /* fork() loop */
- while(!child && !quit) {
- while(child_to_wait_for > 0) {
- pid = wait(&status);
- if(pid < 0) {
- perror("wait");
- } else {
- printf("child(%d) terminated with status %d\n", pid, status);
- }
- --child_to_wait_for;
- }
- /* TODO : add a select() call in order to handle the case
- * when a signal is caught */
- client_addrlen = sizeof(struct sockaddr_storage);
- c = accept(s, (struct sockaddr *)&client_addr,
- &client_addrlen);
- if(c < 0) {
- perror("accept");
- return 1;
- }
- printf("accept...\n");
- pid = fork();
- if(pid < 0) {
- perror("fork");
- return 1;
- } else if(pid == 0) {
- /* child */
- child = 1;
- close(s);
- s = -1;
- handle_http_connection(c);
- }
- close(c);
- }
- if(s >= 0) {
- close(s);
- s = -1;
- }
- if(!child) {
- while(child_to_wait_for > 0) {
- pid = wait(&status);
- if(pid < 0) {
- perror("wait");
- } else {
- printf("child(%d) terminated with status %d\n", pid, status);
- }
- --child_to_wait_for;
- }
- printf("Bye...\n");
- }
- return 0;
-}
-
diff --git a/contrib/miniupnpc/minisoap.c b/contrib/miniupnpc/minisoap.c
deleted file mode 100644
index e45a481a..00000000
--- a/contrib/miniupnpc/minisoap.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $Id: minisoap.c,v 1.22 2012/01/21 13:30:31 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2012 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- *
- * Minimal SOAP implementation for UPnP protocol.
- */
-#include
-#include
-#ifdef _WIN32
-#include
-#include
-#define snprintf _snprintf
-#else
-#include
-#include
-#include
-#endif
-#include "minisoap.h"
-#include "miniupnpcstrings.h"
-
-/* only for malloc */
-#include
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-/* httpWrite sends the headers and the body to the socket
- * and returns the number of bytes sent */
-static int
-httpWrite(int fd, const char * body, int bodysize,
- const char * headers, int headerssize)
-{
- int n = 0;
- /*n = write(fd, headers, headerssize);*/
- /*if(bodysize>0)
- n += write(fd, body, bodysize);*/
- /* Note : my old linksys router only took into account
- * soap request that are sent into only one packet */
- char * p;
- /* TODO: AVOID MALLOC */
- p = malloc(headerssize+bodysize);
- if(!p)
- return 0;
- memcpy(p, headers, headerssize);
- memcpy(p+headerssize, body, bodysize);
- /*n = write(fd, p, headerssize+bodysize);*/
- n = send(fd, p, headerssize+bodysize, 0);
- if(n<0) {
- PRINT_SOCKET_ERROR("send");
- }
- /* disable send on the socket */
- /* draytek routers dont seems to like that... */
-#if 0
-#ifdef _WIN32
- if(shutdown(fd, SD_SEND)<0) {
-#else
- if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/
-#endif
- PRINT_SOCKET_ERROR("shutdown");
- }
-#endif
- free(p);
- return n;
-}
-
-/* self explanatory */
-int soapPostSubmit(int fd,
- const char * url,
- const char * host,
- unsigned short port,
- const char * action,
- const char * body,
- const char * httpversion)
-{
- int bodysize;
- char headerbuf[512];
- int headerssize;
- char portstr[8];
- bodysize = (int)strlen(body);
- /* We are not using keep-alive HTTP connections.
- * HTTP/1.1 needs the header Connection: close to do that.
- * This is the default with HTTP/1.0
- * Using HTTP/1.1 means we need to support chunked transfer-encoding :
- * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked
- * transfer encoding. */
- /* Connection: Close is normally there only in HTTP/1.1 but who knows */
- portstr[0] = '\0';
- if(port != 80)
- snprintf(portstr, sizeof(portstr), ":%hu", port);
- headerssize = snprintf(headerbuf, sizeof(headerbuf),
- "POST %s HTTP/%s\r\n"
- "Host: %s%s\r\n"
- "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
- "Content-Length: %d\r\n"
- "Content-Type: text/xml\r\n"
- "SOAPAction: \"%s\"\r\n"
- "Connection: Close\r\n"
- "Cache-Control: no-cache\r\n" /* ??? */
- "Pragma: no-cache\r\n"
- "\r\n",
- url, httpversion, host, portstr, bodysize, action);
-#ifdef DEBUG
- /*printf("SOAP request : headersize=%d bodysize=%d\n",
- headerssize, bodysize);
- */
- printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n",
- url, httpversion, host, portstr);
- printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
- printf("Headers :\n%s", headerbuf);
- printf("Body :\n%s\n", body);
-#endif
- return httpWrite(fd, body, bodysize, headerbuf, headerssize);
-}
-
-
diff --git a/contrib/miniupnpc/minisoap.h b/contrib/miniupnpc/minisoap.h
deleted file mode 100644
index 14c859d1..00000000
--- a/contrib/miniupnpc/minisoap.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: minisoap.h,v 1.5 2012/09/27 15:42:10 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-#ifndef MINISOAP_H_INCLUDED
-#define MINISOAP_H_INCLUDED
-
-/*int httpWrite(int, const char *, int, const char *);*/
-int soapPostSubmit(int, const char *, const char *, unsigned short,
- const char *, const char *, const char *);
-
-#endif
-
diff --git a/contrib/miniupnpc/minissdpc.c b/contrib/miniupnpc/minissdpc.c
deleted file mode 100644
index c4913fb8..00000000
--- a/contrib/miniupnpc/minissdpc.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* $Id: minissdpc.c,v 1.16 2012/03/05 19:42:46 nanard Exp $ */
-/* Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2012 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-/*#include */
-#include
-#include
-#include
-#include
-#include
-#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
-#ifdef _WIN32
-#include
-#include
-#include
-#include
-#include
-#endif
-#if defined(__amigaos__) || defined(__amigaos4__)
-#include
-#endif
-#if defined(__amigaos__)
-#define uint16_t unsigned short
-#endif
-/* Hack */
-#define UNIX_PATH_LEN 108
-struct sockaddr_un {
- uint16_t sun_family;
- char sun_path[UNIX_PATH_LEN];
-};
-#else
-#include
-#include
-#endif
-
-#include "minissdpc.h"
-#include "miniupnpc.h"
-
-#include "codelength.h"
-
-struct UPNPDev *
-getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
-{
- struct UPNPDev * tmp;
- struct UPNPDev * devlist = NULL;
- unsigned char buffer[2048];
- ssize_t n;
- unsigned char * p;
- unsigned char * url;
- unsigned int i;
- unsigned int urlsize, stsize, usnsize, l;
- int s;
- struct sockaddr_un addr;
-
- s = socket(AF_UNIX, SOCK_STREAM, 0);
- if(s < 0)
- {
- /*syslog(LOG_ERR, "socket(unix): %m");*/
- perror("socket(unix)");
- return NULL;
- }
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
- /* TODO : check if we need to handle the EINTR */
- if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
- {
- /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
- close(s);
- return NULL;
- }
- stsize = strlen(devtype);
- buffer[0] = 1; /* request type 1 : request devices/services by type */
- p = buffer + 1;
- l = stsize; CODELENGTH(l, p);
- if(p + stsize > buffer + sizeof(buffer))
- {
- /* devtype is too long ! */
- close(s);
- return NULL;
- }
- memcpy(p, devtype, stsize);
- p += stsize;
- if(write(s, buffer, p - buffer) < 0)
- {
- /*syslog(LOG_ERR, "write(): %m");*/
- perror("minissdpc.c: write()");
- close(s);
- return NULL;
- }
- n = read(s, buffer, sizeof(buffer));
- if(n<=0)
- {
- perror("minissdpc.c: read()");
- close(s);
- return NULL;
- }
- p = buffer + 1;
- for(i = 0; i < buffer[0]; i++)
- {
- if(p+2>=buffer+sizeof(buffer))
- break;
- DECODELENGTH(urlsize, p);
- if(p+urlsize+2>=buffer+sizeof(buffer))
- break;
- url = p;
- p += urlsize;
- DECODELENGTH(stsize, p);
- if(p+stsize+2>=buffer+sizeof(buffer))
- break;
- tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
- tmp->pNext = devlist;
- tmp->descURL = tmp->buffer;
- tmp->st = tmp->buffer + 1 + urlsize;
- memcpy(tmp->buffer, url, urlsize);
- tmp->buffer[urlsize] = '\0';
- memcpy(tmp->buffer + urlsize + 1, p, stsize);
- p += stsize;
- tmp->buffer[urlsize+1+stsize] = '\0';
- devlist = tmp;
- /* added for compatibility with recent versions of MiniSSDPd
- * >= 2007/12/19 */
- DECODELENGTH(usnsize, p);
- p += usnsize;
- if(p>buffer + sizeof(buffer))
- break;
- }
- close(s);
- return devlist;
-}
-
diff --git a/contrib/miniupnpc/minissdpc.h b/contrib/miniupnpc/minissdpc.h
deleted file mode 100644
index 915b0026..00000000
--- a/contrib/miniupnpc/minissdpc.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: minissdpc.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2007 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINISSDPC_H_INCLUDED
-#define MINISSDPC_H_INCLUDED
-
-struct UPNPDev *
-getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath);
-
-#endif
-
diff --git a/contrib/miniupnpc/miniupnpc.c b/contrib/miniupnpc/miniupnpc.c
deleted file mode 100644
index f661c2e6..00000000
--- a/contrib/miniupnpc/miniupnpc.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-/* $Id: miniupnpc.c,v 1.117 2014/01/31 14:19:13 nanard Exp $ */
-/* Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2014 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENSE file. */
-#define __EXTENSIONS__ 1
-#if !defined(MACOSX) && !defined(__sun)
-#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__)
-#ifndef __cplusplus
-#define _XOPEN_SOURCE 600
-#endif
-#endif
-#ifndef __BSD_VISIBLE
-#define __BSD_VISIBLE 1
-#endif
-#endif
-
-#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(MACOSX) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun)
-#define HAS_IP_MREQN
-#endif
-
-#include
-#include
-#include
-#ifdef _WIN32
-/* Win32 Specific includes and defines */
-#include
-#include
-#include
-#include
-#define snprintf _snprintf
-#define strdup _strdup
-#ifndef strncasecmp
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define strncasecmp _memicmp
-#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#define strncasecmp memicmp
-#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#endif /* #ifndef strncasecmp */
-#define MAXHOSTNAMELEN 64
-#else /* #ifdef _WIN32 */
-/* Standard POSIX includes */
-#include
-#if defined(__amigaos__) && !defined(__amigaos4__)
-/* Amiga OS 3 specific stuff */
-#define socklen_t int
-#else
-#include
-#endif
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#if !defined(__amigaos__) && !defined(__amigaos4__)
-#include
-#endif
-#include
-#include
-#define closesocket close
-#endif /* #else _WIN32 */
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-#include
-#endif
-#if defined(__amigaos__) || defined(__amigaos4__)
-/* Amiga OS specific stuff */
-#define TIMEVAL struct timeval
-#endif
-
-
-#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN)
-/* Several versions of glibc don't define this structure, define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */
-struct ip_mreqn
-{
- struct in_addr imr_multiaddr; /* IP multicast address of group */
- struct in_addr imr_address; /* local IP address of interface */
- int imr_ifindex; /* Interface index */
-};
-#endif
-
-#include "miniupnpc.h"
-#include "minissdpc.h"
-#include "miniwget.h"
-#include "minisoap.h"
-#include "minixml.h"
-#include "upnpcommands.h"
-#include "connecthostport.h"
-#include "receivedata.h"
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#define SOAPPREFIX "s"
-#define SERVICEPREFIX "u"
-#define SERVICEPREFIX2 'u'
-
-/* root description parsing */
-LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
-{
- struct xmlparser parser;
- /* xmlparser object */
- parser.xmlstart = buffer;
- parser.xmlsize = bufsize;
- parser.data = data;
- parser.starteltfunc = IGDstartelt;
- parser.endeltfunc = IGDendelt;
- parser.datafunc = IGDdata;
- parser.attfunc = 0;
- parsexml(&parser);
-#ifdef DEBUG
- printIGD(data);
-#endif
-}
-
-/* simpleUPnPcommand2 :
- * not so simple !
- * return values :
- * pointer - OK
- * NULL - error */
-char * simpleUPnPcommand2(int s, const char * url, const char * service,
- const char * action, struct UPNParg * args,
- int * bufsize, const char * httpversion)
-{
- char hostname[MAXHOSTNAMELEN+1];
- unsigned short port = 0;
- char * path;
- char soapact[128];
- char soapbody[2048];
- char * buf;
- int n;
-
- *bufsize = 0;
- snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
- if(args==NULL)
- {
- /*soapbodylen = */snprintf(soapbody, sizeof(soapbody),
- "\r\n"
- "<" SOAPPREFIX ":Envelope "
- "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
- SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
- "<" SOAPPREFIX ":Body>"
- "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">"
- "" SERVICEPREFIX ":%s>"
- "" SOAPPREFIX ":Body>" SOAPPREFIX ":Envelope>"
- "\r\n", action, service, action);
- }
- else
- {
- char * p;
- const char * pe, * pv;
- int soapbodylen;
- soapbodylen = snprintf(soapbody, sizeof(soapbody),
- "\r\n"
- "<" SOAPPREFIX ":Envelope "
- "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
- SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
- "<" SOAPPREFIX ":Body>"
- "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">",
- action, service);
- p = soapbody + soapbodylen;
- while(args->elt)
- {
- /* check that we are never overflowing the string... */
- if(soapbody + sizeof(soapbody) <= p + 100)
- {
- /* we keep a margin of at least 100 bytes */
- return NULL;
- }
- *(p++) = '<';
- pe = args->elt;
- while(*pe)
- *(p++) = *(pe++);
- *(p++) = '>';
- if((pv = args->val))
- {
- while(*pv)
- *(p++) = *(pv++);
- }
- *(p++) = '<';
- *(p++) = '/';
- pe = args->elt;
- while(*pe)
- *(p++) = *(pe++);
- *(p++) = '>';
- args++;
- }
- *(p++) = '<';
- *(p++) = '/';
- *(p++) = SERVICEPREFIX2;
- *(p++) = ':';
- pe = action;
- while(*pe)
- *(p++) = *(pe++);
- strncpy(p, ">" SOAPPREFIX ":Body>" SOAPPREFIX ":Envelope>\r\n",
- soapbody + sizeof(soapbody) - p);
- }
- if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
- if(s < 0) {
- s = connecthostport(hostname, port, 0);
- if(s < 0) {
- /* failed to connect */
- return NULL;
- }
- }
-
- n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion);
- if(n<=0) {
-#ifdef DEBUG
- printf("Error sending SOAP request\n");
-#endif
- closesocket(s);
- return NULL;
- }
-
- buf = getHTTPResponse(s, bufsize);
-#ifdef DEBUG
- if(*bufsize > 0 && buf)
- {
- printf("SOAP Response :\n%.*s\n", *bufsize, buf);
- }
-#endif
- closesocket(s);
- return buf;
-}
-
-/* simpleUPnPcommand :
- * not so simple !
- * return values :
- * pointer - OK
- * NULL - error */
-char * simpleUPnPcommand(int s, const char * url, const char * service,
- const char * action, struct UPNParg * args,
- int * bufsize)
-{
- char * buf;
-
-#if 1
- buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
-#else
- buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
- if (!buf || *bufsize == 0)
- {
-#if DEBUG
- printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
-#endif
- buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
- }
-#endif
- return buf;
-}
-
-/* parseMSEARCHReply()
- * the last 4 arguments are filled during the parsing :
- * - location/locationsize : "location:" field of the SSDP reply packet
- * - st/stsize : "st:" field of the SSDP reply packet.
- * The strings are NOT null terminated */
-static void
-parseMSEARCHReply(const char * reply, int size,
- const char * * location, int * locationsize,
- const char * * st, int * stsize)
-{
- int a, b, i;
- i = 0;
- a = i; /* start of the line */
- b = 0; /* end of the "header" (position of the colon) */
- while(isin6_family = AF_INET6;
- if(sameport)
- p->sin6_port = htons(PORT);
- p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */
- } else {
- struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
- p->sin_family = AF_INET;
- if(sameport)
- p->sin_port = htons(PORT);
- p->sin_addr.s_addr = INADDR_ANY;
- }
-#ifdef _WIN32
-/* This code could help us to use the right Network interface for
- * SSDP multicast traffic */
-/* Get IP associated with the index given in the ip_forward struct
- * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
- if(!ipv6
- && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) {
- DWORD dwRetVal = 0;
- PMIB_IPADDRTABLE pIPAddrTable;
- DWORD dwSize = 0;
-#ifdef DEBUG
- IN_ADDR IPAddr;
-#endif
- int i;
-#ifdef DEBUG
- printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop);
-#endif
- pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE));
- if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
- free(pIPAddrTable);
- pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize);
- }
- if(pIPAddrTable) {
- dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
-#ifdef DEBUG
- printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries);
-#endif
- for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) {
-#ifdef DEBUG
- printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex);
- IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr;
- printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr) );
- IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask;
- printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr) );
- IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr;
- printf("\tBroadCast[%d]: \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr);
- printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize);
- printf("\tType and State[%d]:", i);
- printf("\n");
-#endif
- if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) {
- /* Set the address of this interface to be used */
- struct in_addr mc_if;
- memset(&mc_if, 0, sizeof(mc_if));
- mc_if.s_addr = pIPAddrTable->table[i].dwAddr;
- if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) {
- PRINT_SOCKET_ERROR("setsockopt");
- }
- ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr;
-#ifndef DEBUG
- break;
-#endif
- }
- }
- free(pIPAddrTable);
- pIPAddrTable = NULL;
- }
- }
-#endif
-
-#ifdef _WIN32
- if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
-#else
- if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
-#endif
- {
- if(error)
- *error = UPNPDISCOVER_SOCKET_ERROR;
- PRINT_SOCKET_ERROR("setsockopt");
- return NULL;
- }
-
- if(multicastif)
- {
- if(ipv6) {
-#if !defined(_WIN32)
- /* according to MSDN, if_nametoindex() is supported since
- * MS Windows Vista and MS Windows Server 2008.
- * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
- unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */
- if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(&ifindex)) < 0)
- {
- PRINT_SOCKET_ERROR("setsockopt");
- }
-#else
-#ifdef DEBUG
- printf("Setting of multicast interface not supported in IPv6 under Windows.\n");
-#endif
-#endif
- } else {
- struct in_addr mc_if;
- mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
- if(mc_if.s_addr != INADDR_NONE)
- {
- ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
- if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
- {
- PRINT_SOCKET_ERROR("setsockopt");
- }
- } else {
-#ifdef HAS_IP_MREQN
- /* was not an ip address, try with an interface name */
- struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */
- memset(&reqn, 0, sizeof(struct ip_mreqn));
- reqn.imr_ifindex = if_nametoindex(multicastif);
- if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0)
- {
- PRINT_SOCKET_ERROR("setsockopt");
- }
-#else
-#ifdef DEBUG
- printf("Setting of multicast interface not supported with interface name.\n");
-#endif
-#endif
- }
- }
- }
-
- /* Before sending the packed, we first "bind" in order to be able
- * to receive the response */
- if (bind(sudp, (const struct sockaddr *)&sockudp_r,
- ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0)
- {
- if(error)
- *error = UPNPDISCOVER_SOCKET_ERROR;
- PRINT_SOCKET_ERROR("bind");
- closesocket(sudp);
- return NULL;
- }
-
- if(error)
- *error = UPNPDISCOVER_SUCCESS;
- /* Calculating maximum response time in seconds */
- mx = ((unsigned int)delay) / 1000u;
- if(mx == 0) {
- mx = 1;
- delay = 1000;
- }
- /* receiving SSDP response packet */
- for(n = 0; deviceList[deviceIndex]; deviceIndex++)
- {
- if(n == 0)
- {
- /* sending the SSDP M-SEARCH packet */
- n = snprintf(bufr, sizeof(bufr),
- MSearchMsgFmt,
- ipv6 ?
- (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]")
- : UPNP_MCAST_ADDR,
- deviceList[deviceIndex], mx);
-#ifdef DEBUG
- printf("Sending %s", bufr);
-#endif
-#ifdef NO_GETADDRINFO
- /* the following code is not using getaddrinfo */
- /* emission */
- memset(&sockudp_w, 0, sizeof(struct sockaddr_storage));
- if(ipv6) {
- struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w;
- p->sin6_family = AF_INET6;
- p->sin6_port = htons(PORT);
- inet_pton(AF_INET6,
- linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR,
- &(p->sin6_addr));
- } else {
- struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w;
- p->sin_family = AF_INET;
- p->sin_port = htons(PORT);
- p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
- }
- n = sendto(sudp, bufr, n, 0,
- &sockudp_w,
- ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
- if (n < 0) {
- if(error)
- *error = UPNPDISCOVER_SOCKET_ERROR;
- PRINT_SOCKET_ERROR("sendto");
- break;
- }
-#else /* #ifdef NO_GETADDRINFO */
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */
- hints.ai_socktype = SOCK_DGRAM;
- /*hints.ai_flags = */
- if ((rv = getaddrinfo(ipv6
- ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR)
- : UPNP_MCAST_ADDR,
- XSTR(PORT), &hints, &servinfo)) != 0) {
- if(error)
- *error = UPNPDISCOVER_SOCKET_ERROR;
-#ifdef _WIN32
- fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
-#else
- fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
-#endif
- break;
- }
- for(p = servinfo; p; p = p->ai_next) {
- n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
- if (n < 0) {
-#ifdef DEBUG
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
- sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
- fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf);
- }
-#endif
- PRINT_SOCKET_ERROR("sendto");
- continue;
- }
- }
- freeaddrinfo(servinfo);
- if(n < 0) {
- if(error)
- *error = UPNPDISCOVER_SOCKET_ERROR;
- break;
- }
-#endif /* #ifdef NO_GETADDRINFO */
- }
- /* Waiting for SSDP REPLY packet to M-SEARCH */
- n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
- if (n < 0) {
- /* error */
- if(error)
- *error = UPNPDISCOVER_SOCKET_ERROR;
- break;
- } else if (n == 0) {
- /* no data or Time Out */
- if (devlist) {
- /* no more device type to look for... */
- if(error)
- *error = UPNPDISCOVER_SUCCESS;
- break;
- }
- if(ipv6) {
- if(linklocal) {
- linklocal = 0;
- --deviceIndex;
- } else {
- linklocal = 1;
- }
- }
- } else {
- const char * descURL=NULL;
- int urlsize=0;
- const char * st=NULL;
- int stsize=0;
- /*printf("%d byte(s) :\n%s\n", n, bufr);*/ /* affichage du message */
- parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize);
- if(st&&descURL)
- {
-#ifdef DEBUG
- printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",
- stsize, st, urlsize, descURL);
-#endif
- for(tmp=devlist; tmp; tmp = tmp->pNext) {
- if(memcmp(tmp->descURL, descURL, urlsize) == 0 &&
- tmp->descURL[urlsize] == '\0' &&
- memcmp(tmp->st, st, stsize) == 0 &&
- tmp->st[stsize] == '\0')
- break;
- }
- /* at the exit of the loop above, tmp is null if
- * no duplicate device was found */
- if(tmp)
- continue;
- tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
- if(!tmp) {
- /* memory allocation error */
- if(error)
- *error = UPNPDISCOVER_MEMORY_ERROR;
- break;
- }
- tmp->pNext = devlist;
- tmp->descURL = tmp->buffer;
- tmp->st = tmp->buffer + 1 + urlsize;
- memcpy(tmp->buffer, descURL, urlsize);
- tmp->buffer[urlsize] = '\0';
- memcpy(tmp->buffer + urlsize + 1, st, stsize);
- tmp->buffer[urlsize+1+stsize] = '\0';
- tmp->scope_id = scope_id;
- devlist = tmp;
- }
- }
- }
- closesocket(sudp);
- return devlist;
-}
-
-/* freeUPNPDevlist() should be used to
- * free the chained list returned by upnpDiscover() */
-LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist)
-{
- struct UPNPDev * next;
- while(devlist)
- {
- next = devlist->pNext;
- free(devlist);
- devlist = next;
- }
-}
-
-static void
-url_cpy_or_cat(char * dst, const char * src, int n)
-{
- if( (src[0] == 'h')
- &&(src[1] == 't')
- &&(src[2] == 't')
- &&(src[3] == 'p')
- &&(src[4] == ':')
- &&(src[5] == '/')
- &&(src[6] == '/'))
- {
- strncpy(dst, src, n);
- }
- else
- {
- int l = strlen(dst);
- if(src[0] != '/')
- dst[l++] = '/';
- if(l<=n)
- strncpy(dst + l, src, n - l);
- }
-}
-
-/* Prepare the Urls for usage...
- */
-LIBSPEC void
-GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
- const char * descURL, unsigned int scope_id)
-{
- char * p;
- int n1, n2, n3, n4;
-#ifdef IF_NAMESIZE
- char ifname[IF_NAMESIZE];
-#else
- char scope_str[8];
-#endif
-
- n1 = strlen(data->urlbase);
- if(n1==0)
- n1 = strlen(descURL);
- if(scope_id != 0) {
-#ifdef IF_NAMESIZE
- if(if_indextoname(scope_id, ifname)) {
- n1 += 3 + strlen(ifname); /* 3 == strlen(%25) */
- }
-#else
- /* under windows, scope is numerical */
- snprintf(scope_str, sizeof(scope_str), "%u", scope_id);
-#endif
- }
- n1 += 2; /* 1 byte more for Null terminator, 1 byte for '/' if needed */
- n2 = n1; n3 = n1; n4 = n1;
- n1 += strlen(data->first.scpdurl);
- n2 += strlen(data->first.controlurl);
- n3 += strlen(data->CIF.controlurl);
- n4 += strlen(data->IPv6FC.controlurl);
-
- /* allocate memory to store URLs */
- urls->ipcondescURL = (char *)malloc(n1);
- urls->controlURL = (char *)malloc(n2);
- urls->controlURL_CIF = (char *)malloc(n3);
- urls->controlURL_6FC = (char *)malloc(n4);
-
- /* strdup descURL */
- urls->rootdescURL = strdup(descURL);
-
- /* get description of WANIPConnection */
- if(data->urlbase[0] != '\0')
- strncpy(urls->ipcondescURL, data->urlbase, n1);
- else
- strncpy(urls->ipcondescURL, descURL, n1);
- p = strchr(urls->ipcondescURL+7, '/');
- if(p) p[0] = '\0';
- if(scope_id != 0) {
- if(0 == memcmp(urls->ipcondescURL, "http://[fe80:", 13)) {
- /* this is a linklocal IPv6 address */
- p = strchr(urls->ipcondescURL, ']');
- if(p) {
- /* insert %25 into URL */
-#ifdef IF_NAMESIZE
- memmove(p + 3 + strlen(ifname), p, strlen(p) + 1);
- memcpy(p, "%25", 3);
- memcpy(p + 3, ifname, strlen(ifname));
-#else
- memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1);
- memcpy(p, "%25", 3);
- memcpy(p + 3, scope_str, strlen(scope_str));
-#endif
- }
- }
- }
- strncpy(urls->controlURL, urls->ipcondescURL, n2);
- strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
- strncpy(urls->controlURL_6FC, urls->ipcondescURL, n4);
-
- url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
-
- url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2);
-
- url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
-
- url_cpy_or_cat(urls->controlURL_6FC, data->IPv6FC.controlurl, n4);
-
-#ifdef DEBUG
- printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL,
- (unsigned)strlen(urls->ipcondescURL), n1);
- printf("urls->controlURL='%s' %u n2=%d\n", urls->controlURL,
- (unsigned)strlen(urls->controlURL), n2);
- printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
- (unsigned)strlen(urls->controlURL_CIF), n3);
- printf("urls->controlURL_6FC='%s' %u n4=%d\n", urls->controlURL_6FC,
- (unsigned)strlen(urls->controlURL_6FC), n4);
-#endif
-}
-
-LIBSPEC void
-FreeUPNPUrls(struct UPNPUrls * urls)
-{
- if(!urls)
- return;
- free(urls->controlURL);
- urls->controlURL = 0;
- free(urls->ipcondescURL);
- urls->ipcondescURL = 0;
- free(urls->controlURL_CIF);
- urls->controlURL_CIF = 0;
- free(urls->controlURL_6FC);
- urls->controlURL_6FC = 0;
- free(urls->rootdescURL);
- urls->rootdescURL = 0;
-}
-
-int
-UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
-{
- char status[64];
- unsigned int uptime;
- status[0] = '\0';
- UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
- status, &uptime, NULL);
- if(0 == strcmp("Connected", status))
- {
- return 1;
- }
- else
- return 0;
-}
-
-
-/* UPNP_GetValidIGD() :
- * return values :
- * -1 = Internal error
- * 0 = NO IGD found
- * 1 = A valid connected IGD has been found
- * 2 = A valid IGD has been found but it reported as
- * not connected
- * 3 = an UPnP device has been found but was not recognized as an IGD
- *
- * In any positive non zero return case, the urls and data structures
- * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
- * free allocated memory.
- */
-LIBSPEC int
-UPNP_GetValidIGD(struct UPNPDev * devlist,
- struct UPNPUrls * urls,
- struct IGDdatas * data,
- char * lanaddr, int lanaddrlen)
-{
- struct xml_desc {
- char * xml;
- int size;
- int is_igd;
- } * desc = NULL;
- struct UPNPDev * dev;
- int ndev = 0;
- int i;
- int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
- int n_igd = 0;
- char extIpAddr[16];
- if(!devlist)
- {
-#ifdef DEBUG
- printf("Empty devlist\n");
-#endif
- return 0;
- }
- /* counting total number of devices in the list */
- for(dev = devlist; dev; dev = dev->pNext)
- ndev++;
- if(ndev > 0)
- {
- desc = calloc(ndev, sizeof(struct xml_desc));
- if(!desc)
- return -1; /* memory allocation error */
- }
- /* Step 1 : downloading descriptions and testing type */
- for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
- {
- /* we should choose an internet gateway device.
- * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
- desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
- lanaddr, lanaddrlen,
- dev->scope_id);
-#ifdef DEBUG
- if(!desc[i].xml)
- {
- printf("error getting XML description %s\n", dev->descURL);
- }
-#endif
- if(desc[i].xml)
- {
- memset(data, 0, sizeof(struct IGDdatas));
- memset(urls, 0, sizeof(struct UPNPUrls));
- parserootdesc(desc[i].xml, desc[i].size, data);
- if(0==strcmp(data->CIF.servicetype,
- "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
- {
- desc[i].is_igd = 1;
- n_igd++;
- }
- }
- }
- /* iterate the list to find a device depending on state */
- for(state = 1; state <= 3; state++)
- {
- for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
- {
- if(desc[i].xml)
- {
- memset(data, 0, sizeof(struct IGDdatas));
- memset(urls, 0, sizeof(struct UPNPUrls));
- parserootdesc(desc[i].xml, desc[i].size, data);
- if(desc[i].is_igd || state >= 3 )
- {
- GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
-
- /* in state 2 and 3 we dont test if device is connected ! */
- if(state >= 2)
- goto free_and_return;
-#ifdef DEBUG
- printf("UPNPIGD_IsConnected(%s) = %d\n",
- urls->controlURL,
- UPNPIGD_IsConnected(urls, data));
-#endif
- /* checks that status is connected AND there is a external IP address assigned */
- if(UPNPIGD_IsConnected(urls, data)
- && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0))
- goto free_and_return;
- FreeUPNPUrls(urls);
- if(data->second.servicetype[0] != '\0') {
-#ifdef DEBUG
- printf("We tried %s, now we try %s !\n",
- data->first.servicetype, data->second.servicetype);
-#endif
- /* swaping WANPPPConnection and WANIPConnection ! */
- memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
- memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
- memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
- GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
-#ifdef DEBUG
- printf("UPNPIGD_IsConnected(%s) = %d\n",
- urls->controlURL,
- UPNPIGD_IsConnected(urls, data));
-#endif
- if(UPNPIGD_IsConnected(urls, data)
- && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0))
- goto free_and_return;
- FreeUPNPUrls(urls);
- }
- }
- memset(data, 0, sizeof(struct IGDdatas));
- }
- }
- }
- state = 0;
-free_and_return:
- if(desc) {
- for(i = 0; i < ndev; i++) {
- if(desc[i].xml) {
- free(desc[i].xml);
- }
- }
- free(desc);
- }
- return state;
-}
-
-/* UPNP_GetIGDFromUrl()
- * Used when skipping the discovery process.
- * return value :
- * 0 - Not ok
- * 1 - OK */
-int
-UPNP_GetIGDFromUrl(const char * rootdescurl,
- struct UPNPUrls * urls,
- struct IGDdatas * data,
- char * lanaddr, int lanaddrlen)
-{
- char * descXML;
- int descXMLsize = 0;
- descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
- lanaddr, lanaddrlen, 0);
- if(descXML) {
- memset(data, 0, sizeof(struct IGDdatas));
- memset(urls, 0, sizeof(struct UPNPUrls));
- parserootdesc(descXML, descXMLsize, data);
- free(descXML);
- descXML = NULL;
- GetUPNPUrls(urls, data, rootdescurl, 0);
- return 1;
- } else {
- return 0;
- }
-}
-
diff --git a/contrib/miniupnpc/miniupnpc.def b/contrib/miniupnpc/miniupnpc.def
deleted file mode 100644
index 33433560..00000000
--- a/contrib/miniupnpc/miniupnpc.def
+++ /dev/null
@@ -1,43 +0,0 @@
-LIBRARY
-; miniupnpc library
- miniupnpc
-
-EXPORTS
-; miniupnpc
- upnpDiscover
- freeUPNPDevlist
- parserootdesc
- UPNP_GetValidIGD
- UPNP_GetIGDFromUrl
- GetUPNPUrls
- FreeUPNPUrls
-; miniwget
- miniwget
- miniwget_getaddr
-; upnpcommands
- UPNP_GetTotalBytesSent
- UPNP_GetTotalBytesReceived
- UPNP_GetTotalPacketsSent
- UPNP_GetTotalPacketsReceived
- UPNP_GetStatusInfo
- UPNP_GetConnectionTypeInfo
- UPNP_GetExternalIPAddress
- UPNP_GetLinkLayerMaxBitRates
- UPNP_AddPortMapping
- UPNP_DeletePortMapping
- UPNP_GetPortMappingNumberOfEntries
- UPNP_GetSpecificPortMappingEntry
- UPNP_GetGenericPortMappingEntry
- UPNP_GetListOfPortMappings
- UPNP_AddPinhole
- UPNP_CheckPinholeWorking
- UPNP_UpdatePinhole
- UPNP_GetPinholePackets
- UPNP_DeletePinhole
- UPNP_GetFirewallStatus
- UPNP_GetOutboundPinholeTimeout
-; upnperrors
- strupnperror
-; portlistingparse
- ParsePortListing
- FreePortListing
diff --git a/contrib/miniupnpc/miniupnpc.h b/contrib/miniupnpc/miniupnpc.h
deleted file mode 100644
index 3af109cf..00000000
--- a/contrib/miniupnpc/miniupnpc.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* $Id: miniupnpc.h,v 1.35 2014/01/31 13:26:34 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2012 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINIUPNPC_H_INCLUDED
-#define MINIUPNPC_H_INCLUDED
-
-#include "declspec.h"
-#include "igd_desc_parse.h"
-
-/* error codes : */
-#define UPNPDISCOVER_SUCCESS (0)
-#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
-#define UPNPDISCOVER_SOCKET_ERROR (-101)
-#define UPNPDISCOVER_MEMORY_ERROR (-102)
-
-/* versions : */
-#define MINIUPNPC_VERSION "1.9.20140401"
-#define MINIUPNPC_API_VERSION 10
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Structures definitions : */
-struct UPNParg { const char * elt; const char * val; };
-
-char *
-simpleUPnPcommand(int, const char *, const char *,
- const char *, struct UPNParg *,
- int *);
-
-struct UPNPDev {
- struct UPNPDev * pNext;
- char * descURL;
- char * st;
- unsigned int scope_id;
- char buffer[2];
-};
-
-/* upnpDiscover()
- * discover UPnP devices on the network.
- * The discovered devices are returned as a chained list.
- * It is up to the caller to free the list with freeUPNPDevlist().
- * delay (in millisecond) is the maximum time for waiting any device
- * response.
- * If available, device list will be obtained from MiniSSDPd.
- * Default path for minissdpd socket will be used if minissdpdsock argument
- * is NULL.
- * If multicastif is not NULL, it will be used instead of the default
- * multicast interface for sending SSDP discover packets.
- * If sameport is not null, SSDP packets will be sent from the source port
- * 1900 (same as destination port) otherwise system assign a source port. */
-LIBSPEC struct UPNPDev *
-upnpDiscover(int delay, const char * multicastif,
- const char * minissdpdsock, int sameport,
- int ipv6,
- int * error);
-/* freeUPNPDevlist()
- * free list returned by upnpDiscover() */
-LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
-
-/* parserootdesc() :
- * parse root XML description of a UPnP device and fill the IGDdatas
- * structure. */
-LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
-
-/* structure used to get fast access to urls
- * controlURL: controlURL of the WANIPConnection
- * ipcondescURL: url of the description of the WANIPConnection
- * controlURL_CIF: controlURL of the WANCommonInterfaceConfig
- * controlURL_6FC: controlURL of the WANIPv6FirewallControl
- */
-struct UPNPUrls {
- char * controlURL;
- char * ipcondescURL;
- char * controlURL_CIF;
- char * controlURL_6FC;
- char * rootdescURL;
-};
-
-/* UPNP_GetValidIGD() :
- * return values :
- * 0 = NO IGD found
- * 1 = A valid connected IGD has been found
- * 2 = A valid IGD has been found but it reported as
- * not connected
- * 3 = an UPnP device has been found but was not recognized as an IGD
- *
- * In any non zero return case, the urls and data structures
- * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
- * free allocated memory.
- */
-LIBSPEC int
-UPNP_GetValidIGD(struct UPNPDev * devlist,
- struct UPNPUrls * urls,
- struct IGDdatas * data,
- char * lanaddr, int lanaddrlen);
-
-/* UPNP_GetIGDFromUrl()
- * Used when skipping the discovery process.
- * return value :
- * 0 - Not ok
- * 1 - OK */
-LIBSPEC int
-UPNP_GetIGDFromUrl(const char * rootdescurl,
- struct UPNPUrls * urls,
- struct IGDdatas * data,
- char * lanaddr, int lanaddrlen);
-
-LIBSPEC void
-GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
- const char *, unsigned int);
-
-LIBSPEC void
-FreeUPNPUrls(struct UPNPUrls *);
-
-/* return 0 or 1 */
-LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/contrib/miniupnpc/miniupnpcmodule.c b/contrib/miniupnpc/miniupnpcmodule.c
deleted file mode 100644
index 4654c987..00000000
--- a/contrib/miniupnpc/miniupnpcmodule.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/* $Id: miniupnpcmodule.c,v 1.22 2014/01/31 13:18:25 nanard Exp $*/
-/* Project : miniupnp
- * Author : Thomas BERNARD
- * website : http://miniupnp.tuxfamily.org/
- * copyright (c) 2007-2014 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#include
-#define STATICLIB
-#include "structmember.h"
-#include "miniupnpc.h"
-#include "upnpcommands.h"
-#include "upnperrors.h"
-
-/* for compatibility with Python < 2.4 */
-#ifndef Py_RETURN_NONE
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
-#ifndef Py_RETURN_TRUE
-#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
-#endif
-
-#ifndef Py_RETURN_FALSE
-#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
-#endif
-
-/* for compatibility with Python < 3.0 */
-#ifndef PyVarObject_HEAD_INIT
-#define PyVarObject_HEAD_INIT(type, size) \
- PyObject_HEAD_INIT(type) size,
-#endif
-
-#ifndef Py_TYPE
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-#endif
-
-typedef struct {
- PyObject_HEAD
- /* Type-specific fields go here. */
- struct UPNPDev * devlist;
- struct UPNPUrls urls;
- struct IGDdatas data;
- unsigned int discoverdelay; /* value passed to upnpDiscover() */
- char lanaddr[40]; /* our ip address on the LAN */
- char * multicastif;
- char * minissdpdsocket;
-} UPnPObject;
-
-static PyMemberDef UPnP_members[] = {
- {"lanaddr", T_STRING_INPLACE, offsetof(UPnPObject, lanaddr),
- READONLY, "ip address on the LAN"
- },
- {"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay),
- 0/*READWRITE*/, "value in ms used to wait for SSDP responses"
- },
- /* T_STRING is allways readonly :( */
- {"multicastif", T_STRING, offsetof(UPnPObject, multicastif),
- 0, "IP of the network interface to be used for multicast operations"
- },
- {"minissdpdsocket", T_STRING, offsetof(UPnPObject, multicastif),
- 0, "path of the MiniSSDPd unix socket"
- },
- {NULL}
-};
-
-static void
-UPnPObject_dealloc(UPnPObject *self)
-{
- freeUPNPDevlist(self->devlist);
- FreeUPNPUrls(&self->urls);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-UPnP_discover(UPnPObject *self)
-{
- struct UPNPDev * dev;
- int i;
- PyObject *res = NULL;
- if(self->devlist)
- {
- freeUPNPDevlist(self->devlist);
- self->devlist = 0;
- }
- Py_BEGIN_ALLOW_THREADS
- self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
- 0/* multicast if*/,
- 0/*minissdpd socket*/,
- 0/*sameport flag*/,
- 0/*ip v6*/,
- 0/*error */);
- Py_END_ALLOW_THREADS
- /* Py_RETURN_NONE ??? */
- for(dev = self->devlist, i = 0; dev; dev = dev->pNext)
- i++;
- res = Py_BuildValue("i", i);
- return res;
-}
-
-static PyObject *
-UPnP_selectigd(UPnPObject *self)
-{
- int r;
-Py_BEGIN_ALLOW_THREADS
- r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data,
- self->lanaddr, sizeof(self->lanaddr));
-Py_END_ALLOW_THREADS
- if(r)
- {
- return Py_BuildValue("s", self->urls.controlURL);
- }
- else
- {
- /* TODO: have our own exception type ! */
- PyErr_SetString(PyExc_Exception, "No UPnP device discovered");
- return NULL;
- }
-}
-
-static PyObject *
-UPnP_totalbytesent(UPnPObject *self)
-{
- UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
- i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF,
- self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
- return Py_BuildValue("I", i);
-}
-
-static PyObject *
-UPnP_totalbytereceived(UPnPObject *self)
-{
- UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
- i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF,
- self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
- return Py_BuildValue("I", i);
-}
-
-static PyObject *
-UPnP_totalpacketsent(UPnPObject *self)
-{
- UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
- i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF,
- self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
- return Py_BuildValue("I", i);
-}
-
-static PyObject *
-UPnP_totalpacketreceived(UPnPObject *self)
-{
- UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
- i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF,
- self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
- return Py_BuildValue("I", i);
-}
-
-static PyObject *
-UPnP_statusinfo(UPnPObject *self)
-{
- char status[64];
- char lastconnerror[64];
- unsigned int uptime = 0;
- int r;
- status[0] = '\0';
- lastconnerror[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
- r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype,
- status, &uptime, lastconnerror);
-Py_END_ALLOW_THREADS
- if(r==UPNPCOMMAND_SUCCESS) {
- return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror);
- } else {
- /* TODO: have our own exception type ! */
- PyErr_SetString(PyExc_Exception, strupnperror(r));
- return NULL;
- }
-}
-
-static PyObject *
-UPnP_connectiontype(UPnPObject *self)
-{
- char connectionType[64];
- int r;
- connectionType[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
- r = UPNP_GetConnectionTypeInfo(self->urls.controlURL,
- self->data.first.servicetype,
- connectionType);
-Py_END_ALLOW_THREADS
- if(r==UPNPCOMMAND_SUCCESS) {
- return Py_BuildValue("s", connectionType);
- } else {
- /* TODO: have our own exception type ! */
- PyErr_SetString(PyExc_Exception, strupnperror(r));
- return NULL;
- }
-}
-
-static PyObject *
-UPnP_externalipaddress(UPnPObject *self)
-{
- char externalIPAddress[40];
- int r;
- externalIPAddress[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
- r = UPNP_GetExternalIPAddress(self->urls.controlURL,
- self->data.first.servicetype,
- externalIPAddress);
-Py_END_ALLOW_THREADS
- if(r==UPNPCOMMAND_SUCCESS) {
- return Py_BuildValue("s", externalIPAddress);
- } else {
- /* TODO: have our own exception type ! */
- PyErr_SetString(PyExc_Exception, strupnperror(r));
- return NULL;
- }
-}
-
-/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc,
- * remoteHost)
- * protocol is 'UDP' or 'TCP' */
-static PyObject *
-UPnP_addportmapping(UPnPObject *self, PyObject *args)
-{
- char extPort[6];
- unsigned short ePort;
- char inPort[6];
- unsigned short iPort;
- const char * proto;
- const char * host;
- const char * desc;
- const char * remoteHost;
- const char * leaseDuration = "0";
- int r;
- if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto,
- &host, &iPort, &desc, &remoteHost))
- return NULL;
-Py_BEGIN_ALLOW_THREADS
- sprintf(extPort, "%hu", ePort);
- sprintf(inPort, "%hu", iPort);
- r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype,
- extPort, inPort, host, desc, proto,
- remoteHost, leaseDuration);
-Py_END_ALLOW_THREADS
- if(r==UPNPCOMMAND_SUCCESS)
- {
- Py_RETURN_TRUE;
- }
- else
- {
- // TODO: RAISE an Exception. See upnpcommands.h for errors codes.
- // upnperrors.c
- //Py_RETURN_FALSE;
- /* TODO: have our own exception type ! */
- PyErr_SetString(PyExc_Exception, strupnperror(r));
- return NULL;
- }
-}
-
-/* DeletePortMapping(extPort, proto, removeHost='')
- * proto = 'UDP', 'TCP' */
-static PyObject *
-UPnP_deleteportmapping(UPnPObject *self, PyObject *args)
-{
- char extPort[6];
- unsigned short ePort;
- const char * proto;
- const char * remoteHost = "";
- int r;
- if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
- return NULL;
-Py_BEGIN_ALLOW_THREADS
- sprintf(extPort, "%hu", ePort);
- r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype,
- extPort, proto, remoteHost);
-Py_END_ALLOW_THREADS
- if(r==UPNPCOMMAND_SUCCESS) {
- Py_RETURN_TRUE;
- } else {
- /* TODO: have our own exception type ! */
- PyErr_SetString(PyExc_Exception, strupnperror(r));
- return NULL;
- }
-}
-
-static PyObject *
-UPnP_getportmappingnumberofentries(UPnPObject *self)
-{
- unsigned int n = 0;
- int r;
-Py_BEGIN_ALLOW_THREADS
- r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL,
- self->data.first.servicetype,
- &n);
-Py_END_ALLOW_THREADS
- if(r==UPNPCOMMAND_SUCCESS) {
- return Py_BuildValue("I", n);
- } else {
- /* TODO: have our own exception type ! */
- PyErr_SetString(PyExc_Exception, strupnperror(r));
- return NULL;
- }
-}
-
-/* GetSpecificPortMapping(ePort, proto, remoteHost='')
- * proto = 'UDP' or 'TCP' */
-static PyObject *
-UPnP_getspecificportmapping(UPnPObject *self, PyObject *args)
-{
- char extPort[6];
- unsigned short ePort;
- const char * proto;
- const char * remoteHost = "";
- char intClient[40];
- char intPort[6];
- unsigned short iPort;
- char desc[80];
- char enabled[4];
- char leaseDuration[16];
- if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
- return NULL;
- extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0';
- desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
- sprintf(extPort, "%hu", ePort);
- UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
- self->data.first.servicetype,
- extPort, proto, remoteHost,
- intClient, intPort,
- desc, enabled, leaseDuration);
-Py_END_ALLOW_THREADS
- if(intClient[0])
- {
- iPort = (unsigned short)atoi(intPort);
- return Py_BuildValue("(s,H,s,O,i)",
- intClient, iPort, desc,
- PyBool_FromLong(atoi(enabled)),
- atoi(leaseDuration));
- }
- else
- {
- Py_RETURN_NONE;
- }
-}
-
-/* GetGenericPortMapping(index) */
-static PyObject *
-UPnP_getgenericportmapping(UPnPObject *self, PyObject *args)
-{
- int i, r;
- char index[8];
- char intClient[40];
- char intPort[6];
- unsigned short iPort;
- char extPort[6];
- unsigned short ePort;
- char protocol[4];
- char desc[80];
- char enabled[6];
- char rHost[64];
- char duration[16]; /* lease duration */
- unsigned int dur;
- if(!PyArg_ParseTuple(args, "i", &i))
- return NULL;
-Py_BEGIN_ALLOW_THREADS
- snprintf(index, sizeof(index), "%d", i);
- rHost[0] = '\0'; enabled[0] = '\0';
- duration[0] = '\0'; desc[0] = '\0';
- extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
- r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL,
- self->data.first.servicetype,
- index,
- extPort, intClient, intPort,
- protocol, desc, enabled, rHost,
- duration);
-Py_END_ALLOW_THREADS
- if(r==UPNPCOMMAND_SUCCESS)
- {
- ePort = (unsigned short)atoi(extPort);
- iPort = (unsigned short)atoi(intPort);
- dur = (unsigned int)strtoul(duration, 0, 0);
- return Py_BuildValue("(H,s,(s,H),s,s,s,I)",
- ePort, protocol, intClient, iPort,
- desc, enabled, rHost, dur);
- }
- else
- {
- Py_RETURN_NONE;
- }
-}
-
-/* miniupnpc.UPnP object Method Table */
-static PyMethodDef UPnP_methods[] = {
- {"discover", (PyCFunction)UPnP_discover, METH_NOARGS,
- "discover UPnP IGD devices on the network"
- },
- {"selectigd", (PyCFunction)UPnP_selectigd, METH_NOARGS,
- "select a valid UPnP IGD among discovered devices"
- },
- {"totalbytesent", (PyCFunction)UPnP_totalbytesent, METH_NOARGS,
- "return the total number of bytes sent by UPnP IGD"
- },
- {"totalbytereceived", (PyCFunction)UPnP_totalbytereceived, METH_NOARGS,
- "return the total number of bytes received by UPnP IGD"
- },
- {"totalpacketsent", (PyCFunction)UPnP_totalpacketsent, METH_NOARGS,
- "return the total number of packets sent by UPnP IGD"
- },
- {"totalpacketreceived", (PyCFunction)UPnP_totalpacketreceived, METH_NOARGS,
- "return the total number of packets received by UPnP IGD"
- },
- {"statusinfo", (PyCFunction)UPnP_statusinfo, METH_NOARGS,
- "return status and uptime"
- },
- {"connectiontype", (PyCFunction)UPnP_connectiontype, METH_NOARGS,
- "return IGD WAN connection type"
- },
- {"externalipaddress", (PyCFunction)UPnP_externalipaddress, METH_NOARGS,
- "return external IP address"
- },
- {"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS,
- "add a port mapping"
- },
- {"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS,
- "delete a port mapping"
- },
- {"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS,
- "-- non standard --"
- },
- {"getspecificportmapping", (PyCFunction)UPnP_getspecificportmapping, METH_VARARGS,
- "get details about a specific port mapping entry"
- },
- {"getgenericportmapping", (PyCFunction)UPnP_getgenericportmapping, METH_VARARGS,
- "get all details about the port mapping at index"
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject UPnPType = {
- PyVarObject_HEAD_INIT(NULL,
- 0) /*ob_size*/
- "miniupnpc.UPnP", /*tp_name*/
- sizeof(UPnPObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)UPnPObject_dealloc,/*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "UPnP objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- UPnP_methods, /* tp_methods */
- UPnP_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0,/*(initproc)UPnP_init,*/ /* tp_init */
- 0, /* tp_alloc */
-#ifndef _WIN32
- PyType_GenericNew,/*UPnP_new,*/ /* tp_new */
-#else
- 0,
-#endif
-};
-
-/* module methods */
-static PyMethodDef miniupnpc_methods[] = {
- {NULL} /* Sentinel */
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "miniupnpc", /* m_name */
- "miniupnpc module.", /* m_doc */
- -1, /* m_size */
- miniupnpc_methods, /* m_methods */
- NULL, /* m_reload */
- NULL, /* m_traverse */
- NULL, /* m_clear */
- NULL, /* m_free */
-};
-#endif
-
-#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-
-PyMODINIT_FUNC
-#if PY_MAJOR_VERSION >= 3
-PyInit_miniupnpc(void)
-#else
-initminiupnpc(void)
-#endif
-{
- PyObject* m;
-
-#ifdef _WIN32
- UPnPType.tp_new = PyType_GenericNew;
-#endif
- if (PyType_Ready(&UPnPType) < 0)
- return;
-
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("miniupnpc", miniupnpc_methods,
- "miniupnpc module.");
-#endif
-
- Py_INCREF(&UPnPType);
- PyModule_AddObject(m, "UPnP", (PyObject *)&UPnPType);
-
-#if PY_MAJOR_VERSION >= 3
- return m;
-#endif
-}
-
diff --git a/contrib/miniupnpc/miniupnpcstrings.h.cmake b/contrib/miniupnpc/miniupnpcstrings.h.cmake
deleted file mode 100644
index 236b2dca..00000000
--- a/contrib/miniupnpc/miniupnpcstrings.h.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef MINIUPNPCSTRINGS_H_INCLUDED
-#define MINIUPNPCSTRINGS_H_INCLUDED
-
-#define OS_STRING "${CMAKE_SYSTEM_NAME}"
-#define MINIUPNPC_VERSION_STRING "${MINIUPNPC_VERSION}"
-
-#endif
diff --git a/contrib/miniupnpc/miniupnpcstrings.h.in b/contrib/miniupnpc/miniupnpcstrings.h.in
deleted file mode 100644
index c32e3a13..00000000
--- a/contrib/miniupnpc/miniupnpcstrings.h.in
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: miniupnpcstrings.h.in,v 1.5 2012/10/16 16:48:26 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2011 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINIUPNPCSTRINGS_H_INCLUDED
-#define MINIUPNPCSTRINGS_H_INCLUDED
-
-#define OS_STRING "OS/version"
-#define MINIUPNPC_VERSION_STRING "version"
-
-#endif
-
diff --git a/contrib/miniupnpc/miniupnpctypes.h b/contrib/miniupnpc/miniupnpctypes.h
deleted file mode 100644
index 591c32fb..00000000
--- a/contrib/miniupnpc/miniupnpctypes.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id: miniupnpctypes.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */
-/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org
- * Author : Thomas Bernard
- * Copyright (c) 2011 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided within this distribution */
-#ifndef MINIUPNPCTYPES_H_INCLUDED
-#define MINIUPNPCTYPES_H_INCLUDED
-
-#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
-#define UNSIGNED_INTEGER unsigned long long
-#define STRTOUI strtoull
-#else
-#define UNSIGNED_INTEGER unsigned int
-#define STRTOUI strtoul
-#endif
-
-#endif
-
diff --git a/contrib/miniupnpc/miniwget.c b/contrib/miniupnpc/miniwget.c
deleted file mode 100644
index 813db932..00000000
--- a/contrib/miniupnpc/miniwget.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* $Id: miniwget.c,v 1.61 2014/02/05 17:27:48 nanard Exp $ */
-/* Project : miniupnp
- * Website : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2014 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include
-#include
-#include
-#include
-#ifdef _WIN32
-#include
-#include
-#include
-#define MAXHOSTNAMELEN 64
-#define MIN(x,y) (((x)<(y))?(x):(y))
-#define snprintf _snprintf
-#define socklen_t int
-#ifndef strncasecmp
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define strncasecmp _memicmp
-#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#define strncasecmp memicmp
-#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#endif /* #ifndef strncasecmp */
-#else /* #ifdef _WIN32 */
-#include
-#include
-#if defined(__amigaos__) && !defined(__amigaos4__)
-#define socklen_t int
-#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
-#include
-#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
-#include