diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..7411a0c6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,75 @@ +--- +BasedOnStyle: LLVM +BreakBeforeBraces: Stroustrup +IndentWidth: 4 +TabWidth: 4 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveMacros: 'true' +AlignConsecutiveAssignments: 'false' +AlignConsecutiveDeclarations: 'false' +AlignEscapedNewlines: Right +AlignOperands: 'true' +AlignTrailingComments: 'true' +AllowAllArgumentsOnNextLine: 'false' +AllowAllConstructorInitializersOnNextLine: 'false' +AllowAllParametersOfDeclarationOnNextLine: 'false' +AllowShortBlocksOnASingleLine: 'true' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AlwaysBreakAfterReturnType: None +BinPackArguments: 'false' +BinPackParameters: 'false' +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeTernaryOperators: 'true' +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +CompactNamespaces: 'false' +ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' +ConstructorInitializerIndentWidth: '4' +ContinuationIndentWidth: '4' +Cpp11BracedListStyle: 'false' +FixNamespaceComments: 'true' +IncludeBlocks: Regroup +IndentCaseLabels: 'true' +IndentPPDirectives: None +IndentWrappedFunctionNames: 'false' +KeepEmptyLinesAtTheStartOfBlocks: 'false' +MaxEmptyLinesToKeep: '1' +NamespaceIndentation: None +PointerAlignment: Left +ReflowComments: 'true' +SortIncludes: 'true' +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'false' +SpaceAfterLogicalNot: 'true' +SpaceAfterTemplateKeyword: 'true' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeCpp11BracedList: 'true' +SpaceBeforeCtorInitializerColon: 'true' +SpaceBeforeInheritanceColon: 'true' +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: 'true' +SpaceInEmptyParentheses: 'false' +SpacesBeforeTrailingComments: '3' +SpacesInAngles: 'false' +SpacesInCStyleCastParentheses: 'false' +SpacesInContainerLiterals: 'true' +SpacesInParentheses: 'false' +SpacesInSquareBrackets: 'false' +UseTab: 'Never' + +--- +Language: Cpp +Standard: Cpp03 +ColumnLimit: '240' +--- +Language: ObjC +ColumnLimit: '240' +--- +Language: Java +ColumnLimit: '240' +--- +Language: CSharp +ColumnLimit: '240' +... diff --git a/.clangd b/.clangd new file mode 100644 index 00000000..0605ccdb --- /dev/null +++ b/.clangd @@ -0,0 +1,6 @@ +CompileFlags: + Add: + - "-std=c++17" + - "-I../ext" + - "-I../ext/prometheus-cpp-lite-1.0/core/include" + - "-I../ext/prometheus-cpp-lite-1.0/simpleapi/include" diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index 44b5eb56..a1562793 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,56 @@ -# Main binaries created in *nix builds -/zerotier-one -/zerotier-idtool -/zerotier-cli -/zerotier-selftest -/zerotier -/nltest - -# OS-created garbage files from various platforms +build/ +/version.h .DS_Store +.Trashes +*.swp +._* +*~ +*~.nib .Apple* Thumbs.db @eaDir -._* +DerivedData/ +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 +*.xccheckout +xcuserdata/ +.vscode +__pycache__ +attic/world/*.c25519 +attic/world/mkworld +*.log +*.opensdf +*.user +*.cache +*.obj +*.tlog +*.pid +*.pkg +*.o +*.o-* +*.core +*.deb +*.rpm +*.autosave +*.tmp +.depend +node_modules +debian/files +debian/zerotier-one +debian/zerotier-one*.debhelper +debian/*.log +debian/zerotier-one.substvars +root/identity.* +root/config.* +/ext/installfiles/windows/chocolatey/zerotier-one/*.nupkg +/go/zerotier -# Windows build droppings /windows/ZeroTierOne.sdf /windows/ZeroTierOne.v11.suo /windows/x64 @@ -32,7 +69,7 @@ Thumbs.db /ext/installfiles/windows/ZeroTier One-SetupFiles /ext/installfiles/windows/Prerequisites /ext/installfiles/windows/*-cache -/ZeroTier One.msi +/*.msi /windows/.vs *.vcxproj.backup /windows/TapDriver6/Win7Debug @@ -43,47 +80,6 @@ enc_temp_folder /windows/copyutil/bin /windows/copyutil/obj -# *nix/Mac build droppings -/build-* -/ZeroTierOneInstaller-* -/examples/docker/zerotier-one -/examples/docker/test-*.env -/world/mkworld -/world/*.c25519 -zt1-src.tar.gz -/MacEthernetTapAgent - -# Miscellaneous temporaries, build files, etc. -*.log -*.opensdf -*.user -*.cache -*.obj -*.tlog -*.pid -*.pkg -*.o -/*.a -*.dylib -*.so -*.so.* -*.o-* -*.core -*.deb -*.rpm -*.autosave -*.tmp -.depend -node_modules -zt1_update_* -debian/files -debian/zerotier-one -debian/zerotier-one*.debhelper -debian/*.log -debian/zerotier-one.substvars -root-watcher/config.json - -# Java/Android/JNI build droppings java/obj/ java/libs/ java/bin/ @@ -95,28 +91,3 @@ java/build_win32/ windows/WinUI/obj/ windows/WinUI/bin/ windows/ZeroTierOne/Debug/ -/ext/installfiles/windows/chocolatey/zerotier-one/*.nupkg - -# Miscellaneous mac/Xcode droppings -.DS_Store -.Trashes -*.swp -*~.nib -DerivedData/ -build/ -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 -*.xccheckout -xcuserdata/ -ext/librethinkdbxx/build -.vscode -__pycache__ -*~ -attic/world/*.c25519 -attic/world/mkworld diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..0e40fe8f --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ + +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/.idea/ZeroTierOne.iml b/.idea/ZeroTierOne.iml new file mode 100644 index 00000000..5e764c4f --- /dev/null +++ b/.idea/ZeroTierOne.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..a55e7a17 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/dictionaries/api.xml b/.idea/dictionaries/api.xml new file mode 100644 index 00000000..53167764 --- /dev/null +++ b/.idea/dictionaries/api.xml @@ -0,0 +1,11 @@ + + + + apisocket + nwid + secrand + sockaddr + unmarshals + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..146ab09b --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..28a804d8 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..6b5db685 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 00000000..97ad6d2d --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index 84bb8631..2d765fb6 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -36,12 +36,6 @@ ZeroTier includes the following third party code, either in ext/ or incorporated * Home page: http://code.google.com/p/lz4/ * License grant: BSD 2-clause - * http-parser by Joyent, Inc. (many authors) - - * Files: ext/http-parser/* - * Home page: https://github.com/joyent/http-parser/ - * License grant: MIT/Expat - * C++11 json (nlohmann/json) by Niels Lohmann * Files: ext/json/* @@ -62,12 +56,6 @@ ZeroTier includes the following third party code, either in ext/ or incorporated * License grant: public domain * ZeroTier Modifications: slight cryptographically-irrelevant modifications for inclusion into ZeroTier core - * MiniUPNPC and libnatpmp by Thomas Bernard - - * Files: ext/libnatpmp/* ext/miniupnpc/* - * Home page: http://miniupnp.free.fr/ - * License grant: BSD attribution no-endorsement - * cpp-httplib by yhirose * Files: ext/cpp-httplib/* diff --git a/CMakeLists.txt b/CMakeLists.txt index fff7808e..e154a45c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,199 @@ -# CMake build script for libzerotiercore.a +cmake_minimum_required (VERSION 3.10) -cmake_minimum_required (VERSION 2.8) -project (zerotiercore) +if(${CMAKE_VERSION} VERSION_LESS 3.15) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +else() + cmake_policy(VERSION 3.15) +endif() -set (PROJ_DIR ${PROJECT_SOURCE_DIR}) -set (ZT_DEFS -std=c++11) +if(WIN32) + # If building on Windows, set minimum target to Windows 7 + set(CMAKE_SYSTEM_VERSION "7" CACHE STRING INTERNAL FORCE) +endif(WIN32) -file(GLOB core_src_glob ${PROJ_DIR}/node/*.cpp) -add_library(zerotiercore STATIC ${core_src_glob}) +set(ZEROTIER_ONE_VERSION_MAJOR 2 CACHE INTERNAL "") +set(ZEROTIER_ONE_VERSION_MINOR 0 CACHE INTERNAL "") +set(ZEROTIER_ONE_VERSION_REVISION 0 CACHE INTERNAL "") +set(ZEROTIER_ONE_VERSION_BUILD 0 CACHE INTERNAL "") -target_compile_options(zerotiercore PRIVATE ${ZT_DEFS}) +set(default_build_type "Release") +if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + set(default_build_type "Debug") +endif() + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE + STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +option(BUILD_CENTRAL_CONTROLLER "Build ZeroTier Central Controller" OFF) +option(ZT_TRACE "Trace Messages" OFF) +option(ZT_DEBUG_TRACE "Debug Trace Messages" OFF) + +if (BUILD_CENTRAL_CONTROLLER) + find_package(PostgreSQL REQUIRED) + set(ENABLE_SSL_SUPPORT OFF) + set(BUILD_SHARED_LIBS OFF) + set(BUILD_EXAMPLES OFF) + set(BUILD_TOOLS OFF) + set(BUILD_TESTS OFF) + set(BUILD_API_DOCS OFF) + add_subdirectory("ext/librabbitmq") +endif(BUILD_CENTRAL_CONTROLLER) + +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X Deployment Version") + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_definitions(-DZT_TRACE) +endif(CMAKE_BUILD_TYPE STREQUAL "Debug") + +project(zerotier + DESCRIPTION "ZeroTier Network Hypervisor" + LANGUAGES CXX C) + +if(WIN32) + add_definitions(-DNOMINMAX) +else(WIN32) + if(APPLE) + + message("Setting macOS Compiler Flags ${CMAKE_BUILD_TYPE}") + add_compile_options( + -Wall + -Wno-deprecated + -mmacosx-version-min=10.9 + $<$:-g> + $<$:-O0> + $<$:-Ofast> + $<$:-fPIE> + $<$:-flto> + $<$:-Ofast> + $<$:-fPIE> + $<$:-g> + ) + add_link_options( + -mmacosx-version-min=10.9 + $<$:-flto> + ) + + elseif ( + CMAKE_SYSTEM_NAME MATCHES "Linux" OR + CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR + CMAKE_SYSTEM_NAME MATCHES "OpenBSD" OR + CMAKE_SYSTEM_NAME MATCHES "NetBSD" + ) + + message("Setting Linux/BSD Compiler Flags (${CMAKE_BUILD_TYPE})") + add_compile_options( + -Wall + -Wno-deprecated + $<$:-g> + $<$:-O0> + $<$:-O3> + $<$:-fPIE> + $<$:-O3> + $<$:-fPIE> + $<$:-g> + ) + + endif(APPLE) +endif(WIN32) + +if ( + CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "amd64" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "i386" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "i486" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "i586" OR + CMAKE_SYSTEM_PROCESSOR MATCHES "i686" +) + message("Adding SSE and AES-NI flags for processor ${CMAKE_SYSTEM_PROCESSOR}") + add_compile_options( + -maes + -mmmx + -mrdrnd + -mpclmul + -msse + -msse2 + -msse3 + -msse4.1 + ) +endif() + +if(ZT_TRACE) + add_definitions(-DZT_TRACE) +endif() +if(ZT_DEBUG_TRACE) + add_definitions(-DZT_DEBUG_TRACE) +endif() + +add_subdirectory(node) +add_subdirectory(controller) +add_subdirectory(osdep) +add_subdirectory(go/native) + +#if(WIN32) +# add_subdirectory("windows/WinUI") +# add_subdirectory("windows/copyutil") +# add_definitions(-DNOMINMAX) +#endif(WIN32) + +set( + zt_osdep + zt_core + zt_controller + zt_go_native +) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/version.h +) + +#set(src +# one.cpp +# "ext/http-parser/http_parser.c" +#) +#set(headers +# "ext/http-parser/http_parser.h" +#) + +if(WIN32) + set(libs ${libs} wsock32 ws2_32 rpcrt4 iphlpapi) +else(WIN32) + set(libs ${libs} pthread) +endif(WIN32) + +#if(WIN32) +# set(libs ${libs} wsock32 ws2_32 rpcrt4 iphlpapi) +# set(src +# ${src} +# "windows/ZeroTierOne/ServiceBase.cpp" +# "windows/ZeroTierOne/ServiceInstaller.cpp" +# "windows/ZeroTierOne/ZeroTierOneService.cpp" +# "windows/ZeroTierOne/ZeroTierOne.rc" +# ) +# set(headers +# ${headers} +# "windows/ZeroTierOne/ServiceBase.h" +# "windows/ZeroTierOne/ServiceInstaller.h" +# "windows/ZeroTierOne/ZeroTierOneService.h" +# ) +#else(WIN32) +# set(libs ${libs} pthread resolv) +#endif(WIN32) + +#if(BUILD_CENTRAL_CONTROLLER) +# set(libs ${libs} rabbitmq-static ${PostgreSQL_LIBRARIES}) +#endif(BUILD_CENTRAL_CONTROLLER) + +#add_executable(${PROJECT_NAME} ${src} ${headers}) +#target_link_libraries(${PROJECT_NAME} ${libs}) +#target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR}) + +add_executable(zerotier-selftest selftest.cpp) +target_link_libraries(zerotier-selftest ${libs} zt_core zt_osdep) +target_compile_features(zerotier-selftest PUBLIC cxx_std_11) diff --git a/Jenkinsfile b/Jenkinsfile index 88989327..455115cb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -14,7 +14,13 @@ parallel 'centos7': { checkout scm stage('Build Centos 7') { - sh 'make -f make-linux.mk' + sh '''. /opt/rh/devtoolset-8/enable + rm -rf build/ + mkdir build && cd build + cmake .. + make -j4 + ./zerotier-selftest + ''' } } catch (err) { diff --git a/Makefile b/Makefile index 144225fc..9c82f78e 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,20 @@ # Common makefile -- loads make rules for each platform -OSTYPE=$(shell uname -s) +BUILDDIR := build -ifeq ($(OSTYPE),Darwin) - include make-mac.mk -endif +.PHONY: all -ifeq ($(OSTYPE),Linux) - include make-linux.mk -endif +all: setup + cd ${BUILDDIR} && $(MAKE) -j$(shell getconf _NPROCESSORS_ONLN) -ifeq ($(OSTYPE),FreeBSD) - CC=clang - CXX=clang++ - ZT_BUILD_PLATFORM=7 - include make-bsd.mk -endif -ifeq ($(OSTYPE),OpenBSD) - CC=egcc - CXX=eg++ - ZT_BUILD_PLATFORM=9 - include make-bsd.mk -endif +setup: + mkdir -p ${BUILDDIR} && cd ${BUILDDIR} && cmake .. -DCMAKE_BUILD_TYPE=Release -ifeq ($(OSTYPE),NetBSD) - include make-netbsd.mk -endif +debug: + mkdir -p ${BUILDDIR} && cd ${BUILDDIR} && cmake .. -DCMAKE_BUILD_TYPE=Debug && $(MAKE) + +clean: + rm -rf ${BUILDDIR} + +distclean: + rm -rf ${BUILDDIR} diff --git a/osdep/Binder.hpp b/attic/Binder.hpp similarity index 98% rename from osdep/Binder.hpp rename to attic/Binder.hpp index 660e6f0c..67debc80 100644 --- a/osdep/Binder.hpp +++ b/attic/Binder.hpp @@ -54,6 +54,12 @@ #include "Phy.hpp" #include "OSUtils.hpp" +#if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__)) +#define ZT_UDP_DESIRED_BUF_SIZE 1048576 +#else +#define ZT_UDP_DESIRED_BUF_SIZE 131072 +#endif + // Period between refreshes of bindings #define ZT_BINDER_REFRESH_PERIOD 30000 diff --git a/osdep/Http.cpp b/attic/Http.cpp similarity index 100% rename from osdep/Http.cpp rename to attic/Http.cpp diff --git a/osdep/Http.hpp b/attic/Http.hpp similarity index 100% rename from osdep/Http.hpp rename to attic/Http.hpp diff --git a/osdep/Phy.hpp b/attic/Phy.hpp similarity index 99% rename from osdep/Phy.hpp rename to attic/Phy.hpp index b65a520e..d4934edf 100644 --- a/osdep/Phy.hpp +++ b/attic/Phy.hpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) diff --git a/attic/PortMapper-libnatpmp.c b/attic/PortMapper-libnatpmp.c new file mode 100644 index 00000000..5da85cba --- /dev/null +++ b/attic/PortMapper-libnatpmp.c @@ -0,0 +1,14 @@ +#define ENABLE_STRNATPMPERR +#define _BSD_SOURCE +#define _DEFAULT_SOURCE +#define _XOPEN_SOURCE 600 + +#ifdef __APPLE__ +#ifndef _DARWIN_C_SOURCE +#define _DARWIN_C_SOURCE +#endif +#endif + +#include "../ext/libnatpmp/getgateway.c" +#include "../ext/libnatpmp/wingettimeofday.c" +#include "../ext/libnatpmp/natpmp.c" diff --git a/attic/PortMapper-miniupnpc.c b/attic/PortMapper-miniupnpc.c new file mode 100644 index 00000000..8d28da10 --- /dev/null +++ b/attic/PortMapper-miniupnpc.c @@ -0,0 +1,41 @@ +#define MINIUPNP_STATICLIB +#define MINIUPNPC_SET_SOCKET_TIMEOUT +#define MINIUPNPC_GET_SRC_ADDR +#define _BSD_SOURCE +#define _DEFAULT_SOURCE +#define _XOPEN_SOURCE 600 +#define MINIUPNPC_VERSION_STRING "2.0" +#define UPNP_VERSION_STRING "UPnP/1.1" + +#ifdef __LINUX__ +#define OS_STRING "Linux" +#endif +#ifdef __APPLE__ +#define OS_STRING "Darwin" +#endif +#ifdef __WINDOWS__ +#define OS_STRING "Windows" +#endif +#ifndef OS_STRING +#define OS_STRING "ZeroTier" +#endif + +#ifdef __APPLE__ +#ifndef _DARWIN_C_SOURCE +#define _DARWIN_C_SOURCE +#endif +#endif + +#include "../ext/miniupnpc/connecthostport.c" +#include "../ext/miniupnpc/igd_desc_parse.c" +#include "../ext/miniupnpc/minisoap.c" +#include "../ext/miniupnpc/miniupnpc.c" +#include "../ext/miniupnpc/miniwget.c" +#include "../ext/miniupnpc/minixml.c" +#include "../ext/miniupnpc/portlistingparse.c" +#include "../ext/miniupnpc/receivedata.c" +#include "../ext/miniupnpc/upnpcommands.c" +#include "../ext/miniupnpc/upnpdev.c" +#include "../ext/miniupnpc/upnperrors.c" +#include "../ext/miniupnpc/upnpreplyparse.c" +#include "../ext/miniupnpc/minissdpc.c" diff --git a/osdep/PortMapper.cpp b/attic/PortMapper.cpp similarity index 83% rename from osdep/PortMapper.cpp rename to attic/PortMapper.cpp index caad3ed4..d0ed87c3 100644 --- a/osdep/PortMapper.cpp +++ b/attic/PortMapper.cpp @@ -11,8 +11,6 @@ */ /****/ -#ifdef ZT_USE_MINIUPNPC - // Uncomment to dump debug messages //#define ZT_PORTMAPPER_TRACE 1 @@ -112,7 +110,7 @@ public: mode = 1; closenatpmp(&natpmp); #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: NAT-PMP: init failed, switching to UPnP mode" ZT_EOL_S); + PM_TRACE("PortMapper: NAT-PMP: init failed, switching to UPnP mode" ZT_EOL_S); #endif break; } @@ -135,7 +133,7 @@ public: publicAddress = InetAddress((uint32_t)response.pnu.publicaddress.addr.s_addr,0); } else { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: NAT-PMP: request for external address failed, aborting..." ZT_EOL_S); + PM_TRACE("PortMapper: NAT-PMP: request for external address failed, aborting..." ZT_EOL_S); #endif closenatpmp(&natpmp); break; @@ -157,8 +155,8 @@ public: if (r == 0) { publicAddress.setPort(response.pnu.newportmapping.mappedpublicport); #ifdef ZT_PORTMAPPER_TRACE - char paddr[128]; - PM_TRACE("PortMapper: NAT-PMP: mapped %u to %s" ZT_EOL_S,(unsigned int)localPort,publicAddress.toString(paddr)); + char paddr[128]; + PM_TRACE("PortMapper: NAT-PMP: mapped %u to %s" ZT_EOL_S,(unsigned int)localPort,publicAddress.toString(paddr)); #endif Mutex::Lock sl(surface_l); surface.clear(); @@ -175,7 +173,7 @@ public: if (!natPmpSuccess) { mode = 1; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: NAT-PMP: request failed, switching to UPnP mode" ZT_EOL_S); + PM_TRACE("PortMapper: NAT-PMP: request failed, switching to UPnP mode" ZT_EOL_S); #endif } } @@ -200,7 +198,7 @@ public: { UPNPDev *dev = devlist; while (dev) { - PM_TRACE("PortMapper: found UPnP device at URL '%s': %s" ZT_EOL_S,dev->descURL,dev->st); + PM_TRACE("PortMapper: found UPnP device at URL '%s': %s" ZT_EOL_S,dev->descURL,dev->st); dev = dev->pNext; } } @@ -214,11 +212,11 @@ public: if ((UPNP_GetValidIGD(devlist,&urls,&data,lanaddr,sizeof(lanaddr)))&&(lanaddr[0])) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: my LAN IP address: %s" ZT_EOL_S,lanaddr); + PM_TRACE("PortMapper: UPnP: my LAN IP address: %s" ZT_EOL_S,lanaddr); #endif if ((UPNP_GetExternalIPAddress(urls.controlURL,data.first.servicetype,externalip) == UPNPCOMMAND_SUCCESS)&&(externalip[0])) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: my external IP address: %s" ZT_EOL_S,externalip); + PM_TRACE("PortMapper: UPnP: my external IP address: %s" ZT_EOL_S,externalip); #endif for(int tries=0;tries<60;++tries) { @@ -244,7 +242,7 @@ public: memset(haveLeaseDuration,0,sizeof(haveLeaseDuration)); if ((UPNP_GetSpecificPortMappingEntry(urls.controlURL,data.first.servicetype,outport,"UDP",(const char *)0,haveIntClient,haveIntPort,haveDesc,haveEnabled,haveLeaseDuration) == UPNPCOMMAND_SUCCESS)&&(uniqueName == haveDesc)) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: reusing previously reserved external port: %s" ZT_EOL_S,outport); + PM_TRACE("PortMapper: UPnP: reusing previously reserved external port: %s" ZT_EOL_S,outport); #endif Mutex::Lock sl(surface_l); surface.clear(); @@ -259,7 +257,7 @@ public: int mapResult = 0; if ((mapResult = UPNP_AddPortMapping(urls.controlURL,data.first.servicetype,outport,inport,lanaddr,uniqueName.c_str(),"UDP",(const char *)0,"0")) == UPNPCOMMAND_SUCCESS) { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: reserved external port: %s" ZT_EOL_S,outport); + PM_TRACE("PortMapper: UPnP: reserved external port: %s" ZT_EOL_S,outport); #endif Mutex::Lock sl(surface_l); surface.clear(); @@ -269,7 +267,7 @@ public: break; } else { #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: UPNP_AddPortMapping(%s) failed: %d" ZT_EOL_S,outport,mapResult); + PM_TRACE("PortMapper: UPnP: UPNP_AddPortMapping(%s) failed: %d" ZT_EOL_S,outport,mapResult); #endif Thread::sleep(1000); } @@ -278,13 +276,13 @@ public: } else { mode = 0; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: UPNP_GetExternalIPAddress failed, returning to NAT-PMP mode" ZT_EOL_S); + PM_TRACE("PortMapper: UPnP: UPNP_GetExternalIPAddress failed, returning to NAT-PMP mode" ZT_EOL_S); #endif } } else { mode = 0; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: UPnP: UPNP_GetValidIGD failed, returning to NAT-PMP mode" ZT_EOL_S); + PM_TRACE("PortMapper: UPnP: UPNP_GetValidIGD failed, returning to NAT-PMP mode" ZT_EOL_S); #endif } @@ -293,14 +291,14 @@ public: } else { mode = 0; #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("PortMapper: upnpDiscover failed, returning to NAT-PMP mode: %d" ZT_EOL_S,upnpError); + PM_TRACE("PortMapper: upnpDiscover failed, returning to NAT-PMP mode: %d" ZT_EOL_S,upnpError); #endif } } // --------------------------------------------------------------------- #ifdef ZT_PORTMAPPER_TRACE - PM_TRACE("UPNPClient: rescanning in %d ms" ZT_EOL_S,ZT_PORTMAPPER_REFRESH_DELAY); + PM_TRACE("UPNPClient: rescanning in %d ms" ZT_EOL_S,ZT_PORTMAPPER_REFRESH_DELAY); #endif Thread::sleep(ZT_PORTMAPPER_REFRESH_DELAY); } @@ -334,5 +332,3 @@ std::vector PortMapper::get() const } } // namespace ZeroTier - -#endif // ZT_USE_MINIUPNPC diff --git a/osdep/PortMapper.hpp b/attic/PortMapper.hpp similarity index 92% rename from osdep/PortMapper.hpp rename to attic/PortMapper.hpp index be2c6468..54b04de1 100644 --- a/osdep/PortMapper.hpp +++ b/attic/PortMapper.hpp @@ -11,8 +11,6 @@ */ /****/ -#ifdef ZT_USE_MINIUPNPC - #ifndef ZT_PORTMAPPER_HPP #define ZT_PORTMAPPER_HPP @@ -26,7 +24,7 @@ /** * How frequently should we refresh our UPNP/NAT-PnP/whatever state? */ -#define ZT_PORTMAPPER_REFRESH_DELAY 300000 +#define ZT_PORTMAPPER_REFRESH_DELAY 120000 namespace ZeroTier { @@ -62,5 +60,3 @@ private: } // namespace ZeroTier #endif - -#endif // ZT_USE_MINIUPNPC diff --git a/attic/Root.hpp b/attic/Root.hpp new file mode 100644 index 00000000..c526007d --- /dev/null +++ b/attic/Root.hpp @@ -0,0 +1,182 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2023-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +#ifndef ZT_ROOT_HPP +#define ZT_ROOT_HPP + +#include "Constants.hpp" +#include "Str.hpp" +#include "ECC384.hpp" +#include "Locator.hpp" +#include "InetAddress.hpp" +#include "Utils.hpp" +#include "Identity.hpp" +#include "Mutex.hpp" + +namespace ZeroTier { + +/** + * A root entry pointing to a node capable of global identity lookup and indirect transit + * + * Root entries point to DNS records that contain TXT entries that decode to Locator objects + * pointing to actual root nodes. A default root identity and static addresses can also be + * provided as fallback if DNS is not available. + * + * Note that root identities can change if DNS returns a different result, but that DNS entries + * are authenticated using their own signature scheme. This allows a root DNS name to serve + * up different roots based on factors like location or relative load of different roots. + * + * It's also possible to create a root with no DNS and no DNS validator public key. This root + * will be a static entry pointing to a single root identity and set of physical addresses. + */ +class Root +{ +public: + ZT_ALWAYS_INLINE Root() : _dnsPublicKeySize(0) {} + + /** + * Create a new root entry + * + * @param dn DNS name + * @param dnspk DNS public key for record validation + * @param dnspksize Size of DNS public key (currently always the size of a NIST P-384 point compressed public key) + * @param dflId Default identity if DNS is not available + * @param dflAddrs Default IP addresses if DNS is not available + */ + template + ZT_ALWAYS_INLINE Root(S dn,const uint8_t *const dnspk,const unsigned int dnspksize,const Identity &dflId,const std::vector &dflAddrs) : + _defaultIdentity(dflId), + _defaultAddresses(dflAddrs), + _dnsName(dn), + _dnsPublicKeySize(dnspksize) + { + if (dnspksize != 0) { + if (dnspksize > sizeof(_dnsPublicKey)) + throw ZT_EXCEPTION_INVALID_ARGUMENT; + memcpy(_dnsPublicKey,dnspk,dnspksize); + } + } + + /** + * @return Current identity (either default or latest locator) + */ + ZT_ALWAYS_INLINE const Identity id() const + { + if (_lastFetchedLocator.id()) + return _lastFetchedLocator.id(); + return _defaultIdentity; + } + + /** + * @param id Identity to check + * @return True if identity equals this root's current identity + */ + ZT_ALWAYS_INLINE bool is(const Identity &id) const + { + return ((_lastFetchedLocator.id()) ? (id == _lastFetchedLocator.id()) : (id == _defaultIdentity)); + } + + /** + * @return Current ZeroTier address (either default or latest locator) + */ + ZT_ALWAYS_INLINE const Address address() const + { + if (_lastFetchedLocator.id()) + return _lastFetchedLocator.id().address(); + return _defaultIdentity.address(); + } + + /** + * @return DNS name for this root or empty string if static entry with no DNS + */ + ZT_ALWAYS_INLINE const Str dnsName() const { return _dnsName; } + + /** + * @return Latest locator or NIL locator object if none + */ + ZT_ALWAYS_INLINE Locator locator() const { return _lastFetchedLocator; } + + /** + * @return Timestamp of latest retrieved locator or 0 if none + */ + ZT_ALWAYS_INLINE int64_t locatorTimestamp() const { return _lastFetchedLocator.timestamp(); } + + /** + * Update locator, returning true if new locator is valid and newer than existing + */ + ZT_ALWAYS_INLINE bool updateLocator(const Locator &loc) + { + if (!loc.verify()) + return false; + if ((loc.phy().size() > 0)&&(loc.timestamp() > _lastFetchedLocator.timestamp())) { + _lastFetchedLocator = loc; + return true; + } + return false; + } + + /** + * Update this root's locator from a series of TXT records + */ + template + ZT_ALWAYS_INLINE bool updateLocatorFromTxt(I start,I end) + { + try { + if (_dnsPublicKeySize != ZT_ECC384_PUBLIC_KEY_SIZE) + return false; + Locator loc; + if (!loc.decodeTxtRecords(start,end,_dnsPublicKey)) // also does verify() + return false; + if ((loc.phy().size() > 0)&&(loc.timestamp() > _lastFetchedLocator.timestamp())) { + _lastFetchedLocator = loc; + return true; + } + return false; + } catch ( ... ) {} + return false; + } + + /** + * Pick a random physical IP for this root with the given address family + * + * @param addressFamily AF_INET or AF_INET6 + * @return Address or InetAddress::NIL if no addresses exist for the given family + */ + ZT_ALWAYS_INLINE const InetAddress &pickPhysical(const int addressFamily) const + { + std::vector pickList; + const std::vector *const av = (_lastFetchedLocator) ? &(_lastFetchedLocator.phy()) : &_defaultAddresses; + for(std::vector::const_iterator i(av->begin());i!=av->end();++i) { + if (addressFamily == (int)i->ss_family) { + pickList.push_back(&(*i)); + } + } + if (pickList.size() == 1) + return *pickList[0]; + else if (pickList.size() > 1) + return *pickList[(unsigned long)Utils::random() % (unsigned long)pickList.size()]; + return InetAddress::NIL; + } + +private: + Identity _defaultIdentity; + std::vector _defaultAddresses; + Str _dnsName; + Locator _lastFetchedLocator; + unsigned int _dnsPublicKeySize; + uint8_t _dnsPublicKey[ZT_ECC384_PUBLIC_KEY_SIZE]; +}; + +} // namespace ZeroTier + +#endif diff --git a/cycle_controllers.sh b/attic/cycle_controllers.sh similarity index 100% rename from cycle_controllers.sh rename to attic/cycle_controllers.sh diff --git a/ext/misc/linux-old-glibc-compat.c b/attic/linux-old-glibc-compat.c similarity index 100% rename from ext/misc/linux-old-glibc-compat.c rename to attic/linux-old-glibc-compat.c diff --git a/attic/listaddrinfo.go b/attic/listaddrinfo.go new file mode 100644 index 00000000..3db54bf0 --- /dev/null +++ b/attic/listaddrinfo.go @@ -0,0 +1,30 @@ +package main + +import ( + "fmt" + "net" +) + +func main() { + ifs, err := net.Interfaces() + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + return + } + for _, i := range ifs { + fmt.Printf("name: %s\n", i.Name) + fmt.Printf("hwaddr: %s\n", i.HardwareAddr.String()) + fmt.Printf("index: %d\n", i.Index) + fmt.Printf("addrs:\n") + addrs, _ := i.Addrs() + for _, a := range addrs { + fmt.Printf(" %s\n", a.String()) + } + fmt.Printf("multicast:\n") + mc, _ := i.MulticastAddrs() + for _, m := range mc { + fmt.Printf(" %s\n", m.String()) + } + fmt.Printf("\n") + } +} diff --git a/make-bsd.mk b/attic/make-bsd.mk similarity index 100% rename from make-bsd.mk rename to attic/make-bsd.mk diff --git a/make-linux.mk b/attic/make-linux.mk similarity index 100% rename from make-linux.mk rename to attic/make-linux.mk diff --git a/make-mac.mk b/attic/make-mac.mk similarity index 94% rename from make-mac.mk rename to attic/make-mac.mk index 1fe2d7a4..3eb8a277 100644 --- a/make-mac.mk +++ b/attic/make-mac.mk @@ -60,14 +60,14 @@ endif # Debug mode -- dump trace output, build binary with -g ifeq ($(ZT_DEBUG),1) ZT_TRACE=1 - CFLAGS+=-Wall -g $(INCLUDES) $(DEFS) + CFLAGS+=-Wall -g -maes -mpclmul $(INCLUDES) $(DEFS) STRIP=echo # The following line enables optimization for the crypto code, since # C25519 in particular is almost UNUSABLE in heavy testing without it. -node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g $(INCLUDES) $(DEFS) +node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o node/AES.o: CFLAGS = -Wall -O2 -g -maes -mpclmul $(INCLUDES) $(DEFS) else CFLAGS?=-Ofast -fstack-protector-strong - CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -mmacosx-version-min=10.7 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS) + CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -maes -msse -msse2 -msse3 -mpclmul -mmacosx-version-min=10.9 -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS) STRIP=strip endif diff --git a/make-netbsd.mk b/attic/make-netbsd.mk similarity index 100% rename from make-netbsd.mk rename to attic/make-netbsd.mk diff --git a/objects.mk b/attic/objects.mk similarity index 83% rename from objects.mk rename to attic/objects.mk index 32f62588..2bc708d8 100644 --- a/objects.mk +++ b/attic/objects.mk @@ -1,8 +1,8 @@ CORE_OBJS=\ + node/AES.o \ node/C25519.o \ - node/Capability.o \ - node/CertificateOfMembership.o \ - node/CertificateOfOwnership.o \ + node/Credential.o \ + node/ECC384.o \ node/Identity.o \ node/IncomingPacket.o \ node/InetAddress.o \ @@ -16,13 +16,10 @@ CORE_OBJS=\ node/Path.o \ node/Peer.o \ node/Poly1305.o \ - node/Revocation.o \ node/Salsa20.o \ node/SelfAwareness.o \ node/SHA512.o \ node/Switch.o \ - node/Tag.o \ - node/Topology.o \ node/Trace.o \ node/Utils.o diff --git a/one.cpp b/attic/one.cpp similarity index 88% rename from one.cpp rename to attic/one.cpp index 06d56e7a..2a3be098 100644 --- a/one.cpp +++ b/attic/one.cpp @@ -66,7 +66,6 @@ #include "node/Utils.hpp" #include "node/NetworkController.hpp" #include "node/Buffer.hpp" -#include "node/World.hpp" #include "osdep/OSUtils.hpp" #include "osdep/Http.hpp" @@ -95,10 +94,9 @@ static OneService *volatile zt1Service = (OneService *)0; static void cliPrintHelp(const char *pn,FILE *out) { fprintf(out, - "%s version %d.%d.%d build %d (platform %d arch %d)" ZT_EOL_S, + "%s version %d.%d.%d build %d" ZT_EOL_S, PROGRAM_NAME, - ZEROTIER_ONE_VERSION_MAJOR, ZEROTIER_ONE_VERSION_MINOR, ZEROTIER_ONE_VERSION_REVISION, ZEROTIER_ONE_VERSION_BUILD, - ZT_BUILD_PLATFORM, ZT_BUILD_ARCHITECTURE); + ZEROTIER_ONE_VERSION_MAJOR, ZEROTIER_ONE_VERSION_MINOR, ZEROTIER_ONE_VERSION_REVISION, ZEROTIER_ONE_VERSION_BUILD); fprintf(out, COPYRIGHT_NOTICE ZT_EOL_S LICENSE_GRANT ZT_EOL_S); @@ -119,9 +117,6 @@ static void cliPrintHelp(const char *pn,FILE *out) fprintf(out," leave - Leave a network" ZT_EOL_S); fprintf(out," set - Set a network setting" ZT_EOL_S); fprintf(out," get - Get a network setting" ZT_EOL_S); - fprintf(out," listmoons - List moons (federated root sets)" ZT_EOL_S); - fprintf(out," orbit - Join a moon via any member root" ZT_EOL_S); - fprintf(out," deorbit - Leave a moon" ZT_EOL_S); fprintf(out,ZT_EOL_S"Available settings:" ZT_EOL_S); fprintf(out," Settings to use with [get/set] may include property names from " ZT_EOL_S); fprintf(out," the JSON output of \"zerotier-cli -j listnetworks\". Additionally, " ZT_EOL_S); @@ -576,80 +571,6 @@ static int cli(int argc,char **argv) printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); return 1; } - } else if (command == "listmoons") { - const unsigned int scode = Http::GET(1024 * 1024 * 16,60000,(const struct sockaddr *)&addr,"/moon",requestHeaders,responseHeaders,responseBody); - - if (scode == 0) { - printf("Error connecting to the ZeroTier service: %s\n\nPlease check that the service is running and that TCP port 9993 can be contacted via 127.0.0.1." ZT_EOL_S, responseBody.c_str()); - return 1; - } - - nlohmann::json j; - try { - j = OSUtils::jsonParse(responseBody); - } catch (std::exception &exc) { - printf("%u %s invalid JSON response (%s)" ZT_EOL_S,scode,command.c_str(),exc.what()); - return 1; - } catch ( ... ) { - printf("%u %s invalid JSON response (unknown exception)" ZT_EOL_S,scode,command.c_str()); - return 1; - } - - if (scode == 200) { - printf("%s" ZT_EOL_S,OSUtils::jsonDump(j).c_str()); - return 0; - } else { - printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); - return 1; - } - } else if (command == "orbit") { - const uint64_t worldId = Utils::hexStrToU64(arg1.c_str()); - const uint64_t seed = Utils::hexStrToU64(arg2.c_str()); - if ((worldId)&&(seed)) { - char jsons[1024]; - OSUtils::ztsnprintf(jsons,sizeof(jsons),"{\"seed\":\"%s\"}",arg2.c_str()); - char cl[128]; - OSUtils::ztsnprintf(cl,sizeof(cl),"%u",(unsigned int)strlen(jsons)); - requestHeaders["Content-Type"] = "application/json"; - requestHeaders["Content-Length"] = cl; - unsigned int scode = Http::POST( - 1024 * 1024 * 16, - 60000, - (const struct sockaddr *)&addr, - (std::string("/moon/") + arg1).c_str(), - requestHeaders, - jsons, - (unsigned long)strlen(jsons), - responseHeaders, - responseBody); - if (scode == 200) { - printf("200 orbit OK" ZT_EOL_S); - return 0; - } else { - printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); - return 1; - } - } - } else if (command == "deorbit") { - unsigned int scode = Http::DEL( - 1024 * 1024 * 16, - 60000, - (const struct sockaddr *)&addr, - (std::string("/moon/") + arg1).c_str(), - requestHeaders, - responseHeaders, - responseBody); - if (scode == 200) { - if (json) { - printf("%s",cliFixJsonCRs(responseBody).c_str()); - } else { - printf("200 deorbit OK" ZT_EOL_S); - } - return 0; - } else { - printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); - return 1; - } } else if (command == "set") { if (arg1.length() != 16) { fprintf(stderr,"invalid format: must be a 16-digit (network) ID\n"); @@ -812,8 +733,6 @@ static void idtoolPrintHelp(FILE *out,const char *pn) fprintf(out," getpublic " ZT_EOL_S); fprintf(out," sign " ZT_EOL_S); fprintf(out," verify " ZT_EOL_S); - fprintf(out," initmoon " ZT_EOL_S); - fprintf(out," genmoon " ZT_EOL_S); } static Identity getIdFromArg(char *arg) @@ -855,7 +774,7 @@ static int idtool(int argc,char **argv) Identity id; for(;;) { - id.generate(); + id.generate(Identity::C25519); if ((id.address().toInt() >> (40 - vanityBits)) == vanity) { if (vanityBits > 0) { fprintf(stderr,"vanity address: found %.10llx !\n",(unsigned long long)id.address().toInt()); @@ -933,9 +852,10 @@ static int idtool(int argc,char **argv) fprintf(stderr,"%s is not readable" ZT_EOL_S,argv[3]); return 1; } - C25519::Signature signature = id.sign(inf.data(),(unsigned int)inf.length()); - char hexbuf[1024]; - printf("%s",Utils::hex(signature.data,ZT_C25519_SIGNATURE_LEN,hexbuf)); + uint8_t signature[ZT_SIGNATURE_BUFFER_SIZE]; + const unsigned int siglen = id.sign(inf.data(),(unsigned int)inf.length(),signature,sizeof(signature)); + char hexbuf[256]; + printf("%s",Utils::hex(signature,siglen,hexbuf)); } else if (!strcmp(argv[1],"verify")) { if (argc < 5) { idtoolPrintHelp(stdout,argv[0]); @@ -973,94 +893,6 @@ static int idtool(int argc,char **argv) return 1; } } - } else if (!strcmp(argv[1],"initmoon")) { - if (argc < 3) { - idtoolPrintHelp(stdout,argv[0]); - } else { - const Identity id = getIdFromArg(argv[2]); - if (!id) { - fprintf(stderr,"%s is not a valid identity" ZT_EOL_S,argv[2]); - return 1; - } - - C25519::Pair kp(C25519::generate()); - - char idtmp[4096]; - nlohmann::json mj; - mj["objtype"] = "world"; - mj["worldType"] = "moon"; - mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN,idtmp); - mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,ZT_C25519_PRIVATE_KEY_LEN,idtmp); - mj["id"] = id.address().toString(idtmp); - nlohmann::json seedj; - seedj["identity"] = id.toString(false,idtmp); - seedj["stableEndpoints"] = nlohmann::json::array(); - (mj["roots"] = nlohmann::json::array()).push_back(seedj); - std::string mjd(OSUtils::jsonDump(mj)); - - printf("%s" ZT_EOL_S,mjd.c_str()); - } - } else if (!strcmp(argv[1],"genmoon")) { - if (argc < 3) { - idtoolPrintHelp(stdout,argv[0]); - } else { - std::string buf; - if (!OSUtils::readFile(argv[2],buf)) { - fprintf(stderr,"cannot read %s" ZT_EOL_S,argv[2]); - return 1; - } - nlohmann::json mj(OSUtils::jsonParse(buf)); - - const uint64_t id = Utils::hexStrToU64(OSUtils::jsonString(mj["id"],"0").c_str()); - if (!id) { - fprintf(stderr,"ID in %s is invalid" ZT_EOL_S,argv[2]); - return 1; - } - - World::Type t; - if (mj["worldType"] == "moon") { - t = World::TYPE_MOON; - } else if (mj["worldType"] == "planet") { - t = World::TYPE_PLANET; - } else { - fprintf(stderr,"invalid worldType" ZT_EOL_S); - return 1; - } - - C25519::Pair signingKey; - C25519::Public updatesMustBeSignedBy; - Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,ZT_C25519_PUBLIC_KEY_LEN); - Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,ZT_C25519_PRIVATE_KEY_LEN); - Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,ZT_C25519_PUBLIC_KEY_LEN); - - std::vector roots; - nlohmann::json &rootsj = mj["roots"]; - if (rootsj.is_array()) { - for(unsigned long i=0;i<(unsigned long)rootsj.size();++i) { - nlohmann::json &r = rootsj[i]; - if (r.is_object()) { - roots.push_back(World::Root()); - roots.back().identity = Identity(OSUtils::jsonString(r["identity"],"").c_str()); - nlohmann::json &stableEndpointsj = r["stableEndpoints"]; - if (stableEndpointsj.is_array()) { - for(unsigned long k=0;k<(unsigned long)stableEndpointsj.size();++k) - roots.back().stableEndpoints.push_back(InetAddress(OSUtils::jsonString(stableEndpointsj[k],"").c_str())); - std::sort(roots.back().stableEndpoints.begin(),roots.back().stableEndpoints.end()); - } - } - } - } - std::sort(roots.begin(),roots.end()); - - const int64_t now = OSUtils::now(); - World w(World::make(t,id,now,updatesMustBeSignedBy,roots,signingKey)); - Buffer wbuf; - w.serialize(wbuf); - char fn[128]; - OSUtils::ztsnprintf(fn,sizeof(fn),"%.16llx.moon",w.id()); - OSUtils::writeFile(fn,wbuf.data(),wbuf.size()); - printf("wrote %s (signed world with timestamp %llu)" ZT_EOL_S,fn,(unsigned long long)now); - } } else { idtoolPrintHelp(stdout,argv[0]); return 1; diff --git a/rule-compiler/README.md b/attic/rule-compiler/README.md similarity index 100% rename from rule-compiler/README.md rename to attic/rule-compiler/README.md diff --git a/rule-compiler/cli.js b/attic/rule-compiler/cli.js similarity index 100% rename from rule-compiler/cli.js rename to attic/rule-compiler/cli.js diff --git a/rule-compiler/examples/capabilities-and-tags.ztrules b/attic/rule-compiler/examples/capabilities-and-tags.ztrules similarity index 100% rename from rule-compiler/examples/capabilities-and-tags.ztrules rename to attic/rule-compiler/examples/capabilities-and-tags.ztrules diff --git a/rule-compiler/package.json b/attic/rule-compiler/package.json similarity index 100% rename from rule-compiler/package.json rename to attic/rule-compiler/package.json diff --git a/rule-compiler/rule-compiler.js b/attic/rule-compiler/rule-compiler.js similarity index 100% rename from rule-compiler/rule-compiler.js rename to attic/rule-compiler/rule-compiler.js diff --git a/attic/service/CMakeLists.txt b/attic/service/CMakeLists.txt new file mode 100644 index 00000000..bebfb2cd --- /dev/null +++ b/attic/service/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 2.8) +project(zt_service) + +if(WIN32) + add_definitions(-DNOMINMAX) +endif(WIN32) + +set(src + OneService.cpp +) + +set(headers + OneService.hpp +) + +add_library(${PROJECT_NAME} STATIC ${src} ${headers}) +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11) diff --git a/service/OneService.cpp b/attic/service/OneService.cpp similarity index 77% rename from service/OneService.cpp rename to attic/service/OneService.cpp index 69b439ae..e84da792 100644 --- a/service/OneService.cpp +++ b/attic/service/OneService.cpp @@ -25,8 +25,7 @@ #include #include -#include "../version.h" -#include "../include/ZeroTierOne.h" +#include "../include/ZeroTierCore.h" #include "../node/Constants.hpp" #include "../node/Mutex.hpp" @@ -35,7 +34,6 @@ #include "../node/InetAddress.hpp" #include "../node/MAC.hpp" #include "../node/Identity.hpp" -#include "../node/World.hpp" #include "../node/Salsa20.hpp" #include "../node/Poly1305.hpp" #include "../node/SHA512.hpp" @@ -50,7 +48,6 @@ #include "../osdep/BlockingQueue.hpp" #include "OneService.hpp" -#include "SoftwareUpdater.hpp" #ifdef __WINDOWS__ #include @@ -75,12 +72,6 @@ #include "../ext/http-parser/http_parser.h" #endif -#if ZT_VAULT_SUPPORT -extern "C" { -#include -} -#endif - #include "../ext/json/json.hpp" using json = nlohmann::json; @@ -92,10 +83,6 @@ using json = nlohmann::json; #include "../osdep/WindowsEthernetTap.hpp" #endif -#ifndef ZT_SOFTWARE_UPDATE_DEFAULT -#define ZT_SOFTWARE_UPDATE_DEFAULT "disable" -#endif - // Sanity limits for HTTP #define ZT_MAX_HTTP_MESSAGE_SIZE (1024 * 1024 * 64) #define ZT_MAX_HTTP_CONNECTIONS 65536 @@ -107,62 +94,16 @@ using json = nlohmann::json; // How often to check for new multicast subscriptions on a tap device #define ZT_TAP_CHECK_MULTICAST_INTERVAL 5000 -// TCP fallback relay (run by ZeroTier, Inc. -- this will eventually go away) -#ifndef ZT_SDK -#define ZT_TCP_FALLBACK_RELAY "204.80.128.1/443" -#endif - -// Frequency at which we re-resolve the TCP fallback relay -#define ZT_TCP_FALLBACK_RERESOLVE_DELAY 86400000 - -// Attempt to engage TCP fallback after this many ms of no reply to packets sent to global-scope IPs -#define ZT_TCP_FALLBACK_AFTER 60000 - // How often to check for local interface addresses #define ZT_LOCAL_INTERFACE_CHECK_INTERVAL 60000 -// Maximum write buffer size for outgoing TCP connections (sanity limit) -#define ZT_TCP_MAX_WRITEQ_SIZE 33554432 - -// TCP activity timeout -#define ZT_TCP_ACTIVITY_TIMEOUT 60000 - -#if ZT_VAULT_SUPPORT -size_t curlResponseWrite(void *ptr, size_t size, size_t nmemb, std::string *data) -{ - data->append((char*)ptr, size * nmemb); - return size * nmemb; -} -#endif +// How often local.conf is checked for changes +#define ZT_LOCAL_CONF_FILE_CHECK_INTERVAL 10000 namespace ZeroTier { namespace { -static const InetAddress NULL_INET_ADDR; - -// Fake TLS hello for TCP tunnel outgoing connections (TUNNELED mode) -static const char ZT_TCP_TUNNEL_HELLO[9] = { 0x17,0x03,0x03,0x00,0x04,(char)ZEROTIER_ONE_VERSION_MAJOR,(char)ZEROTIER_ONE_VERSION_MINOR,(char)((ZEROTIER_ONE_VERSION_REVISION >> 8) & 0xff),(char)(ZEROTIER_ONE_VERSION_REVISION & 0xff) }; - -static std::string _trimString(const std::string &s) -{ - unsigned long end = (unsigned long)s.length(); - while (end) { - char c = s[end - 1]; - if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) - --end; - else break; - } - unsigned long start = 0; - while (start < end) { - char c = s[start]; - if ((c == ' ')||(c == '\r')||(c == '\n')||(!c)||(c == '\t')) - ++start; - else break; - } - return s.substr(start,end - start); -} - static void _networkToJson(nlohmann::json &nj,const ZT_VirtualNetworkConfig *nc,const std::string &portDeviceName,const OneService::NetworkSettings &localSettings) { char tmp[256]; @@ -300,28 +241,6 @@ static void _peerAggregateLinkToJson(nlohmann::json &pj,const ZT_Peer *peer) pj["paths"] = pa; } -static void _moonToJson(nlohmann::json &mj,const World &world) -{ - char tmp[4096]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",world.id()); - mj["id"] = tmp; - mj["timestamp"] = world.timestamp(); - mj["signature"] = Utils::hex(world.signature().data,ZT_C25519_SIGNATURE_LEN,tmp); - mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data,ZT_C25519_PUBLIC_KEY_LEN,tmp); - nlohmann::json ra = nlohmann::json::array(); - for(std::vector::const_iterator r(world.roots().begin());r!=world.roots().end();++r) { - nlohmann::json rj; - rj["identity"] = r->identity.toString(false,tmp); - nlohmann::json eps = nlohmann::json::array(); - for(std::vector::const_iterator a(r->stableEndpoints.begin());a!=r->stableEndpoints.end();++a) - eps.push_back(a->toString(tmp)); - rj["stableEndpoints"] = eps; - ra.push_back(rj); - } - mj["roots"] = ra; - mj["waiting"] = false; -} - class OneServiceImpl; static int SnodeVirtualNetworkConfigFunction(ZT_Node *node,void *uptr,void *tptr,uint64_t nwid,void **nuptr,enum ZT_VirtualNetworkConfigOperation op,const ZT_VirtualNetworkConfig *nwconf); @@ -378,8 +297,6 @@ struct TcpConnection enum { TCP_UNCATEGORIZED_INCOMING, // uncategorized incoming connection TCP_HTTP_INCOMING, - TCP_HTTP_OUTGOING, - TCP_TUNNEL_OUTGOING // TUNNELED mode proxy outbound connection } type; OneServiceImpl *parent; @@ -401,15 +318,6 @@ struct TcpConnection Mutex writeq_m; }; -struct OneServiceIncomingPacket -{ - uint64_t now; - int64_t sock; - struct sockaddr_storage from; - unsigned int size; - uint8_t data[ZT_MAX_MTU]; -}; - class OneServiceImpl : public OneService { public: @@ -424,17 +332,14 @@ public: EmbeddedNetworkController *_controller; Phy _phy; Node *_node; - SoftwareUpdater *_updater; PhySocket *_localControlSocket4; PhySocket *_localControlSocket6; bool _updateAutoApply; - bool _allowTcpFallbackRelay; bool _allowSecondaryPort; unsigned int _multipathMode; unsigned int _primaryPort; unsigned int _secondaryPort; unsigned int _tertiaryPort; - volatile unsigned int _udpPortPickerCounter; // Local configuration and memo-ized information from it json _localConfig; @@ -448,7 +353,7 @@ public: std::vector< std::string > _interfacePrefixBlacklist; Mutex _localConfig_m; - std::vector explicitBind; + std::vector _explicitBind; /* * To attempt to handle NAT/gateway craziness we use three local UDP ports: @@ -466,9 +371,6 @@ public: // Time we last received a packet from a global address uint64_t _lastDirectReceiveFromGlobal; -#ifdef ZT_TCP_FALLBACK_RELAY - uint64_t _lastSendToGlobalV4; -#endif // Last potential sleep/wake event uint64_t _lastRestart; @@ -500,7 +402,6 @@ public: // Active TCP/IP connections std::vector< TcpConnection * > _tcpConnections; Mutex _tcpConnections_m; - TcpConnection *_tcpFallbackTunnel; // Termination status information ReasonForTermination _termReason; @@ -509,17 +410,7 @@ public: // uPnP/NAT-PMP port mapper if enabled bool _portMappingEnabled; // local.conf settings -#ifdef ZT_USE_MINIUPNPC PortMapper *_portMapper; -#endif - - // HashiCorp Vault Settings -#if ZT_VAULT_SUPPORT - bool _vaultEnabled; - std::string _vaultURL; - std::string _vaultToken; - std::string _vaultPath; // defaults to cubbyhole/zerotier/identity.secret for per-access key storage -#endif // Set to false to force service to stop volatile bool _run; @@ -537,40 +428,22 @@ public: ,_controller((EmbeddedNetworkController *)0) ,_phy(this,false,true) ,_node((Node *)0) - ,_updater((SoftwareUpdater *)0) ,_localControlSocket4((PhySocket *)0) ,_localControlSocket6((PhySocket *)0) ,_updateAutoApply(false) ,_primaryPort(port) - ,_udpPortPickerCounter(0) ,_lastDirectReceiveFromGlobal(0) -#ifdef ZT_TCP_FALLBACK_RELAY - ,_lastSendToGlobalV4(0) -#endif ,_lastRestart(0) ,_nextBackgroundTaskDeadline(0) - ,_tcpFallbackTunnel((TcpConnection *)0) ,_termReason(ONE_STILL_RUNNING) ,_portMappingEnabled(true) -#ifdef ZT_USE_MINIUPNPC ,_portMapper((PortMapper *)0) -#endif -#ifdef ZT_VAULT_SUPPORT - ,_vaultEnabled(false) - ,_vaultURL() - ,_vaultToken() - ,_vaultPath("cubbyhole/zerotier") -#endif ,_run(true) ,_mqc(NULL) { _ports[0] = 0; _ports[1] = 0; _ports[2] = 0; - -#if ZT_VAULT_SUPPORT - curl_global_init(CURL_GLOBAL_DEFAULT); -#endif } virtual ~OneServiceImpl() @@ -579,13 +452,7 @@ public: _phy.close(_localControlSocket4); _phy.close(_localControlSocket6); -#if ZT_VAULT_SUPPORT - curl_global_cleanup(); -#endif - -#ifdef ZT_USE_MINIUPNPC delete _portMapper; -#endif delete _controller; delete _mqc; } @@ -610,12 +477,11 @@ public: OSUtils::lockDownFile(authTokenPath.c_str(),false); } } - _authToken = _trimString(_authToken); + _authToken = OSUtils::trimString(_authToken); } { struct ZT_Node_Callbacks cb; - cb.version = 0; cb.stateGetFunction = SnodeStateGetFunction; cb.statePutFunction = SnodeStatePutFunction; cb.wirePacketSendFunction = SnodeWirePacketSendFunction; @@ -691,7 +557,6 @@ public: } } -#ifdef ZT_USE_MINIUPNPC if (_portMappingEnabled) { // If we're running uPnP/NAT-PMP, bind a *third* port for that. We can't // use the other two ports for that because some NATs do really funky @@ -715,14 +580,13 @@ public: } } } -#endif // Delete legacy iddb.d if present (cleanup) OSUtils::rmDashRf((_homePath + ZT_PATH_SEPARATOR_S "iddb.d").c_str()); // Network controller is now enabled by default for desktop and server _controller = new EmbeddedNetworkController(_node,_homePath.c_str(),_controllerDbPath.c_str(),_ports[0], _mqc); - _node->setNetconfMaster((void *)_controller); + _node->setController((void *)_controller); // Join existing networks in networks.d { @@ -734,23 +598,12 @@ public: } } - // Orbit existing moons in moons.d - { - std::vector moonsDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S "moons.d").c_str())); - for(std::vector::iterator f(moonsDotD.begin());f!=moonsDotD.end();++f) { - std::size_t dot = f->find_last_of('.'); - if ((dot == 16)&&(f->substr(16) == ".moon")) - _node->orbit((void *)0,Utils::hexStrToU64(f->substr(0,dot).c_str()),0); - } - } - // Main I/O loop _nextBackgroundTaskDeadline = 0; int64_t clockShouldBe = OSUtils::now(); _lastRestart = clockShouldBe; int64_t lastTapMulticastGroupCheck = 0; int64_t lastBindRefresh = 0; - int64_t lastUpdateCheck = clockShouldBe; int64_t lastMultipathModeUpdate = 0; int64_t lastCleanedPeersDb = 0; int64_t lastLocalInterfaceAddressCheck = (clockShouldBe - ZT_LOCAL_INTERFACE_CHECK_INTERVAL) + 15000; // do this in 15s to give portmapper time to configure and other things time to settle @@ -776,13 +629,6 @@ public: restarted = true; } - // Check for updates (if enabled) - if ((_updater)&&((now - lastUpdateCheck) > 10000)) { - lastUpdateCheck = now; - if (_updater->check(now) && _updateAutoApply) - _updater->apply(); - } - // Reload local.conf if anything changed recently if ((now - lastLocalConfFileCheck) >= ZT_LOCAL_CONF_FILE_CHECK_INTERVAL) { lastLocalConfFileCheck = now; @@ -805,7 +651,7 @@ public: if (_ports[i]) p[pc++] = _ports[i]; } - _binder.refresh(_phy,p,pc,explicitBind,*this); + _binder.refresh(_phy,p,pc,_explicitBind,*this); { Mutex::Lock _l(_nets_m); for(std::map::iterator n(_nets.begin());n!=_nets.end();++n) { @@ -827,10 +673,6 @@ public: dl = _nextBackgroundTaskDeadline; } - // Close TCP fallback tunnel if we have direct UDP - if ((_tcpFallbackTunnel)&&((now - _lastDirectReceiveFromGlobal) < (ZT_TCP_FALLBACK_AFTER / 2))) - _phy.close(_tcpFallbackTunnel->sock); - // Sync multicast group memberships if ((now - lastTapMulticastGroupCheck) >= ZT_TAP_CHECK_MULTICAST_INTERVAL) { lastTapMulticastGroupCheck = now; @@ -859,13 +701,11 @@ public: _node->clearLocalInterfaceAddresses(); -#ifdef ZT_USE_MINIUPNPC if (_portMapper) { std::vector mappedAddresses(_portMapper->get()); for(std::vector::const_iterator ext(mappedAddresses.begin());ext!=mappedAddresses.end();++ext) _node->addLocalInterfaceAddress(reinterpret_cast(&(*ext))); } -#endif std::vector boundAddrs(_binder.allBoundLocalInterfaceAddresses()); for(std::vector::const_iterator i(boundAddrs.begin());i!=boundAddrs.end();++i) @@ -903,8 +743,6 @@ public: _nets.clear(); } - delete _updater; - _updater = (SoftwareUpdater *)0; delete _node; _node = (Node *)0; @@ -1003,7 +841,7 @@ public: if (ips.length() > 0) { InetAddress ip(ips.c_str()); if ((ip.ss_family == AF_INET)||(ip.ss_family == AF_INET6)) - explicitBind.push_back(ip); + _explicitBind.push_back(ip); } } } @@ -1199,7 +1037,6 @@ public: res["address"] = tmp; res["publicIdentity"] = status.publicIdentity; res["online"] = (bool)(status.online != 0); - res["tcpFallbackActive"] = (_tcpFallbackTunnel != (TcpConnection *)0); res["versionMajor"] = ZEROTIER_ONE_VERSION_MAJOR; res["versionMinor"] = ZEROTIER_ONE_VERSION_MINOR; res["versionRev"] = ZEROTIER_ONE_VERSION_REVISION; @@ -1214,7 +1051,6 @@ public: } json &settings = res["config"]["settings"]; settings["primaryPort"] = OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff; - settings["allowTcpFallbackRelay"] = OSUtils::jsonBool(settings["allowTcpFallbackRelay"],_allowTcpFallbackRelay); if (_multipathMode) { json &multipathConfig = res["multipath"]; @@ -1232,46 +1068,9 @@ public: } } -#ifdef ZT_USE_MINIUPNPC settings["portMappingEnabled"] = OSUtils::jsonBool(settings["portMappingEnabled"],true); -#else - settings["portMappingEnabled"] = false; // not supported in build -#endif -#ifndef ZT_SDK - settings["softwareUpdate"] = OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT); - settings["softwareUpdateChannel"] = OSUtils::jsonString(settings["softwareUpdateChannel"],ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL); -#endif - const World planet(_node->planet()); - res["planetWorldId"] = planet.id(); - res["planetWorldTimestamp"] = planet.timestamp(); scode = 200; - } else if (ps[0] == "moon") { - std::vector moons(_node->moons()); - if (ps.size() == 1) { - // Return [array] of all moons - - res = json::array(); - for(std::vector::const_iterator m(moons.begin());m!=moons.end();++m) { - json mj; - _moonToJson(mj,*m); - res.push_back(mj); - } - - scode = 200; - } else { - // Return a single moon by ID - - const uint64_t id = Utils::hexStrToU64(ps[1].c_str()); - for(std::vector::const_iterator m(moons.begin());m!=moons.end();++m) { - if (m->id() == id) { - _moonToJson(res,*m); - scode = 200; - break; - } - } - - } } else if (ps[0] == "network") { ZT_VirtualNetworkList *nws = _node->networks(); if (nws) { @@ -1344,44 +1143,7 @@ public: } else if ((httpMethod == HTTP_POST)||(httpMethod == HTTP_PUT)) { if (isAuth) { - if (ps[0] == "moon") { - if (ps.size() == 2) { - - uint64_t seed = 0; - try { - json j(OSUtils::jsonParse(body)); - if (j.is_object()) { - seed = Utils::hexStrToU64(OSUtils::jsonString(j["seed"],"0").c_str()); - } - } catch (std::exception &exc) { - } catch ( ... ) { - } - - std::vector moons(_node->moons()); - const uint64_t id = Utils::hexStrToU64(ps[1].c_str()); - for(std::vector::const_iterator m(moons.begin());m!=moons.end();++m) { - if (m->id() == id) { - _moonToJson(res,*m); - scode = 200; - break; - } - } - - if ((scode != 200)&&(seed != 0)) { - char tmp[64]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"%.16llx",id); - res["id"] = tmp; - res["roots"] = json::array(); - res["timestamp"] = 0; - res["signature"] = json(); - res["updatesMustBeSignedBy"] = json(); - res["waiting"] = true; - _node->orbit((void *)0,id,seed); - scode = 200; - } - - } else scode = 404; - } else if (ps[0] == "network") { + if (ps[0] == "network") { if (ps.size() == 2) { uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str()); @@ -1428,13 +1190,7 @@ public: } else if (httpMethod == HTTP_DELETE) { if (isAuth) { - if (ps[0] == "moon") { - if (ps.size() == 2) { - _node->deorbit((void *)0,Utils::hexStrToU64(ps[1].c_str())); - res["result"] = true; - scode = 200; - } // else 404 - } else if (ps[0] == "network") { + if (ps[0] == "network") { ZT_VirtualNetworkList *nws = _node->networks(); if (nws) { if (ps.size() == 2) { @@ -1559,7 +1315,6 @@ public: json &settings = lc["settings"]; _primaryPort = (unsigned int)OSUtils::jsonInt(settings["primaryPort"],(uint64_t)_primaryPort) & 0xffff; - _allowTcpFallbackRelay = OSUtils::jsonBool(settings["allowTcpFallbackRelay"],true); _allowSecondaryPort = OSUtils::jsonBool(settings["allowSecondaryPort"],true); _secondaryPort = (unsigned int)OSUtils::jsonInt(settings["secondaryPort"],0); _tertiaryPort = (unsigned int)OSUtils::jsonInt(settings["tertiaryPort"],0); @@ -1567,28 +1322,8 @@ public: fprintf(stderr,"WARNING: using manually-specified ports. This can cause NAT issues." ZT_EOL_S); } _multipathMode = (unsigned int)OSUtils::jsonInt(settings["multipathMode"],0); - if (_multipathMode != 0 && _allowTcpFallbackRelay) { - fprintf(stderr,"WARNING: multipathMode cannot be used with allowTcpFallbackRelay. Disabling allowTcpFallbackRelay" ZT_EOL_S); - _allowTcpFallbackRelay = false; - } _portMappingEnabled = OSUtils::jsonBool(settings["portMappingEnabled"],true); -#ifndef ZT_SDK - const std::string up(OSUtils::jsonString(settings["softwareUpdate"],ZT_SOFTWARE_UPDATE_DEFAULT)); - const bool udist = OSUtils::jsonBool(settings["softwareUpdateDist"],false); - if (((up == "apply")||(up == "download"))||(udist)) { - if (!_updater) - _updater = new SoftwareUpdater(*_node,_homePath); - _updateAutoApply = (up == "apply"); - _updater->setUpdateDistribution(udist); - _updater->setChannel(OSUtils::jsonString(settings["softwareUpdateChannel"],ZT_SOFTWARE_UPDATE_DEFAULT_CHANNEL)); - } else { - delete _updater; - _updater = (SoftwareUpdater *)0; - _updateAutoApply = false; - } -#endif - json &ignoreIfs = settings["interfacePrefixBlacklist"]; if (ignoreIfs.is_array()) { for(unsigned long i=0;i(&(n.config.routes[i].target)); const InetAddress *const via = reinterpret_cast(&(n.config.routes[i].via)); - const InetAddress *src = NULL; - for (unsigned int j=0; j(&(n.config.assignedAddresses[j])); - if (target->isV4() && tmp->isV4()) { - src = reinterpret_cast(&(n.config.assignedAddresses[j])); - break; - } else if (target->isV6() && tmp->isV6()) { - src = reinterpret_cast(&(n.config.assignedAddresses[j])); - break; - } - } - if (!src) - src = &NULL_INET_ADDR; - if ( (!checkIfManagedIsAllowed(n,*target)) || ((via->ss_family == target->ss_family)&&(matchIpOnly(myIps,*via))) ) continue; @@ -1807,7 +1487,7 @@ public: continue; // Add and apply new routes - n.managedRoutes.push_back(SharedPtr(new ManagedRoute(*target,*via,*src,tapdev))); + n.managedRoutes.push_back(SharedPtr(new ManagedRoute(*target,*via,tapdev))); if (!n.managedRoutes.back()->sync()) n.managedRoutes.pop_back(); #endif @@ -1837,26 +1517,7 @@ public: inline void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) { - if (!success) { - phyOnTcpClose(sock,uptr); - return; - } - - TcpConnection *const tc = reinterpret_cast(*uptr); - if (!tc) { // sanity check - _phy.close(sock,true); - return; - } - tc->sock = sock; - - if (tc->type == TcpConnection::TCP_TUNNEL_OUTGOING) { - if (_tcpFallbackTunnel) - _phy.close(_tcpFallbackTunnel->sock); - _tcpFallbackTunnel = tc; - _phy.streamSend(sock,ZT_TCP_TUNNEL_HELLO,sizeof(ZT_TCP_TUNNEL_HELLO)); - } else { - _phy.close(sock,true); - } + _phy.close(sock,true); } inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) @@ -1895,9 +1556,6 @@ public: { TcpConnection *tc = (TcpConnection *)*uptr; if (tc) { - if (tc == _tcpFallbackTunnel) { - _tcpFallbackTunnel = (TcpConnection *)0; - } { Mutex::Lock _l(_tcpConnections_m); _tcpConnections.erase(std::remove(_tcpConnections.begin(),_tcpConnections.end(),tc),_tcpConnections.end()); @@ -1954,86 +1612,11 @@ public: return; case TcpConnection::TCP_HTTP_INCOMING: - case TcpConnection::TCP_HTTP_OUTGOING: http_parser_execute(&(tc->parser),&HTTP_PARSER_SETTINGS,(const char *)data,len); if ((tc->parser.upgrade)||(tc->parser.http_errno != HPE_OK)) _phy.close(sock); return; - case TcpConnection::TCP_TUNNEL_OUTGOING: - tc->readq.append((const char *)data,len); - while (tc->readq.length() >= 5) { - const char *data = tc->readq.data(); - const unsigned long mlen = ( ((((unsigned long)data[3]) & 0xff) << 8) | (((unsigned long)data[4]) & 0xff) ); - if (tc->readq.length() >= (mlen + 5)) { - InetAddress from; - - unsigned long plen = mlen; // payload length, modified if there's an IP header - data += 5; // skip forward past pseudo-TLS junk and mlen - if (plen == 4) { - // Hello message, which isn't sent by proxy and would be ignored by client - } else if (plen) { - // Messages should contain IPv4 or IPv6 source IP address data - switch(data[0]) { - case 4: // IPv4 - if (plen >= 7) { - from.set((const void *)(data + 1),4,((((unsigned int)data[5]) & 0xff) << 8) | (((unsigned int)data[6]) & 0xff)); - data += 7; // type + 4 byte IP + 2 byte port - plen -= 7; - } else { - _phy.close(sock); - return; - } - break; - case 6: // IPv6 - if (plen >= 19) { - from.set((const void *)(data + 1),16,((((unsigned int)data[17]) & 0xff) << 8) | (((unsigned int)data[18]) & 0xff)); - data += 19; // type + 16 byte IP + 2 byte port - plen -= 19; - } else { - _phy.close(sock); - return; - } - break; - case 0: // none/omitted - ++data; - --plen; - break; - default: // invalid address type - _phy.close(sock); - return; - } - - if (from) { - InetAddress fakeTcpLocalInterfaceAddress((uint32_t)0xffffffff,0xffff); - const ZT_ResultCode rc = _node->processWirePacket( - (void *)0, - OSUtils::now(), - -1, - reinterpret_cast(&from), - data, - plen, - &_nextBackgroundTaskDeadline); - if (ZT_ResultCode_isFatal(rc)) { - char tmp[256]; - OSUtils::ztsnprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket: %d",(int)rc); - Mutex::Lock _l(_termReason_m); - _termReason = ONE_UNRECOVERABLE_ERROR; - _fatalErrorMessage = tmp; - this->terminate(); - _phy.close(sock); - return; - } - } - } - - if (tc->readq.length() > (mlen + 5)) - tc->readq.erase(tc->readq.begin(),tc->readq.begin() + (mlen + 5)); - else tc->readq.clear(); - } else break; - } - return; - } } catch (std::exception &exc) { _phy.close(sock); @@ -2204,12 +1787,6 @@ public: inline void nodeEventCallback(enum ZT_Event event,const void *metaData) { switch(event) { - case ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION: { - Mutex::Lock _l(_termReason_m); - _termReason = ONE_IDENTITY_COLLISION; - _fatalErrorMessage = "identity/address collision"; - this->terminate(); - } break; case ZT_EVENT_TRACE: { if (metaData) { @@ -2218,106 +1795,18 @@ public: } } break; - case ZT_EVENT_USER_MESSAGE: { - const ZT_UserMessage *um = reinterpret_cast(metaData); - if ((um->typeId == ZT_SOFTWARE_UPDATE_USER_MESSAGE_TYPE)&&(_updater)) { - _updater->handleSoftwareUpdateUserMessage(um->origin,um->data,um->length); - } - } break; - case ZT_EVENT_REMOTE_TRACE: { - const ZT_RemoteTrace *rt = reinterpret_cast(metaData); - if ((rt)&&(rt->len > 0)&&(rt->len <= ZT_MAX_REMOTE_TRACE_SIZE)&&(rt->data)) - _controller->handleRemoteTrace(*rt); + // TODO } default: break; + } } -#if ZT_VAULT_SUPPORT - inline bool nodeVaultPutIdentity(enum ZT_StateObjectType type, const void *data, int len) - { - bool retval = false; - if (type != ZT_STATE_OBJECT_IDENTITY_PUBLIC && type != ZT_STATE_OBJECT_IDENTITY_SECRET) { - return retval; - } - - CURL *curl = curl_easy_init(); - if (curl) { - char token[512] = { 0 }; - snprintf(token, sizeof(token), "X-Vault-Token: %s", _vaultToken.c_str()); - - struct curl_slist *chunk = NULL; - chunk = curl_slist_append(chunk, token); - - - char content_type[512] = { 0 }; - snprintf(content_type, sizeof(content_type), "Content-Type: application/json"); - - chunk = curl_slist_append(chunk, content_type); - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); - - char url[2048] = { 0 }; - snprintf(url, sizeof(url), "%s/v1/%s", _vaultURL.c_str(), _vaultPath.c_str()); - - curl_easy_setopt(curl, CURLOPT_URL, url); - - json d = json::object(); - if (type == ZT_STATE_OBJECT_IDENTITY_PUBLIC) { - std::string key((const char*)data, len); - d["public"] = key; - } - else if (type == ZT_STATE_OBJECT_IDENTITY_SECRET) { - std::string key((const char*)data, len); - d["secret"] = key; - } - - if (!d.empty()) { - std::string post = d.dump(); - - if (!post.empty()) { - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post.c_str()); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, post.length()); - -#ifndef NDEBUG - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); -#endif - - CURLcode res = curl_easy_perform(curl); - if (res == CURLE_OK) { - long response_code = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); - if (response_code == 200 || response_code == 204) { - retval = true; - } - } - } - } - - curl_easy_cleanup(curl); - curl = NULL; - curl_slist_free_all(chunk); - chunk = NULL; - } - - return retval; - } -#endif - inline void nodeStatePutFunction(enum ZT_StateObjectType type,const uint64_t id[2],const void *data,int len) { -#if ZT_VAULT_SUPPORT - if (_vaultEnabled && (type == ZT_STATE_OBJECT_IDENTITY_SECRET || type == ZT_STATE_OBJECT_IDENTITY_PUBLIC)) { - if (nodeVaultPutIdentity(type, data, len)) { - // value successfully written to Vault - return; - } - // else fallback to disk - } -#endif char p[1024]; FILE *f; bool secure = false; @@ -2332,13 +1821,6 @@ public: OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str()); secure = true; break; - case ZT_STATE_OBJECT_PLANET: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str()); - break; - case ZT_STATE_OBJECT_MOON: - OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "moons.d",_homePath.c_str()); - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.moon",dirname,(unsigned long long)id[0]); - break; case ZT_STATE_OBJECT_NETWORK_CONFIG: OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "networks.d",_homePath.c_str()); OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx.conf",dirname,(unsigned long long)id[0]); @@ -2348,6 +1830,9 @@ public: OSUtils::ztsnprintf(dirname,sizeof(dirname),"%s" ZT_PATH_SEPARATOR_S "peers.d",_homePath.c_str()); OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.10llx.peer",dirname,(unsigned long long)id[0]); break; + case ZT_STATE_OBJECT_ROOT_LIST: + OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "roots",_homePath.c_str()); + break; default: return; } @@ -2389,93 +1874,8 @@ public: } } -#if ZT_VAULT_SUPPORT - inline int nodeVaultGetIdentity(enum ZT_StateObjectType type, void *data, unsigned int maxlen) - { - if (type != ZT_STATE_OBJECT_IDENTITY_SECRET && type != ZT_STATE_OBJECT_IDENTITY_PUBLIC) { - return -1; - } - - int ret = -1; - CURL *curl = curl_easy_init(); - if (curl) { - char token[512] = { 0 }; - snprintf(token, sizeof(token), "X-Vault-Token: %s", _vaultToken.c_str()); - - struct curl_slist *chunk = NULL; - chunk = curl_slist_append(chunk, token); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); - - char url[2048] = { 0 }; - snprintf(url, sizeof(url), "%s/v1/%s", _vaultURL.c_str(), _vaultPath.c_str()); - - curl_easy_setopt(curl, CURLOPT_URL, url); - - std::string response; - std::string res_headers; - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlResponseWrite); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); - curl_easy_setopt(curl, CURLOPT_HEADERDATA, &res_headers); - -#ifndef NDEBUG - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); -#endif - - CURLcode res = curl_easy_perform(curl); - - if (res == CURLE_OK) { - long response_code = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); - if (response_code == 200) { - try { - json payload = json::parse(response); - if (!payload["data"].is_null()) { - json &d = payload["data"]; - if (type == ZT_STATE_OBJECT_IDENTITY_SECRET) { - std::string secret = OSUtils::jsonString(d["secret"],""); - - if (!secret.empty()) { - ret = (int)secret.length(); - memcpy(data, secret.c_str(), ret); - } - } - else if (type == ZT_STATE_OBJECT_IDENTITY_PUBLIC) { - std::string pub = OSUtils::jsonString(d["public"],""); - - if (!pub.empty()) { - ret = (int)pub.length(); - memcpy(data, pub.c_str(), ret); - } - } - } - } - catch (...) { - ret = -1; - } - } - } - - curl_easy_cleanup(curl); - curl = NULL; - curl_slist_free_all(chunk); - chunk = NULL; - } - return ret; - } -#endif - inline int nodeStateGetFunction(enum ZT_StateObjectType type,const uint64_t id[2],void *data,unsigned int maxlen) { -#if ZT_VAULT_SUPPORT - if (_vaultEnabled && (type == ZT_STATE_OBJECT_IDENTITY_SECRET || type == ZT_STATE_OBJECT_IDENTITY_PUBLIC) ) { - int retval = nodeVaultGetIdentity(type, data, maxlen); - if (retval >= 0) - return retval; - - // else continue file based lookup - } -#endif char p[4096]; switch(type) { case ZT_STATE_OBJECT_IDENTITY_PUBLIC: @@ -2484,12 +1884,6 @@ public: case ZT_STATE_OBJECT_IDENTITY_SECRET: OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "identity.secret",_homePath.c_str()); break; - case ZT_STATE_OBJECT_PLANET: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "planet",_homePath.c_str()); - break; - case ZT_STATE_OBJECT_MOON: - OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "moons.d" ZT_PATH_SEPARATOR_S "%.16llx.moon",_homePath.c_str(),(unsigned long long)id[0]); - break; case ZT_STATE_OBJECT_NETWORK_CONFIG: OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.conf",_homePath.c_str(),(unsigned long long)id[0]); break; @@ -2503,17 +1897,6 @@ public: if (f) { int n = (int)fread(data,1,maxlen,f); fclose(f); -#if ZT_VAULT_SUPPORT - if (_vaultEnabled && (type == ZT_STATE_OBJECT_IDENTITY_SECRET || type == ZT_STATE_OBJECT_IDENTITY_PUBLIC)) { - // If we've gotten here while Vault is enabled, Vault does not know the key and it's been - // read from disk instead. - // - // We should put the value in Vault and remove the local file. - if (nodeVaultPutIdentity(type, data, n)) { - unlink(p); - } - } -#endif if (n >= 0) return n; } @@ -2522,68 +1905,6 @@ public: inline int nodeWirePacketSendFunction(const int64_t localSocket,const struct sockaddr_storage *addr,const void *data,unsigned int len,unsigned int ttl) { -#ifdef ZT_TCP_FALLBACK_RELAY - if(_allowTcpFallbackRelay) { - if (addr->ss_family == AF_INET) { - // TCP fallback tunnel support, currently IPv4 only - if ((len >= 16)&&(reinterpret_cast(addr)->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) { - // Engage TCP tunnel fallback if we haven't received anything valid from a global - // IP address in ZT_TCP_FALLBACK_AFTER milliseconds. If we do start getting - // valid direct traffic we'll stop using it and close the socket after a while. - const int64_t now = OSUtils::now(); - if (((now - _lastDirectReceiveFromGlobal) > ZT_TCP_FALLBACK_AFTER)&&((now - _lastRestart) > ZT_TCP_FALLBACK_AFTER)) { - if (_tcpFallbackTunnel) { - bool flushNow = false; - { - Mutex::Lock _l(_tcpFallbackTunnel->writeq_m); - if (_tcpFallbackTunnel->writeq.size() < (1024 * 64)) { - if (_tcpFallbackTunnel->writeq.length() == 0) { - _phy.setNotifyWritable(_tcpFallbackTunnel->sock,true); - flushNow = true; - } - const unsigned long mlen = len + 7; - _tcpFallbackTunnel->writeq.push_back((char)0x17); - _tcpFallbackTunnel->writeq.push_back((char)0x03); - _tcpFallbackTunnel->writeq.push_back((char)0x03); // fake TLS 1.2 header - _tcpFallbackTunnel->writeq.push_back((char)((mlen >> 8) & 0xff)); - _tcpFallbackTunnel->writeq.push_back((char)(mlen & 0xff)); - _tcpFallbackTunnel->writeq.push_back((char)4); // IPv4 - _tcpFallbackTunnel->writeq.append(reinterpret_cast(reinterpret_cast(&(reinterpret_cast(addr)->sin_addr.s_addr))),4); - _tcpFallbackTunnel->writeq.append(reinterpret_cast(reinterpret_cast(&(reinterpret_cast(addr)->sin_port))),2); - _tcpFallbackTunnel->writeq.append((const char *)data,len); - } - } - if (flushNow) { - void *tmpptr = (void *)_tcpFallbackTunnel; - phyOnTcpWritable(_tcpFallbackTunnel->sock,&tmpptr); - } - } else if (((now - _lastSendToGlobalV4) < ZT_TCP_FALLBACK_AFTER)&&((now - _lastSendToGlobalV4) > (ZT_PING_CHECK_INVERVAL / 2))) { - const InetAddress addr(ZT_TCP_FALLBACK_RELAY); - TcpConnection *tc = new TcpConnection(); - { - Mutex::Lock _l(_tcpConnections_m); - _tcpConnections.push_back(tc); - } - tc->type = TcpConnection::TCP_TUNNEL_OUTGOING; - tc->remoteAddr = addr; - tc->lastReceive = OSUtils::now(); - tc->parent = this; - tc->sock = (PhySocket *)0; // set in connect handler - tc->messageSize = 0; - bool connected = false; - _phy.tcpConnect(reinterpret_cast(&addr),connected,(void *)tc,true); - } - } - _lastSendToGlobalV4 = now; - } - } - } -#endif // ZT_TCP_FALLBACK_RELAY - - // Even when relaying we still send via UDP. This way if UDP starts - // working we can instantly "fail forward" to it and stop using TCP - // proxy fallback, which is slow. - if ((localSocket != -1)&&(localSocket != 0)&&(_binder.isUdpSocketValid((PhySocket *)((uintptr_t)localSocket)))) { if ((ttl)&&(addr->ss_family == AF_INET)) _phy.setIp4UdpTtl((PhySocket *)((uintptr_t)localSocket),ttl); const bool r = _phy.udpSend((PhySocket *)((uintptr_t)localSocket),(const struct sockaddr *)addr,data,len); @@ -2658,7 +1979,7 @@ public: { const Hashtable< uint64_t,std::vector > *lh = (const Hashtable< uint64_t,std::vector > *)0; if (family < 0) - lh = (_node->prng() & 1) ? &_v4Hints : &_v6Hints; + lh = (Utils::random() & 1) ? &_v4Hints : &_v6Hints; else if (family == AF_INET) lh = &_v4Hints; else if (family == AF_INET6) @@ -2666,7 +1987,7 @@ public: else return 0; const std::vector *l = lh->get(ztaddr); if ((l)&&(l->size() > 0)) { - memcpy(result,&((*l)[(unsigned long)_node->prng() % l->size()]),sizeof(struct sockaddr_storage)); + memcpy(result,&((*l)[(unsigned long)Utils::random() % l->size()]),sizeof(struct sockaddr_storage)); return 1; } else return 0; } diff --git a/service/OneService.hpp b/attic/service/OneService.hpp similarity index 100% rename from service/OneService.hpp rename to attic/service/OneService.hpp diff --git a/service/README.md b/attic/service/README.md similarity index 100% rename from service/README.md rename to attic/service/README.md diff --git a/update_controllers.sh b/attic/update_controllers.sh similarity index 100% rename from update_controllers.sh rename to attic/update_controllers.sh diff --git a/windows-clean.bat b/attic/windows-clean.bat similarity index 100% rename from windows-clean.bat rename to attic/windows-clean.bat diff --git a/attic/world/README.md b/attic/world/README.md deleted file mode 100644 index dda4920a..00000000 --- a/attic/world/README.md +++ /dev/null @@ -1,7 +0,0 @@ -World Definitions and Generator Code -====== - -This little bit of code is used to generate world updates. Ordinary users probably will never need this unless they want to test or experiment. - -See mkworld.cpp for documentation. To build from this directory use 'source ./build.sh'. - diff --git a/attic/world/build.sh b/attic/world/build.sh deleted file mode 100755 index d8800cd4..00000000 --- a/attic/world/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -c++ -std=c++11 -I../.. -I.. -g -o mkworld ../../node/C25519.cpp ../../node/Salsa20.cpp ../../node/SHA512.cpp ../../node/Identity.cpp ../../node/Utils.cpp ../../node/InetAddress.cpp ../../osdep/OSUtils.cpp mkworld.cpp -lm diff --git a/attic/world/mkworld.cpp b/attic/world/mkworld.cpp deleted file mode 100644 index 6b9bbe8d..00000000 --- a/attic/world/mkworld.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* - * This utility makes the World from the configuration specified below. - * It probably won't be much use to anyone outside ZeroTier, Inc. except - * for testing and experimentation purposes. - * - * If you want to make your own World you must edit this file. - * - * When run, it expects two files in the current directory: - * - * previous.c25519 - key pair to sign this world (key from previous world) - * current.c25519 - key pair whose public key should be embedded in this world - * - * If these files do not exist, they are both created with the same key pair - * and a self-signed initial World is born. - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace ZeroTier; - -int main(int argc,char **argv) -{ - std::string previous,current; - if ((!OSUtils::readFile("previous.c25519",previous))||(!OSUtils::readFile("current.c25519",current))) { - C25519::Pair np(C25519::generate()); - previous = std::string(); - previous.append((const char *)np.pub.data,ZT_C25519_PUBLIC_KEY_LEN); - previous.append((const char *)np.priv.data,ZT_C25519_PRIVATE_KEY_LEN); - current = previous; - OSUtils::writeFile("previous.c25519",previous); - OSUtils::writeFile("current.c25519",current); - fprintf(stderr,"INFO: created initial world keys: previous.c25519 and current.c25519 (both initially the same)" ZT_EOL_S); - } - - if ((previous.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))||(current.length() != (ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_PRIVATE_KEY_LEN))) { - fprintf(stderr,"FATAL: previous.c25519 or current.c25519 empty or invalid" ZT_EOL_S); - return 1; - } - C25519::Pair previousKP; - memcpy(previousKP.pub.data,previous.data(),ZT_C25519_PUBLIC_KEY_LEN); - memcpy(previousKP.priv.data,previous.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); - C25519::Pair currentKP; - memcpy(currentKP.pub.data,current.data(),ZT_C25519_PUBLIC_KEY_LEN); - memcpy(currentKP.priv.data,current.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); - - // ========================================================================= - // EDIT BELOW HERE - - std::vector roots; - - const uint64_t id = ZT_WORLD_ID_EARTH; - const uint64_t ts = 1567191349589ULL; // August 30th, 2019 - - // Los Angeles - roots.push_back(World::Root()); - roots.back().identity = Identity("3a46f1bf30:0:76e66fab33e28549a62ee2064d1843273c2c300ba45c3f20bef02dbad225723bb59a9bb4b13535730961aeecf5a163ace477cceb0727025b99ac14a5166a09a3"); - roots.back().stableEndpoints.push_back(InetAddress("185.180.13.82/9993")); - roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c815::/9993")); - - // Miami - roots.push_back(World::Root()); - roots.back().identity = Identity("de8950a8b2:0:1b3ada8251b91b6b6fa6535b8c7e2460918f4f729abdec97d3c7f3796868fb02f0de0b0ee554b2d59fc3524743eebfcf5315e790ed6d92db5bd10c28c09b40ef"); - roots.back().stableEndpoints.push_back(InetAddress("207.246.73.245/443")); - roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:9002:5cb:ec4:7aff:fe8f:69d9/443")); - - // Tokyo - roots.push_back(World::Root()); - roots.back().identity = Identity("34e0a5e174:0:93efb50934788f856d5cfb9ca5be88e85b40965586b75befac900df77352c145a1ba7007569d37c77bfe52c0999f3bdc67a47a4a6000b720a883ce47aa2fb7f8"); - roots.back().stableEndpoints.push_back(InetAddress("147.75.92.2/443")); - roots.back().stableEndpoints.push_back(InetAddress("2604:1380:3000:7100::1/443")); - - // Amsterdam - roots.push_back(World::Root()); - roots.back().identity = Identity("992fcf1db7:0:206ed59350b31916f749a1f85dffb3a8787dcbf83b8c6e9448d4e3ea0e3369301be716c3609344a9d1533850fb4460c50af43322bcfc8e13d3301a1f1003ceb6"); - roots.back().stableEndpoints.push_back(InetAddress("195.181.173.159/443")); - roots.back().stableEndpoints.push_back(InetAddress("2a02:6ea0:c024::/443")); - - // Alice - //roots.push_back(World::Root()); - //roots.back().identity = Identity("9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e"); - //roots.back().stableEndpoints.push_back(InetAddress("188.166.94.177/9993")); // Amsterdam - //roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:2:d0::7d:1/9993")); // Amsterdam - //roots.back().stableEndpoints.push_back(InetAddress("154.66.197.33/9993")); // Johannesburg - //roots.back().stableEndpoints.push_back(InetAddress("2c0f:f850:154:197::33/9993")); // Johannesburg - //roots.back().stableEndpoints.push_back(InetAddress("159.203.97.171/9993")); // New York - //roots.back().stableEndpoints.push_back(InetAddress("2604:a880:800:a1::54:6001/9993")); // New York - //roots.back().stableEndpoints.push_back(InetAddress("131.255.6.16/9993")); // Buenos Aires - //roots.back().stableEndpoints.push_back(InetAddress("2803:eb80:0:e::2/9993")); // Buenos Aires - //roots.back().stableEndpoints.push_back(InetAddress("107.170.197.14/9993")); // San Francisco - //roots.back().stableEndpoints.push_back(InetAddress("2604:a880:1:20::200:e001/9993")); // San Francisco - //roots.back().stableEndpoints.push_back(InetAddress("128.199.197.217/9993")); // Singapore - //roots.back().stableEndpoints.push_back(InetAddress("2400:6180:0:d0::b7:4001/9993")); // Singapore - - // Bob - //roots.push_back(World::Root()); - //roots.back().identity = Identity("8841408a2e:0:bb1d31f2c323e264e9e64172c1a74f77899555ed10751cd56e86405cde118d02dffe555d462ccf6a85b5631c12350c8d5dc409ba10b9025d0f445cf449d92b1c"); - //roots.back().stableEndpoints.push_back(InetAddress("45.32.198.130/9993")); // Dallas - //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6400:81c3:5400:00ff:fe18:1d61/9993")); // Dallas - //roots.back().stableEndpoints.push_back(InetAddress("46.101.160.249/9993")); // Frankfurt - //roots.back().stableEndpoints.push_back(InetAddress("2a03:b0c0:3:d0::6a:3001/9993")); // Frankfurt - //roots.back().stableEndpoints.push_back(InetAddress("107.191.46.210/9993")); // Paris - //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:6800:83a4::64/9993")); // Paris - //roots.back().stableEndpoints.push_back(InetAddress("45.32.246.179/9993")); // Sydney - //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:5800:8bf8:5400:ff:fe15:b39a/9993")); // Sydney - //roots.back().stableEndpoints.push_back(InetAddress("45.32.248.87/9993")); // Tokyo - //roots.back().stableEndpoints.push_back(InetAddress("2001:19f0:7000:9bc9:5400:00ff:fe15:c4f5/9993")); // Tokyo - //roots.back().stableEndpoints.push_back(InetAddress("159.203.2.154/9993")); // Toronto - //roots.back().stableEndpoints.push_back(InetAddress("2604:a880:cad:d0::26:7001/9993")); // Toronto - - // END WORLD DEFINITION - // ========================================================================= - - fprintf(stderr,"INFO: generating and signing id==%llu ts==%llu" ZT_EOL_S,(unsigned long long)id,(unsigned long long)ts); - - World nw = World::make(World::TYPE_PLANET,id,ts,currentKP.pub,roots,previousKP); - - Buffer outtmp; - nw.serialize(outtmp,false); - World testw; - testw.deserialize(outtmp,0); - if (testw != nw) { - fprintf(stderr,"FATAL: serialization test failed!" ZT_EOL_S); - return 1; - } - - OSUtils::writeFile("world.bin",std::string((const char *)outtmp.data(),outtmp.size())); - fprintf(stderr,"INFO: world.bin written with %u bytes of binary world data." ZT_EOL_S,outtmp.size()); - - fprintf(stdout,ZT_EOL_S); - fprintf(stdout,"#define ZT_DEFAULT_WORLD_LENGTH %u" ZT_EOL_S,outtmp.size()); - fprintf(stdout,"static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {"); - for(unsigned int i=0;i 0) - fprintf(stdout,","); - fprintf(stdout,"0x%.2x",(unsigned int)d[i]); - } - fprintf(stdout,"};" ZT_EOL_S); - - return 0; -} diff --git a/attic/world/world.bin b/attic/world/world.bin deleted file mode 100644 index 88049ccd..00000000 Binary files a/attic/world/world.bin and /dev/null differ diff --git a/attic/world/world.c b/attic/world/world.c deleted file mode 100644 index ecf30e6f..00000000 --- a/attic/world/world.c +++ /dev/null @@ -1,3 +0,0 @@ - -#define ZT_DEFAULT_WORLD_LENGTH 732 -static const unsigned char ZT_DEFAULT_WORLD[ZT_DEFAULT_WORLD_LENGTH] = {0x01,0x00,0x00,0x00,0x00,0x08,0xea,0xc9,0x0a,0x00,0x00,0x01,0x6b,0xd4,0x16,0x08,0xc1,0xb8,0xb3,0x88,0xa4,0x69,0x22,0x14,0x91,0xaa,0x9a,0xcd,0x66,0xcc,0x76,0x4c,0xde,0xfd,0x56,0x03,0x9f,0x10,0x67,0xae,0x15,0xe6,0x9c,0x6f,0xb4,0x2d,0x7b,0x55,0x33,0x0e,0x3f,0xda,0xac,0x52,0x9c,0x07,0x92,0xfd,0x73,0x40,0xa6,0xaa,0x21,0xab,0xa8,0xa4,0x89,0xfd,0xae,0xa4,0x4a,0x39,0xbf,0x2d,0x00,0x65,0x9a,0xc9,0xc8,0x18,0xeb,0x16,0x93,0xf4,0xe5,0xbd,0x20,0xda,0x10,0xad,0xc7,0x05,0xf4,0x99,0xfe,0x04,0x08,0x9b,0xe0,0x9e,0x77,0x1d,0x9f,0x47,0x16,0xaa,0x92,0x4f,0x10,0x16,0x3d,0xc7,0xec,0xd3,0x90,0x9e,0xd1,0x74,0xfc,0xb3,0xb5,0x07,0x9c,0x4d,0x95,0xc5,0x17,0x8b,0x3d,0x0b,0x60,0x76,0xe8,0x51,0xbb,0xb6,0x3d,0x74,0xb5,0x21,0x83,0x7b,0x95,0x1d,0x02,0x9b,0xcd,0xaf,0x5c,0x3e,0x96,0xdf,0x37,0x2c,0x56,0x6d,0xfa,0x75,0x0f,0xda,0x55,0x85,0x13,0xf4,0x76,0x1a,0x66,0x4d,0x3b,0x8d,0xcf,0x12,0xc9,0x34,0xb9,0x0d,0x61,0x03,0x3a,0x46,0xf1,0xbf,0x30,0x00,0x76,0xe6,0x6f,0xab,0x33,0xe2,0x85,0x49,0xa6,0x2e,0xe2,0x06,0x4d,0x18,0x43,0x27,0x3c,0x2c,0x30,0x0b,0xa4,0x5c,0x3f,0x20,0xbe,0xf0,0x2d,0xba,0xd2,0x25,0x72,0x3b,0xb5,0x9a,0x9b,0xb4,0xb1,0x35,0x35,0x73,0x09,0x61,0xae,0xec,0xf5,0xa1,0x63,0xac,0xe4,0x77,0xcc,0xeb,0x07,0x27,0x02,0x5b,0x99,0xac,0x14,0xa5,0x16,0x6a,0x09,0xa3,0x00,0x02,0x04,0xb9,0xb4,0x0d,0x52,0x27,0x09,0x06,0x2a,0x02,0x6e,0xa0,0xc8,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x09,0x9d,0x21,0x90,0x39,0xf3,0x00,0x01,0xf0,0x92,0x2a,0x98,0xe3,0xb3,0x4e,0xbc,0xbf,0xf3,0x33,0x26,0x9d,0xc2,0x65,0xd7,0xa0,0x20,0xaa,0xb6,0x9d,0x72,0xbe,0x4d,0x4a,0xcc,0x9c,0x8c,0x92,0x94,0x78,0x57,0x71,0x25,0x6c,0xd1,0xd9,0x42,0xa9,0x0d,0x1b,0xd1,0xd2,0xdc,0xa3,0xea,0x84,0xef,0x7d,0x85,0xaf,0xe6,0x61,0x1f,0xb4,0x3f,0xf0,0xb7,0x41,0x26,0xd9,0x0a,0x6e,0x00,0x0c,0x04,0xbc,0xa6,0x5e,0xb1,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x7d,0x00,0x01,0x27,0x09,0x04,0x9a,0x42,0xc5,0x21,0x27,0x09,0x06,0x2c,0x0f,0xf8,0x50,0x01,0x54,0x01,0x97,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x27,0x09,0x04,0x9f,0xcb,0x61,0xab,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,0x54,0x60,0x01,0x27,0x09,0x04,0x83,0xff,0x06,0x10,0x27,0x09,0x06,0x28,0x03,0xeb,0x80,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x27,0x09,0x04,0x6b,0xaa,0xc5,0x0e,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x00,0xe0,0x01,0x27,0x09,0x04,0x80,0xc7,0xc5,0xd9,0x27,0x09,0x06,0x24,0x00,0x61,0x80,0x00,0x00,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0xb7,0x40,0x01,0x27,0x09,0x88,0x41,0x40,0x8a,0x2e,0x00,0xbb,0x1d,0x31,0xf2,0xc3,0x23,0xe2,0x64,0xe9,0xe6,0x41,0x72,0xc1,0xa7,0x4f,0x77,0x89,0x95,0x55,0xed,0x10,0x75,0x1c,0xd5,0x6e,0x86,0x40,0x5c,0xde,0x11,0x8d,0x02,0xdf,0xfe,0x55,0x5d,0x46,0x2c,0xcf,0x6a,0x85,0xb5,0x63,0x1c,0x12,0x35,0x0c,0x8d,0x5d,0xc4,0x09,0xba,0x10,0xb9,0x02,0x5d,0x0f,0x44,0x5c,0xf4,0x49,0xd9,0x2b,0x1c,0x00,0x0c,0x04,0x2d,0x20,0xc6,0x82,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x64,0x00,0x81,0xc3,0x54,0x00,0x00,0xff,0xfe,0x18,0x1d,0x61,0x27,0x09,0x04,0x2e,0x65,0xa0,0xf9,0x27,0x09,0x06,0x2a,0x03,0xb0,0xc0,0x00,0x03,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x6a,0x30,0x01,0x27,0x09,0x04,0x6b,0xbf,0x2e,0xd2,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x68,0x00,0x83,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x27,0x09,0x04,0x2d,0x20,0xf6,0xb3,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x58,0x00,0x8b,0xf8,0x54,0x00,0x00,0xff,0xfe,0x15,0xb3,0x9a,0x27,0x09,0x04,0x2d,0x20,0xf8,0x57,0x27,0x09,0x06,0x20,0x01,0x19,0xf0,0x70,0x00,0x9b,0xc9,0x54,0x00,0x00,0xff,0xfe,0x15,0xc4,0xf5,0x27,0x09,0x04,0x9f,0xcb,0x02,0x9a,0x27,0x09,0x06,0x26,0x04,0xa8,0x80,0x0c,0xad,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x26,0x70,0x01,0x27,0x09}; diff --git a/controller/CMakeLists.txt b/controller/CMakeLists.txt new file mode 100644 index 00000000..c886b54b --- /dev/null +++ b/controller/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 2.8) +project(zt_controller) + +if(WIN32) + add_definitions(-DNOMINMAX) +endif(WIN32) + +set(ctl_src + DB.cpp + DBMirrorSet.cpp + EmbeddedNetworkController.cpp + FileDB.cpp + LFDB.cpp + RabbitMQ.cpp +) + +set(ctl_hdr + DB.hpp + DBMirrorSet.hpp + EmbeddedNetworkController.hpp + FileDB.hpp + LFDB.hpp + RabbitMQ.hpp +) + +if(BUILD_CENTRAL_CONTROLLER) + add_definitions(-DZT_CONTROLLER_USE_LIBPQ) + include_directories("../ext/librabbitmq/librabbitmq" ${PostgreSQL_INCLUDE_DIRS}) + + set(ctl_src ${ctl_src} PostgreSQL.cpp) + set(ctl_hdr ${ctl_hdr} PostgreSQL.hpp) +endif(BUILD_CENTRAL_CONTROLLER) + +add_library(${PROJECT_NAME} STATIC ${ctl_src} ${ctl_hdr}) +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11) + diff --git a/controller/DBMirrorSet.cpp b/controller/DBMirrorSet.cpp index b2c7c71b..c467e171 100644 --- a/controller/DBMirrorSet.cpp +++ b/controller/DBMirrorSet.cpp @@ -36,7 +36,7 @@ DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) : } for(auto db=dbs.begin();db!=dbs.end();++db) { - (*db)->each([this,&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) { + (*db)->each([&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) { try { if (network.is_object()) { if (memberId == 0) { diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index e0e2a3ea..0b6c4405 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -29,8 +29,14 @@ #include #include +#include "../node/Constants.hpp" +#include "../node/Node.hpp" +#include "../node/CertificateOfMembership.hpp" +#include "../node/NetworkConfig.hpp" +#include "../node/Dictionary.hpp" +#include "../node/MAC.hpp" + #include "../include/ZeroTierOne.h" -#include "../version.h" #include "EmbeddedNetworkController.hpp" #include "LFDB.hpp" @@ -39,12 +45,6 @@ #include "PostgreSQL.hpp" #endif -#include "../node/Node.hpp" -#include "../node/CertificateOfMembership.hpp" -#include "../node/NetworkConfig.hpp" -#include "../node/Dictionary.hpp" -#include "../node/MAC.hpp" - using json = nlohmann::json; // API version reported via JSON control plane @@ -548,8 +548,6 @@ void EmbeddedNetworkController::request( unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET( const std::vector &path, - const std::map &urlArgs, - const std::map &headers, const std::string &body, std::string &responseBody, std::string &responseContentType) @@ -645,8 +643,6 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET( unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( const std::vector &path, - const std::map &urlArgs, - const std::map &headers, const std::string &body, std::string &responseBody, std::string &responseContentType) @@ -1055,8 +1051,6 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST( unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE( const std::vector &path, - const std::map &urlArgs, - const std::map &headers, const std::string &body, std::string &responseBody, std::string &responseContentType) @@ -1113,56 +1107,6 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpDELETE( return 404; } -void EmbeddedNetworkController::handleRemoteTrace(const ZT_RemoteTrace &rt) -{ - static volatile unsigned long idCounter = 0; - char id[128],tmp[128]; - std::string k,v; - - try { - // Convert Dictionary into JSON object - json d; - char *saveptr = (char *)0; - for(char *l=Utils::stok(rt.data,"\n",&saveptr);(l);l=Utils::stok((char *)0,"\n",&saveptr)) { - char *eq = strchr(l,'='); - if (eq > l) { - k.assign(l,(unsigned long)(eq - l)); - v.clear(); - ++eq; - while (*eq) { - if (*eq == '\\') { - ++eq; - if (*eq) { - switch(*eq) { - case 'r': v.push_back('\r'); break; - case 'n': v.push_back('\n'); break; - case '0': v.push_back((char)0); break; - case 'e': v.push_back('='); break; - default: v.push_back(*eq); break; - } - ++eq; - } - } else { - v.push_back(*(eq++)); - } - } - if ((k.length() > 0)&&(v.length() > 0)) - d[k] = v; - } - } - - const int64_t now = OSUtils::now(); - OSUtils::ztsnprintf(id,sizeof(id),"%.10llx-%.16llx-%.10llx-%.4x",_signingId.address().toInt(),now,rt.origin,(unsigned int)(idCounter++ & 0xffff)); - d["id"] = id; - d["objtype"] = "trace"; - d["ts"] = now; - d["nodeId"] = Utils::hex10(rt.origin,tmp); - _db.save(d,true); - } catch ( ... ) { - // drop invalid trace messages if an error occurs - } -} - void EmbeddedNetworkController::onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network) { // Send an update to all members of the network that are online @@ -1188,7 +1132,7 @@ void EmbeddedNetworkController::onNetworkMemberUpdate(const void *db,uint64_t ne void EmbeddedNetworkController::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId) { const int64_t now = OSUtils::now(); - Revocation rev((uint32_t)_node->prng(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),Revocation::CREDENTIAL_TYPE_COM); + Revocation rev((uint32_t)Utils::random(),networkId,0,now,ZT_REVOCATION_FLAG_FAST_PROPAGATE,Address(memberId),Revocation::CREDENTIAL_TYPE_COM); rev.sign(_signingId); { std::lock_guard l(_memberStatus_l); @@ -1704,7 +1648,7 @@ void EmbeddedNetworkController::_request( DB::cleanMember(member); _db.save(member,true); - _sender->ncSendConfig(nwid,requestPacketId,identity.address(),*(nc.get()),metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_VERSION,0) < 6); + _sender->ncSendConfig(nwid,requestPacketId,identity.address(),*(nc.get()),false); } void EmbeddedNetworkController::_startThreads() diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp index 1db4cf42..82946940 100644 --- a/controller/EmbeddedNetworkController.hpp +++ b/controller/EmbeddedNetworkController.hpp @@ -51,6 +51,7 @@ class EmbeddedNetworkController : public NetworkController,public DB::ChangeList public: /** * @param node Parent node + * @param ztPath ZeroTier base path * @param dbPath Database path (file path or database credentials) */ EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, MQConfig *mqc = NULL); @@ -67,28 +68,20 @@ public: unsigned int handleControlPlaneHttpGET( const std::vector &path, - const std::map &urlArgs, - const std::map &headers, const std::string &body, std::string &responseBody, std::string &responseContentType); unsigned int handleControlPlaneHttpPOST( const std::vector &path, - const std::map &urlArgs, - const std::map &headers, const std::string &body, std::string &responseBody, std::string &responseContentType); unsigned int handleControlPlaneHttpDELETE( const std::vector &path, - const std::map &urlArgs, - const std::map &headers, const std::string &body, std::string &responseBody, std::string &responseContentType); - void handleRemoteTrace(const ZT_RemoteTrace &rt); - virtual void onNetworkUpdate(const void *db,uint64_t networkId,const nlohmann::json &network); virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member); virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId); diff --git a/controller/FileDB.cpp b/controller/FileDB.cpp index b4eaf58c..0b360d88 100644 --- a/controller/FileDB.cpp +++ b/controller/FileDB.cpp @@ -20,13 +20,11 @@ FileDB::FileDB(const char *path) : DB(), _path(path), _networksPath(_path + ZT_PATH_SEPARATOR_S + "network"), - _tracePath(_path + ZT_PATH_SEPARATOR_S + "trace"), _running(true) { OSUtils::mkdir(_path.c_str()); OSUtils::lockDownFile(_path.c_str(),true); OSUtils::mkdir(_networksPath.c_str()); - OSUtils::mkdir(_tracePath.c_str()); std::vector networks(OSUtils::listDirectory(_networksPath.c_str(),false)); std::string buf; diff --git a/controller/FileDB.hpp b/controller/FileDB.hpp index fcd7af0f..82e634e6 100644 --- a/controller/FileDB.hpp +++ b/controller/FileDB.hpp @@ -35,7 +35,6 @@ public: protected: std::string _path; std::string _networksPath; - std::string _tracePath; std::thread _onlineUpdateThread; std::map< uint64_t,std::map > > _online; std::mutex _online_l; diff --git a/ext/arm32-neon-salsa2012-asm/README.md b/ext/arm32-neon-salsa2012-asm/README.md deleted file mode 100644 index 54fc6f5f..00000000 --- a/ext/arm32-neon-salsa2012-asm/README.md +++ /dev/null @@ -1,6 +0,0 @@ -ARM NEON (32-bit) ASM implementation of Salsa20/12 -====== - -This is from [supercop](http://bench.cr.yp.to/supercop.html) and was originally written by Daniel J. Bernstein. Code is in the public domain like the rest of Salsa20. It's much faster than the naive implementation. - -It's included automatically in 32-bit Linux ARM builds. It likely will not work on 64-bit ARM, so it'll need to be ported at least. That will unfortunately keep it out of mobile versions for now since those are all going 64-bit. diff --git a/ext/arm32-neon-salsa2012-asm/salsa2012.h b/ext/arm32-neon-salsa2012-asm/salsa2012.h deleted file mode 100644 index 262c9b9b..00000000 --- a/ext/arm32-neon-salsa2012-asm/salsa2012.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef ZT_SALSA2012_ARM32NEON_ASM -#define ZT_SALSA2012_ARM32NEON_ASM - -#if defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) -#include -#include -#define zt_arm_has_neon() ((getauxval(AT_HWCAP) & HWCAP_NEON) != 0) -#elif defined(__ARM_NEON__) || defined(__ARM_NEON) -#define zt_arm_has_neon() (true) -#else -#define zt_arm_has_neon() (false) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// ciphertext buffer, message/NULL, length, nonce (8 bytes), key (32 bytes) -extern int zt_salsa2012_armneon3_xor(unsigned char *c,const unsigned char *m,unsigned long long len,const unsigned char *n,const unsigned char *k); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ext/arm32-neon-salsa2012-asm/salsa2012.s b/ext/arm32-neon-salsa2012-asm/salsa2012.s deleted file mode 100644 index 9e5989cd..00000000 --- a/ext/arm32-neon-salsa2012-asm/salsa2012.s +++ /dev/null @@ -1,2231 +0,0 @@ - -# qhasm: int32 input_0 - -# qhasm: int32 input_1 - -# qhasm: int32 input_2 - -# qhasm: int32 input_3 - -# qhasm: stack32 input_4 - -# qhasm: stack32 input_5 - -# qhasm: stack32 input_6 - -# qhasm: stack32 input_7 - -# qhasm: int32 caller_r4 - -# qhasm: int32 caller_r5 - -# qhasm: int32 caller_r6 - -# qhasm: int32 caller_r7 - -# qhasm: int32 caller_r8 - -# qhasm: int32 caller_r9 - -# qhasm: int32 caller_r10 - -# qhasm: int32 caller_r11 - -# qhasm: int32 caller_r14 - -# qhasm: reg128 caller_q4 - -# qhasm: reg128 caller_q5 - -# qhasm: reg128 caller_q6 - -# qhasm: reg128 caller_q7 - -# qhasm: startcode -.fpu neon -.text - -# qhasm: constant sigma: -.align 2 -sigma: - -# qhasm: const32 1634760805 -.word 1634760805 - -# qhasm: const32 857760878 -.word 857760878 - -# qhasm: const32 2036477234 -.word 2036477234 - -# qhasm: const32 1797285236 -.word 1797285236 - -# qhasm: int128 abab - -# qhasm: int128 diag0 - -# qhasm: int128 diag1 - -# qhasm: int128 diag2 - -# qhasm: int128 diag3 - -# qhasm: int128 a0 - -# qhasm: int128 a1 - -# qhasm: int128 a2 - -# qhasm: int128 a3 - -# qhasm: int128 b0 - -# qhasm: int128 b1 - -# qhasm: int128 b2 - -# qhasm: int128 b3 - -# qhasm: int128 next_diag0 - -# qhasm: int128 next_diag1 - -# qhasm: int128 next_diag2 - -# qhasm: int128 next_diag3 - -# qhasm: int128 next_a0 - -# qhasm: int128 next_a1 - -# qhasm: int128 next_a2 - -# qhasm: int128 next_a3 - -# qhasm: int128 next_b0 - -# qhasm: int128 next_b1 - -# qhasm: int128 next_b2 - -# qhasm: int128 next_b3 - -# qhasm: int128 x0x5x10x15 - -# qhasm: int128 x12x1x6x11 - -# qhasm: int128 x8x13x2x7 - -# qhasm: int128 x4x9x14x3 - -# qhasm: int128 x0x1x10x11 - -# qhasm: int128 x12x13x6x7 - -# qhasm: int128 x8x9x2x3 - -# qhasm: int128 x4x5x14x15 - -# qhasm: int128 x0x1x2x3 - -# qhasm: int128 x4x5x6x7 - -# qhasm: int128 x8x9x10x11 - -# qhasm: int128 x12x13x14x15 - -# qhasm: int128 m0m1m2m3 - -# qhasm: int128 m4m5m6m7 - -# qhasm: int128 m8m9m10m11 - -# qhasm: int128 m12m13m14m15 - -# qhasm: int128 start0 - -# qhasm: int128 start1 - -# qhasm: int128 start2 - -# qhasm: int128 start3 - -# qhasm: stack128 stack_start3 - -# qhasm: stack128 next_start2 - -# qhasm: stack128 next_start3 - -# qhasm: int128 k0k1k2k3 - -# qhasm: int128 k4k5k6k7 - -# qhasm: int128 k1n1k7k2 - -# qhasm: int128 n2n3n3n2 - -# qhasm: int128 k2k3k6k7 - -# qhasm: int128 nextblock - -# qhasm: stack128 stack_q4 - -# qhasm: stack128 stack_q5 - -# qhasm: stack128 stack_q6 - -# qhasm: stack128 stack_q7 - -# qhasm: stack32 stack_r4 - -# qhasm: stack128 k2k3k6k7_stack - -# qhasm: stack128 k1n1k7k2_stack - -# qhasm: stack512 tmp - -# qhasm: stack32 savec - -# qhasm: int32 i - -# qhasm: int32 ci - -# qhasm: int32 mi - -# qhasm: enter zt_salsa2012_armneon3_xor -.align 2 -.global _zt_salsa2012_armneon3_xor -.global zt_salsa2012_armneon3_xor -.type _zt_salsa2012_armneon3_xor STT_FUNC -.type zt_salsa2012_armneon3_xor STT_FUNC -_zt_salsa2012_armneon3_xor: -zt_salsa2012_armneon3_xor: -sub sp,sp,#256 - -# qhasm: new stack_q4 - -# qhasm: new stack_q5 - -# qhasm: new stack_q6 - -# qhasm: new stack_q7 - -# qhasm: stack_q4 bot = caller_q4 bot -# asm 1: vstr stack_r4=stack32#2 -# asm 2: str stack_r4=[sp,#68] -str r4,[sp,#68] - -# qhasm: int32 c - -# qhasm: c = input_0 -# asm 1: mov >c=int32#1,c=r0,m=int32#2,m=r1,mlenlow=int32#3,mlenlow=r2,mlenhigh=int32#4,mlenhigh=r3,n=int32#5,n=r4,k=int32#13,k=r12,k0k1k2k3=reg128#1%bot->k0k1k2k3=reg128#1%top},[k0k1k2k3=d0->k0k1k2k3=d1},[k4k5k6k7=reg128#2%bot->k4k5k6k7=reg128#2%top},[k4k5k6k7=d2->k4k5k6k7=d3},[i=int32#13,=sigma -# asm 2: ldr >i=r12,=sigma -ldr r12,=sigma - -# qhasm: start0 = mem128[i] -# asm 1: vld1.8 {>start0=reg128#3%bot->start0=reg128#3%top},[start0=d4->start0=d5},[start1=reg128#4,#0 -# asm 2: vmov.i64 >start1=q3,#0 -vmov.i64 q3,#0 - -# qhasm: start1 bot = mem64[n] -# asm 1: vld1.8 {k2k3k6k7=reg128#6,k2k3k6k7=q5,n2n3n3n2=reg128#1,#0 -# asm 2: vmov.i64 >n2n3n3n2=q0,#0 -vmov.i64 q0,#0 - -# qhasm: unsigneddiag0=reg128#8,diag0=q7,diag1=reg128#9,diag1=q8,start2=reg128#10,start2=q9,nextblock=reg128#11,#0xff -# asm 2: vmov.i64 >nextblock=q10,#0xff -vmov.i64 q10,#0xff - -# qhasm: 4x nextblock unsigned>>= 7 -# asm 1: vshr.u32 >nextblock=reg128#11,nextblock=q10,n2n3n3n2=reg128#1,n2n3n3n2=q0,n2n3n3n2=reg128#1,n2n3n3n2=q0,next_diag0=reg128#2,next_diag0=q1,next_diag1=reg128#5,next_diag1=q4,i=int32#5,=12 -# asm 2: ldr >i=r4,=12 -ldr r4,=12 - -# qhasm: mainloop2: -._mainloop2: - -# qhasm: 4x a0 = diag1 + diag0 -# asm 1: vadd.i32 >a0=reg128#11,a0=q10,next_a0=reg128#14,next_a0=q13,b0=reg128#15,b0=q14,next_b0=reg128#16,next_b0=q15,> 25 -# asm 1: vsri.i32 > 25 -# asm 1: vsri.i32 diag3=reg128#7,diag3=q6,next_diag3=reg128#11,next_diag3=q10,a1=reg128#13,a1=q12,next_a1=reg128#14,next_a1=q13,b1=reg128#15,b1=q14,next_b1=reg128#16,next_b1=q15,> 23 -# asm 1: vsri.i32 > 23 -# asm 1: vsri.i32 diag2=reg128#6,diag2=q5,next_diag2=reg128#12,next_diag2=q11,a2=reg128#13,a2=q12,diag3=reg128#7,diag3=q6,next_a2=reg128#14,next_a2=q13,b2=reg128#15,b2=q14,next_diag3=reg128#11,next_diag3=q10,next_b2=reg128#16,next_b2=q15,> 19 -# asm 1: vsri.i32 > 19 -# asm 1: vsri.i32 diag1=reg128#9,diag1=q8,next_diag1=reg128#5,next_diag1=q4,a3=reg128#13,a3=q12,next_a3=reg128#14,next_a3=q13,b3=reg128#15,b3=q14,next_b3=reg128#16,next_b3=q15,> 14 -# asm 1: vsri.i32 diag1=reg128#9,diag1=q8,> 14 -# asm 1: vsri.i32 diag0=reg128#8,diag0=q7,next_diag1=reg128#5,next_diag1=q4,next_diag0=reg128#2,next_diag0=q1,a0=reg128#13,a0=q12,next_a0=reg128#14,next_a0=q13,b0=reg128#15,b0=q14,next_b0=reg128#16,next_b0=q15,> 25 -# asm 1: vsri.i32 > 25 -# asm 1: vsri.i32 diag1=reg128#9,diag1=q8,next_diag1=reg128#5,next_diag1=q4,a1=reg128#13,a1=q12,next_a1=reg128#14,next_a1=q13,b1=reg128#15,b1=q14,next_b1=reg128#16,next_b1=q15,> 23 -# asm 1: vsri.i32 ? i -= 2 -# asm 1: subs > 23 -# asm 1: vsri.i32 diag2=reg128#6,diag2=q5,next_diag2=reg128#12,next_diag2=q11,a2=reg128#13,a2=q12,diag1=reg128#9,diag1=q8,next_a2=reg128#14,next_a2=q13,b2=reg128#15,b2=q14,next_diag1=reg128#5,next_diag1=q4,next_b2=reg128#16,next_b2=q15,> 19 -# asm 1: vsri.i32 > 19 -# asm 1: vsri.i32 diag3=reg128#7,diag3=q6,next_diag3=reg128#11,next_diag3=q10,a3=reg128#13,a3=q12,next_a3=reg128#14,next_a3=q13,b3=reg128#15,b3=q14,next_b3=reg128#16,next_b3=q15,> 14 -# asm 1: vsri.i32 diag3=reg128#7,diag3=q6,> 14 -# asm 1: vsri.i32 diag0=reg128#8,diag0=q7,next_diag3=reg128#13,next_diag3=q12,next_diag0=reg128#2,next_diag0=q1, -bhi ._mainloop2 - -# qhasm: 2x abab = 0xffffffff -# asm 1: vmov.i64 >abab=reg128#11,#0xffffffff -# asm 2: vmov.i64 >abab=q10,#0xffffffff -vmov.i64 q10,#0xffffffff - -# qhasm: new x4x9x14x3 - -# qhasm: x4x9x14x3 bot = stack_start3 bot -# asm 1: vldr x0x5x10x15=reg128#8,x0x5x10x15=q7,x12x1x6x11=reg128#9,x12x1x6x11=q8,x8x13x2x7=reg128#6,x8x13x2x7=q5,x4x9x14x3=reg128#7,x4x9x14x3=q6,x0x1x10x11=reg128#10,x0x1x10x11=q9,x12x13x6x7=reg128#14,x12x13x6x7=q13,x8x9x2x3=reg128#15,x8x9x2x3=q14,x4x5x14x15=reg128#16,x4x5x14x15=q15,x0x1x2x3=reg128#6,x0x1x2x3=q5,x4x5x6x7=reg128#7,x4x5x6x7=q6,x8x9x10x11=reg128#8,x8x9x10x11=q7,x12x13x14x15=reg128#9,x12x13x14x15=q8,m0m1m2m3=reg128#10%bot->m0m1m2m3=reg128#10%top},[m0m1m2m3=d18->m0m1m2m3=d19},[m4m5m6m7=reg128#14%bot->m4m5m6m7=reg128#14%top},[m4m5m6m7=d26->m4m5m6m7=d27},[m8m9m10m11=reg128#15%bot->m8m9m10m11=reg128#15%top},[m8m9m10m11=d28->m8m9m10m11=d29},[m12m13m14m15=reg128#16%bot->m12m13m14m15=reg128#16%top},[m12m13m14m15=d30->m12m13m14m15=d31},[x0x1x2x3=reg128#6,x0x1x2x3=q5,x4x5x6x7=reg128#7,x4x5x6x7=q6,x8x9x10x11=reg128#8,x8x9x10x11=q7,x12x13x14x15=reg128#9,x12x13x14x15=q8,x0x5x10x15=reg128#2,x0x5x10x15=q1,x12x1x6x11=reg128#5,x12x1x6x11=q4,x8x13x2x7=reg128#6,x8x13x2x7=q5,x4x9x14x3=reg128#7,x4x9x14x3=q6,x0x1x10x11=reg128#8,x0x1x10x11=q7,x12x13x6x7=reg128#9,x12x13x6x7=q8,x8x9x2x3=reg128#10,x8x9x2x3=q9,x4x5x14x15=reg128#12,x4x5x14x15=q11,x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,m0m1m2m3=reg128#8%bot->m0m1m2m3=reg128#8%top},[m0m1m2m3=d14->m0m1m2m3=d15},[m4m5m6m7=reg128#9%bot->m4m5m6m7=reg128#9%top},[m4m5m6m7=d16->m4m5m6m7=d17},[m8m9m10m11=reg128#10%bot->m8m9m10m11=reg128#10%top},[m8m9m10m11=d18->m8m9m10m11=d19},[m12m13m14m15=reg128#11%bot->m12m13m14m15=reg128#11%top},[m12m13m14m15=d20->m12m13m14m15=d21},[x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,? mlenhigh - 0 -# asm 1: cmp -bhi ._mlenatleast128 - -# qhasm: =? mlenlow - 0 -# asm 1: cmp savec=stack32#1 -# asm 2: str savec=[sp,#64] -str r0,[sp,#64] - -# qhasm: c = &tmp -# asm 1: lea >c=int32#1,c=r0,i=int32#4,=0 -# asm 2: ldr >i=r3,=0 -ldr r3,=0 - -# qhasm: mcopy: -._mcopy: - -# qhasm: mi = mem8[m + 0] -# asm 1: ldrb >mi=int32#5,[mi=r4,[mi=int32#2,=0 -# asm 2: ldr >mi=r1,=0 -ldr r1,=0 - -# qhasm: pad: -._pad: - -# qhasm: mem8[c + 0] = mi -# asm 1: strb m=int32#2,m=r1,diag0=reg128#2,diag0=q1,diag1=reg128#5,diag1=q4,diag2=reg128#8,diag2=q7,diag3=reg128#9,diag3=q8,nextblock=reg128#10,#0xff -# asm 2: vmov.i64 >nextblock=q9,#0xff -vmov.i64 q9,#0xff - -# qhasm: 4x nextblock unsigned>>= 7 -# asm 1: vshr.u32 >nextblock=reg128#10,nextblock=q9,n2n3n3n2=reg128#1,n2n3n3n2=q0,i=int32#4,=12 -# asm 2: ldr >i=r3,=12 -ldr r3,=12 - -# qhasm: mainloop1: -._mainloop1: - -# qhasm: 4x a0 = diag1 + diag0 -# asm 1: vadd.i32 >a0=reg128#10,a0=q9,b0=reg128#11,b0=q10,> 25 -# asm 1: vsri.i32 diag3=reg128#9,diag3=q8,a1=reg128#10,a1=q9,b1=reg128#11,b1=q10,> 23 -# asm 1: vsri.i32 diag2=reg128#8,diag2=q7,a2=reg128#10,a2=q9,diag3=reg128#9,diag3=q8,b2=reg128#11,b2=q10,> 19 -# asm 1: vsri.i32 diag1=reg128#5,diag1=q4,a3=reg128#10,a3=q9,b3=reg128#11,b3=q10,> 14 -# asm 1: vsri.i32 diag1=reg128#5,diag1=q4,diag0=reg128#2,diag0=q1,a0=reg128#10,a0=q9,b0=reg128#11,b0=q10,> 25 -# asm 1: vsri.i32 diag1=reg128#5,diag1=q4,a1=reg128#10,a1=q9,b1=reg128#11,b1=q10,> 23 -# asm 1: vsri.i32 ? i -= 2 -# asm 1: subs diag2=reg128#8,diag2=q7,a2=reg128#10,a2=q9,diag1=reg128#5,diag1=q4,b2=reg128#11,b2=q10,> 19 -# asm 1: vsri.i32 diag3=reg128#9,diag3=q8,a3=reg128#10,a3=q9,b3=reg128#11,b3=q10,> 14 -# asm 1: vsri.i32 diag3=reg128#9,diag3=q8,diag0=reg128#2,diag0=q1, -bhi ._mainloop1 - -# qhasm: 2x abab = 0xffffffff -# asm 1: vmov.i64 >abab=reg128#10,#0xffffffff -# asm 2: vmov.i64 >abab=q9,#0xffffffff -vmov.i64 q9,#0xffffffff - -# qhasm: 4x x0x5x10x15 = diag0 + start0 -# asm 1: vadd.i32 >x0x5x10x15=reg128#2,x0x5x10x15=q1,x12x1x6x11=reg128#5,x12x1x6x11=q4,x8x13x2x7=reg128#6,x8x13x2x7=q5,x4x9x14x3=reg128#7,x4x9x14x3=q6,x0x1x10x11=reg128#8,x0x1x10x11=q7,x12x13x6x7=reg128#9,x12x13x6x7=q8,x8x9x2x3=reg128#11,x8x9x2x3=q10,x4x5x14x15=reg128#12,x4x5x14x15=q11,x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,m0m1m2m3=reg128#8%bot->m0m1m2m3=reg128#8%top},[m0m1m2m3=d14->m0m1m2m3=d15},[m4m5m6m7=reg128#9%bot->m4m5m6m7=reg128#9%top},[m4m5m6m7=d16->m4m5m6m7=d17},[m8m9m10m11=reg128#10%bot->m8m9m10m11=reg128#10%top},[m8m9m10m11=d18->m8m9m10m11=d19},[m12m13m14m15=reg128#11%bot->m12m13m14m15=reg128#11%top},[m12m13m14m15=d20->m12m13m14m15=d21},[x0x1x2x3=reg128#2,x0x1x2x3=q1,x4x5x6x7=reg128#5,x4x5x6x7=q4,x8x9x10x11=reg128#6,x8x9x10x11=q5,x12x13x14x15=reg128#7,x12x13x14x15=q6,i=int32#4,=0 -# asm 2: ldr >i=r3,=0 -ldr r3,=0 - -# qhasm: m = c - 64 -# asm 1: sub >m=int32#2,m=r1,c=int32#1,c=r0,ci=int32#5,[ci=r4,[? mlenlow -= 64 -# asm 1: subs -bhi ._mlenatleast1 - -# qhasm: done: -._done: - -# qhasm: new caller_r4 - -# qhasm: caller_r4 = stack_r4 -# asm 1: ldr >caller_r4=int32#5,caller_r4=r4,result=int32#1,=0 -# asm 2: ldr >result=r0,=0 -ldr r0,=0 - -# qhasm: return result -add sp,sp,#256 -bx lr diff --git a/ext/curl-7.58.0/Win32/include/curl/curl.h b/ext/curl-7.58.0/Win32/include/curl/curl.h deleted file mode 100644 index 7680acd1..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/curl.h +++ /dev/null @@ -1,2751 +0,0 @@ -#ifndef __CURL_CURL_H -#define __CURL_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * If you have libcurl problems, all docs and details are found here: - * https://curl.haxx.se/libcurl/ - * - * curl-library mailing list subscription and unsubscription web interface: - * https://cool.haxx.se/mailman/listinfo/curl-library/ - */ - -#ifdef CURL_NO_OLDIES -#define CURL_STRICTER -#endif - -#include "curlver.h" /* libcurl version defines */ -#include "system.h" /* determine things run-time */ - -/* - * Define WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__)) && \ - !defined(WIN32) && !defined(__SYMBIAN32__) -#define WIN32 -#endif - -#include -#include - -#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) -/* Needed for __FreeBSD_version symbol definition */ -#include -#endif - -/* The include stuff here below is mainly for time_t! */ -#include -#include - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ - defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) -/* The check above prevents the winsock2 inclusion if winsock.h already was - included, since they can't co-exist without problems */ -#include -#include -#endif -#endif - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on systems that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ - defined(__CYGWIN__) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) -#include -#endif - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#include -#endif - -#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) -#include -#endif - -#ifdef __BEOS__ -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) -typedef struct Curl_easy CURL; -typedef struct Curl_share CURLSH; -#else -typedef void CURL; -typedef void CURLSH; -#endif - -/* - * libcurl external API function linkage decorations. - */ - -#ifdef CURL_STATICLIB -# define CURL_EXTERN -#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) -# if defined(BUILDING_LIBCURL) -# define CURL_EXTERN __declspec(dllexport) -# else -# define CURL_EXTERN __declspec(dllimport) -# endif -#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) -# define CURL_EXTERN CURL_EXTERN_SYMBOL -#else -# define CURL_EXTERN -#endif - -#ifndef curl_socket_typedef -/* socket typedef */ -#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD -1 -#endif -#define curl_socket_typedef -#endif /* curl_socket_typedef */ - -/* enum for the different supported SSL backends */ -typedef enum { - CURLSSLBACKEND_NONE = 0, - CURLSSLBACKEND_OPENSSL = 1, - CURLSSLBACKEND_GNUTLS = 2, - CURLSSLBACKEND_NSS = 3, - CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ - CURLSSLBACKEND_GSKIT = 5, - CURLSSLBACKEND_POLARSSL = 6, - CURLSSLBACKEND_WOLFSSL = 7, - CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_DARWINSSL = 9, - CURLSSLBACKEND_AXTLS = 10, - CURLSSLBACKEND_MBEDTLS = 11 -} curl_sslbackend; - -/* aliases for library clones and renames */ -#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL - -struct curl_httppost { - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field, see also - CURL_HTTPPOST_LARGE */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist *contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ - -/* specified content is a file name */ -#define CURL_HTTPPOST_FILENAME (1<<0) -/* specified content is a file name */ -#define CURL_HTTPPOST_READFILE (1<<1) -/* name is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRNAME (1<<2) -/* contents is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRCONTENTS (1<<3) -/* upload file from buffer */ -#define CURL_HTTPPOST_BUFFER (1<<4) -/* upload file from pointer contents */ -#define CURL_HTTPPOST_PTRBUFFER (1<<5) -/* upload file contents by using the regular read callback to get the data and - pass the given pointer as custom pointer */ -#define CURL_HTTPPOST_CALLBACK (1<<6) -/* use size in 'contentlen', added in 7.46.0 */ -#define CURL_HTTPPOST_LARGE (1<<7) - - char *showfilename; /* The file name to show. If not set, the - actual file name will be used (if this - is a file part) */ - void *userp; /* custom pointer used for - HTTPPOST_CALLBACK posts */ - curl_off_t contentlen; /* alternative length of contents - field. Used if CURL_HTTPPOST_LARGE is - set. Added in 7.46.0 */ -}; - -/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered - deprecated but was the only choice up until 7.31.0 */ -typedef int (*curl_progress_callback)(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - -/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in - 7.32.0, it avoids floating point and provides more detailed information. */ -typedef int (*curl_xferinfo_callback)(void *clientp, - curl_off_t dltotal, - curl_off_t dlnow, - curl_off_t ultotal, - curl_off_t ulnow); - -#ifndef CURL_MAX_READ_SIZE - /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ -#define CURL_MAX_READ_SIZE 524288 -#endif - -#ifndef CURL_MAX_WRITE_SIZE - /* Tests have proven that 20K is a very bad buffer size for uploads on - Windows, while 16K for some odd reason performed a lot better. - We do the ifndef check to allow this value to easier be changed at build - time for those who feel adventurous. The practical minimum is about - 400 bytes since libcurl uses a buffer of this size as a scratch area - (unrelated to network send operations). */ -#define CURL_MAX_WRITE_SIZE 16384 -#endif - -#ifndef CURL_MAX_HTTP_HEADER -/* The only reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause reallocs - infinitely */ -#define CURL_MAX_HTTP_HEADER (100*1024) -#endif - -/* This is a magic return code for the write callback that, when returned, - will signal libcurl to pause receiving on the current transfer. */ -#define CURL_WRITEFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - - - -/* enumeration of file types */ -typedef enum { - CURLFILETYPE_FILE = 0, - CURLFILETYPE_DIRECTORY, - CURLFILETYPE_SYMLINK, - CURLFILETYPE_DEVICE_BLOCK, - CURLFILETYPE_DEVICE_CHAR, - CURLFILETYPE_NAMEDPIPE, - CURLFILETYPE_SOCKET, - CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ - - CURLFILETYPE_UNKNOWN /* should never occur */ -} curlfiletype; - -#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) -#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) -#define CURLFINFOFLAG_KNOWN_TIME (1<<2) -#define CURLFINFOFLAG_KNOWN_PERM (1<<3) -#define CURLFINFOFLAG_KNOWN_UID (1<<4) -#define CURLFINFOFLAG_KNOWN_GID (1<<5) -#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) -#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) - -/* Content of this structure depends on information which is known and is - achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man - page for callbacks returning this structure -- some fields are mandatory, - some others are optional. The FLAG field has special meaning. */ -struct curl_fileinfo { - char *filename; - curlfiletype filetype; - time_t time; - unsigned int perm; - int uid; - int gid; - curl_off_t size; - long int hardlinks; - - struct { - /* If some of these fields is not NULL, it is a pointer to b_data. */ - char *time; - char *perm; - char *user; - char *group; - char *target; /* pointer to the target filename of a symlink */ - } strings; - - unsigned int flags; - - /* used internally */ - char *b_data; - size_t b_size; - size_t b_used; -}; - -/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ -#define CURL_CHUNK_BGN_FUNC_OK 0 -#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ -#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ - -/* if splitting of data transfer is enabled, this callback is called before - download of an individual chunk started. Note that parameter "remains" works - only for FTP wildcard downloading (for now), otherwise is not used */ -typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, - void *ptr, - int remains); - -/* return codes for CURLOPT_CHUNK_END_FUNCTION */ -#define CURL_CHUNK_END_FUNC_OK 0 -#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ - -/* If splitting of data transfer is enabled this callback is called after - download of an individual chunk finished. - Note! After this callback was set then it have to be called FOR ALL chunks. - Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. - This is the reason why we don't need "transfer_info" parameter in this - callback and we are not interested in "remains" parameter too. */ -typedef long (*curl_chunk_end_callback)(void *ptr); - -/* return codes for FNMATCHFUNCTION */ -#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ -#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ -#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ - -/* callback type for wildcard downloading pattern matching. If the - string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ -typedef int (*curl_fnmatch_callback)(void *ptr, - const char *pattern, - const char *string); - -/* These are the return codes for the seek callbacks */ -#define CURL_SEEKFUNC_OK 0 -#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ -#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so - libcurl might try other means instead */ -typedef int (*curl_seek_callback)(void *instream, - curl_off_t offset, - int origin); /* 'whence' */ - -/* This is a return code for the read callback that, when returned, will - signal libcurl to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -/* This is a return code for the read callback that, when returned, will - signal libcurl to pause sending data on the current transfer. */ -#define CURL_READFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - -typedef enum { - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ - CURLSOCKTYPE_LAST /* never use */ -} curlsocktype; - -/* The return code from the sockopt_callback can signal information back - to libcurl: */ -#define CURL_SOCKOPT_OK 0 -#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return - CURLE_ABORTED_BY_CALLBACK */ -#define CURL_SOCKOPT_ALREADY_CONNECTED 2 - -typedef int (*curl_sockopt_callback)(void *clientp, - curl_socket_t curlfd, - curlsocktype purpose); - -struct curl_sockaddr { - int family; - int socktype; - int protocol; - unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it - turned really ugly and painful on the systems that - lack this type */ - struct sockaddr addr; -}; - -typedef curl_socket_t -(*curl_opensocket_callback)(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *address); - -typedef int -(*curl_closesocket_callback)(void *clientp, curl_socket_t item); - -typedef enum { - CURLIOE_OK, /* I/O operation successful */ - CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ - CURLIOE_FAILRESTART, /* failed to restart the read */ - CURLIOE_LAST /* never use */ -} curlioerr; - -typedef enum { - CURLIOCMD_NOP, /* no operation */ - CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ - CURLIOCMD_LAST /* never use */ -} curliocmd; - -typedef curlioerr (*curl_ioctl_callback)(CURL *handle, - int cmd, - void *clientp); - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -#define CURL_DID_MEMORY_FUNC_TYPEDEFS -#endif - -/* the kind of data that is passed to information_callback*/ -typedef enum { - CURLINFO_TEXT = 0, - CURLINFO_HEADER_IN, /* 1 */ - CURLINFO_HEADER_OUT, /* 2 */ - CURLINFO_DATA_IN, /* 3 */ - CURLINFO_DATA_OUT, /* 4 */ - CURLINFO_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - CURLINFO_END -} curl_infotype; - -typedef int (*curl_debug_callback) - (CURL *handle, /* the handle/transfer this concerns */ - curl_infotype type, /* what kind of data */ - char *data, /* points to the data */ - size_t size, /* size of the data pointed to */ - void *userptr); /* whatever the user please */ - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum { - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for - 7.17.0, reused in April 2011 for 7.21.5] */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server - due to lack of access - when login fails - this is not returned. */ - CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for - 7.15.4, reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server - [was obsoleted in August 2007 for 7.17.0, - reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. - [was obsoleted in August 2007 for 7.17.0, - reused in July 2014 for 7.38.0] */ - CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_OBSOLETE20, /* 20 - NOT USED */ - CURLE_QUOTE_ERROR, /* 21 - quote command failure */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_OBSOLETE24, /* 24 - NOT USED */ - CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ - CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error - instead of a memory allocation error if CURL_DOES_CONVERSIONS - is defined - */ - CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ - CURLE_OBSOLETE29, /* 29 - NOT USED */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_OBSOLETE32, /* 32 - NOT USED */ - CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ - CURLE_HTTP_POST_ERROR, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_OBSOLETE44, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ - CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_SEND_ERROR, /* 55 - failed sending network data */ - CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - CURLE_OBSOLETE57, /* 57 - NOT IN USE */ - CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ - CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ - CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ - CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind - that failed */ - CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ - CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not - accepted and we failed to login */ - CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ - CURLE_TFTP_PERM, /* 69 - permission problem on server */ - CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ - CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ - CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ - CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ - CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_CONV_FAILED, /* 75 - conversion failed */ - CURLE_CONV_REQD, /* 76 - caller must register conversion - callbacks using curl_easy_setopt options - CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOPT_CONV_TO_NETWORK_FUNCTION, and - CURLOPT_CONV_FROM_UTF8_FUNCTION */ - CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing - or wrong format */ - CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ - CURLE_SSH, /* 79 - error from the SSH layer, somewhat - generic so the error message will be of - interest when this has happened */ - - CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL - connection */ - CURLE_AGAIN, /* 81 - socket is not ready for send/recv, - wait till it's ready and try again (Added - in 7.18.2) */ - CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or - wrong format (Added in 7.19.0) */ - CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in - 7.19.0) */ - CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ - CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ - CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ - CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ - CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ - CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the - session will be queued */ - CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not - match */ - CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ - CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer - */ - CURL_LAST /* never use! */ -} CURLcode; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Previously obsolete error code re-used in 7.38.0 */ -#define CURLE_OBSOLETE16 CURLE_HTTP2 - -/* Previously obsolete error codes re-used in 7.24.0 */ -#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED -#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT - -/* compatibility with older names */ -#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING -#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY - -/* The following were added in 7.21.5, April 2011 */ -#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION - -/* The following were added in 7.17.1 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.17.0 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ -#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 -#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 -#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 -#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 -#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 -#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 -#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 -#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 -#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 -#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 -#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 -#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN - -#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED -#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE -#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR -#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL -#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS -#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR -#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED - -/* The following were added earlier */ - -#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT - -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED -#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED - -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME - -/* This was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -/* Provide defines for really old option names */ -#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ -#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ -#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA - -/* Since long deprecated options with no code in the lib that does anything - with them. */ -#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 -#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 - -#endif /*!CURL_NO_OLDIES*/ - -/* This prototype applies to all conversion callbacks */ -typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an - OpenSSL SSL_CTX */ - void *userptr); - -typedef enum { - CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use - CONNECT HTTP/1.1 */ - CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT - HTTP/1.0 */ - CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ - CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already - in 7.10 */ - CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ - CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ - CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the - host name rather than the IP address. added - in 7.18.0 */ -} curl_proxytype; /* this enum was added in 7.10 */ - -/* - * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: - * - * CURLAUTH_NONE - No HTTP authentication - * CURLAUTH_BASIC - HTTP Basic authentication (default) - * CURLAUTH_DIGEST - HTTP Digest authentication - * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication - * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) - * CURLAUTH_NTLM - HTTP NTLM authentication - * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour - * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper - * CURLAUTH_ONLY - Use together with a single other type to force no - * authentication or just that single type - * CURLAUTH_ANY - All fine types set - * CURLAUTH_ANYSAFE - All fine types except Basic - */ - -#define CURLAUTH_NONE ((unsigned long)0) -#define CURLAUTH_BASIC (((unsigned long)1)<<0) -#define CURLAUTH_DIGEST (((unsigned long)1)<<1) -#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) -/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ -#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE -/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ -#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE -#define CURLAUTH_NTLM (((unsigned long)1)<<3) -#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) -#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) -#define CURLAUTH_ONLY (((unsigned long)1)<<31) -#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) -#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) - -#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ -#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ -#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ -#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ -#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ -#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ -#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ -#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */ -#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY - -#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ -#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ -#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ - -#define CURL_ERROR_SIZE 256 - -enum curl_khtype { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS, - CURLKHTYPE_ECDSA, - CURLKHTYPE_ED25519 -}; - -struct curl_khkey { - const char *key; /* points to a zero-terminated string encoded with base64 - if len is zero, otherwise to the "raw" data */ - size_t len; - enum curl_khtype keytype; -}; - -/* this is the set of return values expected from the curl_sshkeycallback - callback */ -enum curl_khstat { - CURLKHSTAT_FINE_ADD_TO_FILE, - CURLKHSTAT_FINE, - CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so - this causes a CURLE_DEFER error but otherwise the - connection will be left intact etc */ - CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ -}; - -/* this is the set of status codes pass in to the callback */ -enum curl_khmatch { - CURLKHMATCH_OK, /* match */ - CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ - CURLKHMATCH_MISSING, /* no matching host/key found */ - CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ -}; - -typedef int - (*curl_sshkeycallback) (CURL *easy, /* easy handle */ - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch, /* libcurl's view on the keys */ - void *clientp); /* custom pointer passed from app */ - -/* parameter for the CURLOPT_USE_SSL option */ -typedef enum { - CURLUSESSL_NONE, /* do not attempt to use SSL */ - CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ - CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ - CURLUSESSL_ALL, /* SSL for all communication or fail */ - CURLUSESSL_LAST /* not an option, never use */ -} curl_usessl; - -/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ - -/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the - name of improving interoperability with older servers. Some SSL libraries - have introduced work-arounds for this flaw but those work-arounds sometimes - make the SSL communication fail. To regain functionality with those broken - servers, a user can this way allow the vulnerability back. */ -#define CURLSSLOPT_ALLOW_BEAST (1<<0) - -/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those - SSL backends where such behavior is present. */ -#define CURLSSLOPT_NO_REVOKE (1<<1) - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2009 */ - -#define CURLFTPSSL_NONE CURLUSESSL_NONE -#define CURLFTPSSL_TRY CURLUSESSL_TRY -#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL -#define CURLFTPSSL_ALL CURLUSESSL_ALL -#define CURLFTPSSL_LAST CURLUSESSL_LAST -#define curl_ftpssl curl_usessl -#endif /*!CURL_NO_OLDIES*/ - -/* parameter for the CURLOPT_FTP_SSL_CCC option */ -typedef enum { - CURLFTPSSL_CCC_NONE, /* do not send CCC */ - CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ - CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ - CURLFTPSSL_CCC_LAST /* not an option, never use */ -} curl_ftpccc; - -/* parameter for the CURLOPT_FTPSSLAUTH option */ -typedef enum { - CURLFTPAUTH_DEFAULT, /* let libcurl decide */ - CURLFTPAUTH_SSL, /* use "AUTH SSL" */ - CURLFTPAUTH_TLS, /* use "AUTH TLS" */ - CURLFTPAUTH_LAST /* not an option, never use */ -} curl_ftpauth; - -/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ -typedef enum { - CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ - CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD - again if MKD succeeded, for SFTP this does - similar magic */ - CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD - again even if MKD failed! */ - CURLFTP_CREATE_DIR_LAST /* not an option, never use */ -} curl_ftpcreatedir; - -/* parameter for the CURLOPT_FTP_FILEMETHOD option */ -typedef enum { - CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ - CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ - CURLFTPMETHOD_NOCWD, /* no CWD at all */ - CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ - CURLFTPMETHOD_LAST /* not an option, never use */ -} curl_ftpmethod; - -/* bitmask defines for CURLOPT_HEADEROPT */ -#define CURLHEADER_UNIFIED 0 -#define CURLHEADER_SEPARATE (1<<0) - -/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ -#define CURLPROTO_HTTP (1<<0) -#define CURLPROTO_HTTPS (1<<1) -#define CURLPROTO_FTP (1<<2) -#define CURLPROTO_FTPS (1<<3) -#define CURLPROTO_SCP (1<<4) -#define CURLPROTO_SFTP (1<<5) -#define CURLPROTO_TELNET (1<<6) -#define CURLPROTO_LDAP (1<<7) -#define CURLPROTO_LDAPS (1<<8) -#define CURLPROTO_DICT (1<<9) -#define CURLPROTO_FILE (1<<10) -#define CURLPROTO_TFTP (1<<11) -#define CURLPROTO_IMAP (1<<12) -#define CURLPROTO_IMAPS (1<<13) -#define CURLPROTO_POP3 (1<<14) -#define CURLPROTO_POP3S (1<<15) -#define CURLPROTO_SMTP (1<<16) -#define CURLPROTO_SMTPS (1<<17) -#define CURLPROTO_RTSP (1<<18) -#define CURLPROTO_RTMP (1<<19) -#define CURLPROTO_RTMPT (1<<20) -#define CURLPROTO_RTMPE (1<<21) -#define CURLPROTO_RTMPTE (1<<22) -#define CURLPROTO_RTMPS (1<<23) -#define CURLPROTO_RTMPTS (1<<24) -#define CURLPROTO_GOPHER (1<<25) -#define CURLPROTO_SMB (1<<26) -#define CURLPROTO_SMBS (1<<27) -#define CURLPROTO_ALL (~0) /* enable everything */ - -/* long may be 32 or 64 bits, but we should never depend on anything else - but 32 */ -#define CURLOPTTYPE_LONG 0 -#define CURLOPTTYPE_OBJECTPOINT 10000 -#define CURLOPTTYPE_STRINGPOINT 10000 -#define CURLOPTTYPE_FUNCTIONPOINT 20000 -#define CURLOPTTYPE_OFF_T 30000 - -/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the - string options from the header file */ - -/* name is uppercase CURLOPT_, - type is one of the defined CURLOPTTYPE_ - number is unique identifier */ -#ifdef CINIT -#undef CINIT -#endif - -#ifdef CURL_ISOCPP -#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLOPT_/**/name = type + number -#endif - -/* - * This macro-mania below setups the CURLOPT_[what] enum, to be used with - * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] - * word. - */ - -typedef enum { - /* This is the FILE * or void * the regular output should be written to. */ - CINIT(WRITEDATA, OBJECTPOINT, 1), - - /* The full URL to get/put */ - CINIT(URL, STRINGPOINT, 2), - - /* Port number to connect to, if other than default. */ - CINIT(PORT, LONG, 3), - - /* Name of proxy to use. */ - CINIT(PROXY, STRINGPOINT, 4), - - /* "user:password;options" to use when fetching. */ - CINIT(USERPWD, STRINGPOINT, 5), - - /* "user:password" to use with proxy. */ - CINIT(PROXYUSERPWD, STRINGPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CINIT(RANGE, STRINGPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CINIT(READDATA, OBJECTPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. */ - CINIT(ERRORBUFFER, OBJECTPOINT, 10), - - /* Function that will be called to store the output (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), - - /* Function that will be called to read the input (instead of fread). The - * parameters will use fread() syntax, make sure to follow them. */ - CINIT(READFUNCTION, FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CINIT(TIMEOUT, LONG, 13), - - /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was successful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CINIT(INFILESIZE, LONG, 14), - - /* POST static input fields. */ - CINIT(POSTFIELDS, OBJECTPOINT, 15), - - /* Set the referrer page (needed by some CGIs) */ - CINIT(REFERER, STRINGPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CINIT(FTPPORT, STRINGPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CINIT(USERAGENT, STRINGPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CINIT(LOW_SPEED_LIMIT, LONG, 19), - - /* Set the "low speed time" */ - CINIT(LOW_SPEED_TIME, LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CINIT(RESUME_FROM, LONG, 21), - - /* Set cookie in request: */ - CINIT(COOKIE, STRINGPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind. This - list is also used for RTSP (in spite of its name) */ - CINIT(HTTPHEADER, OBJECTPOINT, 23), - - /* This points to a linked list of post entries, struct curl_httppost */ - CINIT(HTTPPOST, OBJECTPOINT, 24), - - /* name of the file keeping your private SSL-certificate */ - CINIT(SSLCERT, STRINGPOINT, 25), - - /* password for the SSL or SSH private key */ - CINIT(KEYPASSWD, STRINGPOINT, 26), - - /* send TYPE parameter? */ - CINIT(CRLF, LONG, 27), - - /* send linked-list of QUOTE commands */ - CINIT(QUOTE, OBJECTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is simply passed to the callback unmodified */ - CINIT(HEADERDATA, OBJECTPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CINIT(COOKIEFILE, STRINGPOINT, 31), - - /* What version to specifically try to use. - See CURL_SSLVERSION defines below. */ - CINIT(SSLVERSION, LONG, 32), - - /* What kind of HTTP time condition to use, see defines */ - CINIT(TIMECONDITION, LONG, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CINIT(TIMEVALUE, LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CINIT(CUSTOMREQUEST, STRINGPOINT, 36), - - /* FILE handle to use instead of stderr */ - CINIT(STDERR, OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CINIT(POSTQUOTE, OBJECTPOINT, 39), - - CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ - - CINIT(VERBOSE, LONG, 41), /* talk a lot */ - CINIT(HEADER, LONG, 42), /* throw the header out too */ - CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ - CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ - CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ - CINIT(UPLOAD, LONG, 46), /* this is an upload */ - CINIT(POST, LONG, 47), /* HTTP POST method */ - CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ - - CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ - - /* Specify whether to read the user+password from the .netrc or the URL. - * This must be one of the CURL_NETRC_* enums below. */ - CINIT(NETRC, LONG, 51), - - CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ - - CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ - CINIT(PUT, LONG, 54), /* HTTP PUT */ - - /* 55 = OBSOLETE */ - - /* DEPRECATED - * Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), - - /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION - callbacks */ - CINIT(PROGRESSDATA, OBJECTPOINT, 57), -#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA - - /* We want the referrer field set automatically when following locations */ - CINIT(AUTOREFERER, LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CINIT(PROXYPORT, LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CINIT(POSTFIELDSIZE, LONG, 60), - - /* tunnel non-http operations through a HTTP proxy */ - CINIT(HTTPPROXYTUNNEL, LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CINIT(INTERFACE, STRINGPOINT, 62), - - /* Set the krb4/5 security level, this also enables krb4/5 awareness. This - * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string - * is set but doesn't match one of these, 'private' will be used. */ - CINIT(KRBLEVEL, STRINGPOINT, 63), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CINIT(SSL_VERIFYPEER, LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAINFO, STRINGPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CINIT(MAXREDIRS, LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CINIT(FILETIME, LONG, 69), - - /* This points to a linked list of telnet options */ - CINIT(TELNETOPTIONS, OBJECTPOINT, 70), - - /* Max amount of cached alive connections */ - CINIT(MAXCONNECTS, LONG, 71), - - CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ - - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you're absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CINIT(FRESH_CONNECT, LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be re-used - when done. Do not use this unless you're absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CINIT(FORBID_REUSE, LONG, 75), - - /* Set to a file name that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CINIT(RANDOM_FILE, STRINGPOINT, 76), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CINIT(EGDSOCKET, STRINGPOINT, 77), - - /* Time-out connect operations after this amount of seconds, if connects are - OK within this time, then fine... This only aborts the connect phase. */ - CINIT(CONNECTTIMEOUT, LONG, 78), - - /* Function that will be called to store headers (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CINIT(HTTPGET, LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CINIT(SSL_VERIFYHOST, LONG, 81), - - /* Specify which file name to write all known cookies in after completed - operation. Set file name to "-" (dash) to make it go to stdout. */ - CINIT(COOKIEJAR, STRINGPOINT, 82), - - /* Specify which SSL ciphers to use */ - CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CINIT(HTTP_VERSION, LONG, 84), - - /* Specifically switch on or off the FTP engine's use of the EPSV command. By - default, that one will always be attempted before the more traditional - PASV command. */ - CINIT(FTP_USE_EPSV, LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CINIT(SSLCERTTYPE, STRINGPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CINIT(SSLKEY, STRINGPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CINIT(SSLKEYTYPE, STRINGPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CINIT(SSLENGINE, STRINGPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CINIT(SSLENGINE_DEFAULT, LONG, 90), - - /* Non-zero value means to use the global dns cache */ - CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ - - /* DNS cache timeout */ - CINIT(DNS_CACHE_TIMEOUT, LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands */ - CINIT(PREQUOTE, OBJECTPOINT, 93), - - /* set the debug function */ - CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CINIT(DEBUGDATA, OBJECTPOINT, 95), - - /* mark this as start of a cookie session */ - CINIT(COOKIESESSION, LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAPATH, STRINGPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CINIT(BUFFERSIZE, LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CINIT(NOSIGNAL, LONG, 99), - - /* Provide a CURLShare for mutexing non-ts data */ - CINIT(SHARE, OBJECTPOINT, 100), - - /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and - CURLPROXY_SOCKS5. */ - CINIT(PROXYTYPE, LONG, 101), - - /* Set the Accept-Encoding string. Use this to tell a server you would like - the response to be compressed. Before 7.21.6, this was known as - CURLOPT_ENCODING */ - CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), - - /* Set pointer to private data */ - CINIT(PRIVATE, OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CINIT(HTTP200ALIASES, OBJECTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentially send off the name - and password to whatever host the server decides. */ - CINIT(UNRESTRICTED_AUTH, LONG, 105), - - /* Specifically switch on or off the FTP engine's use of the EPRT command ( - it also disables the LPRT attempt). By default, those ones will always be - attempted before the good old traditional PORT command. */ - CINIT(FTP_USE_EPRT, LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(HTTPAUTH, LONG, 107), - - /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx - in second argument. The function must be matching the - curl_ssl_ctx_callback proto. */ - CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server. - In 7.19.4 we introduced the convenience enums for this option using the - CURLFTP_CREATE_DIR prefix. - */ - CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(PROXYAUTH, LONG, 111), - - /* FTP option that changes the timeout, in seconds, associated with - getting a response. This is different from transfer timeout time and - essentially places a demand on the FTP server to acknowledge commands - in a timely manner. */ - CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), -#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to resolve names to those IP versions only. This only has - affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CINIT(IPRESOLVE, LONG, 113), - - /* Set this option to limit the size of a file that will be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CINIT(MAXFILESIZE, LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CINIT(INFILESIZE_LARGE, OFF_T, 115), - - /* Sets the continuation offset. There is also a LONG version of this; - * look above for RESUME_FROM. - */ - CINIT(RESUME_FROM_LARGE, OFF_T, 116), - - /* Sets the maximum size of data that will be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CINIT(MAXFILESIZE_LARGE, OFF_T, 117), - - /* Set this option to the file name of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl will do - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CINIT(NETRC_FILE, STRINGPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLUSESSL_TRY - try using SSL, proceed anyway otherwise - CURLUSESSL_CONTROL - SSL for the control connection or fail - CURLUSESSL_ALL - SSL for all communication or fail - */ - CINIT(USE_SSL, LONG, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CINIT(TCP_NODELAY, LONG, 121), - - /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 123 OBSOLETE. Gone in 7.16.0 */ - /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 127 OBSOLETE. Gone in 7.16.0 */ - /* 128 OBSOLETE. Gone in 7.16.0 */ - - /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option - can be used to change libcurl's default action which is to first try - "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK - response has been received. - - Available parameters are: - CURLFTPAUTH_DEFAULT - let libcurl decide - CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS - CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL - */ - CINIT(FTPSSLAUTH, LONG, 129), - - CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), - CINIT(IOCTLDATA, OBJECTPOINT, 131), - - /* 132 OBSOLETE. Gone in 7.16.0 */ - /* 133 OBSOLETE. Gone in 7.16.0 */ - - /* zero terminated string for pass on to the FTP server when asked for - "account" info */ - CINIT(FTP_ACCOUNT, STRINGPOINT, 134), - - /* feed cookie into cookie engine */ - CINIT(COOKIELIST, STRINGPOINT, 135), - - /* ignore Content-Length */ - CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), - - /* Set to non-zero to skip the IP address received in a 227 PASV FTP server - response. Typically used for FTP-SSL purposes but is not restricted to - that. libcurl will then instead use the same IP address it used for the - control connection. */ - CINIT(FTP_SKIP_PASV_IP, LONG, 137), - - /* Select "file method" to use when doing FTP, see the curl_ftpmethod - above. */ - CINIT(FTP_FILEMETHOD, LONG, 138), - - /* Local port number to bind the socket to */ - CINIT(LOCALPORT, LONG, 139), - - /* Number of ports to try, including the first one set with LOCALPORT. - Thus, setting it to 1 will make no additional attempts but the first. - */ - CINIT(LOCALPORTRANGE, LONG, 140), - - /* no transfer, set up connection and let application use the socket by - extracting it with CURLINFO_LASTSOCKET */ - CINIT(CONNECT_ONLY, LONG, 141), - - /* Function that will be called to convert from the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), - - /* Function that will be called to convert to the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), - - /* Function that will be called to convert from UTF8 - (instead of using the iconv calls in libcurl) - Note that this is used only for SSL certificate processing */ - CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), - - /* if the connection proceeds too quickly then need to slow it down */ - /* limit-rate: maximum number of bytes per second to send or receive */ - CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), - CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), - - /* Pointer to command string to send if USER/PASS fails. */ - CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), - - /* callback function for setting socket options */ - CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), - CINIT(SOCKOPTDATA, OBJECTPOINT, 149), - - /* set to 0 to disable session ID re-use for this transfer, default is - enabled (== 1) */ - CINIT(SSL_SESSIONID_CACHE, LONG, 150), - - /* allowed SSH authentication methods */ - CINIT(SSH_AUTH_TYPES, LONG, 151), - - /* Used by scp/sftp to do public/private key authentication */ - CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), - CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), - - /* Send CCC (Clear Command Channel) after authentication */ - CINIT(FTP_SSL_CCC, LONG, 154), - - /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CINIT(TIMEOUT_MS, LONG, 155), - CINIT(CONNECTTIMEOUT_MS, LONG, 156), - - /* set to zero to disable the libcurl's decoding and thus pass the raw body - data to the application even when it is encoded/compressed */ - CINIT(HTTP_TRANSFER_DECODING, LONG, 157), - CINIT(HTTP_CONTENT_DECODING, LONG, 158), - - /* Permission used when creating new files and directories on the remote - server for protocols that support it, SFTP/SCP/FILE */ - CINIT(NEW_FILE_PERMS, LONG, 159), - CINIT(NEW_DIRECTORY_PERMS, LONG, 160), - - /* Set the behaviour of POST when redirecting. Values must be set to one - of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CINIT(POSTREDIR, LONG, 161), - - /* used by scp/sftp to verify the host's public key */ - CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), - - /* Callback function for opening socket (instead of socket(2)). Optionally, - callback is able change the address or refuse to connect returning - CURL_SOCKET_BAD. The callback should have type - curl_opensocket_callback */ - CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), - CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), - - /* POST volatile input fields. */ - CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), - - /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CINIT(PROXY_TRANSFER_MODE, LONG, 166), - - /* Callback function for seeking in the input stream */ - CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), - CINIT(SEEKDATA, OBJECTPOINT, 168), - - /* CRL file */ - CINIT(CRLFILE, STRINGPOINT, 169), - - /* Issuer certificate */ - CINIT(ISSUERCERT, STRINGPOINT, 170), - - /* (IPv6) Address scope */ - CINIT(ADDRESS_SCOPE, LONG, 171), - - /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. */ - CINIT(CERTINFO, LONG, 172), - - /* "name" and "pwd" to use when fetching. */ - CINIT(USERNAME, STRINGPOINT, 173), - CINIT(PASSWORD, STRINGPOINT, 174), - - /* "name" and "pwd" to use with Proxy when fetching. */ - CINIT(PROXYUSERNAME, STRINGPOINT, 175), - CINIT(PROXYPASSWORD, STRINGPOINT, 176), - - /* Comma separated list of hostnames defining no-proxy zones. These should - match both hostnames directly, and hostnames within a domain. For - example, local.com will match local.com and www.local.com, but NOT - notlocal.com or www.notlocal.com. For compatibility with other - implementations of this, .local.com will be considered to be the same as - local.com. A single * is the only valid wildcard, and effectively - disables the use of proxy. */ - CINIT(NOPROXY, STRINGPOINT, 177), - - /* block size for TFTP transfers */ - CINIT(TFTP_BLKSIZE, LONG, 178), - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), - - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - CINIT(PROTOCOLS, LONG, 181), - - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. Defaults - to all protocols except FILE and SCP. */ - CINIT(REDIR_PROTOCOLS, LONG, 182), - - /* set the SSH knownhost file name to use */ - CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), - - /* set the SSH host key callback custom pointer */ - CINIT(SSH_KEYDATA, OBJECTPOINT, 185), - - /* set the SMTP mail originator */ - CINIT(MAIL_FROM, STRINGPOINT, 186), - - /* set the list of SMTP mail receiver(s) */ - CINIT(MAIL_RCPT, OBJECTPOINT, 187), - - /* FTP: send PRET before PASV */ - CINIT(FTP_USE_PRET, LONG, 188), - - /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CINIT(RTSP_REQUEST, LONG, 189), - - /* The RTSP session identifier */ - CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), - - /* The RTSP stream URI */ - CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), - - /* The Transport: header to use in RTSP requests */ - CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), - - /* Manually initialize the client RTSP CSeq for this handle */ - CINIT(RTSP_CLIENT_CSEQ, LONG, 193), - - /* Manually initialize the server RTSP CSeq for this handle */ - CINIT(RTSP_SERVER_CSEQ, LONG, 194), - - /* The stream to pass to INTERLEAVEFUNCTION. */ - CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), - - /* Let the application define a custom write method for RTP data */ - CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), - - /* Turn on wildcard matching */ - CINIT(WILDCARDMATCH, LONG, 197), - - /* Directory matching callback called before downloading of an - individual file (chunk) started */ - CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), - - /* Directory matching callback called after the file (chunk) - was downloaded, or skipped */ - CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), - - /* Change match (fnmatch-like) callback for wildcard matching */ - CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), - - /* Let the application define custom chunk data pointer */ - CINIT(CHUNK_DATA, OBJECTPOINT, 201), - - /* FNMATCH_FUNCTION user pointer */ - CINIT(FNMATCH_DATA, OBJECTPOINT, 202), - - /* send linked-list of name:port:address sets */ - CINIT(RESOLVE, OBJECTPOINT, 203), - - /* Set a username for authenticated TLS */ - CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), - - /* Set a password for authenticated TLS */ - CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), - - /* Set authentication type for authenticated TLS */ - CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), - - /* Set to 1 to enable the "TE:" header in HTTP requests to ask for - compressed transfer-encoded responses. Set to 0 to disable the use of TE: - in outgoing requests. The current default is 0, but it might change in a - future libcurl release. - - libcurl will ask for the compressed methods it knows of, and if that - isn't any, it will not ask for transfer-encoding at all even if this - option is set to 1. - - */ - CINIT(TRANSFER_ENCODING, LONG, 207), - - /* Callback function for closing socket (instead of close(2)). The callback - should have type curl_closesocket_callback */ - CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), - CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), - - /* allow GSSAPI credential delegation */ - CINIT(GSSAPI_DELEGATION, LONG, 210), - - /* Set the name servers to use for DNS resolution */ - CINIT(DNS_SERVERS, STRINGPOINT, 211), - - /* Time-out accept operations (currently for FTP only) after this amount - of milliseconds. */ - CINIT(ACCEPTTIMEOUT_MS, LONG, 212), - - /* Set TCP keepalive */ - CINIT(TCP_KEEPALIVE, LONG, 213), - - /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ - CINIT(TCP_KEEPIDLE, LONG, 214), - CINIT(TCP_KEEPINTVL, LONG, 215), - - /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ - CINIT(SSL_OPTIONS, LONG, 216), - - /* Set the SMTP auth originator */ - CINIT(MAIL_AUTH, STRINGPOINT, 217), - - /* Enable/disable SASL initial response */ - CINIT(SASL_IR, LONG, 218), - - /* Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_xferinfo_callback - * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ - CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), - - /* The XOAUTH2 bearer token */ - CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), - - /* Set the interface string to use as outgoing network - * interface for DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_INTERFACE, STRINGPOINT, 221), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), - - /* Set authentication options directly */ - CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), - - /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ - CINIT(SSL_ENABLE_NPN, LONG, 225), - - /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ - CINIT(SSL_ENABLE_ALPN, LONG, 226), - - /* Time to wait for a response to a HTTP request containing an - * Expect: 100-continue header before sending the data anyway. */ - CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), - - /* This points to a linked list of headers used for proxy requests only, - struct curl_slist kind */ - CINIT(PROXYHEADER, OBJECTPOINT, 228), - - /* Pass in a bitmask of "header options" */ - CINIT(HEADEROPT, LONG, 229), - - /* The public key in DER form used to validate the peer public key - this option is used only if SSL_VERIFYPEER is true */ - CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), - - /* Path to Unix domain socket */ - CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), - - /* Set if we should verify the certificate status. */ - CINIT(SSL_VERIFYSTATUS, LONG, 232), - - /* Set if we should enable TLS false start. */ - CINIT(SSL_FALSESTART, LONG, 233), - - /* Do not squash dot-dot sequences */ - CINIT(PATH_AS_IS, LONG, 234), - - /* Proxy Service Name */ - CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), - - /* Service Name */ - CINIT(SERVICE_NAME, STRINGPOINT, 236), - - /* Wait/don't wait for pipe/mutex to clarify */ - CINIT(PIPEWAIT, LONG, 237), - - /* Set the protocol used when curl is given a URL without a protocol */ - CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), - - /* Set stream weight, 1 - 256 (default is 16) */ - CINIT(STREAM_WEIGHT, LONG, 239), - - /* Set stream dependency on another CURL handle */ - CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), - - /* Set E-xclusive stream dependency on another CURL handle */ - CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), - - /* Do not send any tftp option requests to the server */ - CINIT(TFTP_NO_OPTIONS, LONG, 242), - - /* Linked-list of host:port:connect-to-host:connect-to-port, - overrides the URL's host:port (only for the network layer) */ - CINIT(CONNECT_TO, OBJECTPOINT, 243), - - /* Set TCP Fast Open */ - CINIT(TCP_FASTOPEN, LONG, 244), - - /* Continue to send data if the server responds early with an - * HTTP status code >= 300 */ - CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), - - /* The CApath or CAfile used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CINIT(PROXY_CAINFO, STRINGPOINT, 246), - - /* The CApath directory used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CINIT(PROXY_CAPATH, STRINGPOINT, 247), - - /* Set if we should verify the proxy in ssl handshake, - set 1 to verify. */ - CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), - - /* Set if we should verify the Common name from the proxy certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches - * the provided hostname. */ - CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), - - /* What version to specifically try to use for proxy. - See CURL_SSLVERSION defines below. */ - CINIT(PROXY_SSLVERSION, LONG, 250), - - /* Set a username for authenticated TLS for proxy */ - CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), - - /* Set a password for authenticated TLS for proxy */ - CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), - - /* Set authentication type for authenticated TLS for proxy */ - CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), - - /* name of the file keeping your private SSL-certificate for proxy */ - CINIT(PROXY_SSLCERT, STRINGPOINT, 254), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for - proxy */ - CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), - - /* name of the file keeping your private SSL-key for proxy */ - CINIT(PROXY_SSLKEY, STRINGPOINT, 256), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for - proxy */ - CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), - - /* password for the SSL private key for proxy */ - CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), - - /* Specify which SSL ciphers to use for proxy */ - CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), - - /* CRL file for proxy */ - CINIT(PROXY_CRLFILE, STRINGPOINT, 260), - - /* Enable/disable specific SSL features with a bitmask for proxy, see - CURLSSLOPT_* */ - CINIT(PROXY_SSL_OPTIONS, LONG, 261), - - /* Name of pre proxy to use. */ - CINIT(PRE_PROXY, STRINGPOINT, 262), - - /* The public key in DER form used to validate the proxy public key - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), - - /* Path to an abstract Unix domain socket */ - CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264), - - /* Suppress proxy CONNECT response headers from user callbacks */ - CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265), - - /* The request target, instead of extracted from the URL */ - CINIT(REQUEST_TARGET, STRINGPOINT, 266), - - /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ - CINIT(SOCKS5_AUTH, LONG, 267), - - /* Enable/disable SSH compression */ - CINIT(SSH_COMPRESSION, LONG, 268), - - /* Post MIME data. */ - CINIT(MIMEPOST, OBJECTPOINT, 269), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2011 */ - -/* This was added in version 7.19.1 */ -#define CURLOPT_POST301 CURLOPT_POSTREDIR - -/* These are scheduled to disappear by 2009 */ - -/* The following were added in 7.17.0 */ -#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_FTPAPPEND CURLOPT_APPEND -#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY -#define CURLOPT_FTP_SSL CURLOPT_USE_SSL - -/* The following were added earlier */ - -#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - - - /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ - - /* three convenient "aliases" that follow the name scheme better */ -#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER - - /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ -enum { - CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd - like the library to choose the best possible - for us! */ - CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ - CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ - CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ - CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 - Upgrade */ - - CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ -}; - -/* Convenience definition simple because the name of the version is HTTP/2 and - not 2.0. The 2_0 version of the enum name was set while the version was - still planned to be 2.0 and we stick to it for compatibility. */ -#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 - -/* - * Public API enums for RTSP requests - */ -enum { - CURL_RTSPREQ_NONE, /* first in list */ - CURL_RTSPREQ_OPTIONS, - CURL_RTSPREQ_DESCRIBE, - CURL_RTSPREQ_ANNOUNCE, - CURL_RTSPREQ_SETUP, - CURL_RTSPREQ_PLAY, - CURL_RTSPREQ_PAUSE, - CURL_RTSPREQ_TEARDOWN, - CURL_RTSPREQ_GET_PARAMETER, - CURL_RTSPREQ_SET_PARAMETER, - CURL_RTSPREQ_RECORD, - CURL_RTSPREQ_RECEIVE, - CURL_RTSPREQ_LAST /* last in list */ -}; - - /* These enums are for use with the CURLOPT_NETRC option. */ -enum CURL_NETRC_OPTION { - CURL_NETRC_IGNORED, /* The .netrc will never be read. - * This is the default. */ - CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred - * to one in the .netrc. */ - CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. - * Unless one is set programmatically, the .netrc - * will be queried. */ - CURL_NETRC_LAST -}; - -enum { - CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, /* TLS 1.x */ - CURL_SSLVERSION_SSLv2, - CURL_SSLVERSION_SSLv3, - CURL_SSLVERSION_TLSv1_0, - CURL_SSLVERSION_TLSv1_1, - CURL_SSLVERSION_TLSv1_2, - CURL_SSLVERSION_TLSv1_3, - - CURL_SSLVERSION_LAST /* never use, keep last */ -}; - -enum { - CURL_SSLVERSION_MAX_NONE = 0, - CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), - CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), - CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), - CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), - CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), - - /* never use, keep last */ - CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) -}; - -enum CURL_TLSAUTH { - CURL_TLSAUTH_NONE, - CURL_TLSAUTH_SRP, - CURL_TLSAUTH_LAST /* never use, keep last */ -}; - -/* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 - can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 - | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ - -#define CURL_REDIR_GET_ALL 0 -#define CURL_REDIR_POST_301 1 -#define CURL_REDIR_POST_302 2 -#define CURL_REDIR_POST_303 4 -#define CURL_REDIR_POST_ALL \ - (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) - -typedef enum { - CURL_TIMECOND_NONE, - - CURL_TIMECOND_IFMODSINCE, - CURL_TIMECOND_IFUNMODSINCE, - CURL_TIMECOND_LASTMOD, - - CURL_TIMECOND_LAST -} curl_TimeCond; - -/* Special size_t value signaling a zero-terminated string. */ -#define CURL_ZERO_TERMINATED ((size_t) -1) - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - release */ -CURL_EXTERN int curl_strequal(const char *s1, const char *s2); -CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n); - -/* Mime/form handling support. */ -typedef struct curl_mime_s curl_mime; /* Mime context. */ -typedef struct curl_mimepart_s curl_mimepart; /* Mime part context. */ - -/* - * NAME curl_mime_init() - * - * DESCRIPTION - * - * Create a mime context and return its handle. The easy parameter is the - * target handle. - */ -CURL_EXTERN curl_mime *curl_mime_init(CURL *easy); - -/* - * NAME curl_mime_free() - * - * DESCRIPTION - * - * release a mime handle and its substructures. - */ -CURL_EXTERN void curl_mime_free(curl_mime *mime); - -/* - * NAME curl_mime_addpart() - * - * DESCRIPTION - * - * Append a new empty part to the given mime context and return a handle to - * the created part. - */ -CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime); - -/* - * NAME curl_mime_name() - * - * DESCRIPTION - * - * Set mime/form part name. - */ -CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name); - -/* - * NAME curl_mime_filename() - * - * DESCRIPTION - * - * Set mime part remote file name. - */ -CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_type() - * - * DESCRIPTION - * - * Set mime part type. - */ -CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); - -/* - * NAME curl_mime_encoder() - * - * DESCRIPTION - * - * Set mime data transfer encoder. - */ -CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part, - const char *encoding); - -/* - * NAME curl_mime_data() - * - * DESCRIPTION - * - * Set mime part data source from memory data, - */ -CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part, - const char *data, size_t datasize); - -/* - * NAME curl_mime_filedata() - * - * DESCRIPTION - * - * Set mime part data source from named file. - */ -CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_data_cb() - * - * DESCRIPTION - * - * Set mime part data source from callback function. - */ -CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part, - curl_off_t datasize, - curl_read_callback readfunc, - curl_seek_callback seekfunc, - curl_free_callback freefunc, - void *arg); - -/* - * NAME curl_mime_subparts() - * - * DESCRIPTION - * - * Set mime part data source from subparts. - */ -CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, - curl_mime *subparts); -/* - * NAME curl_mime_headers() - * - * DESCRIPTION - * - * Set mime part headers. - */ -CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, - struct curl_slist *headers, - int take_ownership); - -/* Old form API. */ -/* name is uppercase CURLFORM_ */ -#ifdef CFINIT -#undef CFINIT -#endif - -#ifdef CURL_ISOCPP -#define CFINIT(name) CURLFORM_ ## name -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define CFINIT(name) CURLFORM_/**/name -#endif - -typedef enum { - CFINIT(NOTHING), /********* the first one is unused ************/ - - /* */ - CFINIT(COPYNAME), - CFINIT(PTRNAME), - CFINIT(NAMELENGTH), - CFINIT(COPYCONTENTS), - CFINIT(PTRCONTENTS), - CFINIT(CONTENTSLENGTH), - CFINIT(FILECONTENT), - CFINIT(ARRAY), - CFINIT(OBSOLETE), - CFINIT(FILE), - - CFINIT(BUFFER), - CFINIT(BUFFERPTR), - CFINIT(BUFFERLENGTH), - - CFINIT(CONTENTTYPE), - CFINIT(CONTENTHEADER), - CFINIT(FILENAME), - CFINIT(END), - CFINIT(OBSOLETE2), - - CFINIT(STREAM), - CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ - - CURLFORM_LASTENTRY /* the last unused */ -} CURLformoption; - -#undef CFINIT /* done */ - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms { - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum { - CURL_FORMADD_OK, /* first, no error */ - - CURL_FORMADD_MEMORY, - CURL_FORMADD_OPTION_TWICE, - CURL_FORMADD_NULL, - CURL_FORMADD_UNKNOWN_OPTION, - CURL_FORMADD_INCOMPLETE, - CURL_FORMADD_ILLEGAL_ARRAY, - CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanced function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * callback function for curl_formget() - * The void *arg pointer will be the one passed as second argument to - * curl_formget(). - * The character buffer passed to it must not be freed. - * Should return the buffer length passed to it as the argument "len" on - * success. - */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, - size_t len); - -/* - * NAME curl_formget() - * - * DESCRIPTION - * - * Serialize a curl_httppost struct built with curl_formadd(). - * Accepts a void pointer as second argument which will be passed to - * the curl_formget_callback function. - * Returns 0 on success. - */ -CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append); -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -CURL_EXTERN void curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -CURL_EXTERN char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ascii string of the libcurl version. - */ -CURL_EXTERN char *curl_version(void); - -/* - * NAME curl_easy_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -CURL_EXTERN char *curl_easy_escape(CURL *handle, - const char *string, - int length); - -/* the previous version: */ -CURL_EXTERN char *curl_escape(const char *string, - int length); - - -/* - * NAME curl_easy_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - * Conversion Note: On non-ASCII platforms the ASCII %XX codes are - * converted into the host encoding. - */ -CURL_EXTERN char *curl_easy_unescape(CURL *handle, - const char *string, - int length, - int *outlength); - -/* the previous version */ -CURL_EXTERN char *curl_unescape(const char *string, - int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -CURL_EXTERN void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl and before any call of other libcurl functions. - * - * This function is not thread-safe! - */ -CURL_EXTERN CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for mis-use of the curl library etc. User registered - * callback routines with be invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURL_EXTERN CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -CURL_EXTERN void curl_global_cleanup(void); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist { - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_global_sslset() - * - * DESCRIPTION - * - * When built with multiple SSL backends, curl_global_sslset() allows to - * choose one. This function can only be called once, and it must be called - * *before* curl_global_init(). - * - * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The - * backend can also be specified via the name parameter (passing -1 as id). - * If both id and name are specified, the name will be ignored. If neither id - * nor name are specified, the function will fail with - * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the - * NULL-terminated list of available backends. - * - * Upon success, the function returns CURLSSLSET_OK. - * - * If the specified SSL backend is not available, the function returns - * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated - * list of available SSL backends. - * - * The SSL backend can be set only once. If it has already been set, a - * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE. - */ - -typedef struct { - curl_sslbackend id; - const char *name; -} curl_ssl_backend; - -typedef enum { - CURLSSLSET_OK = 0, - CURLSSLSET_UNKNOWN_BACKEND, - CURLSSLSET_TOO_LATE, - CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */ -} CURLsslset; - -CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail); - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it will be created - * first. Returns the new list, after appending. - */ -CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, - const char *); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -CURL_EXTERN void curl_slist_free_all(struct curl_slist *); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is unused - * and should be set to NULL. - */ -CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); - -/* info about the certificate chain, only for OpenSSL builds. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -struct curl_certinfo { - int num_of_certs; /* number of certificates with information */ - struct curl_slist **certinfo; /* for each index in this array, there's a - linked list with textual information in the - format "name: value" */ -}; - -/* Information about the SSL library used and the respective internal SSL - handle, which can be used to obtain further information regarding the - connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ -struct curl_tlssessioninfo { - curl_sslbackend backend; - void *internals; -}; - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_SLIST 0x400000 -#define CURLINFO_PTR 0x400000 /* same as SLIST */ -#define CURLINFO_SOCKET 0x500000 -#define CURLINFO_OFF_T 0x600000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum { - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, - CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, - CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, - CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, - CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, - CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, - CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, - CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, - CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, - CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, - CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, - CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, - CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, - CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, - CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_PTR + 34, - CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, - CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, - CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, - CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, - CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, - CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, - CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, - CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, - CURLINFO_TLS_SESSION = CURLINFO_PTR + 43, - CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, - CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, - CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, - CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, - CURLINFO_PROTOCOL = CURLINFO_LONG + 48, - CURLINFO_SCHEME = CURLINFO_STRING + 49, - /* Fill in new entries below here! */ - - CURLINFO_LASTONE = 49 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum { - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */ -#define CURL_GLOBAL_WIN32 (1<<1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL -#define CURL_GLOBAL_ACK_EINTR (1<<2) - - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum { - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internally to say that - * the locking is just made to change the internal state of the share - * itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum { - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - - -typedef enum { - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* 4 out of memory */ - CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum { - CURLSHOPT_NONE, /* don't use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURL_EXTERN CURLSH *curl_share_init(void); -CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); -CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum { - CURLVERSION_FIRST, - CURLVERSION_SECOND, - CURLVERSION_THIRD, - CURLVERSION_FOURTH, - CURLVERSION_FIFTH, - CURLVERSION_LAST /* never actually use this */ -} CURLversion; - -/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by - basically all programs ever that want to get version information. It is - meant to be a built-in version number for what kind of struct the caller - expects. If the struct ever changes, we redefine the NOW to another enum - from above. */ -#define CURLVERSION_NOW CURLVERSION_FIFTH - -typedef struct { - CURLversion age; /* age of the returned struct */ - const char *version; /* LIBCURL_VERSION */ - unsigned int version_num; /* LIBCURL_VERSION_NUM */ - const char *host; /* OS/host/cpu/machine when configured */ - int features; /* bitmask, see defines below */ - const char *ssl_version; /* human readable string */ - long ssl_version_num; /* not used anymore, always 0 */ - const char *libz_version; /* human readable string */ - /* protocols is terminated by an entry with a NULL protoname */ - const char * const *protocols; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was added in CURLVERSION_THIRD */ - const char *libidn; - - /* These field were added in CURLVERSION_FOURTH */ - - /* Same as '_libiconv_version' if built with HAVE_ICONV */ - int iconv_ver_num; - - const char *libssh_version; /* human readable string */ - - /* These fields were added in CURLVERSION_FIFTH */ - - unsigned int brotli_ver_num; /* Numeric Brotli version - (MAJOR << 24) | (MINOR << 12) | PATCH */ - const char *brotli_version; /* human readable string. */ - -} curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported - (deprecated) */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported - (deprecated) */ -#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ -#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are - supported */ -#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ -#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ -#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ -#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper - is supported */ -#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ -#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ -#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ -#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ -#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used - for cookie domain verification */ -#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ -#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ -#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ - - /* - * NAME curl_version_info() - * - * DESCRIPTION - * - * This function returns a pointer to a static copy of the version info - * struct. See above. - */ -CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_easy_strerror(CURLcode); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_share_strerror(CURLSHcode); - -/* - * NAME curl_easy_pause() - * - * DESCRIPTION - * - * The curl_easy_pause function pauses or unpauses transfers. Select the new - * state by setting the bitmask, use the convenience defines below. - * - */ -CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); - -#define CURLPAUSE_RECV (1<<0) -#define CURLPAUSE_RECV_CONT (0) - -#define CURLPAUSE_SEND (1<<2) -#define CURLPAUSE_SEND_CONT (0) - -#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) -#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) - -#ifdef __cplusplus -} -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" - -/* the typechecker doesn't work in C++ (yet) */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ - !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) -#include "typecheck-gcc.h" -#else -#if defined(__STDC__) && (__STDC__ >= 1) -/* This preprocessor magic that replaces a call with the exact same call is - only done to make sure application authors pass exactly three arguments - to these functions. */ -#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) -#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) -#endif /* __STDC__ >= 1 */ -#endif /* gcc >= 4.3 && !__cplusplus */ - -#endif /* __CURL_CURL_H */ diff --git a/ext/curl-7.58.0/Win32/include/curl/curlver.h b/ext/curl-7.58.0/Win32/include/curl/curlver.h deleted file mode 100644 index 6d93cc11..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/curlver.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __CURL_CURLVER_H -#define __CURL_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, ." - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "7.58.0" - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 58 -#define LIBCURL_VERSION_PATCH 0 - -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparions by programs. The LIBCURL_VERSION_NUM define will - always follow this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal (using 8 bits each). All three numbers are always represented - using two digits. 1.2 would appear as "0x010200" while version 9.11.7 - appears as "0x090b07". - - This 6-digit (24 bits) hexadecimal number does not show pre-release number, - and it is always a greater number in a more recent release. It makes - comparisons with greater than and less than work. - - Note: This define is the full hex number and _does not_ use the - CURL_VERSION_BITS() macro since curl's own configure script greps for it - and needs it to contain the full number. -*/ -#define LIBCURL_VERSION_NUM 0x073a00 - -/* - * This is the date and time when the full source package was created. The - * timestamp is not stored in git, as the timestamp is properly set in the - * tarballs by the maketgz script. - * - * The format of the date follows this template: - * - * "2007-11-23" - */ -#define LIBCURL_TIMESTAMP "2018-01-24" - -#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) -#define CURL_AT_LEAST_VERSION(x,y,z) \ - (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) - -#endif /* __CURL_CURLVER_H */ diff --git a/ext/curl-7.58.0/Win32/include/curl/easy.h b/ext/curl-7.58.0/Win32/include/curl/easy.h deleted file mode 100644 index 752c5049..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/easy.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __CURL_EASY_H -#define __CURL_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN CURL *curl_easy_init(void); -CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); -CURL_EXTERN void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. The - * third argument MUST be a pointer to a long, a pointer to a char * or a - * pointer to a double (as the documentation describes elsewhere). The data - * pointed to will be filled in accordingly and can be relied upon only if the - * function returns CURLE_OK. This function is intended to get used *AFTER* a - * performed transfer, all results from this function are undefined until the - * transfer is completed. - */ -CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistent connections cannot - * be transferred. It is useful in multithreaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a CURL handle to the default values. This puts back the - * handle to the same state as it was in when it was just created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -CURL_EXTERN void curl_easy_reset(CURL *curl); - -/* - * NAME curl_easy_recv() - * - * DESCRIPTION - * - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, - size_t *n); - -/* - * NAME curl_easy_send() - * - * DESCRIPTION - * - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, - size_t buflen, size_t *n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ext/curl-7.58.0/Win32/include/curl/mprintf.h b/ext/curl-7.58.0/Win32/include/curl/mprintf.h deleted file mode 100644 index e20f546e..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/mprintf.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __CURL_MPRINTF_H -#define __CURL_MPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include -#include /* needed for FILE */ -#include "curl.h" /* for CURL_EXTERN */ - -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN int curl_mprintf(const char *format, ...); -CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); -CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); -CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, - const char *format, ...); -CURL_EXTERN int curl_mvprintf(const char *format, va_list args); -CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); -CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); -CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, - const char *format, va_list args); -CURL_EXTERN char *curl_maprintf(const char *format, ...); -CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); - -#ifdef __cplusplus -} -#endif - -#endif /* __CURL_MPRINTF_H */ diff --git a/ext/curl-7.58.0/Win32/include/curl/multi.h b/ext/curl-7.58.0/Win32/include/curl/multi.h deleted file mode 100644 index 911c91dd..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/multi.h +++ /dev/null @@ -1,439 +0,0 @@ -#ifndef __CURL_MULTI_H -#define __CURL_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* - This is an "external" header file. Don't give away any internals here! - - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ - -/* - * This header file should not really need to include "curl.h" since curl.h - * itself includes this file and we expect user applications to do #include - * without the need for especially including multi.h. - * - * For some reason we added this include here at one point, and rather than to - * break existing (wrongly written) libcurl applications, we leave it as-is - * but with this warning attached. - */ -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) -typedef struct Curl_multi CURLM; -#else -typedef void CURLM; -#endif - -typedef enum { - CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or - curl_multi_socket*() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ - CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ - CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was - attempted to get added - again */ - CURLM_LAST -} CURLMcode; - -/* just to make code nicer when using curl_multi_socket() you can now check - for CURLM_CALL_MULTI_SOCKET too in the same style it works for - curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ -#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM - -/* bitmask bits for CURLMOPT_PIPELINING */ -#define CURLPIPE_NOTHING 0L -#define CURLPIPE_HTTP1 1L -#define CURLPIPE_MULTIPLEX 2L - -typedef enum { - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg { - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* Based on poll(2) structure and values. - * We don't use pollfd and POLL* constants explicitly - * to cover platforms without poll(). */ -#define CURL_WAIT_POLLIN 0x0001 -#define CURL_WAIT_POLLPRI 0x0002 -#define CURL_WAIT_POLLOUT 0x0004 - -struct curl_waitfd { - curl_socket_t fd; - short events; - short revents; /* not supported yet */ -}; - -/* - * Name: curl_multi_init() - * - * Desc: inititalize multi-style curl usage - * - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURL_EXTERN CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - -/* - * Name: curl_multi_wait() - * - * Desc: Poll on all fds within a CURLM set as well as any - * additional fds passed to the function. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret); - - /* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there's data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called just in case. It returns - * the number of handles that still transfer data in the second - * argument's integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. - */ -CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, - int *running_handles); - - /* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles will be if this function is called - * in the middle of a transfer. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there's any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or just the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function will return a new struct each - * time, until a special "end of msgs" struct is returned as a signal - * that there is no more to get at this point. - * - * The data the returned pointer points to will not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic information. If more involved information is wanted, - * we will provide the particular "transfer handle" in that struct - * and that should/could/would be used in subsequent - * curl_easy_getinfo() calls (or similar). The point being that we - * must never expose complex structs to applications, as then we'll - * undoubtably get backwards compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, - int *msgs_in_queue); - -/* - * Name: curl_multi_strerror() - * - * Desc: The curl_multi_strerror function may be used to turn a CURLMcode - * value into the equivalent human readable error string. This is - * useful for printing meaningful error messages. - * - * Returns: A pointer to a zero-terminated error message. - */ -CURL_EXTERN const char *curl_multi_strerror(CURLMcode); - -/* - * Name: curl_multi_socket() and - * curl_multi_socket_all() - * - * Desc: An alternative version of curl_multi_perform() that allows the - * application to pass in one of the file descriptors that have been - * detected to have "action" on them and let libcurl perform. - * See man page for details. - */ -#define CURL_POLL_NONE 0 -#define CURL_POLL_IN 1 -#define CURL_POLL_OUT 2 -#define CURL_POLL_INOUT 3 -#define CURL_POLL_REMOVE 4 - -#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD - -#define CURL_CSELECT_IN 0x01 -#define CURL_CSELECT_OUT 0x02 -#define CURL_CSELECT_ERR 0x04 - -typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp); /* private socket - pointer */ -/* - * Name: curl_multi_timer_callback - * - * Desc: Called by libcurl whenever the library detects a change in the - * maximum number of milliseconds the app is allowed to wait before - * curl_multi_socket() or curl_multi_perform() must be called - * (to allow libcurl's timed events to take place). - * - * Returns: The callback should return zero. - */ -typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp); /* private callback - pointer */ - -CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, - curl_socket_t s, - int ev_bitmask, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, - int *running_handles); - -#ifndef CURL_ALLOW_OLD_MULTI_SOCKET -/* This macro below was added in 7.16.3 to push users who recompile to use - the new curl_multi_socket_action() instead of the old curl_multi_socket() -*/ -#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) -#endif - -/* - * Name: curl_multi_timeout() - * - * Desc: Returns the maximum number of milliseconds the app is allowed to - * wait before curl_multi_socket() or curl_multi_perform() must be - * called (to allow libcurl's timed events to take place). - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, - long *milliseconds); - -#undef CINIT /* re-using the same name as in curl.h */ - -#ifdef CURL_ISOCPP -#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLMOPT_/**/name = type + number -#endif - -typedef enum { - /* This is the socket callback function pointer */ - CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), - - /* This is the argument passed to the socket callback */ - CINIT(SOCKETDATA, OBJECTPOINT, 2), - - /* set to 1 to enable pipelining for this multi handle */ - CINIT(PIPELINING, LONG, 3), - - /* This is the timer callback function pointer */ - CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), - - /* This is the argument passed to the timer callback */ - CINIT(TIMERDATA, OBJECTPOINT, 5), - - /* maximum number of entries in the connection cache */ - CINIT(MAXCONNECTS, LONG, 6), - - /* maximum number of (pipelining) connections to one host */ - CINIT(MAX_HOST_CONNECTIONS, LONG, 7), - - /* maximum number of requests in a pipeline */ - CINIT(MAX_PIPELINE_LENGTH, LONG, 8), - - /* a connection with a content-length longer than this - will not be considered for pipelining */ - CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), - - /* a connection with a chunk length longer than this - will not be considered for pipelining */ - CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), - - /* a list of site names(+port) that are blacklisted from - pipelining */ - CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), - - /* a list of server types that are blacklisted from - pipelining */ - CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), - - /* maximum number of open connections in total */ - CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), - - /* This is the server push callback function pointer */ - CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), - - /* This is the argument passed to the server push callback */ - CINIT(PUSHDATA, OBJECTPOINT, 15), - - CURLMOPT_LASTENTRY /* the last unused */ -} CURLMoption; - - -/* - * Name: curl_multi_setopt() - * - * Desc: Sets options for the multi handle. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, - CURLMoption option, ...); - - -/* - * Name: curl_multi_assign() - * - * Desc: This function sets an association in the multi handle between the - * given socket and a private pointer of the application. This is - * (only) useful for curl_multi_socket uses. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, - curl_socket_t sockfd, void *sockp); - - -/* - * Name: curl_push_callback - * - * Desc: This callback gets called when a new stream is being pushed by the - * server. It approves or denies the new stream. - * - * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. - */ -#define CURL_PUSH_OK 0 -#define CURL_PUSH_DENY 1 - -struct curl_pushheaders; /* forward declaration only */ - -CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, - size_t num); -CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, - const char *name); - -typedef int (*curl_push_callback)(CURL *parent, - CURL *easy, - size_t num_headers, - struct curl_pushheaders *headers, - void *userp); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/ext/curl-7.58.0/Win32/include/curl/stdcheaders.h b/ext/curl-7.58.0/Win32/include/curl/stdcheaders.h deleted file mode 100644 index 027b6f42..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/stdcheaders.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __STDC_HEADERS_H -#define __STDC_HEADERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -size_t fread(void *, size_t, size_t, FILE *); -size_t fwrite(const void *, size_t, size_t, FILE *); - -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); - -#endif /* __STDC_HEADERS_H */ diff --git a/ext/curl-7.58.0/Win32/include/curl/system.h b/ext/curl-7.58.0/Win32/include/curl/system.h deleted file mode 100644 index 07bbd9ca..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/system.h +++ /dev/null @@ -1,473 +0,0 @@ -#ifndef __CURL_SYSTEM_H -#define __CURL_SYSTEM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Try to keep one section per platform, compiler and architecture, otherwise, - * if an existing section is reused for a different one and later on the - * original is adjusted, probably the piggybacking one can be adversely - * changed. - * - * In order to differentiate between platforms/compilers/architectures use - * only compiler built in predefined preprocessor symbols. - * - * curl_off_t - * ---------- - * - * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit - * wide signed integral data type. The width of this data type must remain - * constant and independent of any possible large file support settings. - * - * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit - * wide signed integral data type if there is no 64-bit type. - * - * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall - * only be violated if off_t is the only 64-bit data type available and the - * size of off_t is independent of large file support settings. Keep your - * build on the safe side avoiding an off_t gating. If you have a 64-bit - * off_t then take for sure that another 64-bit data type exists, dig deeper - * and you will find it. - * - */ - -#if defined(__DJGPP__) || defined(__GO32__) -# if defined(__DJGPP__) && (__DJGPP__ > 1) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__SALFORDC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__BORLANDC__) -# if (__BORLANDC__ < 0x520) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__TURBOC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__WATCOMC__) -# if defined(__386__) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__POCC__) -# if (__POCC__ < 280) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# elif defined(_MSC_VER) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__LCC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__SYMBIAN32__) -# if defined(__EABI__) /* Treat all ARM compilers equally */ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__CW32__) -# pragma longlong on -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__VC32__) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__MWERKS__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(_WIN32_WCE) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__MINGW32__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_WS2TCPIP_H 1 - -#elif defined(__VMS) -# if defined(__VAX) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__OS400__) -# if defined(__ILEC400__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(__MVS__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_ILP32) -# elif defined(_LP64) -# endif -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(__370__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_ILP32) -# elif defined(_LP64) -# endif -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(TPF) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__TINYC__) /* also known as tcc */ - -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__SUNPRO_C) /* Oracle Solaris Studio */ -# if !defined(__LP64) && (defined(__ILP32) || \ - defined(__i386) || defined(__sparcv8)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64) || \ - defined(__amd64) || defined(__sparcv9) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -/* ===================================== */ -/* KEEP MSVC THE PENULTIMATE ENTRY */ -/* ===================================== */ - -#elif defined(_MSC_VER) -# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -/* ===================================== */ -/* KEEP GENERIC GCC THE LAST ENTRY */ -/* ===================================== */ - -#elif defined(__GNUC__) -# if !defined(__LP64__) && \ - (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \ - defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ - defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ - defined(__XTENSA__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64__) || \ - defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#else -/* generic "safe guess" on old 32 bit style */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -#endif - -#ifdef _AIX -/* AIX needs */ -#define CURL_PULL_SYS_POLL_H -#endif - - -/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */ -/* ws2tcpip.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_WS2TCPIP_H -# include -# include -# include -#endif - -/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ -/* sys/types.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ -/* sys/socket.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */ -/* sys/poll.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_POLL_H -# include -#endif - -/* Data type definition of curl_socklen_t. */ -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T - typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; -#endif - -/* Data type definition of curl_off_t. */ - -#ifdef CURL_TYPEOF_CURL_OFF_T - typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; -#endif - -/* - * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow - * these to be visible and exported by the external libcurl interface API, - * while also making them visible to the library internals, simply including - * curl_setup.h, without actually needing to include curl.h internally. - * If some day this section would grow big enough, all this should be moved - * to its own header file. - */ - -/* - * Figure out if we can use the ## preprocessor operator, which is supported - * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ - * or __cplusplus so we need to carefully check for them too. - */ - -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ - defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ - defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ - defined(__ILEC400__) - /* This compiler is believed to have an ISO compatible preprocessor */ -#define CURL_ISOCPP -#else - /* This compiler is believed NOT to have an ISO compatible preprocessor */ -#undef CURL_ISOCPP -#endif - -/* - * Macros for minimum-width signed and unsigned curl_off_t integer constants. - */ - -#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) -# define __CURL_OFF_T_C_HLPR2(x) x -# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) -#else -# ifdef CURL_ISOCPP -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix -# else -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix -# endif -# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) -#endif - -#endif /* __CURL_SYSTEM_H */ diff --git a/ext/curl-7.58.0/Win32/include/curl/typecheck-gcc.h b/ext/curl-7.58.0/Win32/include/curl/typecheck-gcc.h deleted file mode 100644 index 10c74c76..00000000 --- a/ext/curl-7.58.0/Win32/include/curl/typecheck-gcc.h +++ /dev/null @@ -1,683 +0,0 @@ -#ifndef __CURL_TYPECHECK_GCC_H -#define __CURL_TYPECHECK_GCC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* wraps curl_easy_setopt() with typechecking */ - -/* To add a new kind of warning, add an - * if(_curl_is_sometype_option(_curl_opt)) - * if(!_curl_is_sometype(value)) - * _curl_easy_setopt_err_sometype(); - * block and define _curl_is_sometype_option, _curl_is_sometype and - * _curl_easy_setopt_err_sometype below - * - * NOTE: We use two nested 'if' statements here instead of the && operator, in - * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x - * when compiling with -Wlogical-op. - * - * To add an option that uses the same type as an existing option, you'll just - * need to extend the appropriate _curl_*_option macro - */ -#define curl_easy_setopt(handle, option, value) \ -__extension__ ({ \ - __typeof__(option) _curl_opt = option; \ - if(__builtin_constant_p(_curl_opt)) { \ - if(_curl_is_long_option(_curl_opt)) \ - if(!_curl_is_long(value)) \ - _curl_easy_setopt_err_long(); \ - if(_curl_is_off_t_option(_curl_opt)) \ - if(!_curl_is_off_t(value)) \ - _curl_easy_setopt_err_curl_off_t(); \ - if(_curl_is_string_option(_curl_opt)) \ - if(!_curl_is_string(value)) \ - _curl_easy_setopt_err_string(); \ - if(_curl_is_write_cb_option(_curl_opt)) \ - if(!_curl_is_write_cb(value)) \ - _curl_easy_setopt_err_write_callback(); \ - if((_curl_opt) == CURLOPT_READFUNCTION) \ - if(!_curl_is_read_cb(value)) \ - _curl_easy_setopt_err_read_cb(); \ - if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ - if(!_curl_is_ioctl_cb(value)) \ - _curl_easy_setopt_err_ioctl_cb(); \ - if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ - if(!_curl_is_sockopt_cb(value)) \ - _curl_easy_setopt_err_sockopt_cb(); \ - if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ - if(!_curl_is_opensocket_cb(value)) \ - _curl_easy_setopt_err_opensocket_cb(); \ - if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ - if(!_curl_is_progress_cb(value)) \ - _curl_easy_setopt_err_progress_cb(); \ - if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ - if(!_curl_is_debug_cb(value)) \ - _curl_easy_setopt_err_debug_cb(); \ - if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ - if(!_curl_is_ssl_ctx_cb(value)) \ - _curl_easy_setopt_err_ssl_ctx_cb(); \ - if(_curl_is_conv_cb_option(_curl_opt)) \ - if(!_curl_is_conv_cb(value)) \ - _curl_easy_setopt_err_conv_cb(); \ - if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ - if(!_curl_is_seek_cb(value)) \ - _curl_easy_setopt_err_seek_cb(); \ - if(_curl_is_cb_data_option(_curl_opt)) \ - if(!_curl_is_cb_data(value)) \ - _curl_easy_setopt_err_cb_data(); \ - if((_curl_opt) == CURLOPT_ERRORBUFFER) \ - if(!_curl_is_error_buffer(value)) \ - _curl_easy_setopt_err_error_buffer(); \ - if((_curl_opt) == CURLOPT_STDERR) \ - if(!_curl_is_FILE(value)) \ - _curl_easy_setopt_err_FILE(); \ - if(_curl_is_postfields_option(_curl_opt)) \ - if(!_curl_is_postfields(value)) \ - _curl_easy_setopt_err_postfields(); \ - if((_curl_opt) == CURLOPT_HTTPPOST) \ - if(!_curl_is_arr((value), struct curl_httppost)) \ - _curl_easy_setopt_err_curl_httpost(); \ - if((_curl_opt) == CURLOPT_MIMEPOST) \ - if(!_curl_is_ptr((value), curl_mime)) \ - _curl_easy_setopt_err_curl_mimepost(); \ - if(_curl_is_slist_option(_curl_opt)) \ - if(!_curl_is_arr((value), struct curl_slist)) \ - _curl_easy_setopt_err_curl_slist(); \ - if((_curl_opt) == CURLOPT_SHARE) \ - if(!_curl_is_ptr((value), CURLSH)) \ - _curl_easy_setopt_err_CURLSH(); \ - } \ - curl_easy_setopt(handle, _curl_opt, value); \ -}) - -/* wraps curl_easy_getinfo() with typechecking */ -/* FIXME: don't allow const pointers */ -#define curl_easy_getinfo(handle, info, arg) \ -__extension__ ({ \ - __typeof__(info) _curl_info = info; \ - if(__builtin_constant_p(_curl_info)) { \ - if(_curl_is_string_info(_curl_info)) \ - if(!_curl_is_arr((arg), char *)) \ - _curl_easy_getinfo_err_string(); \ - if(_curl_is_long_info(_curl_info)) \ - if(!_curl_is_arr((arg), long)) \ - _curl_easy_getinfo_err_long(); \ - if(_curl_is_double_info(_curl_info)) \ - if(!_curl_is_arr((arg), double)) \ - _curl_easy_getinfo_err_double(); \ - if(_curl_is_slist_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_slist *)) \ - _curl_easy_getinfo_err_curl_slist(); \ - if(_curl_is_tlssessioninfo_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_tlssessioninfo *)) \ - _curl_easy_getinfo_err_curl_tlssesssioninfo(); \ - if(_curl_is_certinfo_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_certinfo *)) \ - _curl_easy_getinfo_err_curl_certinfo(); \ - if(_curl_is_socket_info(_curl_info)) \ - if(!_curl_is_arr((arg), curl_socket_t)) \ - _curl_easy_getinfo_err_curl_socket(); \ - if(_curl_is_off_t_info(_curl_info)) \ - if(!_curl_is_arr((arg), curl_off_t)) \ - _curl_easy_getinfo_err_curl_off_t(); \ - } \ - curl_easy_getinfo(handle, _curl_info, arg); \ -}) - -/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), - * for now just make sure that the functions are called with three - * arguments - */ -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) - - -/* the actual warnings, triggered by calling the _curl_easy_setopt_err* - * functions */ - -/* To define a new warning, use _CURL_WARNING(identifier, "message") */ -#define _CURL_WARNING(id, message) \ - static void __attribute__((__warning__(message))) \ - __attribute__((__unused__)) __attribute__((__noinline__)) \ - id(void) { __asm__(""); } - -_CURL_WARNING(_curl_easy_setopt_err_long, - "curl_easy_setopt expects a long argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, - "curl_easy_setopt expects a curl_off_t argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_string, - "curl_easy_setopt expects a " - "string ('char *' or char[]) argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_write_callback, - "curl_easy_setopt expects a curl_write_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_read_cb, - "curl_easy_setopt expects a curl_read_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, - "curl_easy_setopt expects a curl_ioctl_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, - "curl_easy_setopt expects a curl_sockopt_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, - "curl_easy_setopt expects a " - "curl_opensocket_callback argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_progress_cb, - "curl_easy_setopt expects a curl_progress_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_debug_cb, - "curl_easy_setopt expects a curl_debug_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, - "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_conv_cb, - "curl_easy_setopt expects a curl_conv_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_seek_cb, - "curl_easy_setopt expects a curl_seek_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_cb_data, - "curl_easy_setopt expects a " - "private data pointer as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_error_buffer, - "curl_easy_setopt expects a " - "char buffer of CURL_ERROR_SIZE as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_FILE, - "curl_easy_setopt expects a 'FILE *' argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_postfields, - "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, - "curl_easy_setopt expects a 'struct curl_httppost *' " - "argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost, - "curl_easy_setopt expects a 'curl_mime *' " - "argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_slist, - "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_CURLSH, - "curl_easy_setopt expects a CURLSH* argument for this option") - -_CURL_WARNING(_curl_easy_getinfo_err_string, - "curl_easy_getinfo expects a pointer to 'char *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_long, - "curl_easy_getinfo expects a pointer to long for this info") -_CURL_WARNING(_curl_easy_getinfo_err_double, - "curl_easy_getinfo expects a pointer to double for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, - "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo, - "curl_easy_getinfo expects a pointer to " - "'struct curl_tlssessioninfo *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo, - "curl_easy_getinfo expects a pointer to " - "'struct curl_certinfo *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_socket, - "curl_easy_getinfo expects a pointer to curl_socket_t for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, - "curl_easy_getinfo expects a pointer to curl_off_t for this info") - -/* groups of curl_easy_setops options that take the same type of argument */ - -/* To add a new option to one of the groups, just add - * (option) == CURLOPT_SOMETHING - * to the or-expression. If the option takes a long or curl_off_t, you don't - * have to do anything - */ - -/* evaluates to true if option takes a long argument */ -#define _curl_is_long_option(option) \ - (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) - -#define _curl_is_off_t_option(option) \ - ((option) > CURLOPTTYPE_OFF_T) - -/* evaluates to true if option takes a char* argument */ -#define _curl_is_string_option(option) \ - ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ - (option) == CURLOPT_ACCEPT_ENCODING || \ - (option) == CURLOPT_CAINFO || \ - (option) == CURLOPT_CAPATH || \ - (option) == CURLOPT_COOKIE || \ - (option) == CURLOPT_COOKIEFILE || \ - (option) == CURLOPT_COOKIEJAR || \ - (option) == CURLOPT_COOKIELIST || \ - (option) == CURLOPT_CRLFILE || \ - (option) == CURLOPT_CUSTOMREQUEST || \ - (option) == CURLOPT_DEFAULT_PROTOCOL || \ - (option) == CURLOPT_DNS_INTERFACE || \ - (option) == CURLOPT_DNS_LOCAL_IP4 || \ - (option) == CURLOPT_DNS_LOCAL_IP6 || \ - (option) == CURLOPT_DNS_SERVERS || \ - (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_FTPPORT || \ - (option) == CURLOPT_FTP_ACCOUNT || \ - (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ - (option) == CURLOPT_INTERFACE || \ - (option) == CURLOPT_ISSUERCERT || \ - (option) == CURLOPT_KEYPASSWD || \ - (option) == CURLOPT_KRBLEVEL || \ - (option) == CURLOPT_LOGIN_OPTIONS || \ - (option) == CURLOPT_MAIL_AUTH || \ - (option) == CURLOPT_MAIL_FROM || \ - (option) == CURLOPT_NETRC_FILE || \ - (option) == CURLOPT_NOPROXY || \ - (option) == CURLOPT_PASSWORD || \ - (option) == CURLOPT_PINNEDPUBLICKEY || \ - (option) == CURLOPT_PRE_PROXY || \ - (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYUSERPWD || \ - (option) == CURLOPT_PROXY_CAINFO || \ - (option) == CURLOPT_PROXY_CAPATH || \ - (option) == CURLOPT_PROXY_CRLFILE || \ - (option) == CURLOPT_PROXY_KEYPASSWD || \ - (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \ - (option) == CURLOPT_PROXY_SERVICE_NAME || \ - (option) == CURLOPT_PROXY_SSLCERT || \ - (option) == CURLOPT_PROXY_SSLCERTTYPE || \ - (option) == CURLOPT_PROXY_SSLKEY || \ - (option) == CURLOPT_PROXY_SSLKEYTYPE || \ - (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ - (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \ - (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \ - (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \ - (option) == CURLOPT_RANDOM_FILE || \ - (option) == CURLOPT_RANGE || \ - (option) == CURLOPT_REFERER || \ - (option) == CURLOPT_RTSP_SESSION_ID || \ - (option) == CURLOPT_RTSP_STREAM_URI || \ - (option) == CURLOPT_RTSP_TRANSPORT || \ - (option) == CURLOPT_SERVICE_NAME || \ - (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ - (option) == CURLOPT_SSH_KNOWNHOSTS || \ - (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ - (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ - (option) == CURLOPT_SSLCERT || \ - (option) == CURLOPT_SSLCERTTYPE || \ - (option) == CURLOPT_SSLENGINE || \ - (option) == CURLOPT_SSLKEY || \ - (option) == CURLOPT_SSLKEYTYPE || \ - (option) == CURLOPT_SSL_CIPHER_LIST || \ - (option) == CURLOPT_TLSAUTH_PASSWORD || \ - (option) == CURLOPT_TLSAUTH_TYPE || \ - (option) == CURLOPT_TLSAUTH_USERNAME || \ - (option) == CURLOPT_UNIX_SOCKET_PATH || \ - (option) == CURLOPT_URL || \ - (option) == CURLOPT_USERAGENT || \ - (option) == CURLOPT_USERNAME || \ - (option) == CURLOPT_USERPWD || \ - (option) == CURLOPT_XOAUTH2_BEARER || \ - 0) - -/* evaluates to true if option takes a curl_write_callback argument */ -#define _curl_is_write_cb_option(option) \ - ((option) == CURLOPT_HEADERFUNCTION || \ - (option) == CURLOPT_WRITEFUNCTION) - -/* evaluates to true if option takes a curl_conv_callback argument */ -#define _curl_is_conv_cb_option(option) \ - ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) - -/* evaluates to true if option takes a data argument to pass to a callback */ -#define _curl_is_cb_data_option(option) \ - ((option) == CURLOPT_CHUNK_DATA || \ - (option) == CURLOPT_CLOSESOCKETDATA || \ - (option) == CURLOPT_DEBUGDATA || \ - (option) == CURLOPT_FNMATCH_DATA || \ - (option) == CURLOPT_HEADERDATA || \ - (option) == CURLOPT_INTERLEAVEDATA || \ - (option) == CURLOPT_IOCTLDATA || \ - (option) == CURLOPT_OPENSOCKETDATA || \ - (option) == CURLOPT_PRIVATE || \ - (option) == CURLOPT_PROGRESSDATA || \ - (option) == CURLOPT_READDATA || \ - (option) == CURLOPT_SEEKDATA || \ - (option) == CURLOPT_SOCKOPTDATA || \ - (option) == CURLOPT_SSH_KEYDATA || \ - (option) == CURLOPT_SSL_CTX_DATA || \ - (option) == CURLOPT_WRITEDATA || \ - 0) - -/* evaluates to true if option takes a POST data argument (void* or char*) */ -#define _curl_is_postfields_option(option) \ - ((option) == CURLOPT_POSTFIELDS || \ - (option) == CURLOPT_COPYPOSTFIELDS || \ - 0) - -/* evaluates to true if option takes a struct curl_slist * argument */ -#define _curl_is_slist_option(option) \ - ((option) == CURLOPT_HTTP200ALIASES || \ - (option) == CURLOPT_HTTPHEADER || \ - (option) == CURLOPT_MAIL_RCPT || \ - (option) == CURLOPT_POSTQUOTE || \ - (option) == CURLOPT_PREQUOTE || \ - (option) == CURLOPT_PROXYHEADER || \ - (option) == CURLOPT_QUOTE || \ - (option) == CURLOPT_RESOLVE || \ - (option) == CURLOPT_TELNETOPTIONS || \ - 0) - -/* groups of curl_easy_getinfo infos that take the same type of argument */ - -/* evaluates to true if info expects a pointer to char * argument */ -#define _curl_is_string_info(info) \ - (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) - -/* evaluates to true if info expects a pointer to long argument */ -#define _curl_is_long_info(info) \ - (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) - -/* evaluates to true if info expects a pointer to double argument */ -#define _curl_is_double_info(info) \ - (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) - -/* true if info expects a pointer to struct curl_slist * argument */ -#define _curl_is_slist_info(info) \ - (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST)) - -/* true if info expects a pointer to struct curl_tlssessioninfo * argument */ -#define _curl_is_tlssessioninfo_info(info) \ - (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION)) - -/* true if info expects a pointer to struct curl_certinfo * argument */ -#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO) - -/* true if info expects a pointer to struct curl_socket_t argument */ -#define _curl_is_socket_info(info) \ - (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T) - -/* true if info expects a pointer to curl_off_t argument */ -#define _curl_is_off_t_info(info) \ - (CURLINFO_OFF_T < (info)) - - -/* typecheck helpers -- check whether given expression has requested type*/ - -/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, - * otherwise define a new macro. Search for __builtin_types_compatible_p - * in the GCC manual. - * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is - * the actual expression passed to the curl_easy_setopt macro. This - * means that you can only apply the sizeof and __typeof__ operators, no - * == or whatsoever. - */ - -/* XXX: should evaluate to true iff expr is a pointer */ -#define _curl_is_any_ptr(expr) \ - (sizeof(expr) == sizeof(void *)) - -/* evaluates to true if expr is NULL */ -/* XXX: must not evaluate expr, so this check is not accurate */ -#define _curl_is_NULL(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) - -/* evaluates to true if expr is type*, const type* or NULL */ -#define _curl_is_ptr(expr, type) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type *) || \ - __builtin_types_compatible_p(__typeof__(expr), const type *)) - -/* evaluates to true if expr is one of type[], type*, NULL or const type* */ -#define _curl_is_arr(expr, type) \ - (_curl_is_ptr((expr), type) || \ - __builtin_types_compatible_p(__typeof__(expr), type [])) - -/* evaluates to true if expr is a string */ -#define _curl_is_string(expr) \ - (_curl_is_arr((expr), char) || \ - _curl_is_arr((expr), signed char) || \ - _curl_is_arr((expr), unsigned char)) - -/* evaluates to true if expr is a long (no matter the signedness) - * XXX: for now, int is also accepted (and therefore short and char, which - * are promoted to int when passed to a variadic function) */ -#define _curl_is_long(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), long) || \ - __builtin_types_compatible_p(__typeof__(expr), signed long) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ - __builtin_types_compatible_p(__typeof__(expr), int) || \ - __builtin_types_compatible_p(__typeof__(expr), signed int) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ - __builtin_types_compatible_p(__typeof__(expr), short) || \ - __builtin_types_compatible_p(__typeof__(expr), signed short) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ - __builtin_types_compatible_p(__typeof__(expr), char) || \ - __builtin_types_compatible_p(__typeof__(expr), signed char) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned char)) - -/* evaluates to true if expr is of type curl_off_t */ -#define _curl_is_off_t(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) - -/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ -/* XXX: also check size of an char[] array? */ -#define _curl_is_error_buffer(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), char *) || \ - __builtin_types_compatible_p(__typeof__(expr), char[])) - -/* evaluates to true if expr is of type (const) void* or (const) FILE* */ -#if 0 -#define _curl_is_cb_data(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_ptr((expr), FILE)) -#else /* be less strict */ -#define _curl_is_cb_data(expr) \ - _curl_is_any_ptr(expr) -#endif - -/* evaluates to true if expr is of type FILE* */ -#define _curl_is_FILE(expr) \ - (_curl_is_NULL(expr) || \ - (__builtin_types_compatible_p(__typeof__(expr), FILE *))) - -/* evaluates to true if expr can be passed as POST data (void* or char*) */ -#define _curl_is_postfields(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_arr((expr), char)) - -/* FIXME: the whole callback checking is messy... - * The idea is to tolerate char vs. void and const vs. not const - * pointers in arguments at least - */ -/* helper: __builtin_types_compatible_p distinguishes between functions and - * function pointers, hide it */ -#define _curl_callback_compatible(func, type) \ - (__builtin_types_compatible_p(__typeof__(func), type) || \ - __builtin_types_compatible_p(__typeof__(func) *, type)) - -/* evaluates to true if expr is of type curl_read_callback or "similar" */ -#define _curl_is_read_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), __typeof__(fread) *) || \ - _curl_callback_compatible((expr), curl_read_callback) || \ - _curl_callback_compatible((expr), _curl_read_callback1) || \ - _curl_callback_compatible((expr), _curl_read_callback2) || \ - _curl_callback_compatible((expr), _curl_read_callback3) || \ - _curl_callback_compatible((expr), _curl_read_callback4) || \ - _curl_callback_compatible((expr), _curl_read_callback5) || \ - _curl_callback_compatible((expr), _curl_read_callback6)) -typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *); -typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *); -typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *); -typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *); -typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *); -typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_write_callback or "similar" */ -#define _curl_is_write_cb(expr) \ - (_curl_is_read_cb(expr) || \ - _curl_callback_compatible((expr), __typeof__(fwrite) *) || \ - _curl_callback_compatible((expr), curl_write_callback) || \ - _curl_callback_compatible((expr), _curl_write_callback1) || \ - _curl_callback_compatible((expr), _curl_write_callback2) || \ - _curl_callback_compatible((expr), _curl_write_callback3) || \ - _curl_callback_compatible((expr), _curl_write_callback4) || \ - _curl_callback_compatible((expr), _curl_write_callback5) || \ - _curl_callback_compatible((expr), _curl_write_callback6)) -typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *); -typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t, - const void *); -typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *); -typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *); -typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t, - const void *); -typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ -#define _curl_is_ioctl_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_ioctl_callback) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback4)) -typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *); -typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *); -typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *); -typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *); - -/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ -#define _curl_is_sockopt_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_sockopt_callback) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback2)) -typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); -typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t, - curlsocktype); - -/* evaluates to true if expr is of type curl_opensocket_callback or - "similar" */ -#define _curl_is_opensocket_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_opensocket_callback) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback4)) -typedef curl_socket_t (*_curl_opensocket_callback1) - (void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (*_curl_opensocket_callback2) - (void *, curlsocktype, const struct curl_sockaddr *); -typedef curl_socket_t (*_curl_opensocket_callback3) - (const void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (*_curl_opensocket_callback4) - (const void *, curlsocktype, const struct curl_sockaddr *); - -/* evaluates to true if expr is of type curl_progress_callback or "similar" */ -#define _curl_is_progress_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_progress_callback) || \ - _curl_callback_compatible((expr), _curl_progress_callback1) || \ - _curl_callback_compatible((expr), _curl_progress_callback2)) -typedef int (*_curl_progress_callback1)(void *, - double, double, double, double); -typedef int (*_curl_progress_callback2)(const void *, - double, double, double, double); - -/* evaluates to true if expr is of type curl_debug_callback or "similar" */ -#define _curl_is_debug_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_debug_callback) || \ - _curl_callback_compatible((expr), _curl_debug_callback1) || \ - _curl_callback_compatible((expr), _curl_debug_callback2) || \ - _curl_callback_compatible((expr), _curl_debug_callback3) || \ - _curl_callback_compatible((expr), _curl_debug_callback4) || \ - _curl_callback_compatible((expr), _curl_debug_callback5) || \ - _curl_callback_compatible((expr), _curl_debug_callback6) || \ - _curl_callback_compatible((expr), _curl_debug_callback7) || \ - _curl_callback_compatible((expr), _curl_debug_callback8)) -typedef int (*_curl_debug_callback1) (CURL *, - curl_infotype, char *, size_t, void *); -typedef int (*_curl_debug_callback2) (CURL *, - curl_infotype, char *, size_t, const void *); -typedef int (*_curl_debug_callback3) (CURL *, - curl_infotype, const char *, size_t, void *); -typedef int (*_curl_debug_callback4) (CURL *, - curl_infotype, const char *, size_t, const void *); -typedef int (*_curl_debug_callback5) (CURL *, - curl_infotype, unsigned char *, size_t, void *); -typedef int (*_curl_debug_callback6) (CURL *, - curl_infotype, unsigned char *, size_t, const void *); -typedef int (*_curl_debug_callback7) (CURL *, - curl_infotype, const unsigned char *, size_t, void *); -typedef int (*_curl_debug_callback8) (CURL *, - curl_infotype, const unsigned char *, size_t, const void *); - -/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ -/* this is getting even messier... */ -#define _curl_is_ssl_ctx_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_ssl_ctx_callback) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) -typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *); -typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *); -typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *); -typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *, - const void *); -#ifdef HEADER_SSL_H -/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX - * this will of course break if we're included before OpenSSL headers... - */ -typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); -typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); -typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); -typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, - const void *); -#else -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; -#endif - -/* evaluates to true if expr is of type curl_conv_callback or "similar" */ -#define _curl_is_conv_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_conv_callback) || \ - _curl_callback_compatible((expr), _curl_conv_callback1) || \ - _curl_callback_compatible((expr), _curl_conv_callback2) || \ - _curl_callback_compatible((expr), _curl_conv_callback3) || \ - _curl_callback_compatible((expr), _curl_conv_callback4)) -typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); -typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); -typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); -typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); - -/* evaluates to true if expr is of type curl_seek_callback or "similar" */ -#define _curl_is_seek_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_seek_callback) || \ - _curl_callback_compatible((expr), _curl_seek_callback1) || \ - _curl_callback_compatible((expr), _curl_seek_callback2)) -typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); -typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); - - -#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/ext/curl-7.58.0/Win32/lib/libcurl_a.lib b/ext/curl-7.58.0/Win32/lib/libcurl_a.lib deleted file mode 100644 index 241a0e8c..00000000 Binary files a/ext/curl-7.58.0/Win32/lib/libcurl_a.lib and /dev/null differ diff --git a/ext/curl-7.58.0/Win32/lib/libcurl_a_debug.lib b/ext/curl-7.58.0/Win32/lib/libcurl_a_debug.lib deleted file mode 100644 index ee9efe50..00000000 Binary files a/ext/curl-7.58.0/Win32/lib/libcurl_a_debug.lib and /dev/null differ diff --git a/ext/curl-7.58.0/x64/include/curl/curl.h b/ext/curl-7.58.0/x64/include/curl/curl.h deleted file mode 100644 index 7680acd1..00000000 --- a/ext/curl-7.58.0/x64/include/curl/curl.h +++ /dev/null @@ -1,2751 +0,0 @@ -#ifndef __CURL_CURL_H -#define __CURL_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * If you have libcurl problems, all docs and details are found here: - * https://curl.haxx.se/libcurl/ - * - * curl-library mailing list subscription and unsubscription web interface: - * https://cool.haxx.se/mailman/listinfo/curl-library/ - */ - -#ifdef CURL_NO_OLDIES -#define CURL_STRICTER -#endif - -#include "curlver.h" /* libcurl version defines */ -#include "system.h" /* determine things run-time */ - -/* - * Define WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__)) && \ - !defined(WIN32) && !defined(__SYMBIAN32__) -#define WIN32 -#endif - -#include -#include - -#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) -/* Needed for __FreeBSD_version symbol definition */ -#include -#endif - -/* The include stuff here below is mainly for time_t! */ -#include -#include - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ - defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) -/* The check above prevents the winsock2 inclusion if winsock.h already was - included, since they can't co-exist without problems */ -#include -#include -#endif -#endif - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on systems that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ - defined(__CYGWIN__) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) -#include -#endif - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#include -#endif - -#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) -#include -#endif - -#ifdef __BEOS__ -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) -typedef struct Curl_easy CURL; -typedef struct Curl_share CURLSH; -#else -typedef void CURL; -typedef void CURLSH; -#endif - -/* - * libcurl external API function linkage decorations. - */ - -#ifdef CURL_STATICLIB -# define CURL_EXTERN -#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) -# if defined(BUILDING_LIBCURL) -# define CURL_EXTERN __declspec(dllexport) -# else -# define CURL_EXTERN __declspec(dllimport) -# endif -#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) -# define CURL_EXTERN CURL_EXTERN_SYMBOL -#else -# define CURL_EXTERN -#endif - -#ifndef curl_socket_typedef -/* socket typedef */ -#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD -1 -#endif -#define curl_socket_typedef -#endif /* curl_socket_typedef */ - -/* enum for the different supported SSL backends */ -typedef enum { - CURLSSLBACKEND_NONE = 0, - CURLSSLBACKEND_OPENSSL = 1, - CURLSSLBACKEND_GNUTLS = 2, - CURLSSLBACKEND_NSS = 3, - CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ - CURLSSLBACKEND_GSKIT = 5, - CURLSSLBACKEND_POLARSSL = 6, - CURLSSLBACKEND_WOLFSSL = 7, - CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_DARWINSSL = 9, - CURLSSLBACKEND_AXTLS = 10, - CURLSSLBACKEND_MBEDTLS = 11 -} curl_sslbackend; - -/* aliases for library clones and renames */ -#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL -#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL - -struct curl_httppost { - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field, see also - CURL_HTTPPOST_LARGE */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist *contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ - -/* specified content is a file name */ -#define CURL_HTTPPOST_FILENAME (1<<0) -/* specified content is a file name */ -#define CURL_HTTPPOST_READFILE (1<<1) -/* name is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRNAME (1<<2) -/* contents is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRCONTENTS (1<<3) -/* upload file from buffer */ -#define CURL_HTTPPOST_BUFFER (1<<4) -/* upload file from pointer contents */ -#define CURL_HTTPPOST_PTRBUFFER (1<<5) -/* upload file contents by using the regular read callback to get the data and - pass the given pointer as custom pointer */ -#define CURL_HTTPPOST_CALLBACK (1<<6) -/* use size in 'contentlen', added in 7.46.0 */ -#define CURL_HTTPPOST_LARGE (1<<7) - - char *showfilename; /* The file name to show. If not set, the - actual file name will be used (if this - is a file part) */ - void *userp; /* custom pointer used for - HTTPPOST_CALLBACK posts */ - curl_off_t contentlen; /* alternative length of contents - field. Used if CURL_HTTPPOST_LARGE is - set. Added in 7.46.0 */ -}; - -/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered - deprecated but was the only choice up until 7.31.0 */ -typedef int (*curl_progress_callback)(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - -/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in - 7.32.0, it avoids floating point and provides more detailed information. */ -typedef int (*curl_xferinfo_callback)(void *clientp, - curl_off_t dltotal, - curl_off_t dlnow, - curl_off_t ultotal, - curl_off_t ulnow); - -#ifndef CURL_MAX_READ_SIZE - /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ -#define CURL_MAX_READ_SIZE 524288 -#endif - -#ifndef CURL_MAX_WRITE_SIZE - /* Tests have proven that 20K is a very bad buffer size for uploads on - Windows, while 16K for some odd reason performed a lot better. - We do the ifndef check to allow this value to easier be changed at build - time for those who feel adventurous. The practical minimum is about - 400 bytes since libcurl uses a buffer of this size as a scratch area - (unrelated to network send operations). */ -#define CURL_MAX_WRITE_SIZE 16384 -#endif - -#ifndef CURL_MAX_HTTP_HEADER -/* The only reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause reallocs - infinitely */ -#define CURL_MAX_HTTP_HEADER (100*1024) -#endif - -/* This is a magic return code for the write callback that, when returned, - will signal libcurl to pause receiving on the current transfer. */ -#define CURL_WRITEFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - - - -/* enumeration of file types */ -typedef enum { - CURLFILETYPE_FILE = 0, - CURLFILETYPE_DIRECTORY, - CURLFILETYPE_SYMLINK, - CURLFILETYPE_DEVICE_BLOCK, - CURLFILETYPE_DEVICE_CHAR, - CURLFILETYPE_NAMEDPIPE, - CURLFILETYPE_SOCKET, - CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ - - CURLFILETYPE_UNKNOWN /* should never occur */ -} curlfiletype; - -#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) -#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) -#define CURLFINFOFLAG_KNOWN_TIME (1<<2) -#define CURLFINFOFLAG_KNOWN_PERM (1<<3) -#define CURLFINFOFLAG_KNOWN_UID (1<<4) -#define CURLFINFOFLAG_KNOWN_GID (1<<5) -#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) -#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) - -/* Content of this structure depends on information which is known and is - achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man - page for callbacks returning this structure -- some fields are mandatory, - some others are optional. The FLAG field has special meaning. */ -struct curl_fileinfo { - char *filename; - curlfiletype filetype; - time_t time; - unsigned int perm; - int uid; - int gid; - curl_off_t size; - long int hardlinks; - - struct { - /* If some of these fields is not NULL, it is a pointer to b_data. */ - char *time; - char *perm; - char *user; - char *group; - char *target; /* pointer to the target filename of a symlink */ - } strings; - - unsigned int flags; - - /* used internally */ - char *b_data; - size_t b_size; - size_t b_used; -}; - -/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ -#define CURL_CHUNK_BGN_FUNC_OK 0 -#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ -#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ - -/* if splitting of data transfer is enabled, this callback is called before - download of an individual chunk started. Note that parameter "remains" works - only for FTP wildcard downloading (for now), otherwise is not used */ -typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, - void *ptr, - int remains); - -/* return codes for CURLOPT_CHUNK_END_FUNCTION */ -#define CURL_CHUNK_END_FUNC_OK 0 -#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ - -/* If splitting of data transfer is enabled this callback is called after - download of an individual chunk finished. - Note! After this callback was set then it have to be called FOR ALL chunks. - Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. - This is the reason why we don't need "transfer_info" parameter in this - callback and we are not interested in "remains" parameter too. */ -typedef long (*curl_chunk_end_callback)(void *ptr); - -/* return codes for FNMATCHFUNCTION */ -#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ -#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ -#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ - -/* callback type for wildcard downloading pattern matching. If the - string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ -typedef int (*curl_fnmatch_callback)(void *ptr, - const char *pattern, - const char *string); - -/* These are the return codes for the seek callbacks */ -#define CURL_SEEKFUNC_OK 0 -#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ -#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so - libcurl might try other means instead */ -typedef int (*curl_seek_callback)(void *instream, - curl_off_t offset, - int origin); /* 'whence' */ - -/* This is a return code for the read callback that, when returned, will - signal libcurl to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -/* This is a return code for the read callback that, when returned, will - signal libcurl to pause sending data on the current transfer. */ -#define CURL_READFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - -typedef enum { - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ - CURLSOCKTYPE_LAST /* never use */ -} curlsocktype; - -/* The return code from the sockopt_callback can signal information back - to libcurl: */ -#define CURL_SOCKOPT_OK 0 -#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return - CURLE_ABORTED_BY_CALLBACK */ -#define CURL_SOCKOPT_ALREADY_CONNECTED 2 - -typedef int (*curl_sockopt_callback)(void *clientp, - curl_socket_t curlfd, - curlsocktype purpose); - -struct curl_sockaddr { - int family; - int socktype; - int protocol; - unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it - turned really ugly and painful on the systems that - lack this type */ - struct sockaddr addr; -}; - -typedef curl_socket_t -(*curl_opensocket_callback)(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *address); - -typedef int -(*curl_closesocket_callback)(void *clientp, curl_socket_t item); - -typedef enum { - CURLIOE_OK, /* I/O operation successful */ - CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ - CURLIOE_FAILRESTART, /* failed to restart the read */ - CURLIOE_LAST /* never use */ -} curlioerr; - -typedef enum { - CURLIOCMD_NOP, /* no operation */ - CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ - CURLIOCMD_LAST /* never use */ -} curliocmd; - -typedef curlioerr (*curl_ioctl_callback)(CURL *handle, - int cmd, - void *clientp); - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -#define CURL_DID_MEMORY_FUNC_TYPEDEFS -#endif - -/* the kind of data that is passed to information_callback*/ -typedef enum { - CURLINFO_TEXT = 0, - CURLINFO_HEADER_IN, /* 1 */ - CURLINFO_HEADER_OUT, /* 2 */ - CURLINFO_DATA_IN, /* 3 */ - CURLINFO_DATA_OUT, /* 4 */ - CURLINFO_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - CURLINFO_END -} curl_infotype; - -typedef int (*curl_debug_callback) - (CURL *handle, /* the handle/transfer this concerns */ - curl_infotype type, /* what kind of data */ - char *data, /* points to the data */ - size_t size, /* size of the data pointed to */ - void *userptr); /* whatever the user please */ - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum { - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for - 7.17.0, reused in April 2011 for 7.21.5] */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server - due to lack of access - when login fails - this is not returned. */ - CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for - 7.15.4, reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server - [was obsoleted in August 2007 for 7.17.0, - reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. - [was obsoleted in August 2007 for 7.17.0, - reused in July 2014 for 7.38.0] */ - CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_OBSOLETE20, /* 20 - NOT USED */ - CURLE_QUOTE_ERROR, /* 21 - quote command failure */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_OBSOLETE24, /* 24 - NOT USED */ - CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ - CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error - instead of a memory allocation error if CURL_DOES_CONVERSIONS - is defined - */ - CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ - CURLE_OBSOLETE29, /* 29 - NOT USED */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_OBSOLETE32, /* 32 - NOT USED */ - CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ - CURLE_HTTP_POST_ERROR, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_OBSOLETE44, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ - CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_SEND_ERROR, /* 55 - failed sending network data */ - CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - CURLE_OBSOLETE57, /* 57 - NOT IN USE */ - CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ - CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ - CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ - CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind - that failed */ - CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ - CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not - accepted and we failed to login */ - CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ - CURLE_TFTP_PERM, /* 69 - permission problem on server */ - CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ - CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ - CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ - CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ - CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_CONV_FAILED, /* 75 - conversion failed */ - CURLE_CONV_REQD, /* 76 - caller must register conversion - callbacks using curl_easy_setopt options - CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOPT_CONV_TO_NETWORK_FUNCTION, and - CURLOPT_CONV_FROM_UTF8_FUNCTION */ - CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing - or wrong format */ - CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ - CURLE_SSH, /* 79 - error from the SSH layer, somewhat - generic so the error message will be of - interest when this has happened */ - - CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL - connection */ - CURLE_AGAIN, /* 81 - socket is not ready for send/recv, - wait till it's ready and try again (Added - in 7.18.2) */ - CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or - wrong format (Added in 7.19.0) */ - CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in - 7.19.0) */ - CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ - CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ - CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ - CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ - CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ - CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the - session will be queued */ - CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not - match */ - CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ - CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer - */ - CURL_LAST /* never use! */ -} CURLcode; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Previously obsolete error code re-used in 7.38.0 */ -#define CURLE_OBSOLETE16 CURLE_HTTP2 - -/* Previously obsolete error codes re-used in 7.24.0 */ -#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED -#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT - -/* compatibility with older names */ -#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING -#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY - -/* The following were added in 7.21.5, April 2011 */ -#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION - -/* The following were added in 7.17.1 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.17.0 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ -#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 -#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 -#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 -#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 -#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 -#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 -#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 -#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 -#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 -#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 -#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 -#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN - -#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED -#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE -#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR -#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL -#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS -#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR -#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED - -/* The following were added earlier */ - -#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT - -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED -#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED - -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME - -/* This was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -/* Provide defines for really old option names */ -#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ -#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ -#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA - -/* Since long deprecated options with no code in the lib that does anything - with them. */ -#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 -#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 - -#endif /*!CURL_NO_OLDIES*/ - -/* This prototype applies to all conversion callbacks */ -typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an - OpenSSL SSL_CTX */ - void *userptr); - -typedef enum { - CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use - CONNECT HTTP/1.1 */ - CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT - HTTP/1.0 */ - CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ - CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already - in 7.10 */ - CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ - CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ - CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the - host name rather than the IP address. added - in 7.18.0 */ -} curl_proxytype; /* this enum was added in 7.10 */ - -/* - * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: - * - * CURLAUTH_NONE - No HTTP authentication - * CURLAUTH_BASIC - HTTP Basic authentication (default) - * CURLAUTH_DIGEST - HTTP Digest authentication - * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication - * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) - * CURLAUTH_NTLM - HTTP NTLM authentication - * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour - * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper - * CURLAUTH_ONLY - Use together with a single other type to force no - * authentication or just that single type - * CURLAUTH_ANY - All fine types set - * CURLAUTH_ANYSAFE - All fine types except Basic - */ - -#define CURLAUTH_NONE ((unsigned long)0) -#define CURLAUTH_BASIC (((unsigned long)1)<<0) -#define CURLAUTH_DIGEST (((unsigned long)1)<<1) -#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) -/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ -#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE -/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ -#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE -#define CURLAUTH_NTLM (((unsigned long)1)<<3) -#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) -#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) -#define CURLAUTH_ONLY (((unsigned long)1)<<31) -#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) -#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) - -#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ -#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ -#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ -#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ -#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ -#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ -#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ -#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */ -#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY - -#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ -#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ -#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ - -#define CURL_ERROR_SIZE 256 - -enum curl_khtype { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS, - CURLKHTYPE_ECDSA, - CURLKHTYPE_ED25519 -}; - -struct curl_khkey { - const char *key; /* points to a zero-terminated string encoded with base64 - if len is zero, otherwise to the "raw" data */ - size_t len; - enum curl_khtype keytype; -}; - -/* this is the set of return values expected from the curl_sshkeycallback - callback */ -enum curl_khstat { - CURLKHSTAT_FINE_ADD_TO_FILE, - CURLKHSTAT_FINE, - CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so - this causes a CURLE_DEFER error but otherwise the - connection will be left intact etc */ - CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ -}; - -/* this is the set of status codes pass in to the callback */ -enum curl_khmatch { - CURLKHMATCH_OK, /* match */ - CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ - CURLKHMATCH_MISSING, /* no matching host/key found */ - CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ -}; - -typedef int - (*curl_sshkeycallback) (CURL *easy, /* easy handle */ - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch, /* libcurl's view on the keys */ - void *clientp); /* custom pointer passed from app */ - -/* parameter for the CURLOPT_USE_SSL option */ -typedef enum { - CURLUSESSL_NONE, /* do not attempt to use SSL */ - CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ - CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ - CURLUSESSL_ALL, /* SSL for all communication or fail */ - CURLUSESSL_LAST /* not an option, never use */ -} curl_usessl; - -/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ - -/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the - name of improving interoperability with older servers. Some SSL libraries - have introduced work-arounds for this flaw but those work-arounds sometimes - make the SSL communication fail. To regain functionality with those broken - servers, a user can this way allow the vulnerability back. */ -#define CURLSSLOPT_ALLOW_BEAST (1<<0) - -/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those - SSL backends where such behavior is present. */ -#define CURLSSLOPT_NO_REVOKE (1<<1) - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2009 */ - -#define CURLFTPSSL_NONE CURLUSESSL_NONE -#define CURLFTPSSL_TRY CURLUSESSL_TRY -#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL -#define CURLFTPSSL_ALL CURLUSESSL_ALL -#define CURLFTPSSL_LAST CURLUSESSL_LAST -#define curl_ftpssl curl_usessl -#endif /*!CURL_NO_OLDIES*/ - -/* parameter for the CURLOPT_FTP_SSL_CCC option */ -typedef enum { - CURLFTPSSL_CCC_NONE, /* do not send CCC */ - CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ - CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ - CURLFTPSSL_CCC_LAST /* not an option, never use */ -} curl_ftpccc; - -/* parameter for the CURLOPT_FTPSSLAUTH option */ -typedef enum { - CURLFTPAUTH_DEFAULT, /* let libcurl decide */ - CURLFTPAUTH_SSL, /* use "AUTH SSL" */ - CURLFTPAUTH_TLS, /* use "AUTH TLS" */ - CURLFTPAUTH_LAST /* not an option, never use */ -} curl_ftpauth; - -/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ -typedef enum { - CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ - CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD - again if MKD succeeded, for SFTP this does - similar magic */ - CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD - again even if MKD failed! */ - CURLFTP_CREATE_DIR_LAST /* not an option, never use */ -} curl_ftpcreatedir; - -/* parameter for the CURLOPT_FTP_FILEMETHOD option */ -typedef enum { - CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ - CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ - CURLFTPMETHOD_NOCWD, /* no CWD at all */ - CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ - CURLFTPMETHOD_LAST /* not an option, never use */ -} curl_ftpmethod; - -/* bitmask defines for CURLOPT_HEADEROPT */ -#define CURLHEADER_UNIFIED 0 -#define CURLHEADER_SEPARATE (1<<0) - -/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ -#define CURLPROTO_HTTP (1<<0) -#define CURLPROTO_HTTPS (1<<1) -#define CURLPROTO_FTP (1<<2) -#define CURLPROTO_FTPS (1<<3) -#define CURLPROTO_SCP (1<<4) -#define CURLPROTO_SFTP (1<<5) -#define CURLPROTO_TELNET (1<<6) -#define CURLPROTO_LDAP (1<<7) -#define CURLPROTO_LDAPS (1<<8) -#define CURLPROTO_DICT (1<<9) -#define CURLPROTO_FILE (1<<10) -#define CURLPROTO_TFTP (1<<11) -#define CURLPROTO_IMAP (1<<12) -#define CURLPROTO_IMAPS (1<<13) -#define CURLPROTO_POP3 (1<<14) -#define CURLPROTO_POP3S (1<<15) -#define CURLPROTO_SMTP (1<<16) -#define CURLPROTO_SMTPS (1<<17) -#define CURLPROTO_RTSP (1<<18) -#define CURLPROTO_RTMP (1<<19) -#define CURLPROTO_RTMPT (1<<20) -#define CURLPROTO_RTMPE (1<<21) -#define CURLPROTO_RTMPTE (1<<22) -#define CURLPROTO_RTMPS (1<<23) -#define CURLPROTO_RTMPTS (1<<24) -#define CURLPROTO_GOPHER (1<<25) -#define CURLPROTO_SMB (1<<26) -#define CURLPROTO_SMBS (1<<27) -#define CURLPROTO_ALL (~0) /* enable everything */ - -/* long may be 32 or 64 bits, but we should never depend on anything else - but 32 */ -#define CURLOPTTYPE_LONG 0 -#define CURLOPTTYPE_OBJECTPOINT 10000 -#define CURLOPTTYPE_STRINGPOINT 10000 -#define CURLOPTTYPE_FUNCTIONPOINT 20000 -#define CURLOPTTYPE_OFF_T 30000 - -/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the - string options from the header file */ - -/* name is uppercase CURLOPT_, - type is one of the defined CURLOPTTYPE_ - number is unique identifier */ -#ifdef CINIT -#undef CINIT -#endif - -#ifdef CURL_ISOCPP -#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLOPT_/**/name = type + number -#endif - -/* - * This macro-mania below setups the CURLOPT_[what] enum, to be used with - * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] - * word. - */ - -typedef enum { - /* This is the FILE * or void * the regular output should be written to. */ - CINIT(WRITEDATA, OBJECTPOINT, 1), - - /* The full URL to get/put */ - CINIT(URL, STRINGPOINT, 2), - - /* Port number to connect to, if other than default. */ - CINIT(PORT, LONG, 3), - - /* Name of proxy to use. */ - CINIT(PROXY, STRINGPOINT, 4), - - /* "user:password;options" to use when fetching. */ - CINIT(USERPWD, STRINGPOINT, 5), - - /* "user:password" to use with proxy. */ - CINIT(PROXYUSERPWD, STRINGPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CINIT(RANGE, STRINGPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CINIT(READDATA, OBJECTPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. */ - CINIT(ERRORBUFFER, OBJECTPOINT, 10), - - /* Function that will be called to store the output (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), - - /* Function that will be called to read the input (instead of fread). The - * parameters will use fread() syntax, make sure to follow them. */ - CINIT(READFUNCTION, FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CINIT(TIMEOUT, LONG, 13), - - /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was successful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CINIT(INFILESIZE, LONG, 14), - - /* POST static input fields. */ - CINIT(POSTFIELDS, OBJECTPOINT, 15), - - /* Set the referrer page (needed by some CGIs) */ - CINIT(REFERER, STRINGPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CINIT(FTPPORT, STRINGPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CINIT(USERAGENT, STRINGPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CINIT(LOW_SPEED_LIMIT, LONG, 19), - - /* Set the "low speed time" */ - CINIT(LOW_SPEED_TIME, LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CINIT(RESUME_FROM, LONG, 21), - - /* Set cookie in request: */ - CINIT(COOKIE, STRINGPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind. This - list is also used for RTSP (in spite of its name) */ - CINIT(HTTPHEADER, OBJECTPOINT, 23), - - /* This points to a linked list of post entries, struct curl_httppost */ - CINIT(HTTPPOST, OBJECTPOINT, 24), - - /* name of the file keeping your private SSL-certificate */ - CINIT(SSLCERT, STRINGPOINT, 25), - - /* password for the SSL or SSH private key */ - CINIT(KEYPASSWD, STRINGPOINT, 26), - - /* send TYPE parameter? */ - CINIT(CRLF, LONG, 27), - - /* send linked-list of QUOTE commands */ - CINIT(QUOTE, OBJECTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is simply passed to the callback unmodified */ - CINIT(HEADERDATA, OBJECTPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CINIT(COOKIEFILE, STRINGPOINT, 31), - - /* What version to specifically try to use. - See CURL_SSLVERSION defines below. */ - CINIT(SSLVERSION, LONG, 32), - - /* What kind of HTTP time condition to use, see defines */ - CINIT(TIMECONDITION, LONG, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CINIT(TIMEVALUE, LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CINIT(CUSTOMREQUEST, STRINGPOINT, 36), - - /* FILE handle to use instead of stderr */ - CINIT(STDERR, OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CINIT(POSTQUOTE, OBJECTPOINT, 39), - - CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ - - CINIT(VERBOSE, LONG, 41), /* talk a lot */ - CINIT(HEADER, LONG, 42), /* throw the header out too */ - CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ - CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ - CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ - CINIT(UPLOAD, LONG, 46), /* this is an upload */ - CINIT(POST, LONG, 47), /* HTTP POST method */ - CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ - - CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ - - /* Specify whether to read the user+password from the .netrc or the URL. - * This must be one of the CURL_NETRC_* enums below. */ - CINIT(NETRC, LONG, 51), - - CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ - - CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ - CINIT(PUT, LONG, 54), /* HTTP PUT */ - - /* 55 = OBSOLETE */ - - /* DEPRECATED - * Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), - - /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION - callbacks */ - CINIT(PROGRESSDATA, OBJECTPOINT, 57), -#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA - - /* We want the referrer field set automatically when following locations */ - CINIT(AUTOREFERER, LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CINIT(PROXYPORT, LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CINIT(POSTFIELDSIZE, LONG, 60), - - /* tunnel non-http operations through a HTTP proxy */ - CINIT(HTTPPROXYTUNNEL, LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CINIT(INTERFACE, STRINGPOINT, 62), - - /* Set the krb4/5 security level, this also enables krb4/5 awareness. This - * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string - * is set but doesn't match one of these, 'private' will be used. */ - CINIT(KRBLEVEL, STRINGPOINT, 63), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CINIT(SSL_VERIFYPEER, LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAINFO, STRINGPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CINIT(MAXREDIRS, LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CINIT(FILETIME, LONG, 69), - - /* This points to a linked list of telnet options */ - CINIT(TELNETOPTIONS, OBJECTPOINT, 70), - - /* Max amount of cached alive connections */ - CINIT(MAXCONNECTS, LONG, 71), - - CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ - - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you're absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CINIT(FRESH_CONNECT, LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be re-used - when done. Do not use this unless you're absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CINIT(FORBID_REUSE, LONG, 75), - - /* Set to a file name that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CINIT(RANDOM_FILE, STRINGPOINT, 76), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CINIT(EGDSOCKET, STRINGPOINT, 77), - - /* Time-out connect operations after this amount of seconds, if connects are - OK within this time, then fine... This only aborts the connect phase. */ - CINIT(CONNECTTIMEOUT, LONG, 78), - - /* Function that will be called to store headers (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CINIT(HTTPGET, LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CINIT(SSL_VERIFYHOST, LONG, 81), - - /* Specify which file name to write all known cookies in after completed - operation. Set file name to "-" (dash) to make it go to stdout. */ - CINIT(COOKIEJAR, STRINGPOINT, 82), - - /* Specify which SSL ciphers to use */ - CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CINIT(HTTP_VERSION, LONG, 84), - - /* Specifically switch on or off the FTP engine's use of the EPSV command. By - default, that one will always be attempted before the more traditional - PASV command. */ - CINIT(FTP_USE_EPSV, LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CINIT(SSLCERTTYPE, STRINGPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CINIT(SSLKEY, STRINGPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CINIT(SSLKEYTYPE, STRINGPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CINIT(SSLENGINE, STRINGPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CINIT(SSLENGINE_DEFAULT, LONG, 90), - - /* Non-zero value means to use the global dns cache */ - CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ - - /* DNS cache timeout */ - CINIT(DNS_CACHE_TIMEOUT, LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands */ - CINIT(PREQUOTE, OBJECTPOINT, 93), - - /* set the debug function */ - CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CINIT(DEBUGDATA, OBJECTPOINT, 95), - - /* mark this as start of a cookie session */ - CINIT(COOKIESESSION, LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAPATH, STRINGPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CINIT(BUFFERSIZE, LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CINIT(NOSIGNAL, LONG, 99), - - /* Provide a CURLShare for mutexing non-ts data */ - CINIT(SHARE, OBJECTPOINT, 100), - - /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and - CURLPROXY_SOCKS5. */ - CINIT(PROXYTYPE, LONG, 101), - - /* Set the Accept-Encoding string. Use this to tell a server you would like - the response to be compressed. Before 7.21.6, this was known as - CURLOPT_ENCODING */ - CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), - - /* Set pointer to private data */ - CINIT(PRIVATE, OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CINIT(HTTP200ALIASES, OBJECTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentially send off the name - and password to whatever host the server decides. */ - CINIT(UNRESTRICTED_AUTH, LONG, 105), - - /* Specifically switch on or off the FTP engine's use of the EPRT command ( - it also disables the LPRT attempt). By default, those ones will always be - attempted before the good old traditional PORT command. */ - CINIT(FTP_USE_EPRT, LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(HTTPAUTH, LONG, 107), - - /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx - in second argument. The function must be matching the - curl_ssl_ctx_callback proto. */ - CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server. - In 7.19.4 we introduced the convenience enums for this option using the - CURLFTP_CREATE_DIR prefix. - */ - CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(PROXYAUTH, LONG, 111), - - /* FTP option that changes the timeout, in seconds, associated with - getting a response. This is different from transfer timeout time and - essentially places a demand on the FTP server to acknowledge commands - in a timely manner. */ - CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), -#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to resolve names to those IP versions only. This only has - affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CINIT(IPRESOLVE, LONG, 113), - - /* Set this option to limit the size of a file that will be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CINIT(MAXFILESIZE, LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CINIT(INFILESIZE_LARGE, OFF_T, 115), - - /* Sets the continuation offset. There is also a LONG version of this; - * look above for RESUME_FROM. - */ - CINIT(RESUME_FROM_LARGE, OFF_T, 116), - - /* Sets the maximum size of data that will be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CINIT(MAXFILESIZE_LARGE, OFF_T, 117), - - /* Set this option to the file name of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl will do - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CINIT(NETRC_FILE, STRINGPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLUSESSL_TRY - try using SSL, proceed anyway otherwise - CURLUSESSL_CONTROL - SSL for the control connection or fail - CURLUSESSL_ALL - SSL for all communication or fail - */ - CINIT(USE_SSL, LONG, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CINIT(TCP_NODELAY, LONG, 121), - - /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 123 OBSOLETE. Gone in 7.16.0 */ - /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 127 OBSOLETE. Gone in 7.16.0 */ - /* 128 OBSOLETE. Gone in 7.16.0 */ - - /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option - can be used to change libcurl's default action which is to first try - "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK - response has been received. - - Available parameters are: - CURLFTPAUTH_DEFAULT - let libcurl decide - CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS - CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL - */ - CINIT(FTPSSLAUTH, LONG, 129), - - CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), - CINIT(IOCTLDATA, OBJECTPOINT, 131), - - /* 132 OBSOLETE. Gone in 7.16.0 */ - /* 133 OBSOLETE. Gone in 7.16.0 */ - - /* zero terminated string for pass on to the FTP server when asked for - "account" info */ - CINIT(FTP_ACCOUNT, STRINGPOINT, 134), - - /* feed cookie into cookie engine */ - CINIT(COOKIELIST, STRINGPOINT, 135), - - /* ignore Content-Length */ - CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), - - /* Set to non-zero to skip the IP address received in a 227 PASV FTP server - response. Typically used for FTP-SSL purposes but is not restricted to - that. libcurl will then instead use the same IP address it used for the - control connection. */ - CINIT(FTP_SKIP_PASV_IP, LONG, 137), - - /* Select "file method" to use when doing FTP, see the curl_ftpmethod - above. */ - CINIT(FTP_FILEMETHOD, LONG, 138), - - /* Local port number to bind the socket to */ - CINIT(LOCALPORT, LONG, 139), - - /* Number of ports to try, including the first one set with LOCALPORT. - Thus, setting it to 1 will make no additional attempts but the first. - */ - CINIT(LOCALPORTRANGE, LONG, 140), - - /* no transfer, set up connection and let application use the socket by - extracting it with CURLINFO_LASTSOCKET */ - CINIT(CONNECT_ONLY, LONG, 141), - - /* Function that will be called to convert from the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), - - /* Function that will be called to convert to the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), - - /* Function that will be called to convert from UTF8 - (instead of using the iconv calls in libcurl) - Note that this is used only for SSL certificate processing */ - CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), - - /* if the connection proceeds too quickly then need to slow it down */ - /* limit-rate: maximum number of bytes per second to send or receive */ - CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), - CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), - - /* Pointer to command string to send if USER/PASS fails. */ - CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), - - /* callback function for setting socket options */ - CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), - CINIT(SOCKOPTDATA, OBJECTPOINT, 149), - - /* set to 0 to disable session ID re-use for this transfer, default is - enabled (== 1) */ - CINIT(SSL_SESSIONID_CACHE, LONG, 150), - - /* allowed SSH authentication methods */ - CINIT(SSH_AUTH_TYPES, LONG, 151), - - /* Used by scp/sftp to do public/private key authentication */ - CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), - CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), - - /* Send CCC (Clear Command Channel) after authentication */ - CINIT(FTP_SSL_CCC, LONG, 154), - - /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CINIT(TIMEOUT_MS, LONG, 155), - CINIT(CONNECTTIMEOUT_MS, LONG, 156), - - /* set to zero to disable the libcurl's decoding and thus pass the raw body - data to the application even when it is encoded/compressed */ - CINIT(HTTP_TRANSFER_DECODING, LONG, 157), - CINIT(HTTP_CONTENT_DECODING, LONG, 158), - - /* Permission used when creating new files and directories on the remote - server for protocols that support it, SFTP/SCP/FILE */ - CINIT(NEW_FILE_PERMS, LONG, 159), - CINIT(NEW_DIRECTORY_PERMS, LONG, 160), - - /* Set the behaviour of POST when redirecting. Values must be set to one - of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CINIT(POSTREDIR, LONG, 161), - - /* used by scp/sftp to verify the host's public key */ - CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), - - /* Callback function for opening socket (instead of socket(2)). Optionally, - callback is able change the address or refuse to connect returning - CURL_SOCKET_BAD. The callback should have type - curl_opensocket_callback */ - CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), - CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), - - /* POST volatile input fields. */ - CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), - - /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CINIT(PROXY_TRANSFER_MODE, LONG, 166), - - /* Callback function for seeking in the input stream */ - CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), - CINIT(SEEKDATA, OBJECTPOINT, 168), - - /* CRL file */ - CINIT(CRLFILE, STRINGPOINT, 169), - - /* Issuer certificate */ - CINIT(ISSUERCERT, STRINGPOINT, 170), - - /* (IPv6) Address scope */ - CINIT(ADDRESS_SCOPE, LONG, 171), - - /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. */ - CINIT(CERTINFO, LONG, 172), - - /* "name" and "pwd" to use when fetching. */ - CINIT(USERNAME, STRINGPOINT, 173), - CINIT(PASSWORD, STRINGPOINT, 174), - - /* "name" and "pwd" to use with Proxy when fetching. */ - CINIT(PROXYUSERNAME, STRINGPOINT, 175), - CINIT(PROXYPASSWORD, STRINGPOINT, 176), - - /* Comma separated list of hostnames defining no-proxy zones. These should - match both hostnames directly, and hostnames within a domain. For - example, local.com will match local.com and www.local.com, but NOT - notlocal.com or www.notlocal.com. For compatibility with other - implementations of this, .local.com will be considered to be the same as - local.com. A single * is the only valid wildcard, and effectively - disables the use of proxy. */ - CINIT(NOPROXY, STRINGPOINT, 177), - - /* block size for TFTP transfers */ - CINIT(TFTP_BLKSIZE, LONG, 178), - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), - - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - CINIT(PROTOCOLS, LONG, 181), - - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. Defaults - to all protocols except FILE and SCP. */ - CINIT(REDIR_PROTOCOLS, LONG, 182), - - /* set the SSH knownhost file name to use */ - CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), - - /* set the SSH host key callback custom pointer */ - CINIT(SSH_KEYDATA, OBJECTPOINT, 185), - - /* set the SMTP mail originator */ - CINIT(MAIL_FROM, STRINGPOINT, 186), - - /* set the list of SMTP mail receiver(s) */ - CINIT(MAIL_RCPT, OBJECTPOINT, 187), - - /* FTP: send PRET before PASV */ - CINIT(FTP_USE_PRET, LONG, 188), - - /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CINIT(RTSP_REQUEST, LONG, 189), - - /* The RTSP session identifier */ - CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), - - /* The RTSP stream URI */ - CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), - - /* The Transport: header to use in RTSP requests */ - CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), - - /* Manually initialize the client RTSP CSeq for this handle */ - CINIT(RTSP_CLIENT_CSEQ, LONG, 193), - - /* Manually initialize the server RTSP CSeq for this handle */ - CINIT(RTSP_SERVER_CSEQ, LONG, 194), - - /* The stream to pass to INTERLEAVEFUNCTION. */ - CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), - - /* Let the application define a custom write method for RTP data */ - CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), - - /* Turn on wildcard matching */ - CINIT(WILDCARDMATCH, LONG, 197), - - /* Directory matching callback called before downloading of an - individual file (chunk) started */ - CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), - - /* Directory matching callback called after the file (chunk) - was downloaded, or skipped */ - CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), - - /* Change match (fnmatch-like) callback for wildcard matching */ - CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), - - /* Let the application define custom chunk data pointer */ - CINIT(CHUNK_DATA, OBJECTPOINT, 201), - - /* FNMATCH_FUNCTION user pointer */ - CINIT(FNMATCH_DATA, OBJECTPOINT, 202), - - /* send linked-list of name:port:address sets */ - CINIT(RESOLVE, OBJECTPOINT, 203), - - /* Set a username for authenticated TLS */ - CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), - - /* Set a password for authenticated TLS */ - CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), - - /* Set authentication type for authenticated TLS */ - CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), - - /* Set to 1 to enable the "TE:" header in HTTP requests to ask for - compressed transfer-encoded responses. Set to 0 to disable the use of TE: - in outgoing requests. The current default is 0, but it might change in a - future libcurl release. - - libcurl will ask for the compressed methods it knows of, and if that - isn't any, it will not ask for transfer-encoding at all even if this - option is set to 1. - - */ - CINIT(TRANSFER_ENCODING, LONG, 207), - - /* Callback function for closing socket (instead of close(2)). The callback - should have type curl_closesocket_callback */ - CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), - CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), - - /* allow GSSAPI credential delegation */ - CINIT(GSSAPI_DELEGATION, LONG, 210), - - /* Set the name servers to use for DNS resolution */ - CINIT(DNS_SERVERS, STRINGPOINT, 211), - - /* Time-out accept operations (currently for FTP only) after this amount - of milliseconds. */ - CINIT(ACCEPTTIMEOUT_MS, LONG, 212), - - /* Set TCP keepalive */ - CINIT(TCP_KEEPALIVE, LONG, 213), - - /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ - CINIT(TCP_KEEPIDLE, LONG, 214), - CINIT(TCP_KEEPINTVL, LONG, 215), - - /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ - CINIT(SSL_OPTIONS, LONG, 216), - - /* Set the SMTP auth originator */ - CINIT(MAIL_AUTH, STRINGPOINT, 217), - - /* Enable/disable SASL initial response */ - CINIT(SASL_IR, LONG, 218), - - /* Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_xferinfo_callback - * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ - CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), - - /* The XOAUTH2 bearer token */ - CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), - - /* Set the interface string to use as outgoing network - * interface for DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_INTERFACE, STRINGPOINT, 221), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), - - /* Set authentication options directly */ - CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), - - /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ - CINIT(SSL_ENABLE_NPN, LONG, 225), - - /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ - CINIT(SSL_ENABLE_ALPN, LONG, 226), - - /* Time to wait for a response to a HTTP request containing an - * Expect: 100-continue header before sending the data anyway. */ - CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), - - /* This points to a linked list of headers used for proxy requests only, - struct curl_slist kind */ - CINIT(PROXYHEADER, OBJECTPOINT, 228), - - /* Pass in a bitmask of "header options" */ - CINIT(HEADEROPT, LONG, 229), - - /* The public key in DER form used to validate the peer public key - this option is used only if SSL_VERIFYPEER is true */ - CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), - - /* Path to Unix domain socket */ - CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), - - /* Set if we should verify the certificate status. */ - CINIT(SSL_VERIFYSTATUS, LONG, 232), - - /* Set if we should enable TLS false start. */ - CINIT(SSL_FALSESTART, LONG, 233), - - /* Do not squash dot-dot sequences */ - CINIT(PATH_AS_IS, LONG, 234), - - /* Proxy Service Name */ - CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), - - /* Service Name */ - CINIT(SERVICE_NAME, STRINGPOINT, 236), - - /* Wait/don't wait for pipe/mutex to clarify */ - CINIT(PIPEWAIT, LONG, 237), - - /* Set the protocol used when curl is given a URL without a protocol */ - CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), - - /* Set stream weight, 1 - 256 (default is 16) */ - CINIT(STREAM_WEIGHT, LONG, 239), - - /* Set stream dependency on another CURL handle */ - CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), - - /* Set E-xclusive stream dependency on another CURL handle */ - CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), - - /* Do not send any tftp option requests to the server */ - CINIT(TFTP_NO_OPTIONS, LONG, 242), - - /* Linked-list of host:port:connect-to-host:connect-to-port, - overrides the URL's host:port (only for the network layer) */ - CINIT(CONNECT_TO, OBJECTPOINT, 243), - - /* Set TCP Fast Open */ - CINIT(TCP_FASTOPEN, LONG, 244), - - /* Continue to send data if the server responds early with an - * HTTP status code >= 300 */ - CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), - - /* The CApath or CAfile used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CINIT(PROXY_CAINFO, STRINGPOINT, 246), - - /* The CApath directory used to validate the proxy certificate - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CINIT(PROXY_CAPATH, STRINGPOINT, 247), - - /* Set if we should verify the proxy in ssl handshake, - set 1 to verify. */ - CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), - - /* Set if we should verify the Common name from the proxy certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches - * the provided hostname. */ - CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), - - /* What version to specifically try to use for proxy. - See CURL_SSLVERSION defines below. */ - CINIT(PROXY_SSLVERSION, LONG, 250), - - /* Set a username for authenticated TLS for proxy */ - CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), - - /* Set a password for authenticated TLS for proxy */ - CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), - - /* Set authentication type for authenticated TLS for proxy */ - CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), - - /* name of the file keeping your private SSL-certificate for proxy */ - CINIT(PROXY_SSLCERT, STRINGPOINT, 254), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for - proxy */ - CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), - - /* name of the file keeping your private SSL-key for proxy */ - CINIT(PROXY_SSLKEY, STRINGPOINT, 256), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for - proxy */ - CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), - - /* password for the SSL private key for proxy */ - CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), - - /* Specify which SSL ciphers to use for proxy */ - CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), - - /* CRL file for proxy */ - CINIT(PROXY_CRLFILE, STRINGPOINT, 260), - - /* Enable/disable specific SSL features with a bitmask for proxy, see - CURLSSLOPT_* */ - CINIT(PROXY_SSL_OPTIONS, LONG, 261), - - /* Name of pre proxy to use. */ - CINIT(PRE_PROXY, STRINGPOINT, 262), - - /* The public key in DER form used to validate the proxy public key - this option is used only if PROXY_SSL_VERIFYPEER is true */ - CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), - - /* Path to an abstract Unix domain socket */ - CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264), - - /* Suppress proxy CONNECT response headers from user callbacks */ - CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265), - - /* The request target, instead of extracted from the URL */ - CINIT(REQUEST_TARGET, STRINGPOINT, 266), - - /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ - CINIT(SOCKS5_AUTH, LONG, 267), - - /* Enable/disable SSH compression */ - CINIT(SSH_COMPRESSION, LONG, 268), - - /* Post MIME data. */ - CINIT(MIMEPOST, OBJECTPOINT, 269), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2011 */ - -/* This was added in version 7.19.1 */ -#define CURLOPT_POST301 CURLOPT_POSTREDIR - -/* These are scheduled to disappear by 2009 */ - -/* The following were added in 7.17.0 */ -#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_FTPAPPEND CURLOPT_APPEND -#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY -#define CURLOPT_FTP_SSL CURLOPT_USE_SSL - -/* The following were added earlier */ - -#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - - - /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ - - /* three convenient "aliases" that follow the name scheme better */ -#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER - - /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ -enum { - CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd - like the library to choose the best possible - for us! */ - CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ - CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ - CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ - CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 - Upgrade */ - - CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ -}; - -/* Convenience definition simple because the name of the version is HTTP/2 and - not 2.0. The 2_0 version of the enum name was set while the version was - still planned to be 2.0 and we stick to it for compatibility. */ -#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 - -/* - * Public API enums for RTSP requests - */ -enum { - CURL_RTSPREQ_NONE, /* first in list */ - CURL_RTSPREQ_OPTIONS, - CURL_RTSPREQ_DESCRIBE, - CURL_RTSPREQ_ANNOUNCE, - CURL_RTSPREQ_SETUP, - CURL_RTSPREQ_PLAY, - CURL_RTSPREQ_PAUSE, - CURL_RTSPREQ_TEARDOWN, - CURL_RTSPREQ_GET_PARAMETER, - CURL_RTSPREQ_SET_PARAMETER, - CURL_RTSPREQ_RECORD, - CURL_RTSPREQ_RECEIVE, - CURL_RTSPREQ_LAST /* last in list */ -}; - - /* These enums are for use with the CURLOPT_NETRC option. */ -enum CURL_NETRC_OPTION { - CURL_NETRC_IGNORED, /* The .netrc will never be read. - * This is the default. */ - CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred - * to one in the .netrc. */ - CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. - * Unless one is set programmatically, the .netrc - * will be queried. */ - CURL_NETRC_LAST -}; - -enum { - CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, /* TLS 1.x */ - CURL_SSLVERSION_SSLv2, - CURL_SSLVERSION_SSLv3, - CURL_SSLVERSION_TLSv1_0, - CURL_SSLVERSION_TLSv1_1, - CURL_SSLVERSION_TLSv1_2, - CURL_SSLVERSION_TLSv1_3, - - CURL_SSLVERSION_LAST /* never use, keep last */ -}; - -enum { - CURL_SSLVERSION_MAX_NONE = 0, - CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), - CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), - CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), - CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), - CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), - - /* never use, keep last */ - CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) -}; - -enum CURL_TLSAUTH { - CURL_TLSAUTH_NONE, - CURL_TLSAUTH_SRP, - CURL_TLSAUTH_LAST /* never use, keep last */ -}; - -/* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 - can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 - | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ - -#define CURL_REDIR_GET_ALL 0 -#define CURL_REDIR_POST_301 1 -#define CURL_REDIR_POST_302 2 -#define CURL_REDIR_POST_303 4 -#define CURL_REDIR_POST_ALL \ - (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) - -typedef enum { - CURL_TIMECOND_NONE, - - CURL_TIMECOND_IFMODSINCE, - CURL_TIMECOND_IFUNMODSINCE, - CURL_TIMECOND_LASTMOD, - - CURL_TIMECOND_LAST -} curl_TimeCond; - -/* Special size_t value signaling a zero-terminated string. */ -#define CURL_ZERO_TERMINATED ((size_t) -1) - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - release */ -CURL_EXTERN int curl_strequal(const char *s1, const char *s2); -CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n); - -/* Mime/form handling support. */ -typedef struct curl_mime_s curl_mime; /* Mime context. */ -typedef struct curl_mimepart_s curl_mimepart; /* Mime part context. */ - -/* - * NAME curl_mime_init() - * - * DESCRIPTION - * - * Create a mime context and return its handle. The easy parameter is the - * target handle. - */ -CURL_EXTERN curl_mime *curl_mime_init(CURL *easy); - -/* - * NAME curl_mime_free() - * - * DESCRIPTION - * - * release a mime handle and its substructures. - */ -CURL_EXTERN void curl_mime_free(curl_mime *mime); - -/* - * NAME curl_mime_addpart() - * - * DESCRIPTION - * - * Append a new empty part to the given mime context and return a handle to - * the created part. - */ -CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime); - -/* - * NAME curl_mime_name() - * - * DESCRIPTION - * - * Set mime/form part name. - */ -CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name); - -/* - * NAME curl_mime_filename() - * - * DESCRIPTION - * - * Set mime part remote file name. - */ -CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_type() - * - * DESCRIPTION - * - * Set mime part type. - */ -CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); - -/* - * NAME curl_mime_encoder() - * - * DESCRIPTION - * - * Set mime data transfer encoder. - */ -CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part, - const char *encoding); - -/* - * NAME curl_mime_data() - * - * DESCRIPTION - * - * Set mime part data source from memory data, - */ -CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part, - const char *data, size_t datasize); - -/* - * NAME curl_mime_filedata() - * - * DESCRIPTION - * - * Set mime part data source from named file. - */ -CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part, - const char *filename); - -/* - * NAME curl_mime_data_cb() - * - * DESCRIPTION - * - * Set mime part data source from callback function. - */ -CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part, - curl_off_t datasize, - curl_read_callback readfunc, - curl_seek_callback seekfunc, - curl_free_callback freefunc, - void *arg); - -/* - * NAME curl_mime_subparts() - * - * DESCRIPTION - * - * Set mime part data source from subparts. - */ -CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, - curl_mime *subparts); -/* - * NAME curl_mime_headers() - * - * DESCRIPTION - * - * Set mime part headers. - */ -CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, - struct curl_slist *headers, - int take_ownership); - -/* Old form API. */ -/* name is uppercase CURLFORM_ */ -#ifdef CFINIT -#undef CFINIT -#endif - -#ifdef CURL_ISOCPP -#define CFINIT(name) CURLFORM_ ## name -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define CFINIT(name) CURLFORM_/**/name -#endif - -typedef enum { - CFINIT(NOTHING), /********* the first one is unused ************/ - - /* */ - CFINIT(COPYNAME), - CFINIT(PTRNAME), - CFINIT(NAMELENGTH), - CFINIT(COPYCONTENTS), - CFINIT(PTRCONTENTS), - CFINIT(CONTENTSLENGTH), - CFINIT(FILECONTENT), - CFINIT(ARRAY), - CFINIT(OBSOLETE), - CFINIT(FILE), - - CFINIT(BUFFER), - CFINIT(BUFFERPTR), - CFINIT(BUFFERLENGTH), - - CFINIT(CONTENTTYPE), - CFINIT(CONTENTHEADER), - CFINIT(FILENAME), - CFINIT(END), - CFINIT(OBSOLETE2), - - CFINIT(STREAM), - CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ - - CURLFORM_LASTENTRY /* the last unused */ -} CURLformoption; - -#undef CFINIT /* done */ - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms { - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum { - CURL_FORMADD_OK, /* first, no error */ - - CURL_FORMADD_MEMORY, - CURL_FORMADD_OPTION_TWICE, - CURL_FORMADD_NULL, - CURL_FORMADD_UNKNOWN_OPTION, - CURL_FORMADD_INCOMPLETE, - CURL_FORMADD_ILLEGAL_ARRAY, - CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanced function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * callback function for curl_formget() - * The void *arg pointer will be the one passed as second argument to - * curl_formget(). - * The character buffer passed to it must not be freed. - * Should return the buffer length passed to it as the argument "len" on - * success. - */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, - size_t len); - -/* - * NAME curl_formget() - * - * DESCRIPTION - * - * Serialize a curl_httppost struct built with curl_formadd(). - * Accepts a void pointer as second argument which will be passed to - * the curl_formget_callback function. - * Returns 0 on success. - */ -CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append); -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -CURL_EXTERN void curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -CURL_EXTERN char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ascii string of the libcurl version. - */ -CURL_EXTERN char *curl_version(void); - -/* - * NAME curl_easy_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -CURL_EXTERN char *curl_easy_escape(CURL *handle, - const char *string, - int length); - -/* the previous version: */ -CURL_EXTERN char *curl_escape(const char *string, - int length); - - -/* - * NAME curl_easy_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - * Conversion Note: On non-ASCII platforms the ASCII %XX codes are - * converted into the host encoding. - */ -CURL_EXTERN char *curl_easy_unescape(CURL *handle, - const char *string, - int length, - int *outlength); - -/* the previous version */ -CURL_EXTERN char *curl_unescape(const char *string, - int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -CURL_EXTERN void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl and before any call of other libcurl functions. - * - * This function is not thread-safe! - */ -CURL_EXTERN CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for mis-use of the curl library etc. User registered - * callback routines with be invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURL_EXTERN CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -CURL_EXTERN void curl_global_cleanup(void); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist { - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_global_sslset() - * - * DESCRIPTION - * - * When built with multiple SSL backends, curl_global_sslset() allows to - * choose one. This function can only be called once, and it must be called - * *before* curl_global_init(). - * - * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The - * backend can also be specified via the name parameter (passing -1 as id). - * If both id and name are specified, the name will be ignored. If neither id - * nor name are specified, the function will fail with - * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the - * NULL-terminated list of available backends. - * - * Upon success, the function returns CURLSSLSET_OK. - * - * If the specified SSL backend is not available, the function returns - * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated - * list of available SSL backends. - * - * The SSL backend can be set only once. If it has already been set, a - * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE. - */ - -typedef struct { - curl_sslbackend id; - const char *name; -} curl_ssl_backend; - -typedef enum { - CURLSSLSET_OK = 0, - CURLSSLSET_UNKNOWN_BACKEND, - CURLSSLSET_TOO_LATE, - CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */ -} CURLsslset; - -CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, - const curl_ssl_backend ***avail); - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it will be created - * first. Returns the new list, after appending. - */ -CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, - const char *); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -CURL_EXTERN void curl_slist_free_all(struct curl_slist *); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is unused - * and should be set to NULL. - */ -CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); - -/* info about the certificate chain, only for OpenSSL builds. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -struct curl_certinfo { - int num_of_certs; /* number of certificates with information */ - struct curl_slist **certinfo; /* for each index in this array, there's a - linked list with textual information in the - format "name: value" */ -}; - -/* Information about the SSL library used and the respective internal SSL - handle, which can be used to obtain further information regarding the - connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ -struct curl_tlssessioninfo { - curl_sslbackend backend; - void *internals; -}; - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_SLIST 0x400000 -#define CURLINFO_PTR 0x400000 /* same as SLIST */ -#define CURLINFO_SOCKET 0x500000 -#define CURLINFO_OFF_T 0x600000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum { - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, - CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, - CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, - CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, - CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, - CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, - CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, - CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, - CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, - CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, - CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, - CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, - CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, - CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, - CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_PTR + 34, - CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, - CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, - CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, - CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, - CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, - CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, - CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, - CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, - CURLINFO_TLS_SESSION = CURLINFO_PTR + 43, - CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, - CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, - CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, - CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, - CURLINFO_PROTOCOL = CURLINFO_LONG + 48, - CURLINFO_SCHEME = CURLINFO_STRING + 49, - /* Fill in new entries below here! */ - - CURLINFO_LASTONE = 49 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum { - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */ -#define CURL_GLOBAL_WIN32 (1<<1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL -#define CURL_GLOBAL_ACK_EINTR (1<<2) - - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum { - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internally to say that - * the locking is just made to change the internal state of the share - * itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum { - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - - -typedef enum { - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* 4 out of memory */ - CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum { - CURLSHOPT_NONE, /* don't use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURL_EXTERN CURLSH *curl_share_init(void); -CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); -CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum { - CURLVERSION_FIRST, - CURLVERSION_SECOND, - CURLVERSION_THIRD, - CURLVERSION_FOURTH, - CURLVERSION_FIFTH, - CURLVERSION_LAST /* never actually use this */ -} CURLversion; - -/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by - basically all programs ever that want to get version information. It is - meant to be a built-in version number for what kind of struct the caller - expects. If the struct ever changes, we redefine the NOW to another enum - from above. */ -#define CURLVERSION_NOW CURLVERSION_FIFTH - -typedef struct { - CURLversion age; /* age of the returned struct */ - const char *version; /* LIBCURL_VERSION */ - unsigned int version_num; /* LIBCURL_VERSION_NUM */ - const char *host; /* OS/host/cpu/machine when configured */ - int features; /* bitmask, see defines below */ - const char *ssl_version; /* human readable string */ - long ssl_version_num; /* not used anymore, always 0 */ - const char *libz_version; /* human readable string */ - /* protocols is terminated by an entry with a NULL protoname */ - const char * const *protocols; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was added in CURLVERSION_THIRD */ - const char *libidn; - - /* These field were added in CURLVERSION_FOURTH */ - - /* Same as '_libiconv_version' if built with HAVE_ICONV */ - int iconv_ver_num; - - const char *libssh_version; /* human readable string */ - - /* These fields were added in CURLVERSION_FIFTH */ - - unsigned int brotli_ver_num; /* Numeric Brotli version - (MAJOR << 24) | (MINOR << 12) | PATCH */ - const char *brotli_version; /* human readable string. */ - -} curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported - (deprecated) */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported - (deprecated) */ -#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ -#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are - supported */ -#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ -#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ -#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ -#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper - is supported */ -#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ -#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ -#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ -#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ -#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used - for cookie domain verification */ -#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ -#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ -#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ - - /* - * NAME curl_version_info() - * - * DESCRIPTION - * - * This function returns a pointer to a static copy of the version info - * struct. See above. - */ -CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_easy_strerror(CURLcode); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_share_strerror(CURLSHcode); - -/* - * NAME curl_easy_pause() - * - * DESCRIPTION - * - * The curl_easy_pause function pauses or unpauses transfers. Select the new - * state by setting the bitmask, use the convenience defines below. - * - */ -CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); - -#define CURLPAUSE_RECV (1<<0) -#define CURLPAUSE_RECV_CONT (0) - -#define CURLPAUSE_SEND (1<<2) -#define CURLPAUSE_SEND_CONT (0) - -#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) -#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) - -#ifdef __cplusplus -} -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" - -/* the typechecker doesn't work in C++ (yet) */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ - !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) -#include "typecheck-gcc.h" -#else -#if defined(__STDC__) && (__STDC__ >= 1) -/* This preprocessor magic that replaces a call with the exact same call is - only done to make sure application authors pass exactly three arguments - to these functions. */ -#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) -#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) -#endif /* __STDC__ >= 1 */ -#endif /* gcc >= 4.3 && !__cplusplus */ - -#endif /* __CURL_CURL_H */ diff --git a/ext/curl-7.58.0/x64/include/curl/curlver.h b/ext/curl-7.58.0/x64/include/curl/curlver.h deleted file mode 100644 index 6d93cc11..00000000 --- a/ext/curl-7.58.0/x64/include/curl/curlver.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __CURL_CURLVER_H -#define __CURL_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, ." - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "7.58.0" - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 58 -#define LIBCURL_VERSION_PATCH 0 - -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparions by programs. The LIBCURL_VERSION_NUM define will - always follow this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal (using 8 bits each). All three numbers are always represented - using two digits. 1.2 would appear as "0x010200" while version 9.11.7 - appears as "0x090b07". - - This 6-digit (24 bits) hexadecimal number does not show pre-release number, - and it is always a greater number in a more recent release. It makes - comparisons with greater than and less than work. - - Note: This define is the full hex number and _does not_ use the - CURL_VERSION_BITS() macro since curl's own configure script greps for it - and needs it to contain the full number. -*/ -#define LIBCURL_VERSION_NUM 0x073a00 - -/* - * This is the date and time when the full source package was created. The - * timestamp is not stored in git, as the timestamp is properly set in the - * tarballs by the maketgz script. - * - * The format of the date follows this template: - * - * "2007-11-23" - */ -#define LIBCURL_TIMESTAMP "2018-01-24" - -#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) -#define CURL_AT_LEAST_VERSION(x,y,z) \ - (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) - -#endif /* __CURL_CURLVER_H */ diff --git a/ext/curl-7.58.0/x64/include/curl/easy.h b/ext/curl-7.58.0/x64/include/curl/easy.h deleted file mode 100644 index 752c5049..00000000 --- a/ext/curl-7.58.0/x64/include/curl/easy.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __CURL_EASY_H -#define __CURL_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN CURL *curl_easy_init(void); -CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); -CURL_EXTERN void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. The - * third argument MUST be a pointer to a long, a pointer to a char * or a - * pointer to a double (as the documentation describes elsewhere). The data - * pointed to will be filled in accordingly and can be relied upon only if the - * function returns CURLE_OK. This function is intended to get used *AFTER* a - * performed transfer, all results from this function are undefined until the - * transfer is completed. - */ -CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistent connections cannot - * be transferred. It is useful in multithreaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a CURL handle to the default values. This puts back the - * handle to the same state as it was in when it was just created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -CURL_EXTERN void curl_easy_reset(CURL *curl); - -/* - * NAME curl_easy_recv() - * - * DESCRIPTION - * - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, - size_t *n); - -/* - * NAME curl_easy_send() - * - * DESCRIPTION - * - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, - size_t buflen, size_t *n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ext/curl-7.58.0/x64/include/curl/mprintf.h b/ext/curl-7.58.0/x64/include/curl/mprintf.h deleted file mode 100644 index e20f546e..00000000 --- a/ext/curl-7.58.0/x64/include/curl/mprintf.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __CURL_MPRINTF_H -#define __CURL_MPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include -#include /* needed for FILE */ -#include "curl.h" /* for CURL_EXTERN */ - -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN int curl_mprintf(const char *format, ...); -CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); -CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); -CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, - const char *format, ...); -CURL_EXTERN int curl_mvprintf(const char *format, va_list args); -CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); -CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); -CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, - const char *format, va_list args); -CURL_EXTERN char *curl_maprintf(const char *format, ...); -CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); - -#ifdef __cplusplus -} -#endif - -#endif /* __CURL_MPRINTF_H */ diff --git a/ext/curl-7.58.0/x64/include/curl/multi.h b/ext/curl-7.58.0/x64/include/curl/multi.h deleted file mode 100644 index 911c91dd..00000000 --- a/ext/curl-7.58.0/x64/include/curl/multi.h +++ /dev/null @@ -1,439 +0,0 @@ -#ifndef __CURL_MULTI_H -#define __CURL_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* - This is an "external" header file. Don't give away any internals here! - - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ - -/* - * This header file should not really need to include "curl.h" since curl.h - * itself includes this file and we expect user applications to do #include - * without the need for especially including multi.h. - * - * For some reason we added this include here at one point, and rather than to - * break existing (wrongly written) libcurl applications, we leave it as-is - * but with this warning attached. - */ -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) -typedef struct Curl_multi CURLM; -#else -typedef void CURLM; -#endif - -typedef enum { - CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or - curl_multi_socket*() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ - CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ - CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was - attempted to get added - again */ - CURLM_LAST -} CURLMcode; - -/* just to make code nicer when using curl_multi_socket() you can now check - for CURLM_CALL_MULTI_SOCKET too in the same style it works for - curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ -#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM - -/* bitmask bits for CURLMOPT_PIPELINING */ -#define CURLPIPE_NOTHING 0L -#define CURLPIPE_HTTP1 1L -#define CURLPIPE_MULTIPLEX 2L - -typedef enum { - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg { - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* Based on poll(2) structure and values. - * We don't use pollfd and POLL* constants explicitly - * to cover platforms without poll(). */ -#define CURL_WAIT_POLLIN 0x0001 -#define CURL_WAIT_POLLPRI 0x0002 -#define CURL_WAIT_POLLOUT 0x0004 - -struct curl_waitfd { - curl_socket_t fd; - short events; - short revents; /* not supported yet */ -}; - -/* - * Name: curl_multi_init() - * - * Desc: inititalize multi-style curl usage - * - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURL_EXTERN CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - -/* - * Name: curl_multi_wait() - * - * Desc: Poll on all fds within a CURLM set as well as any - * additional fds passed to the function. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret); - - /* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there's data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called just in case. It returns - * the number of handles that still transfer data in the second - * argument's integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. - */ -CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, - int *running_handles); - - /* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles will be if this function is called - * in the middle of a transfer. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there's any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or just the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function will return a new struct each - * time, until a special "end of msgs" struct is returned as a signal - * that there is no more to get at this point. - * - * The data the returned pointer points to will not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic information. If more involved information is wanted, - * we will provide the particular "transfer handle" in that struct - * and that should/could/would be used in subsequent - * curl_easy_getinfo() calls (or similar). The point being that we - * must never expose complex structs to applications, as then we'll - * undoubtably get backwards compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, - int *msgs_in_queue); - -/* - * Name: curl_multi_strerror() - * - * Desc: The curl_multi_strerror function may be used to turn a CURLMcode - * value into the equivalent human readable error string. This is - * useful for printing meaningful error messages. - * - * Returns: A pointer to a zero-terminated error message. - */ -CURL_EXTERN const char *curl_multi_strerror(CURLMcode); - -/* - * Name: curl_multi_socket() and - * curl_multi_socket_all() - * - * Desc: An alternative version of curl_multi_perform() that allows the - * application to pass in one of the file descriptors that have been - * detected to have "action" on them and let libcurl perform. - * See man page for details. - */ -#define CURL_POLL_NONE 0 -#define CURL_POLL_IN 1 -#define CURL_POLL_OUT 2 -#define CURL_POLL_INOUT 3 -#define CURL_POLL_REMOVE 4 - -#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD - -#define CURL_CSELECT_IN 0x01 -#define CURL_CSELECT_OUT 0x02 -#define CURL_CSELECT_ERR 0x04 - -typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp); /* private socket - pointer */ -/* - * Name: curl_multi_timer_callback - * - * Desc: Called by libcurl whenever the library detects a change in the - * maximum number of milliseconds the app is allowed to wait before - * curl_multi_socket() or curl_multi_perform() must be called - * (to allow libcurl's timed events to take place). - * - * Returns: The callback should return zero. - */ -typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp); /* private callback - pointer */ - -CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, - curl_socket_t s, - int ev_bitmask, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, - int *running_handles); - -#ifndef CURL_ALLOW_OLD_MULTI_SOCKET -/* This macro below was added in 7.16.3 to push users who recompile to use - the new curl_multi_socket_action() instead of the old curl_multi_socket() -*/ -#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) -#endif - -/* - * Name: curl_multi_timeout() - * - * Desc: Returns the maximum number of milliseconds the app is allowed to - * wait before curl_multi_socket() or curl_multi_perform() must be - * called (to allow libcurl's timed events to take place). - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, - long *milliseconds); - -#undef CINIT /* re-using the same name as in curl.h */ - -#ifdef CURL_ISOCPP -#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLMOPT_/**/name = type + number -#endif - -typedef enum { - /* This is the socket callback function pointer */ - CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), - - /* This is the argument passed to the socket callback */ - CINIT(SOCKETDATA, OBJECTPOINT, 2), - - /* set to 1 to enable pipelining for this multi handle */ - CINIT(PIPELINING, LONG, 3), - - /* This is the timer callback function pointer */ - CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), - - /* This is the argument passed to the timer callback */ - CINIT(TIMERDATA, OBJECTPOINT, 5), - - /* maximum number of entries in the connection cache */ - CINIT(MAXCONNECTS, LONG, 6), - - /* maximum number of (pipelining) connections to one host */ - CINIT(MAX_HOST_CONNECTIONS, LONG, 7), - - /* maximum number of requests in a pipeline */ - CINIT(MAX_PIPELINE_LENGTH, LONG, 8), - - /* a connection with a content-length longer than this - will not be considered for pipelining */ - CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), - - /* a connection with a chunk length longer than this - will not be considered for pipelining */ - CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), - - /* a list of site names(+port) that are blacklisted from - pipelining */ - CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), - - /* a list of server types that are blacklisted from - pipelining */ - CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), - - /* maximum number of open connections in total */ - CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), - - /* This is the server push callback function pointer */ - CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), - - /* This is the argument passed to the server push callback */ - CINIT(PUSHDATA, OBJECTPOINT, 15), - - CURLMOPT_LASTENTRY /* the last unused */ -} CURLMoption; - - -/* - * Name: curl_multi_setopt() - * - * Desc: Sets options for the multi handle. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, - CURLMoption option, ...); - - -/* - * Name: curl_multi_assign() - * - * Desc: This function sets an association in the multi handle between the - * given socket and a private pointer of the application. This is - * (only) useful for curl_multi_socket uses. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, - curl_socket_t sockfd, void *sockp); - - -/* - * Name: curl_push_callback - * - * Desc: This callback gets called when a new stream is being pushed by the - * server. It approves or denies the new stream. - * - * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. - */ -#define CURL_PUSH_OK 0 -#define CURL_PUSH_DENY 1 - -struct curl_pushheaders; /* forward declaration only */ - -CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, - size_t num); -CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, - const char *name); - -typedef int (*curl_push_callback)(CURL *parent, - CURL *easy, - size_t num_headers, - struct curl_pushheaders *headers, - void *userp); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/ext/curl-7.58.0/x64/include/curl/stdcheaders.h b/ext/curl-7.58.0/x64/include/curl/stdcheaders.h deleted file mode 100644 index 027b6f42..00000000 --- a/ext/curl-7.58.0/x64/include/curl/stdcheaders.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __STDC_HEADERS_H -#define __STDC_HEADERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -size_t fread(void *, size_t, size_t, FILE *); -size_t fwrite(const void *, size_t, size_t, FILE *); - -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); - -#endif /* __STDC_HEADERS_H */ diff --git a/ext/curl-7.58.0/x64/include/curl/system.h b/ext/curl-7.58.0/x64/include/curl/system.h deleted file mode 100644 index 07bbd9ca..00000000 --- a/ext/curl-7.58.0/x64/include/curl/system.h +++ /dev/null @@ -1,473 +0,0 @@ -#ifndef __CURL_SYSTEM_H -#define __CURL_SYSTEM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Try to keep one section per platform, compiler and architecture, otherwise, - * if an existing section is reused for a different one and later on the - * original is adjusted, probably the piggybacking one can be adversely - * changed. - * - * In order to differentiate between platforms/compilers/architectures use - * only compiler built in predefined preprocessor symbols. - * - * curl_off_t - * ---------- - * - * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit - * wide signed integral data type. The width of this data type must remain - * constant and independent of any possible large file support settings. - * - * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit - * wide signed integral data type if there is no 64-bit type. - * - * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall - * only be violated if off_t is the only 64-bit data type available and the - * size of off_t is independent of large file support settings. Keep your - * build on the safe side avoiding an off_t gating. If you have a 64-bit - * off_t then take for sure that another 64-bit data type exists, dig deeper - * and you will find it. - * - */ - -#if defined(__DJGPP__) || defined(__GO32__) -# if defined(__DJGPP__) && (__DJGPP__ > 1) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__SALFORDC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__BORLANDC__) -# if (__BORLANDC__ < 0x520) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__TURBOC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__WATCOMC__) -# if defined(__386__) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__POCC__) -# if (__POCC__ < 280) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# elif defined(_MSC_VER) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__LCC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__SYMBIAN32__) -# if defined(__EABI__) /* Treat all ARM compilers equally */ -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__CW32__) -# pragma longlong on -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__VC32__) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__MWERKS__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(_WIN32_WCE) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__MINGW32__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_WS2TCPIP_H 1 - -#elif defined(__VMS) -# if defined(__VAX) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int - -#elif defined(__OS400__) -# if defined(__ILEC400__) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(__MVS__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_ILP32) -# elif defined(_LP64) -# endif -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(__370__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_ILP32) -# elif defined(_LP64) -# endif -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(TPF) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -#elif defined(__TINYC__) /* also known as tcc */ - -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#elif defined(__SUNPRO_C) /* Oracle Solaris Studio */ -# if !defined(__LP64) && (defined(__ILP32) || \ - defined(__i386) || defined(__sparcv8)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64) || \ - defined(__amd64) || defined(__sparcv9) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -/* ===================================== */ -/* KEEP MSVC THE PENULTIMATE ENTRY */ -/* ===================================== */ - -#elif defined(_MSC_VER) -# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int - -/* ===================================== */ -/* KEEP GENERIC GCC THE LAST ENTRY */ -/* ===================================== */ - -#elif defined(__GNUC__) -# if !defined(__LP64__) && \ - (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \ - defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ - defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ - defined(__XTENSA__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L)) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64__) || \ - defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ - (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ - (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#else -/* generic "safe guess" on old 32 bit style */ -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -#endif - -#ifdef _AIX -/* AIX needs */ -#define CURL_PULL_SYS_POLL_H -#endif - - -/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */ -/* ws2tcpip.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_WS2TCPIP_H -# include -# include -# include -#endif - -/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ -/* sys/types.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ -/* sys/socket.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */ -/* sys/poll.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_POLL_H -# include -#endif - -/* Data type definition of curl_socklen_t. */ -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T - typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; -#endif - -/* Data type definition of curl_off_t. */ - -#ifdef CURL_TYPEOF_CURL_OFF_T - typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; -#endif - -/* - * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow - * these to be visible and exported by the external libcurl interface API, - * while also making them visible to the library internals, simply including - * curl_setup.h, without actually needing to include curl.h internally. - * If some day this section would grow big enough, all this should be moved - * to its own header file. - */ - -/* - * Figure out if we can use the ## preprocessor operator, which is supported - * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ - * or __cplusplus so we need to carefully check for them too. - */ - -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ - defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ - defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ - defined(__ILEC400__) - /* This compiler is believed to have an ISO compatible preprocessor */ -#define CURL_ISOCPP -#else - /* This compiler is believed NOT to have an ISO compatible preprocessor */ -#undef CURL_ISOCPP -#endif - -/* - * Macros for minimum-width signed and unsigned curl_off_t integer constants. - */ - -#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) -# define __CURL_OFF_T_C_HLPR2(x) x -# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) -#else -# ifdef CURL_ISOCPP -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix -# else -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix -# endif -# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) -#endif - -#endif /* __CURL_SYSTEM_H */ diff --git a/ext/curl-7.58.0/x64/include/curl/typecheck-gcc.h b/ext/curl-7.58.0/x64/include/curl/typecheck-gcc.h deleted file mode 100644 index 10c74c76..00000000 --- a/ext/curl-7.58.0/x64/include/curl/typecheck-gcc.h +++ /dev/null @@ -1,683 +0,0 @@ -#ifndef __CURL_TYPECHECK_GCC_H -#define __CURL_TYPECHECK_GCC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* wraps curl_easy_setopt() with typechecking */ - -/* To add a new kind of warning, add an - * if(_curl_is_sometype_option(_curl_opt)) - * if(!_curl_is_sometype(value)) - * _curl_easy_setopt_err_sometype(); - * block and define _curl_is_sometype_option, _curl_is_sometype and - * _curl_easy_setopt_err_sometype below - * - * NOTE: We use two nested 'if' statements here instead of the && operator, in - * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x - * when compiling with -Wlogical-op. - * - * To add an option that uses the same type as an existing option, you'll just - * need to extend the appropriate _curl_*_option macro - */ -#define curl_easy_setopt(handle, option, value) \ -__extension__ ({ \ - __typeof__(option) _curl_opt = option; \ - if(__builtin_constant_p(_curl_opt)) { \ - if(_curl_is_long_option(_curl_opt)) \ - if(!_curl_is_long(value)) \ - _curl_easy_setopt_err_long(); \ - if(_curl_is_off_t_option(_curl_opt)) \ - if(!_curl_is_off_t(value)) \ - _curl_easy_setopt_err_curl_off_t(); \ - if(_curl_is_string_option(_curl_opt)) \ - if(!_curl_is_string(value)) \ - _curl_easy_setopt_err_string(); \ - if(_curl_is_write_cb_option(_curl_opt)) \ - if(!_curl_is_write_cb(value)) \ - _curl_easy_setopt_err_write_callback(); \ - if((_curl_opt) == CURLOPT_READFUNCTION) \ - if(!_curl_is_read_cb(value)) \ - _curl_easy_setopt_err_read_cb(); \ - if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ - if(!_curl_is_ioctl_cb(value)) \ - _curl_easy_setopt_err_ioctl_cb(); \ - if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ - if(!_curl_is_sockopt_cb(value)) \ - _curl_easy_setopt_err_sockopt_cb(); \ - if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ - if(!_curl_is_opensocket_cb(value)) \ - _curl_easy_setopt_err_opensocket_cb(); \ - if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ - if(!_curl_is_progress_cb(value)) \ - _curl_easy_setopt_err_progress_cb(); \ - if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ - if(!_curl_is_debug_cb(value)) \ - _curl_easy_setopt_err_debug_cb(); \ - if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ - if(!_curl_is_ssl_ctx_cb(value)) \ - _curl_easy_setopt_err_ssl_ctx_cb(); \ - if(_curl_is_conv_cb_option(_curl_opt)) \ - if(!_curl_is_conv_cb(value)) \ - _curl_easy_setopt_err_conv_cb(); \ - if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ - if(!_curl_is_seek_cb(value)) \ - _curl_easy_setopt_err_seek_cb(); \ - if(_curl_is_cb_data_option(_curl_opt)) \ - if(!_curl_is_cb_data(value)) \ - _curl_easy_setopt_err_cb_data(); \ - if((_curl_opt) == CURLOPT_ERRORBUFFER) \ - if(!_curl_is_error_buffer(value)) \ - _curl_easy_setopt_err_error_buffer(); \ - if((_curl_opt) == CURLOPT_STDERR) \ - if(!_curl_is_FILE(value)) \ - _curl_easy_setopt_err_FILE(); \ - if(_curl_is_postfields_option(_curl_opt)) \ - if(!_curl_is_postfields(value)) \ - _curl_easy_setopt_err_postfields(); \ - if((_curl_opt) == CURLOPT_HTTPPOST) \ - if(!_curl_is_arr((value), struct curl_httppost)) \ - _curl_easy_setopt_err_curl_httpost(); \ - if((_curl_opt) == CURLOPT_MIMEPOST) \ - if(!_curl_is_ptr((value), curl_mime)) \ - _curl_easy_setopt_err_curl_mimepost(); \ - if(_curl_is_slist_option(_curl_opt)) \ - if(!_curl_is_arr((value), struct curl_slist)) \ - _curl_easy_setopt_err_curl_slist(); \ - if((_curl_opt) == CURLOPT_SHARE) \ - if(!_curl_is_ptr((value), CURLSH)) \ - _curl_easy_setopt_err_CURLSH(); \ - } \ - curl_easy_setopt(handle, _curl_opt, value); \ -}) - -/* wraps curl_easy_getinfo() with typechecking */ -/* FIXME: don't allow const pointers */ -#define curl_easy_getinfo(handle, info, arg) \ -__extension__ ({ \ - __typeof__(info) _curl_info = info; \ - if(__builtin_constant_p(_curl_info)) { \ - if(_curl_is_string_info(_curl_info)) \ - if(!_curl_is_arr((arg), char *)) \ - _curl_easy_getinfo_err_string(); \ - if(_curl_is_long_info(_curl_info)) \ - if(!_curl_is_arr((arg), long)) \ - _curl_easy_getinfo_err_long(); \ - if(_curl_is_double_info(_curl_info)) \ - if(!_curl_is_arr((arg), double)) \ - _curl_easy_getinfo_err_double(); \ - if(_curl_is_slist_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_slist *)) \ - _curl_easy_getinfo_err_curl_slist(); \ - if(_curl_is_tlssessioninfo_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_tlssessioninfo *)) \ - _curl_easy_getinfo_err_curl_tlssesssioninfo(); \ - if(_curl_is_certinfo_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_certinfo *)) \ - _curl_easy_getinfo_err_curl_certinfo(); \ - if(_curl_is_socket_info(_curl_info)) \ - if(!_curl_is_arr((arg), curl_socket_t)) \ - _curl_easy_getinfo_err_curl_socket(); \ - if(_curl_is_off_t_info(_curl_info)) \ - if(!_curl_is_arr((arg), curl_off_t)) \ - _curl_easy_getinfo_err_curl_off_t(); \ - } \ - curl_easy_getinfo(handle, _curl_info, arg); \ -}) - -/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), - * for now just make sure that the functions are called with three - * arguments - */ -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) - - -/* the actual warnings, triggered by calling the _curl_easy_setopt_err* - * functions */ - -/* To define a new warning, use _CURL_WARNING(identifier, "message") */ -#define _CURL_WARNING(id, message) \ - static void __attribute__((__warning__(message))) \ - __attribute__((__unused__)) __attribute__((__noinline__)) \ - id(void) { __asm__(""); } - -_CURL_WARNING(_curl_easy_setopt_err_long, - "curl_easy_setopt expects a long argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, - "curl_easy_setopt expects a curl_off_t argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_string, - "curl_easy_setopt expects a " - "string ('char *' or char[]) argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_write_callback, - "curl_easy_setopt expects a curl_write_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_read_cb, - "curl_easy_setopt expects a curl_read_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, - "curl_easy_setopt expects a curl_ioctl_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, - "curl_easy_setopt expects a curl_sockopt_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, - "curl_easy_setopt expects a " - "curl_opensocket_callback argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_progress_cb, - "curl_easy_setopt expects a curl_progress_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_debug_cb, - "curl_easy_setopt expects a curl_debug_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, - "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_conv_cb, - "curl_easy_setopt expects a curl_conv_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_seek_cb, - "curl_easy_setopt expects a curl_seek_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_cb_data, - "curl_easy_setopt expects a " - "private data pointer as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_error_buffer, - "curl_easy_setopt expects a " - "char buffer of CURL_ERROR_SIZE as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_FILE, - "curl_easy_setopt expects a 'FILE *' argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_postfields, - "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, - "curl_easy_setopt expects a 'struct curl_httppost *' " - "argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost, - "curl_easy_setopt expects a 'curl_mime *' " - "argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_slist, - "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_CURLSH, - "curl_easy_setopt expects a CURLSH* argument for this option") - -_CURL_WARNING(_curl_easy_getinfo_err_string, - "curl_easy_getinfo expects a pointer to 'char *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_long, - "curl_easy_getinfo expects a pointer to long for this info") -_CURL_WARNING(_curl_easy_getinfo_err_double, - "curl_easy_getinfo expects a pointer to double for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, - "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo, - "curl_easy_getinfo expects a pointer to " - "'struct curl_tlssessioninfo *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo, - "curl_easy_getinfo expects a pointer to " - "'struct curl_certinfo *' for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_socket, - "curl_easy_getinfo expects a pointer to curl_socket_t for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t, - "curl_easy_getinfo expects a pointer to curl_off_t for this info") - -/* groups of curl_easy_setops options that take the same type of argument */ - -/* To add a new option to one of the groups, just add - * (option) == CURLOPT_SOMETHING - * to the or-expression. If the option takes a long or curl_off_t, you don't - * have to do anything - */ - -/* evaluates to true if option takes a long argument */ -#define _curl_is_long_option(option) \ - (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) - -#define _curl_is_off_t_option(option) \ - ((option) > CURLOPTTYPE_OFF_T) - -/* evaluates to true if option takes a char* argument */ -#define _curl_is_string_option(option) \ - ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ - (option) == CURLOPT_ACCEPT_ENCODING || \ - (option) == CURLOPT_CAINFO || \ - (option) == CURLOPT_CAPATH || \ - (option) == CURLOPT_COOKIE || \ - (option) == CURLOPT_COOKIEFILE || \ - (option) == CURLOPT_COOKIEJAR || \ - (option) == CURLOPT_COOKIELIST || \ - (option) == CURLOPT_CRLFILE || \ - (option) == CURLOPT_CUSTOMREQUEST || \ - (option) == CURLOPT_DEFAULT_PROTOCOL || \ - (option) == CURLOPT_DNS_INTERFACE || \ - (option) == CURLOPT_DNS_LOCAL_IP4 || \ - (option) == CURLOPT_DNS_LOCAL_IP6 || \ - (option) == CURLOPT_DNS_SERVERS || \ - (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_FTPPORT || \ - (option) == CURLOPT_FTP_ACCOUNT || \ - (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ - (option) == CURLOPT_INTERFACE || \ - (option) == CURLOPT_ISSUERCERT || \ - (option) == CURLOPT_KEYPASSWD || \ - (option) == CURLOPT_KRBLEVEL || \ - (option) == CURLOPT_LOGIN_OPTIONS || \ - (option) == CURLOPT_MAIL_AUTH || \ - (option) == CURLOPT_MAIL_FROM || \ - (option) == CURLOPT_NETRC_FILE || \ - (option) == CURLOPT_NOPROXY || \ - (option) == CURLOPT_PASSWORD || \ - (option) == CURLOPT_PINNEDPUBLICKEY || \ - (option) == CURLOPT_PRE_PROXY || \ - (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYUSERPWD || \ - (option) == CURLOPT_PROXY_CAINFO || \ - (option) == CURLOPT_PROXY_CAPATH || \ - (option) == CURLOPT_PROXY_CRLFILE || \ - (option) == CURLOPT_PROXY_KEYPASSWD || \ - (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \ - (option) == CURLOPT_PROXY_SERVICE_NAME || \ - (option) == CURLOPT_PROXY_SSLCERT || \ - (option) == CURLOPT_PROXY_SSLCERTTYPE || \ - (option) == CURLOPT_PROXY_SSLKEY || \ - (option) == CURLOPT_PROXY_SSLKEYTYPE || \ - (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ - (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \ - (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \ - (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \ - (option) == CURLOPT_RANDOM_FILE || \ - (option) == CURLOPT_RANGE || \ - (option) == CURLOPT_REFERER || \ - (option) == CURLOPT_RTSP_SESSION_ID || \ - (option) == CURLOPT_RTSP_STREAM_URI || \ - (option) == CURLOPT_RTSP_TRANSPORT || \ - (option) == CURLOPT_SERVICE_NAME || \ - (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ - (option) == CURLOPT_SSH_KNOWNHOSTS || \ - (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ - (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ - (option) == CURLOPT_SSLCERT || \ - (option) == CURLOPT_SSLCERTTYPE || \ - (option) == CURLOPT_SSLENGINE || \ - (option) == CURLOPT_SSLKEY || \ - (option) == CURLOPT_SSLKEYTYPE || \ - (option) == CURLOPT_SSL_CIPHER_LIST || \ - (option) == CURLOPT_TLSAUTH_PASSWORD || \ - (option) == CURLOPT_TLSAUTH_TYPE || \ - (option) == CURLOPT_TLSAUTH_USERNAME || \ - (option) == CURLOPT_UNIX_SOCKET_PATH || \ - (option) == CURLOPT_URL || \ - (option) == CURLOPT_USERAGENT || \ - (option) == CURLOPT_USERNAME || \ - (option) == CURLOPT_USERPWD || \ - (option) == CURLOPT_XOAUTH2_BEARER || \ - 0) - -/* evaluates to true if option takes a curl_write_callback argument */ -#define _curl_is_write_cb_option(option) \ - ((option) == CURLOPT_HEADERFUNCTION || \ - (option) == CURLOPT_WRITEFUNCTION) - -/* evaluates to true if option takes a curl_conv_callback argument */ -#define _curl_is_conv_cb_option(option) \ - ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) - -/* evaluates to true if option takes a data argument to pass to a callback */ -#define _curl_is_cb_data_option(option) \ - ((option) == CURLOPT_CHUNK_DATA || \ - (option) == CURLOPT_CLOSESOCKETDATA || \ - (option) == CURLOPT_DEBUGDATA || \ - (option) == CURLOPT_FNMATCH_DATA || \ - (option) == CURLOPT_HEADERDATA || \ - (option) == CURLOPT_INTERLEAVEDATA || \ - (option) == CURLOPT_IOCTLDATA || \ - (option) == CURLOPT_OPENSOCKETDATA || \ - (option) == CURLOPT_PRIVATE || \ - (option) == CURLOPT_PROGRESSDATA || \ - (option) == CURLOPT_READDATA || \ - (option) == CURLOPT_SEEKDATA || \ - (option) == CURLOPT_SOCKOPTDATA || \ - (option) == CURLOPT_SSH_KEYDATA || \ - (option) == CURLOPT_SSL_CTX_DATA || \ - (option) == CURLOPT_WRITEDATA || \ - 0) - -/* evaluates to true if option takes a POST data argument (void* or char*) */ -#define _curl_is_postfields_option(option) \ - ((option) == CURLOPT_POSTFIELDS || \ - (option) == CURLOPT_COPYPOSTFIELDS || \ - 0) - -/* evaluates to true if option takes a struct curl_slist * argument */ -#define _curl_is_slist_option(option) \ - ((option) == CURLOPT_HTTP200ALIASES || \ - (option) == CURLOPT_HTTPHEADER || \ - (option) == CURLOPT_MAIL_RCPT || \ - (option) == CURLOPT_POSTQUOTE || \ - (option) == CURLOPT_PREQUOTE || \ - (option) == CURLOPT_PROXYHEADER || \ - (option) == CURLOPT_QUOTE || \ - (option) == CURLOPT_RESOLVE || \ - (option) == CURLOPT_TELNETOPTIONS || \ - 0) - -/* groups of curl_easy_getinfo infos that take the same type of argument */ - -/* evaluates to true if info expects a pointer to char * argument */ -#define _curl_is_string_info(info) \ - (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) - -/* evaluates to true if info expects a pointer to long argument */ -#define _curl_is_long_info(info) \ - (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) - -/* evaluates to true if info expects a pointer to double argument */ -#define _curl_is_double_info(info) \ - (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) - -/* true if info expects a pointer to struct curl_slist * argument */ -#define _curl_is_slist_info(info) \ - (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST)) - -/* true if info expects a pointer to struct curl_tlssessioninfo * argument */ -#define _curl_is_tlssessioninfo_info(info) \ - (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION)) - -/* true if info expects a pointer to struct curl_certinfo * argument */ -#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO) - -/* true if info expects a pointer to struct curl_socket_t argument */ -#define _curl_is_socket_info(info) \ - (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T) - -/* true if info expects a pointer to curl_off_t argument */ -#define _curl_is_off_t_info(info) \ - (CURLINFO_OFF_T < (info)) - - -/* typecheck helpers -- check whether given expression has requested type*/ - -/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, - * otherwise define a new macro. Search for __builtin_types_compatible_p - * in the GCC manual. - * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is - * the actual expression passed to the curl_easy_setopt macro. This - * means that you can only apply the sizeof and __typeof__ operators, no - * == or whatsoever. - */ - -/* XXX: should evaluate to true iff expr is a pointer */ -#define _curl_is_any_ptr(expr) \ - (sizeof(expr) == sizeof(void *)) - -/* evaluates to true if expr is NULL */ -/* XXX: must not evaluate expr, so this check is not accurate */ -#define _curl_is_NULL(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) - -/* evaluates to true if expr is type*, const type* or NULL */ -#define _curl_is_ptr(expr, type) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type *) || \ - __builtin_types_compatible_p(__typeof__(expr), const type *)) - -/* evaluates to true if expr is one of type[], type*, NULL or const type* */ -#define _curl_is_arr(expr, type) \ - (_curl_is_ptr((expr), type) || \ - __builtin_types_compatible_p(__typeof__(expr), type [])) - -/* evaluates to true if expr is a string */ -#define _curl_is_string(expr) \ - (_curl_is_arr((expr), char) || \ - _curl_is_arr((expr), signed char) || \ - _curl_is_arr((expr), unsigned char)) - -/* evaluates to true if expr is a long (no matter the signedness) - * XXX: for now, int is also accepted (and therefore short and char, which - * are promoted to int when passed to a variadic function) */ -#define _curl_is_long(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), long) || \ - __builtin_types_compatible_p(__typeof__(expr), signed long) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ - __builtin_types_compatible_p(__typeof__(expr), int) || \ - __builtin_types_compatible_p(__typeof__(expr), signed int) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ - __builtin_types_compatible_p(__typeof__(expr), short) || \ - __builtin_types_compatible_p(__typeof__(expr), signed short) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ - __builtin_types_compatible_p(__typeof__(expr), char) || \ - __builtin_types_compatible_p(__typeof__(expr), signed char) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned char)) - -/* evaluates to true if expr is of type curl_off_t */ -#define _curl_is_off_t(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) - -/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ -/* XXX: also check size of an char[] array? */ -#define _curl_is_error_buffer(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), char *) || \ - __builtin_types_compatible_p(__typeof__(expr), char[])) - -/* evaluates to true if expr is of type (const) void* or (const) FILE* */ -#if 0 -#define _curl_is_cb_data(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_ptr((expr), FILE)) -#else /* be less strict */ -#define _curl_is_cb_data(expr) \ - _curl_is_any_ptr(expr) -#endif - -/* evaluates to true if expr is of type FILE* */ -#define _curl_is_FILE(expr) \ - (_curl_is_NULL(expr) || \ - (__builtin_types_compatible_p(__typeof__(expr), FILE *))) - -/* evaluates to true if expr can be passed as POST data (void* or char*) */ -#define _curl_is_postfields(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_arr((expr), char)) - -/* FIXME: the whole callback checking is messy... - * The idea is to tolerate char vs. void and const vs. not const - * pointers in arguments at least - */ -/* helper: __builtin_types_compatible_p distinguishes between functions and - * function pointers, hide it */ -#define _curl_callback_compatible(func, type) \ - (__builtin_types_compatible_p(__typeof__(func), type) || \ - __builtin_types_compatible_p(__typeof__(func) *, type)) - -/* evaluates to true if expr is of type curl_read_callback or "similar" */ -#define _curl_is_read_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), __typeof__(fread) *) || \ - _curl_callback_compatible((expr), curl_read_callback) || \ - _curl_callback_compatible((expr), _curl_read_callback1) || \ - _curl_callback_compatible((expr), _curl_read_callback2) || \ - _curl_callback_compatible((expr), _curl_read_callback3) || \ - _curl_callback_compatible((expr), _curl_read_callback4) || \ - _curl_callback_compatible((expr), _curl_read_callback5) || \ - _curl_callback_compatible((expr), _curl_read_callback6)) -typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *); -typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *); -typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *); -typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *); -typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *); -typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_write_callback or "similar" */ -#define _curl_is_write_cb(expr) \ - (_curl_is_read_cb(expr) || \ - _curl_callback_compatible((expr), __typeof__(fwrite) *) || \ - _curl_callback_compatible((expr), curl_write_callback) || \ - _curl_callback_compatible((expr), _curl_write_callback1) || \ - _curl_callback_compatible((expr), _curl_write_callback2) || \ - _curl_callback_compatible((expr), _curl_write_callback3) || \ - _curl_callback_compatible((expr), _curl_write_callback4) || \ - _curl_callback_compatible((expr), _curl_write_callback5) || \ - _curl_callback_compatible((expr), _curl_write_callback6)) -typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *); -typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t, - const void *); -typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *); -typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *); -typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t, - const void *); -typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ -#define _curl_is_ioctl_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_ioctl_callback) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback4)) -typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *); -typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *); -typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *); -typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *); - -/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ -#define _curl_is_sockopt_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_sockopt_callback) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback2)) -typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); -typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t, - curlsocktype); - -/* evaluates to true if expr is of type curl_opensocket_callback or - "similar" */ -#define _curl_is_opensocket_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_opensocket_callback) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback4)) -typedef curl_socket_t (*_curl_opensocket_callback1) - (void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (*_curl_opensocket_callback2) - (void *, curlsocktype, const struct curl_sockaddr *); -typedef curl_socket_t (*_curl_opensocket_callback3) - (const void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (*_curl_opensocket_callback4) - (const void *, curlsocktype, const struct curl_sockaddr *); - -/* evaluates to true if expr is of type curl_progress_callback or "similar" */ -#define _curl_is_progress_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_progress_callback) || \ - _curl_callback_compatible((expr), _curl_progress_callback1) || \ - _curl_callback_compatible((expr), _curl_progress_callback2)) -typedef int (*_curl_progress_callback1)(void *, - double, double, double, double); -typedef int (*_curl_progress_callback2)(const void *, - double, double, double, double); - -/* evaluates to true if expr is of type curl_debug_callback or "similar" */ -#define _curl_is_debug_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_debug_callback) || \ - _curl_callback_compatible((expr), _curl_debug_callback1) || \ - _curl_callback_compatible((expr), _curl_debug_callback2) || \ - _curl_callback_compatible((expr), _curl_debug_callback3) || \ - _curl_callback_compatible((expr), _curl_debug_callback4) || \ - _curl_callback_compatible((expr), _curl_debug_callback5) || \ - _curl_callback_compatible((expr), _curl_debug_callback6) || \ - _curl_callback_compatible((expr), _curl_debug_callback7) || \ - _curl_callback_compatible((expr), _curl_debug_callback8)) -typedef int (*_curl_debug_callback1) (CURL *, - curl_infotype, char *, size_t, void *); -typedef int (*_curl_debug_callback2) (CURL *, - curl_infotype, char *, size_t, const void *); -typedef int (*_curl_debug_callback3) (CURL *, - curl_infotype, const char *, size_t, void *); -typedef int (*_curl_debug_callback4) (CURL *, - curl_infotype, const char *, size_t, const void *); -typedef int (*_curl_debug_callback5) (CURL *, - curl_infotype, unsigned char *, size_t, void *); -typedef int (*_curl_debug_callback6) (CURL *, - curl_infotype, unsigned char *, size_t, const void *); -typedef int (*_curl_debug_callback7) (CURL *, - curl_infotype, const unsigned char *, size_t, void *); -typedef int (*_curl_debug_callback8) (CURL *, - curl_infotype, const unsigned char *, size_t, const void *); - -/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ -/* this is getting even messier... */ -#define _curl_is_ssl_ctx_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_ssl_ctx_callback) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) -typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *); -typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *); -typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *); -typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *, - const void *); -#ifdef HEADER_SSL_H -/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX - * this will of course break if we're included before OpenSSL headers... - */ -typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); -typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); -typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); -typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, - const void *); -#else -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; -#endif - -/* evaluates to true if expr is of type curl_conv_callback or "similar" */ -#define _curl_is_conv_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_conv_callback) || \ - _curl_callback_compatible((expr), _curl_conv_callback1) || \ - _curl_callback_compatible((expr), _curl_conv_callback2) || \ - _curl_callback_compatible((expr), _curl_conv_callback3) || \ - _curl_callback_compatible((expr), _curl_conv_callback4)) -typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); -typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); -typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); -typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); - -/* evaluates to true if expr is of type curl_seek_callback or "similar" */ -#define _curl_is_seek_cb(expr) \ - (_curl_is_NULL(expr) || \ - _curl_callback_compatible((expr), curl_seek_callback) || \ - _curl_callback_compatible((expr), _curl_seek_callback1) || \ - _curl_callback_compatible((expr), _curl_seek_callback2)) -typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); -typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); - - -#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/ext/curl-7.58.0/x64/lib/libcurl_a.lib b/ext/curl-7.58.0/x64/lib/libcurl_a.lib deleted file mode 100644 index 7efe65b1..00000000 Binary files a/ext/curl-7.58.0/x64/lib/libcurl_a.lib and /dev/null differ diff --git a/ext/curl-7.58.0/x64/lib/libcurl_a_debug.lib b/ext/curl-7.58.0/x64/lib/libcurl_a_debug.lib deleted file mode 100644 index 867964b2..00000000 Binary files a/ext/curl-7.58.0/x64/lib/libcurl_a_debug.lib and /dev/null differ diff --git a/ext/ed25519-amd64-asm/batch.c b/ext/ed25519-amd64-asm/batch.c deleted file mode 100644 index 955392ea..00000000 --- a/ext/ed25519-amd64-asm/batch.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "crypto_sign.h" - -#include "crypto_verify_32.h" -#include "crypto_hash_sha512.h" -#include "randombytes.h" - -#include "ge25519.h" -#include "hram.h" - -#define MAXBATCH 64 - -int crypto_sign_open_batch( - unsigned char* const m[],unsigned long long mlen[], - unsigned char* const sm[],const unsigned long long smlen[], - unsigned char* const pk[], - unsigned long long num - ) -{ - int ret = 0; - unsigned long long i, j; - shortsc25519 r[MAXBATCH]; - sc25519 scalars[2*MAXBATCH+1]; - ge25519 points[2*MAXBATCH+1]; - unsigned char hram[crypto_hash_sha512_BYTES]; - unsigned long long batchsize; - - for (i = 0;i < num;++i) mlen[i] = -1; - - while (num >= 3) { - batchsize = num; - if (batchsize > MAXBATCH) batchsize = MAXBATCH; - - for (i = 0;i < batchsize;++i) - if (smlen[i] < 64) goto fallback; - - randombytes((unsigned char*)r,sizeof(shortsc25519) * batchsize); - - /* Computing scalars[0] = ((r1s1 + r2s2 + ...)) */ - for(i=0;icaller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: tp_stack = tp -# asm 1: movq tp_stack=stack64#8 -# asm 2: movq tp_stack=56(%rsp) -movq %rdi,56(%rsp) - -# qhasm: pos *= 768 -# asm 1: imulq $768,pos=int64#1 -# asm 2: imulq $768,pos=%rdi -imulq $768,%rsi,%rdi - -# qhasm: mask = b -# asm 1: mov mask=int64#2 -# asm 2: mov mask=%rsi -mov %rdx,%rsi - -# qhasm: (int64) mask >>= 7 -# asm 1: sar $7,u=int64#5 -# asm 2: mov u=%r8 -mov %rdx,%r8 - -# qhasm: u += mask -# asm 1: add tysubx0=int64#2 -# asm 2: mov $1,>tysubx0=%rsi -mov $1,%rsi - -# qhasm: tysubx1 = 0 -# asm 1: mov $0,>tysubx1=int64#6 -# asm 2: mov $0,>tysubx1=%r9 -mov $0,%r9 - -# qhasm: tysubx2 = 0 -# asm 1: mov $0,>tysubx2=int64#7 -# asm 2: mov $0,>tysubx2=%rax -mov $0,%rax - -# qhasm: tysubx3 = 0 -# asm 1: mov $0,>tysubx3=int64#8 -# asm 2: mov $0,>tysubx3=%r10 -mov $0,%r10 - -# qhasm: txaddy0 = 1 -# asm 1: mov $1,>txaddy0=int64#9 -# asm 2: mov $1,>txaddy0=%r11 -mov $1,%r11 - -# qhasm: txaddy1 = 0 -# asm 1: mov $0,>txaddy1=int64#10 -# asm 2: mov $0,>txaddy1=%r12 -mov $0,%r12 - -# qhasm: txaddy2 = 0 -# asm 1: mov $0,>txaddy2=int64#11 -# asm 2: mov $0,>txaddy2=%r13 -mov $0,%r13 - -# qhasm: txaddy3 = 0 -# asm 1: mov $0,>txaddy3=int64#12 -# asm 2: mov $0,>txaddy3=%r14 -mov $0,%r14 - -# qhasm: =? u - 1 -# asm 1: cmp $1,t=int64#13 -# asm 2: movq 0(t=%r15 -movq 0(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 8(t=%r15 -movq 8(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 16(t=%r15 -movq 16(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 24(t=%r15 -movq 24(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 32(t=%r15 -movq 32(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 40(t=%r15 -movq 40(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 48(t=%r15 -movq 48(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 56(t=%r15 -movq 56(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 96(t=%r15 -movq 96(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 104(t=%r15 -movq 104(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 112(t=%r15 -movq 112(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 120(t=%r15 -movq 120(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 128(t=%r15 -movq 128(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 136(t=%r15 -movq 136(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 144(t=%r15 -movq 144(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 152(t=%r15 -movq 152(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 192(t=%r15 -movq 192(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 200(t=%r15 -movq 200(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 208(t=%r15 -movq 208(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 216(t=%r15 -movq 216(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 224(t=%r15 -movq 224(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 232(t=%r15 -movq 232(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 240(t=%r15 -movq 240(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 248(t=%r15 -movq 248(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 288(t=%r15 -movq 288(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 296(t=%r15 -movq 296(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 304(t=%r15 -movq 304(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 312(t=%r15 -movq 312(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 320(t=%r15 -movq 320(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 328(t=%r15 -movq 328(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 336(t=%r15 -movq 336(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 344(t=%r15 -movq 344(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 384(t=%r15 -movq 384(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 392(t=%r15 -movq 392(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 400(t=%r15 -movq 400(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 408(t=%r15 -movq 408(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 416(t=%r15 -movq 416(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 424(t=%r15 -movq 424(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 432(t=%r15 -movq 432(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 440(t=%r15 -movq 440(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 480(t=%r15 -movq 480(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 488(t=%r15 -movq 488(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 496(t=%r15 -movq 496(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 504(t=%r15 -movq 504(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 512(t=%r15 -movq 512(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 520(t=%r15 -movq 520(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 528(t=%r15 -movq 528(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 536(t=%r15 -movq 536(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 576(t=%r15 -movq 576(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 584(t=%r15 -movq 584(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 592(t=%r15 -movq 592(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 600(t=%r15 -movq 600(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 608(t=%r15 -movq 608(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 616(t=%r15 -movq 616(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 624(t=%r15 -movq 624(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 632(t=%r15 -movq 632(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 672(t=%r15 -movq 672(%rcx,%rdi),%r15 - -# qhasm: tysubx0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 680(t=%r15 -movq 680(%rcx,%rdi),%r15 - -# qhasm: tysubx1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 688(t=%r15 -movq 688(%rcx,%rdi),%r15 - -# qhasm: tysubx2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 696(t=%r15 -movq 696(%rcx,%rdi),%r15 - -# qhasm: tysubx3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 704(t=%r15 -movq 704(%rcx,%rdi),%r15 - -# qhasm: txaddy0 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 712(t=%r15 -movq 712(%rcx,%rdi),%r15 - -# qhasm: txaddy1 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 720(t=%r15 -movq 720(%rcx,%rdi),%r15 - -# qhasm: txaddy2 = t if = -# asm 1: cmove t=int64#13 -# asm 2: movq 728(t=%r15 -movq 728(%rcx,%rdi),%r15 - -# qhasm: txaddy3 = t if = -# asm 1: cmove t=int64#13 -# asm 2: mov t=%r15 -mov %rsi,%r15 - -# qhasm: tysubx0 = txaddy0 if signed< -# asm 1: cmovl t=int64#13 -# asm 2: mov t=%r15 -mov %r9,%r15 - -# qhasm: tysubx1 = txaddy1 if signed< -# asm 1: cmovl t=int64#13 -# asm 2: mov t=%r15 -mov %rax,%r15 - -# qhasm: tysubx2 = txaddy2 if signed< -# asm 1: cmovl t=int64#13 -# asm 2: mov t=%r15 -mov %r10,%r15 - -# qhasm: tysubx3 = txaddy3 if signed< -# asm 1: cmovl tp=int64#13 -# asm 2: movq tp=%r15 -movq 56(%rsp),%r15 - -# qhasm: *(uint64 *)(tp + 0) = tysubx0 -# asm 1: movq tt2d0=int64#2 -# asm 2: mov $0,>tt2d0=%rsi -mov $0,%rsi - -# qhasm: tt2d1 = 0 -# asm 1: mov $0,>tt2d1=int64#6 -# asm 2: mov $0,>tt2d1=%r9 -mov $0,%r9 - -# qhasm: tt2d2 = 0 -# asm 1: mov $0,>tt2d2=int64#7 -# asm 2: mov $0,>tt2d2=%rax -mov $0,%rax - -# qhasm: tt2d3 = 0 -# asm 1: mov $0,>tt2d3=int64#8 -# asm 2: mov $0,>tt2d3=%r10 -mov $0,%r10 - -# qhasm: =? u - 1 -# asm 1: cmp $1,t=int64#9 -# asm 2: movq 64(t=%r11 -movq 64(%rcx,%rdi),%r11 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 72(t=%r11 -movq 72(%rcx,%rdi),%r11 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 80(t=%r11 -movq 80(%rcx,%rdi),%r11 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 88(t=%r11 -movq 88(%rcx,%rdi),%r11 - -# qhasm: tt2d3 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 160(t=%r11 -movq 160(%rcx,%rdi),%r11 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 168(t=%r11 -movq 168(%rcx,%rdi),%r11 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 176(t=%r11 -movq 176(%rcx,%rdi),%r11 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 184(t=%r11 -movq 184(%rcx,%rdi),%r11 - -# qhasm: tt2d3 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 256(t=%r11 -movq 256(%rcx,%rdi),%r11 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 264(t=%r11 -movq 264(%rcx,%rdi),%r11 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 272(t=%r11 -movq 272(%rcx,%rdi),%r11 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 280(t=%r11 -movq 280(%rcx,%rdi),%r11 - -# qhasm: tt2d3 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 352(t=%r11 -movq 352(%rcx,%rdi),%r11 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 360(t=%r11 -movq 360(%rcx,%rdi),%r11 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 368(t=%r11 -movq 368(%rcx,%rdi),%r11 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 376(t=%r11 -movq 376(%rcx,%rdi),%r11 - -# qhasm: tt2d3 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 448(t=%r11 -movq 448(%rcx,%rdi),%r11 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 456(t=%r11 -movq 456(%rcx,%rdi),%r11 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 464(t=%r11 -movq 464(%rcx,%rdi),%r11 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 472(t=%r11 -movq 472(%rcx,%rdi),%r11 - -# qhasm: tt2d3 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 544(t=%r11 -movq 544(%rcx,%rdi),%r11 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 552(t=%r11 -movq 552(%rcx,%rdi),%r11 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 560(t=%r11 -movq 560(%rcx,%rdi),%r11 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 568(t=%r11 -movq 568(%rcx,%rdi),%r11 - -# qhasm: tt2d3 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 640(t=%r11 -movq 640(%rcx,%rdi),%r11 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 648(t=%r11 -movq 648(%rcx,%rdi),%r11 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 656(t=%r11 -movq 656(%rcx,%rdi),%r11 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#9 -# asm 2: movq 664(t=%r11 -movq 664(%rcx,%rdi),%r11 - -# qhasm: tt2d3 = t if = -# asm 1: cmove t=int64#5 -# asm 2: movq 736(t=%r8 -movq 736(%rcx,%rdi),%r8 - -# qhasm: tt2d0 = t if = -# asm 1: cmove t=int64#5 -# asm 2: movq 744(t=%r8 -movq 744(%rcx,%rdi),%r8 - -# qhasm: tt2d1 = t if = -# asm 1: cmove t=int64#5 -# asm 2: movq 752(t=%r8 -movq 752(%rcx,%rdi),%r8 - -# qhasm: tt2d2 = t if = -# asm 1: cmove t=int64#1 -# asm 2: movq 760(t=%rdi -movq 760(%rcx,%rdi),%rdi - -# qhasm: tt2d3 = t if = -# asm 1: cmove tt0=int64#1 -# asm 2: mov $0,>tt0=%rdi -mov $0,%rdi - -# qhasm: tt1 = 0 -# asm 1: mov $0,>tt1=int64#4 -# asm 2: mov $0,>tt1=%rcx -mov $0,%rcx - -# qhasm: tt2 = 0 -# asm 1: mov $0,>tt2=int64#5 -# asm 2: mov $0,>tt2=%r8 -mov $0,%r8 - -# qhasm: tt3 = 0 -# asm 1: mov $0,>tt3=int64#9 -# asm 2: mov $0,>tt3=%r11 -mov $0,%r11 - -# qhasm: carry? tt0 -= tt2d0 -# asm 1: sub subt0=int64#10 -# asm 2: mov $0,>subt0=%r12 -mov $0,%r12 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#11 -# asm 2: mov $38,>subt1=%r13 -mov $38,%r13 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/consts.s b/ext/ed25519-amd64-asm/consts.s deleted file mode 100644 index c272383f..00000000 --- a/ext/ed25519-amd64-asm/consts.s +++ /dev/null @@ -1,39 +0,0 @@ -.data - -.globl crypto_sign_ed25519_amd64_64_121666 -.globl crypto_sign_ed25519_amd64_64_MU0 -.globl crypto_sign_ed25519_amd64_64_MU1 -.globl crypto_sign_ed25519_amd64_64_MU2 -.globl crypto_sign_ed25519_amd64_64_MU3 -.globl crypto_sign_ed25519_amd64_64_MU4 -.globl crypto_sign_ed25519_amd64_64_ORDER0 -.globl crypto_sign_ed25519_amd64_64_ORDER1 -.globl crypto_sign_ed25519_amd64_64_ORDER2 -.globl crypto_sign_ed25519_amd64_64_ORDER3 -.globl crypto_sign_ed25519_amd64_64_EC2D0 -.globl crypto_sign_ed25519_amd64_64_EC2D1 -.globl crypto_sign_ed25519_amd64_64_EC2D2 -.globl crypto_sign_ed25519_amd64_64_EC2D3 -.globl crypto_sign_ed25519_amd64_64_38 - -.p2align 4 - -crypto_sign_ed25519_amd64_64_121666: .quad 121666 - -crypto_sign_ed25519_amd64_64_MU0: .quad 0xED9CE5A30A2C131B -crypto_sign_ed25519_amd64_64_MU1: .quad 0x2106215D086329A7 -crypto_sign_ed25519_amd64_64_MU2: .quad 0xFFFFFFFFFFFFFFEB -crypto_sign_ed25519_amd64_64_MU3: .quad 0xFFFFFFFFFFFFFFFF -crypto_sign_ed25519_amd64_64_MU4: .quad 0x000000000000000F - -crypto_sign_ed25519_amd64_64_ORDER0: .quad 0x5812631A5CF5D3ED -crypto_sign_ed25519_amd64_64_ORDER1: .quad 0x14DEF9DEA2F79CD6 -crypto_sign_ed25519_amd64_64_ORDER2: .quad 0x0000000000000000 -crypto_sign_ed25519_amd64_64_ORDER3: .quad 0x1000000000000000 - -crypto_sign_ed25519_amd64_64_EC2D0: .quad 0xEBD69B9426B2F146 -crypto_sign_ed25519_amd64_64_EC2D1: .quad 0x00E0149A8283B156 -crypto_sign_ed25519_amd64_64_EC2D2: .quad 0x198E80F2EEF3D130 -crypto_sign_ed25519_amd64_64_EC2D3: .quad 0xA406D9DC56DFFCE7 - -crypto_sign_ed25519_amd64_64_38: .quad 38 diff --git a/ext/ed25519-amd64-asm/fe25519.h b/ext/ed25519-amd64-asm/fe25519.h deleted file mode 100644 index 33ffabbe..00000000 --- a/ext/ed25519-amd64-asm/fe25519.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef FE25519_H -#define FE25519_H - -#define fe25519 crypto_sign_ed25519_amd64_64_fe25519 -#define fe25519_freeze crypto_sign_ed25519_amd64_64_fe25519_freeze -#define fe25519_unpack crypto_sign_ed25519_amd64_64_fe25519_unpack -#define fe25519_pack crypto_sign_ed25519_amd64_64_fe25519_pack -#define fe25519_iszero_vartime crypto_sign_ed25519_amd64_64_fe25519_iszero_vartime -#define fe25519_iseq_vartime crypto_sign_ed25519_amd64_64_fe25519_iseq_vartime -#define fe25519_cmov crypto_sign_ed25519_amd64_64_fe25519_cmov -#define fe25519_setint crypto_sign_ed25519_amd64_64_fe25519_setint -#define fe25519_neg crypto_sign_ed25519_amd64_64_fe25519_neg -#define fe25519_getparity crypto_sign_ed25519_amd64_64_fe25519_getparity -#define fe25519_add crypto_sign_ed25519_amd64_64_fe25519_add -#define fe25519_sub crypto_sign_ed25519_amd64_64_fe25519_sub -#define fe25519_mul crypto_sign_ed25519_amd64_64_fe25519_mul -#define fe25519_mul121666 crypto_sign_ed25519_amd64_64_fe25519_mul121666 -#define fe25519_square crypto_sign_ed25519_amd64_64_fe25519_square -#define fe25519_invert crypto_sign_ed25519_amd64_64_fe25519_invert -#define fe25519_pow2523 crypto_sign_ed25519_amd64_64_fe25519_pow2523 - -typedef struct -{ - unsigned long long v[4]; -} -fe25519; - -void fe25519_freeze(fe25519 *r); - -void fe25519_unpack(fe25519 *r, const unsigned char x[32]); - -void fe25519_pack(unsigned char r[32], const fe25519 *x); - -void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b); - -void fe25519_cswap(fe25519 *r, fe25519 *x, unsigned char b); - -void fe25519_setint(fe25519 *r, unsigned int v); - -void fe25519_neg(fe25519 *r, const fe25519 *x); - -unsigned char fe25519_getparity(const fe25519 *x); - -int fe25519_iszero_vartime(const fe25519 *x); - -int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y); - -void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y); - -void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); - -void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y); - -void fe25519_mul121666(fe25519 *r, const fe25519 *x); - -void fe25519_square(fe25519 *r, const fe25519 *x); - -void fe25519_pow(fe25519 *r, const fe25519 *x, const unsigned char *e); - -void fe25519_invert(fe25519 *r, const fe25519 *x); - -void fe25519_pow2523(fe25519 *r, const fe25519 *x); - -#endif diff --git a/ext/ed25519-amd64-asm/fe25519_add.s b/ext/ed25519-amd64-asm/fe25519_add.s deleted file mode 100644 index b2e56252..00000000 --- a/ext/ed25519-amd64-asm/fe25519_add.s +++ /dev/null @@ -1,189 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: int64 yp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: input yp - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 addt0 - -# qhasm: int64 addt1 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_add -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_fe25519_add -.globl crypto_sign_ed25519_amd64_64_fe25519_add -_crypto_sign_ed25519_amd64_64_fe25519_add: -crypto_sign_ed25519_amd64_64_fe25519_add: -mov %rsp,%r11 -and $31,%r11 -add $0,%r11 -sub %r11,%rsp - -# qhasm: r0 = *(uint64 *)(xp + 0) -# asm 1: movq 0(r0=int64#4 -# asm 2: movq 0(r0=%rcx -movq 0(%rsi),%rcx - -# qhasm: r1 = *(uint64 *)(xp + 8) -# asm 1: movq 8(r1=int64#5 -# asm 2: movq 8(r1=%r8 -movq 8(%rsi),%r8 - -# qhasm: r2 = *(uint64 *)(xp + 16) -# asm 1: movq 16(r2=int64#6 -# asm 2: movq 16(r2=%r9 -movq 16(%rsi),%r9 - -# qhasm: r3 = *(uint64 *)(xp + 24) -# asm 1: movq 24(r3=int64#2 -# asm 2: movq 24(r3=%rsi -movq 24(%rsi),%rsi - -# qhasm: carry? r0 += *(uint64 *)(yp + 0) -# asm 1: addq 0(addt0=int64#3 -# asm 2: mov $0,>addt0=%rdx -mov $0,%rdx - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#7 -# asm 2: mov $38,>addt1=%rax -mov $38,%rax - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: r0 = *(uint64 *) (rp + 0) -# asm 1: movq 0(r0=int64#2 -# asm 2: movq 0(r0=%rsi -movq 0(%rdi),%rsi - -# qhasm: r1 = *(uint64 *) (rp + 8) -# asm 1: movq 8(r1=int64#3 -# asm 2: movq 8(r1=%rdx -movq 8(%rdi),%rdx - -# qhasm: r2 = *(uint64 *) (rp + 16) -# asm 1: movq 16(r2=int64#4 -# asm 2: movq 16(r2=%rcx -movq 16(%rdi),%rcx - -# qhasm: r3 = *(uint64 *) (rp + 24) -# asm 1: movq 24(r3=int64#5 -# asm 2: movq 24(r3=%r8 -movq 24(%rdi),%r8 - -# qhasm: t0 = r0 -# asm 1: mov t0=int64#6 -# asm 2: mov t0=%r9 -mov %rsi,%r9 - -# qhasm: t1 = r1 -# asm 1: mov t1=int64#7 -# asm 2: mov t1=%rax -mov %rdx,%rax - -# qhasm: t2 = r2 -# asm 1: mov t2=int64#8 -# asm 2: mov t2=%r10 -mov %rcx,%r10 - -# qhasm: t3 = r3 -# asm 1: mov t3=int64#9 -# asm 2: mov t3=%r11 -mov %r8,%r11 - -# qhasm: two63 = 1 -# asm 1: mov $1,>two63=int64#10 -# asm 2: mov $1,>two63=%r12 -mov $1,%r12 - -# qhasm: two63 <<= 63 -# asm 1: shl $63,t0=int64#6 -# asm 2: mov t0=%r9 -mov %rsi,%r9 - -# qhasm: t1 = r1 -# asm 1: mov t1=int64#7 -# asm 2: mov t1=%rax -mov %rdx,%rax - -# qhasm: t2 = r2 -# asm 1: mov t2=int64#8 -# asm 2: mov t2=%r10 -mov %rcx,%r10 - -# qhasm: t3 = r3 -# asm 1: mov t3=int64#9 -# asm 2: mov t3=%r11 -mov %r8,%r11 - -# qhasm: carry? t0 += 19 -# asm 1: add $19,caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/fe25519_getparity.c b/ext/ed25519-amd64-asm/fe25519_getparity.c deleted file mode 100644 index a003ec8f..00000000 --- a/ext/ed25519-amd64-asm/fe25519_getparity.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "fe25519.h" - -unsigned char fe25519_getparity(const fe25519 *x) -{ - fe25519 t = *x; - fe25519_freeze(&t); - return (unsigned char)t.v[0] & 1; -} diff --git a/ext/ed25519-amd64-asm/fe25519_invert.c b/ext/ed25519-amd64-asm/fe25519_invert.c deleted file mode 100644 index a46d141f..00000000 --- a/ext/ed25519-amd64-asm/fe25519_invert.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "fe25519.h" - -void fe25519_invert(fe25519 *r, const fe25519 *x) -{ - fe25519 z2; - fe25519 z9; - fe25519 z11; - fe25519 z2_5_0; - fe25519 z2_10_0; - fe25519 z2_20_0; - fe25519 z2_50_0; - fe25519 z2_100_0; - fe25519 t; - int i; - - /* 2 */ fe25519_square(&z2,x); - /* 4 */ fe25519_square(&t,&z2); - /* 8 */ fe25519_square(&t,&t); - /* 9 */ fe25519_mul(&z9,&t,x); - /* 11 */ fe25519_mul(&z11,&z9,&z2); - /* 22 */ fe25519_square(&t,&z11); - /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9); - - /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0); - /* 2^20 - 2^10 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); } - /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0); - - /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0); - /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } - /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0); - - /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0); - /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); } - /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0); - - /* 2^41 - 2^1 */ fe25519_square(&t,&t); - /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } - /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0); - - /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0); - /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } - /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0); - - /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0); - /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); } - /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0); - - /* 2^201 - 2^1 */ fe25519_square(&t,&t); - /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } - /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0); - - /* 2^251 - 2^1 */ fe25519_square(&t,&t); - /* 2^252 - 2^2 */ fe25519_square(&t,&t); - /* 2^253 - 2^3 */ fe25519_square(&t,&t); - - /* 2^254 - 2^4 */ fe25519_square(&t,&t); - - /* 2^255 - 2^5 */ fe25519_square(&t,&t); - /* 2^255 - 21 */ fe25519_mul(r,&t,&z11); -} diff --git a/ext/ed25519-amd64-asm/fe25519_iseq.c b/ext/ed25519-amd64-asm/fe25519_iseq.c deleted file mode 100644 index bf72f8c9..00000000 --- a/ext/ed25519-amd64-asm/fe25519_iseq.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "fe25519.h" - -int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y) -{ - fe25519 t1 = *x; - fe25519 t2 = *y; - fe25519_freeze(&t1); - fe25519_freeze(&t2); - if(t1.v[0] != t2.v[0]) return 0; - if(t1.v[1] != t2.v[1]) return 0; - if(t1.v[2] != t2.v[2]) return 0; - if(t1.v[3] != t2.v[3]) return 0; - return 1; -} diff --git a/ext/ed25519-amd64-asm/fe25519_iszero.c b/ext/ed25519-amd64-asm/fe25519_iszero.c deleted file mode 100644 index 99e4dafa..00000000 --- a/ext/ed25519-amd64-asm/fe25519_iszero.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "fe25519.h" - -int fe25519_iszero_vartime(const fe25519 *x) -{ - fe25519 t = *x; - fe25519_freeze(&t); - if (t.v[0]) return 0; - if (t.v[1]) return 0; - if (t.v[2]) return 0; - if (t.v[3]) return 0; - return 1; -} diff --git a/ext/ed25519-amd64-asm/fe25519_mul.s b/ext/ed25519-amd64-asm/fe25519_mul.s deleted file mode 100644 index 14784281..00000000 --- a/ext/ed25519-amd64-asm/fe25519_mul.s +++ /dev/null @@ -1,865 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: int64 yp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: input yp - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_mul -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_fe25519_mul -.globl crypto_sign_ed25519_amd64_64_fe25519_mul -_crypto_sign_ed25519_amd64_64_fe25519_mul: -crypto_sign_ed25519_amd64_64_fe25519_mul: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: yp = yp -# asm 1: mov yp=int64#4 -# asm 2: mov yp=%rcx -mov %rdx,%rcx - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = *(uint64 *)(xp + 0) -# asm 1: movq 0(mulx0=int64#10 -# asm 2: movq 0(mulx0=%r12 -movq 0(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(yp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul r0=int64#11 -# asm 2: mov r0=%r13 -mov %rax,%r13 - -# qhasm: r1 = mulrdx -# asm 1: mov r1=int64#12 -# asm 2: mov r1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(yp + 8) -# asm 1: movq 8(mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul r2=int64#13 -# asm 2: mov $0,>r2=%r15 -mov $0,%r15 - -# qhasm: r2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul r3=int64#14 -# asm 2: mov $0,>r3=%rbx -mov $0,%rbx - -# qhasm: r3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq 8(mulx1=%r12 -movq 8(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(yp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq 16(mulx2=%r12 -movq 16(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(yp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#2 -# asm 2: movq 24(mulx3=%rsi -movq 24(%rsi),%rsi - -# qhasm: mulrax = *(uint64 *)(yp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? r0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: r0 += mulzero -# asm 1: add caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/fe25519_neg.c b/ext/ed25519-amd64-asm/fe25519_neg.c deleted file mode 100644 index 235b209d..00000000 --- a/ext/ed25519-amd64-asm/fe25519_neg.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "fe25519.h" - -void fe25519_neg(fe25519 *r, const fe25519 *x) -{ - fe25519 t; - fe25519_setint(&t,0); - fe25519_sub(r,&t,x); -} diff --git a/ext/ed25519-amd64-asm/fe25519_pack.c b/ext/ed25519-amd64-asm/fe25519_pack.c deleted file mode 100644 index caf51853..00000000 --- a/ext/ed25519-amd64-asm/fe25519_pack.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "fe25519.h" - -/* Assumes input x being reduced below 2^255 */ -void fe25519_pack(unsigned char r[32], const fe25519 *x) -{ - int i; - fe25519 t; - t = *x; - fe25519_freeze(&t); - /* assuming little-endian */ - for(i=0;i<32;i++) r[i] = i[(unsigned char *)&t.v]; -} - diff --git a/ext/ed25519-amd64-asm/fe25519_pow2523.c b/ext/ed25519-amd64-asm/fe25519_pow2523.c deleted file mode 100644 index 60042a0a..00000000 --- a/ext/ed25519-amd64-asm/fe25519_pow2523.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "fe25519.h" - -void fe25519_pow2523(fe25519 *r, const fe25519 *x) -{ - fe25519 z2; - fe25519 z9; - fe25519 z11; - fe25519 z2_5_0; - fe25519 z2_10_0; - fe25519 z2_20_0; - fe25519 z2_50_0; - fe25519 z2_100_0; - fe25519 t; - int i; - - /* 2 */ fe25519_square(&z2,x); - /* 4 */ fe25519_square(&t,&z2); - /* 8 */ fe25519_square(&t,&t); - /* 9 */ fe25519_mul(&z9,&t,x); - /* 11 */ fe25519_mul(&z11,&z9,&z2); - /* 22 */ fe25519_square(&t,&z11); - /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9); - - /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0); - /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); } - /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0); - - /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0); - /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } - /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0); - - /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0); - /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); } - /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0); - - /* 2^41 - 2^1 */ fe25519_square(&t,&t); - /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } - /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0); - - /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0); - /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } - /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0); - - /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0); - /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); } - /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0); - - /* 2^201 - 2^1 */ fe25519_square(&t,&t); - /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } - /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0); - - /* 2^251 - 2^1 */ fe25519_square(&t,&t); - /* 2^252 - 2^2 */ fe25519_square(&t,&t); - /* 2^252 - 3 */ fe25519_mul(r,&t,x); -} diff --git a/ext/ed25519-amd64-asm/fe25519_setint.c b/ext/ed25519-amd64-asm/fe25519_setint.c deleted file mode 100644 index 585c4bdd..00000000 --- a/ext/ed25519-amd64-asm/fe25519_setint.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "fe25519.h" - -void fe25519_setint(fe25519 *r, unsigned int v) -{ - r->v[0] = v; - r->v[1] = 0; - r->v[2] = 0; - r->v[3] = 0; -} diff --git a/ext/ed25519-amd64-asm/fe25519_square.s b/ext/ed25519-amd64-asm/fe25519_square.s deleted file mode 100644 index a74d9e88..00000000 --- a/ext/ed25519-amd64-asm/fe25519_square.s +++ /dev/null @@ -1,639 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 squarer4 - -# qhasm: int64 squarer5 - -# qhasm: int64 squarer6 - -# qhasm: int64 squarer7 - -# qhasm: int64 squarer8 - -# qhasm: int64 squarerax - -# qhasm: int64 squarerdx - -# qhasm: int64 squaret1 - -# qhasm: int64 squaret2 - -# qhasm: int64 squaret3 - -# qhasm: int64 squarec - -# qhasm: int64 squarezero - -# qhasm: int64 squarei38 - -# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_square -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_fe25519_square -.globl crypto_sign_ed25519_amd64_64_fe25519_square -_crypto_sign_ed25519_amd64_64_fe25519_square: -crypto_sign_ed25519_amd64_64_fe25519_square: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarerax = *(uint64 *)(xp + 8) -# asm 1: movq 8(squarerax=int64#7 -# asm 2: movq 8(squarerax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) -# asm 1: mulq 0(r1=int64#5 -# asm 2: mov r1=%r8 -mov %rax,%r8 - -# qhasm: r2 = squarerdx -# asm 1: mov r2=int64#6 -# asm 2: mov r2=%r9 -mov %rdx,%r9 - -# qhasm: squarerax = *(uint64 *)(xp + 16) -# asm 1: movq 16(squarerax=int64#7 -# asm 2: movq 16(squarerax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 8) -# asm 1: mulq 8(r3=int64#8 -# asm 2: mov r3=%r10 -mov %rax,%r10 - -# qhasm: squarer4 = squarerdx -# asm 1: mov squarer4=int64#9 -# asm 2: mov squarer4=%r11 -mov %rdx,%r11 - -# qhasm: squarerax = *(uint64 *)(xp + 24) -# asm 1: movq 24(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 16) -# asm 1: mulq 16(squarer5=int64#10 -# asm 2: mov squarer5=%r12 -mov %rax,%r12 - -# qhasm: squarer6 = squarerdx -# asm 1: mov squarer6=int64#11 -# asm 2: mov squarer6=%r13 -mov %rdx,%r13 - -# qhasm: squarerax = *(uint64 *)(xp + 16) -# asm 1: movq 16(squarerax=int64#7 -# asm 2: movq 16(squarerax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) -# asm 1: mulq 0(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 8) -# asm 1: mulq 8(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) -# asm 1: mulq 0(squarerax=int64#7 -# asm 2: movq 0(squarerax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 0) -# asm 1: mulq 0(r0=int64#12 -# asm 2: mov r0=%r14 -mov %rax,%r14 - -# qhasm: squaret1 = squarerdx -# asm 1: mov squaret1=int64#13 -# asm 2: mov squaret1=%r15 -mov %rdx,%r15 - -# qhasm: squarerax = *(uint64 *)(xp + 8) -# asm 1: movq 8(squarerax=int64#7 -# asm 2: movq 8(squarerax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 8) -# asm 1: mulq 8(squaret2=int64#14 -# asm 2: mov squaret2=%rbx -mov %rax,%rbx - -# qhasm: squaret3 = squarerdx -# asm 1: mov squaret3=int64#15 -# asm 2: mov squaret3=%rbp -mov %rdx,%rbp - -# qhasm: squarerax = *(uint64 *)(xp + 16) -# asm 1: movq 16(squarerax=int64#7 -# asm 2: movq 16(squarerax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 16) -# asm 1: mulq 16(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(xp + 24) -# asm 1: mulq 24(squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r11,%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: squarer4 = squarerax -# asm 1: mov squarer4=int64#2 -# asm 2: mov squarer4=%rsi -mov %rax,%rsi - -# qhasm: squarerax = squarer5 -# asm 1: mov squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r12,%rax - -# qhasm: squarer5 = squarerdx -# asm 1: mov squarer5=int64#9 -# asm 2: mov squarer5=%r11 -mov %rdx,%r11 - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? squarer5 += squarerax -# asm 1: add squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r13,%rax - -# qhasm: squarer6 = 0 -# asm 1: mov $0,>squarer6=int64#10 -# asm 2: mov $0,>squarer6=%r12 -mov $0,%r12 - -# qhasm: squarer6 += squarerdx + carry -# asm 1: adc squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %rcx,%rax - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarer7 += squarerdx + carry -# asm 1: adc squarer8=int64#7 -# asm 2: mov $0,>squarer8=%rax -mov $0,%rax - -# qhasm: squarer8 += squarerdx + carry -# asm 1: adc squarezero=int64#2 -# asm 2: mov $0,>squarezero=%rsi -mov $0,%rsi - -# qhasm: squarer8 += squarezero + carry -# asm 1: adc squarer8=int64#3 -# asm 2: imulq $38,squarer8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? r0 += squarer8 -# asm 1: add squarezero=int64#2 -# asm 2: imulq $38,squarezero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: r0 += squarezero -# asm 1: add caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/fe25519_sub.s b/ext/ed25519-amd64-asm/fe25519_sub.s deleted file mode 100644 index 0b395bce..00000000 --- a/ext/ed25519-amd64-asm/fe25519_sub.s +++ /dev/null @@ -1,189 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: int64 yp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: input yp - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 subt0 - -# qhasm: int64 subt1 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_fe25519_sub -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_fe25519_sub -.globl crypto_sign_ed25519_amd64_64_fe25519_sub -_crypto_sign_ed25519_amd64_64_fe25519_sub: -crypto_sign_ed25519_amd64_64_fe25519_sub: -mov %rsp,%r11 -and $31,%r11 -add $0,%r11 -sub %r11,%rsp - -# qhasm: r0 = *(uint64 *)(xp + 0) -# asm 1: movq 0(r0=int64#4 -# asm 2: movq 0(r0=%rcx -movq 0(%rsi),%rcx - -# qhasm: r1 = *(uint64 *)(xp + 8) -# asm 1: movq 8(r1=int64#5 -# asm 2: movq 8(r1=%r8 -movq 8(%rsi),%r8 - -# qhasm: r2 = *(uint64 *)(xp + 16) -# asm 1: movq 16(r2=int64#6 -# asm 2: movq 16(r2=%r9 -movq 16(%rsi),%r9 - -# qhasm: r3 = *(uint64 *)(xp + 24) -# asm 1: movq 24(r3=int64#2 -# asm 2: movq 24(r3=%rsi -movq 24(%rsi),%rsi - -# qhasm: carry? r0 -= *(uint64 *)(yp + 0) -# asm 1: subq 0(subt0=int64#3 -# asm 2: mov $0,>subt0=%rdx -mov $0,%rdx - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#7 -# asm 2: mov $38,>subt1=%rax -mov $38,%rax - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae v[0] = *(unsigned long long *)x; - r->v[1] = *(((unsigned long long *)x)+1); - r->v[2] = *(((unsigned long long *)x)+2); - r->v[3] = *(((unsigned long long *)x)+3); - r->v[3] &= 0x7fffffffffffffffULL; -} diff --git a/ext/ed25519-amd64-asm/ge25519.h b/ext/ed25519-amd64-asm/ge25519.h deleted file mode 100644 index 0b15136b..00000000 --- a/ext/ed25519-amd64-asm/ge25519.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef GE25519_H -#define GE25519_H - -#include "fe25519.h" -#include "sc25519.h" - -#define ge25519 crypto_sign_ed25519_amd64_64_ge25519 -#define ge25519_base crypto_sign_ed25519_amd64_64_ge25519_base -#define ge25519_unpackneg_vartime crypto_sign_ed25519_amd64_64_unpackneg_vartime -#define ge25519_pack crypto_sign_ed25519_amd64_64_pack -#define ge25519_isneutral_vartime crypto_sign_ed25519_amd64_64_isneutral_vartime -#define ge25519_add crypto_sign_ed25519_amd64_64_ge25519_add -#define ge25519_double crypto_sign_ed25519_amd64_64_ge25519_double -#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_amd64_64_double_scalarmult_vartime -#define ge25519_multi_scalarmult_vartime crypto_sign_ed25519_amd64_64_ge25519_multi_scalarmult_vartime -#define ge25519_scalarmult_base crypto_sign_ed25519_amd64_64_scalarmult_base -#define ge25519_p1p1_to_p2 crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 -#define ge25519_p1p1_to_p3 crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 -#define ge25519_add_p1p1 crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 -#define ge25519_dbl_p1p1 crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 -#define choose_t crypto_sign_ed25519_amd64_64_choose_t -#define ge25519_nielsadd2 crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 -#define ge25519_nielsadd_p1p1 crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 -#define ge25519_pnielsadd_p1p1 crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 - - -#define ge25519_p3 ge25519 - -typedef struct -{ - fe25519 x; - fe25519 y; - fe25519 z; - fe25519 t; -} ge25519; - -typedef struct -{ - fe25519 x; - fe25519 z; - fe25519 y; - fe25519 t; -} ge25519_p1p1; - -typedef struct -{ - fe25519 x; - fe25519 y; - fe25519 z; -} ge25519_p2; - -typedef struct -{ - fe25519 ysubx; - fe25519 xaddy; - fe25519 t2d; -} ge25519_niels; - -typedef struct -{ - fe25519 ysubx; - fe25519 xaddy; - fe25519 z; - fe25519 t2d; -} ge25519_pniels; - -extern void ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p); -extern void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p); -extern void ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q); -extern void ge25519_dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p); -extern void choose_t(ge25519_niels *t, unsigned long long pos, signed long long b, const ge25519_niels *base_multiples); -extern void ge25519_nielsadd2(ge25519_p3 *r, const ge25519_niels *q); -extern void ge25519_nielsadd_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_niels *q); -extern void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_pniels *q); - -extern const ge25519 ge25519_base; - -extern int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]); - -extern void ge25519_pack(unsigned char r[32], const ge25519 *p); - -extern int ge25519_isneutral_vartime(const ge25519 *p); - -extern void ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q); - -extern void ge25519_double(ge25519 *r, const ge25519 *p); - -/* computes [s1]p1 + [s2]ge25519_base */ -extern void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const sc25519 *s2); - -extern void ge25519_multi_scalarmult_vartime(ge25519 *r, ge25519 *p, sc25519 *s, const unsigned long long npoints); - -extern void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s); - -#endif diff --git a/ext/ed25519-amd64-asm/ge25519_add.c b/ext/ed25519-amd64-asm/ge25519_add.c deleted file mode 100644 index c4d1c68a..00000000 --- a/ext/ed25519-amd64-asm/ge25519_add.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "ge25519.h" - -void ge25519_add(ge25519_p3 *r, const ge25519_p3 *p, const ge25519_p3 *q) -{ - ge25519_p1p1 grp1p1; - ge25519_add_p1p1(&grp1p1, p, q); - ge25519_p1p1_to_p3(r, &grp1p1); -} diff --git a/ext/ed25519-amd64-asm/ge25519_add_p1p1.s b/ext/ed25519-amd64-asm/ge25519_add_p1p1.s deleted file mode 100644 index 0cb13898..00000000 --- a/ext/ed25519-amd64-asm/ge25519_add_p1p1.s +++ /dev/null @@ -1,4554 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 pp - -# qhasm: int64 qp - -# qhasm: input rp - -# qhasm: input pp - -# qhasm: input qp - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 a0 - -# qhasm: int64 a1 - -# qhasm: int64 a2 - -# qhasm: int64 a3 - -# qhasm: stack64 a0_stack - -# qhasm: stack64 a1_stack - -# qhasm: stack64 a2_stack - -# qhasm: stack64 a3_stack - -# qhasm: int64 b0 - -# qhasm: int64 b1 - -# qhasm: int64 b2 - -# qhasm: int64 b3 - -# qhasm: stack64 b0_stack - -# qhasm: stack64 b1_stack - -# qhasm: stack64 b2_stack - -# qhasm: stack64 b3_stack - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: stack64 c0_stack - -# qhasm: stack64 c1_stack - -# qhasm: stack64 c2_stack - -# qhasm: stack64 c3_stack - -# qhasm: int64 d0 - -# qhasm: int64 d1 - -# qhasm: int64 d2 - -# qhasm: int64 d3 - -# qhasm: stack64 d0_stack - -# qhasm: stack64 d1_stack - -# qhasm: stack64 d2_stack - -# qhasm: stack64 d3_stack - -# qhasm: int64 t10 - -# qhasm: int64 t11 - -# qhasm: int64 t12 - -# qhasm: int64 t13 - -# qhasm: stack64 t10_stack - -# qhasm: stack64 t11_stack - -# qhasm: stack64 t12_stack - -# qhasm: stack64 t13_stack - -# qhasm: int64 t20 - -# qhasm: int64 t21 - -# qhasm: int64 t22 - -# qhasm: int64 t23 - -# qhasm: stack64 t20_stack - -# qhasm: stack64 t21_stack - -# qhasm: stack64 t22_stack - -# qhasm: stack64 t23_stack - -# qhasm: int64 rx0 - -# qhasm: int64 rx1 - -# qhasm: int64 rx2 - -# qhasm: int64 rx3 - -# qhasm: int64 ry0 - -# qhasm: int64 ry1 - -# qhasm: int64 ry2 - -# qhasm: int64 ry3 - -# qhasm: int64 rz0 - -# qhasm: int64 rz1 - -# qhasm: int64 rz2 - -# qhasm: int64 rz3 - -# qhasm: int64 rt0 - -# qhasm: int64 rt1 - -# qhasm: int64 rt2 - -# qhasm: int64 rt3 - -# qhasm: int64 x0 - -# qhasm: int64 x1 - -# qhasm: int64 x2 - -# qhasm: int64 x3 - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: int64 addt0 - -# qhasm: int64 addt1 - -# qhasm: int64 subt0 - -# qhasm: int64 subt1 - -# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 -.globl crypto_sign_ed25519_amd64_64_ge25519_add_p1p1 -_crypto_sign_ed25519_amd64_64_ge25519_add_p1p1: -crypto_sign_ed25519_amd64_64_ge25519_add_p1p1: -mov %rsp,%r11 -and $31,%r11 -add $192,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: qp = qp -# asm 1: mov qp=int64#4 -# asm 2: mov qp=%rcx -mov %rdx,%rcx - -# qhasm: a0 = *(uint64 *)(pp + 32) -# asm 1: movq 32(a0=int64#3 -# asm 2: movq 32(a0=%rdx -movq 32(%rsi),%rdx - -# qhasm: a1 = *(uint64 *)(pp + 40) -# asm 1: movq 40(a1=int64#5 -# asm 2: movq 40(a1=%r8 -movq 40(%rsi),%r8 - -# qhasm: a2 = *(uint64 *)(pp + 48) -# asm 1: movq 48(a2=int64#6 -# asm 2: movq 48(a2=%r9 -movq 48(%rsi),%r9 - -# qhasm: a3 = *(uint64 *)(pp + 56) -# asm 1: movq 56(a3=int64#7 -# asm 2: movq 56(a3=%rax -movq 56(%rsi),%rax - -# qhasm: b0 = a0 -# asm 1: mov b0=int64#8 -# asm 2: mov b0=%r10 -mov %rdx,%r10 - -# qhasm: b1 = a1 -# asm 1: mov b1=int64#9 -# asm 2: mov b1=%r11 -mov %r8,%r11 - -# qhasm: b2 = a2 -# asm 1: mov b2=int64#10 -# asm 2: mov b2=%r12 -mov %r9,%r12 - -# qhasm: b3 = a3 -# asm 1: mov b3=int64#11 -# asm 2: mov b3=%r13 -mov %rax,%r13 - -# qhasm: carry? a0 -= *(uint64 *)(pp + 0) -# asm 1: subq 0(subt0=int64#12 -# asm 2: mov $0,>subt0=%r14 -mov $0,%r14 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#13 -# asm 2: mov $38,>subt1=%r15 -mov $38,%r15 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#12 -# asm 2: mov $0,>addt0=%r14 -mov $0,%r14 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#13 -# asm 2: mov $38,>addt1=%r15 -mov $38,%r15 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %rdx,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r8,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r9,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %rax,80(%rsp) - -# qhasm: b0_stack = b0 -# asm 1: movq b0_stack=stack64#12 -# asm 2: movq b0_stack=88(%rsp) -movq %r10,88(%rsp) - -# qhasm: b1_stack = b1 -# asm 1: movq b1_stack=stack64#13 -# asm 2: movq b1_stack=96(%rsp) -movq %r11,96(%rsp) - -# qhasm: b2_stack = b2 -# asm 1: movq b2_stack=stack64#14 -# asm 2: movq b2_stack=104(%rsp) -movq %r12,104(%rsp) - -# qhasm: b3_stack = b3 -# asm 1: movq b3_stack=stack64#15 -# asm 2: movq b3_stack=112(%rsp) -movq %r13,112(%rsp) - -# qhasm: t10 = *(uint64 *)(qp + 32) -# asm 1: movq 32(t10=int64#3 -# asm 2: movq 32(t10=%rdx -movq 32(%rcx),%rdx - -# qhasm: t11 = *(uint64 *)(qp + 40) -# asm 1: movq 40(t11=int64#5 -# asm 2: movq 40(t11=%r8 -movq 40(%rcx),%r8 - -# qhasm: t12 = *(uint64 *)(qp + 48) -# asm 1: movq 48(t12=int64#6 -# asm 2: movq 48(t12=%r9 -movq 48(%rcx),%r9 - -# qhasm: t13 = *(uint64 *)(qp + 56) -# asm 1: movq 56(t13=int64#7 -# asm 2: movq 56(t13=%rax -movq 56(%rcx),%rax - -# qhasm: t20 = t10 -# asm 1: mov t20=int64#8 -# asm 2: mov t20=%r10 -mov %rdx,%r10 - -# qhasm: t21 = t11 -# asm 1: mov t21=int64#9 -# asm 2: mov t21=%r11 -mov %r8,%r11 - -# qhasm: t22 = t12 -# asm 1: mov t22=int64#10 -# asm 2: mov t22=%r12 -mov %r9,%r12 - -# qhasm: t23 = t13 -# asm 1: mov t23=int64#11 -# asm 2: mov t23=%r13 -mov %rax,%r13 - -# qhasm: carry? t10 -= *(uint64 *) (qp + 0) -# asm 1: subq 0(subt0=int64#12 -# asm 2: mov $0,>subt0=%r14 -mov $0,%r14 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#13 -# asm 2: mov $38,>subt1=%r15 -mov $38,%r15 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#12 -# asm 2: mov $0,>addt0=%r14 -mov $0,%r14 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#13 -# asm 2: mov $38,>addt1=%r15 -mov $38,%r15 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae t10_stack=stack64#16 -# asm 2: movq t10_stack=120(%rsp) -movq %rdx,120(%rsp) - -# qhasm: t11_stack = t11 -# asm 1: movq t11_stack=stack64#17 -# asm 2: movq t11_stack=128(%rsp) -movq %r8,128(%rsp) - -# qhasm: t12_stack = t12 -# asm 1: movq t12_stack=stack64#18 -# asm 2: movq t12_stack=136(%rsp) -movq %r9,136(%rsp) - -# qhasm: t13_stack = t13 -# asm 1: movq t13_stack=stack64#19 -# asm 2: movq t13_stack=144(%rsp) -movq %rax,144(%rsp) - -# qhasm: t20_stack = t20 -# asm 1: movq t20_stack=stack64#20 -# asm 2: movq t20_stack=152(%rsp) -movq %r10,152(%rsp) - -# qhasm: t21_stack = t21 -# asm 1: movq t21_stack=stack64#21 -# asm 2: movq t21_stack=160(%rsp) -movq %r11,160(%rsp) - -# qhasm: t22_stack = t22 -# asm 1: movq t22_stack=stack64#22 -# asm 2: movq t22_stack=168(%rsp) -movq %r12,168(%rsp) - -# qhasm: t23_stack = t23 -# asm 1: movq t23_stack=stack64#23 -# asm 2: movq t23_stack=176(%rsp) -movq %r13,176(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = a0_stack -# asm 1: movq mulx0=int64#10 -# asm 2: movq mulx0=%r12 -movq 56(%rsp),%r12 - -# qhasm: mulrax = t10_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a0=int64#11 -# asm 2: mov a0=%r13 -mov %rax,%r13 - -# qhasm: a1 = mulrdx -# asm 1: mov a1=int64#12 -# asm 2: mov a1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = t11_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a2=int64#13 -# asm 2: mov $0,>a2=%r15 -mov $0,%r15 - -# qhasm: a2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a3=int64#14 -# asm 2: mov $0,>a3=%rbx -mov $0,%rbx - -# qhasm: a3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq mulx1=%r12 -movq 64(%rsp),%r12 - -# qhasm: mulrax = t10_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq mulx2=%r12 -movq 72(%rsp),%r12 - -# qhasm: mulrax = t10_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq mulx3=%r12 -movq 80(%rsp),%r12 - -# qhasm: mulrax = t10_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? a0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: a0 += mulzero -# asm 1: add a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %r13,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r14,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r15,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %rbx,80(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = b0_stack -# asm 1: movq mulx0=int64#10 -# asm 2: movq mulx0=%r12 -movq 88(%rsp),%r12 - -# qhasm: mulrax = t20_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx0=int64#11 -# asm 2: mov rx0=%r13 -mov %rax,%r13 - -# qhasm: rx1 = mulrdx -# asm 1: mov rx1=int64#12 -# asm 2: mov rx1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = t21_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx2=int64#13 -# asm 2: mov $0,>rx2=%r15 -mov $0,%r15 - -# qhasm: rx2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx3=int64#14 -# asm 2: mov $0,>rx3=%rbx -mov $0,%rbx - -# qhasm: rx3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq mulx1=%r12 -movq 96(%rsp),%r12 - -# qhasm: mulrax = t20_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq mulx2=%r12 -movq 104(%rsp),%r12 - -# qhasm: mulrax = t20_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq mulx3=%r12 -movq 112(%rsp),%r12 - -# qhasm: mulrax = t20_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? rx0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: rx0 += mulzero -# asm 1: add ry0=int64#3 -# asm 2: mov ry0=%rdx -mov %r13,%rdx - -# qhasm: ry1 = rx1 -# asm 1: mov ry1=int64#5 -# asm 2: mov ry1=%r8 -mov %r14,%r8 - -# qhasm: ry2 = rx2 -# asm 1: mov ry2=int64#6 -# asm 2: mov ry2=%r9 -mov %r15,%r9 - -# qhasm: ry3 = rx3 -# asm 1: mov ry3=int64#7 -# asm 2: mov ry3=%rax -mov %rbx,%rax - -# qhasm: carry? ry0 += a0_stack -# asm 1: addq addt0=int64#8 -# asm 2: mov $0,>addt0=%r10 -mov $0,%r10 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#9 -# asm 2: mov $38,>addt1=%r11 -mov $38,%r11 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae subt0=int64#8 -# asm 2: mov $0,>subt0=%r10 -mov $0,%r10 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#9 -# asm 2: mov $38,>subt1=%r11 -mov $38,%r11 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulx0=int64#10 -# asm 2: movq 96(mulx0=%r12 -movq 96(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c0=int64#11 -# asm 2: mov c0=%r13 -mov %rax,%r13 - -# qhasm: c1 = mulrdx -# asm 1: mov c1=int64#12 -# asm 2: mov c1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 104) -# asm 1: movq 104(mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c2=int64#13 -# asm 2: mov $0,>c2=%r15 -mov $0,%r15 - -# qhasm: c2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c3=int64#14 -# asm 2: mov $0,>c3=%rbx -mov $0,%rbx - -# qhasm: c3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq 104(mulx1=%r12 -movq 104(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq 112(mulx2=%r12 -movq 112(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq 120(mulx3=%r12 -movq 120(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? c0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: c0 += mulzero -# asm 1: add c0_stack=stack64#8 -# asm 2: movq c0_stack=56(%rsp) -movq %r13,56(%rsp) - -# qhasm: c1_stack = c1 -# asm 1: movq c1_stack=stack64#9 -# asm 2: movq c1_stack=64(%rsp) -movq %r14,64(%rsp) - -# qhasm: c2_stack = c2 -# asm 1: movq c2_stack=stack64#10 -# asm 2: movq c2_stack=72(%rsp) -movq %r15,72(%rsp) - -# qhasm: c3_stack = c3 -# asm 1: movq c3_stack=stack64#11 -# asm 2: movq c3_stack=80(%rsp) -movq %rbx,80(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = c0_stack -# asm 1: movq mulx0=int64#10 -# asm 2: movq mulx0=%r12 -movq 56(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 -# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c0=int64#11 -# asm 2: mov c0=%r13 -mov %rax,%r13 - -# qhasm: c1 = mulrdx -# asm 1: mov c1=int64#12 -# asm 2: mov c1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D1 -# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c2=int64#13 -# asm 2: mov $0,>c2=%r15 -mov $0,%r15 - -# qhasm: c2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c3=int64#14 -# asm 2: mov $0,>c3=%rbx -mov $0,%rbx - -# qhasm: c3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq mulx1=%r12 -movq 64(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 -# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq mulx2=%r12 -movq 72(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 -# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq mulx3=%r12 -movq 80(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)&crypto_sign_ed25519_amd64_64_EC2D0 -# asm 1: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D0,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D0(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D1,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D1(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D2,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D2(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq crypto_sign_ed25519_amd64_64_EC2D3,>mulrax=%rax -movq crypto_sign_ed25519_amd64_64_EC2D3(%rip),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? c0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: c0 += mulzero -# asm 1: add c0_stack=stack64#8 -# asm 2: movq c0_stack=56(%rsp) -movq %r13,56(%rsp) - -# qhasm: c1_stack = c1 -# asm 1: movq c1_stack=stack64#9 -# asm 2: movq c1_stack=64(%rsp) -movq %r14,64(%rsp) - -# qhasm: c2_stack = c2 -# asm 1: movq c2_stack=stack64#10 -# asm 2: movq c2_stack=72(%rsp) -movq %r15,72(%rsp) - -# qhasm: c3_stack = c3 -# asm 1: movq c3_stack=stack64#11 -# asm 2: movq c3_stack=80(%rsp) -movq %rbx,80(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulx0=int64#10 -# asm 2: movq 64(mulx0=%r12 -movq 64(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt0=int64#11 -# asm 2: mov rt0=%r13 -mov %rax,%r13 - -# qhasm: rt1 = mulrdx -# asm 1: mov rt1=int64#12 -# asm 2: mov rt1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 72) -# asm 1: movq 72(mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt2=int64#13 -# asm 2: mov $0,>rt2=%r15 -mov $0,%r15 - -# qhasm: rt2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt3=int64#14 -# asm 2: mov $0,>rt3=%rbx -mov $0,%rbx - -# qhasm: rt3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq 72(mulx1=%r12 -movq 72(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq 80(mulx2=%r12 -movq 80(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#2 -# asm 2: movq 88(mulx3=%rsi -movq 88(%rsi),%rsi - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rt0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rt0 += mulzero -# asm 1: add addt0=int64#2 -# asm 2: mov $0,>addt0=%rsi -mov $0,%rsi - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#3 -# asm 2: mov $38,>addt1=%rdx -mov $38,%rdx - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae rz0=int64#2 -# asm 2: mov rz0=%rsi -mov %r13,%rsi - -# qhasm: rz1 = rt1 -# asm 1: mov rz1=int64#3 -# asm 2: mov rz1=%rdx -mov %r14,%rdx - -# qhasm: rz2 = rt2 -# asm 1: mov rz2=int64#4 -# asm 2: mov rz2=%rcx -mov %r15,%rcx - -# qhasm: rz3 = rt3 -# asm 1: mov rz3=int64#5 -# asm 2: mov rz3=%r8 -mov %rbx,%r8 - -# qhasm: carry? rz0 += c0_stack -# asm 1: addq addt0=int64#6 -# asm 2: mov $0,>addt0=%r9 -mov $0,%r9 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#7 -# asm 2: mov $38,>addt1=%rax -mov $38,%rax - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae subt0=int64#6 -# asm 2: mov $0,>subt0=%r9 -mov $0,%r9 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#7 -# asm 2: mov $38,>subt1=%rax -mov $38,%rax - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/ge25519_base.c b/ext/ed25519-amd64-asm/ge25519_base.c deleted file mode 100644 index a7ae9786..00000000 --- a/ext/ed25519-amd64-asm/ge25519_base.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "ge25519.h" - -const ge25519 ge25519_base = {{{0xC9562D608F25D51A, 0x692CC7609525A7B2, 0xC0A4E231FDD6DC5C, 0x216936D3CD6E53FE}}, - {{0x6666666666666658, 0x6666666666666666, 0x6666666666666666, 0x6666666666666666}}, - {{0x0000000000000001, 0x0000000000000000, 0x0000000000000000, 000000000000000000}}, - {{0x6DDE8AB3A5B7DDA3, 0x20F09F80775152F5, 0x66EA4E8E64ABE37D, 0x67875F0FD78B7665}}}; - diff --git a/ext/ed25519-amd64-asm/ge25519_base_niels.data b/ext/ed25519-amd64-asm/ge25519_base_niels.data deleted file mode 100644 index 8e3300cf..00000000 --- a/ext/ed25519-amd64-asm/ge25519_base_niels.data +++ /dev/null @@ -1,1536 +0,0 @@ -{{{0x9d103905d740913e, 0xfd399f05d140beb3, 0xa5c18434688f8a09, 0x44fd2f9298f81267}}, - {{0x2fbc93c6f58c3b85, 0xcf932dc6fb8c0e19, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65}}, - {{0xdbbd15674b6fbb59, 0x41e13f00eea2a5ea, 0xcdd49d1cc957c6fa, 0x4f0ebe1faf16ecca}}}, -{{{0x8a99a56042b4d5a8, 0x8f2b810c4e60acf6, 0xe09e236bb16e37aa, 0x6bb595a669c92555}}, - {{0x9224e7fc933c71d7, 0x9f469d967a0ff5b5, 0x5aa69a65e1d60702, 0x590c063fa87d2e2e}}, - {{0x6e347eaadad36802, 0xbaf3599383ee4805, 0x3bcabe10e6076826, 0x49314f0a165ed1b8}}}, -{{{0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, 0x8131f31a214bd6bd, 0x2ab91587555bda62}}, - {{0xaf25b0a84cee9730, 0x025a8430e8864b8a, 0xc11b50029f016732, 0x7a164e1b9a80f8f4}}, - {{0x9bf211f4f1674834, 0xb84e6b17f62df895, 0xd7de6f075b722a4e, 0x549a04b963bb2a21}}}, -{{{0x95fe050a056818bf, 0x327e89715660faa9, 0xc3e8e3cd06a05073, 0x27933f4c7445a49a}}, - {{0x287351b98efc099f, 0x6765c6f47dfd2538, 0xca348d3dfb0a9265, 0x680e910321e58727}}, - {{0xbf1e45ece51426b0, 0xe32bc63d6dba0f94, 0xe42974d58cf852c0, 0x44f079b1b0e64c18}}}, -{{{0x7f9182c3a447d6ba, 0xd50014d14b2729b7, 0xe33cf11cb864a087, 0x154a7e73eb1b55f3}}, - {{0xa212bc4408a5bb33, 0x8d5048c3c75eed02, 0xdd1beb0c5abfec44, 0x2945ccf146e206eb}}, - {{0xc832a179e7d003b3, 0x5f729d0a00124d7e, 0x62c1d4a10e6d8ff3, 0x68b8ac5938b27a98}}}, -{{{0x499806b67b7d8ca4, 0x575be28427d22739, 0xbb085ce7204553b9, 0x38b64c41ae417884}}, - {{0x3a0ceeeb77157131, 0x9b27158900c8af88, 0x8065b668da59a736, 0x51e57bb6a2cc38bd}}, - {{0x8f9dad91689de3a4, 0x175f2428f8fb9137, 0x050ab5329fcfb988, 0x7865dfa21354c09f}}}, -{{{0xba6f2c9aaa3221b1, 0x6ca021533bba23a7, 0x9dea764f92192c3a, 0x1d6edd5d2e5317e0}}, - {{0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e}}, - {{0x217a8aacab0fda36, 0xa528c6543d3549c8, 0x37d05b8b13ab7568, 0x233cef623a2cbc37}}}, -{{{0xe2a75dedf39234d9, 0x963d7680e1b558f9, 0x2c2741ac6e3c23fb, 0x3a9024a1320e01c3}}, - {{0x59b7596604dd3e8f, 0x6cb30377e288702c, 0xb1339c665ed9c323, 0x0915e76061bce52f}}, - {{0xdf7de835a834a37e, 0x8be19cda689857ea, 0x2c1185367167b326, 0x589eb3d9dbefd5c2}}}, -{{{0x7ec851ca553e2df3, 0xa71284cba64878b3, 0xe6b5e4193288d1e7, 0x4cf210ec5a9a8883}}, - {{0x322d04a52d9021f6, 0xb9c19f3375c6bf9c, 0x587a3a4342d20b09, 0x143b1cf8aa64fe61}}, - {{0x9f867c7d968acaab, 0x5f54258e27092729, 0xd0a7d34bea180975, 0x21b546a3374126e1}}}, -{{{0xa94ff858a2888343, 0xce0ed4565313ed3c, 0xf55c3dcfb5bf34fa, 0x0a653ca5c9eab371}}, - {{0x490a7a45d185218f, 0x9a15377846049335, 0x0060ea09cc31e1f6, 0x7e041577f86ee965}}, - {{0x66b2a496ce5b67f3, 0xff5492d8bd569796, 0x503cec294a592cd0, 0x566943650813acb2}}}, -{{{0xb818db0c26620798, 0x5d5c31d9606e354a, 0x0982fa4f00a8cdc7, 0x17e12bcd4653e2d4}}, - {{0x5672f9eb1dabb69d, 0xba70b535afe853fc, 0x47ac0f752796d66d, 0x32a5351794117275}}, - {{0xd3a644a6df648437, 0x703b6559880fbfdd, 0xcb852540ad3a1aa5, 0x0900b3f78e4c6468}}}, -{{{0x0a851b9f679d651b, 0xe108cb61033342f2, 0xd601f57fe88b30a3, 0x371f3acaed2dd714}}, - {{0xed280fbec816ad31, 0x52d9595bd8e6efe3, 0x0fe71772f6c623f5, 0x4314030b051e293c}}, - {{0xd560005efbf0bcad, 0x8eb70f2ed1870c5e, 0x201f9033d084e6a0, 0x4c3a5ae1ce7b6670}}}, -{{{0x4138a434dcb8fa95, 0x870cf67d6c96840b, 0xde388574297be82c, 0x7c814db27262a55a}}, - {{0xbaf875e4c93da0dd, 0xb93282a771b9294d, 0x80d63fb7f4c6c460, 0x6de9c73dea66c181}}, - {{0x478904d5a04df8f2, 0xfafbae4ab10142d3, 0xf6c8ac63555d0998, 0x5aac4a412f90b104}}}, -{{{0xc64f326b3ac92908, 0x5551b282e663e1e0, 0x476b35f54a1a4b83, 0x1b9da3fe189f68c2}}, - {{0x603a0d0abd7f5134, 0x8089c932e1d3ae46, 0xdf2591398798bd63, 0x1c145cd274ba0235}}, - {{0x32e8386475f3d743, 0x365b8baf6ae5d9ef, 0x825238b6385b681e, 0x234929c1167d65e1}}}, -{{{0x984decaba077ade8, 0x383f77ad19eb389d, 0xc7ec6b7e2954d794, 0x59c77b3aeb7c3a7a}}, - {{0x48145cc21d099fcf, 0x4535c192cc28d7e5, 0x80e7c1e548247e01, 0x4a5f28743b2973ee}}, - {{0xd3add725225ccf62, 0x911a3381b2152c5d, 0xd8b39fad5b08f87d, 0x6f05606b4799fe3b}}}, -{{{0x9ffe9e92177ba962, 0x98aee71d0de5cae1, 0x3ff4ae942d831044, 0x714de12e58533ac8}}, - {{0x5b433149f91b6483, 0xadb5dc655a2cbf62, 0x87fa8412632827b3, 0x60895e91ab49f8d8}}, - {{0xe9ecf2ed0cf86c18, 0xb46d06120735dfd4, 0xbc9da09804b96be7, 0x73e2e62fd96dc26b}}}, -{{{0xed5b635449aa515e, 0xa865c49f0bc6823a, 0x850c1fe95b42d1c4, 0x30d76d6f03d315b9}}, - {{0x2eccdd0e632f9c1d, 0x51d0b69676893115, 0x52dfb76ba8637a58, 0x6dd37d49a00eef39}}, - {{0x6c4444172106e4c7, 0xfb53d680928d7f69, 0xb4739ea4694d3f26, 0x10c697112e864bb0}}}, -{{{0x6493c4277dbe5fde, 0x265d4fad19ad7ea2, 0x0e00dfc846304590, 0x25e61cabed66fe09}}, - {{0x0ca62aa08358c805, 0x6a3d4ae37a204247, 0x7464d3a63b11eddc, 0x03bf9baf550806ef}}, - {{0x3f13e128cc586604, 0x6f5873ecb459747e, 0xa0b63dedcc1268f5, 0x566d78634586e22c}}}, -{{{0x1637a49f9cc10834, 0xbc8e56d5a89bc451, 0x1cb5ec0f7f7fd2db, 0x33975bca5ecc35d9}}, - {{0xa1054285c65a2fd0, 0x6c64112af31667c3, 0x680ae240731aee58, 0x14fba5f34793b22a}}, - {{0x3cd746166985f7d4, 0x593e5e84c9c80057, 0x2fc3f2b67b61131e, 0x14829cea83fc526c}}}, -{{{0xff437b8497dd95c2, 0x6c744e30aa4eb5a7, 0x9e0c5d613c85e88b, 0x2fd9c71e5f758173}}, - {{0x21e70b2f4e71ecb8, 0xe656ddb940a477e3, 0xbf6556cece1d4f80, 0x05fc3bc4535d7b7e}}, - {{0x24b8b3ae52afdedd, 0x3495638ced3b30cf, 0x33a4bc83a9be8195, 0x373767475c651f04}}}, -{{{0x2fba99fd40d1add9, 0xb307166f96f4d027, 0x4363f05215f03bae, 0x1fbea56c3b18f999}}, - {{0x634095cb14246590, 0xef12144016c15535, 0x9e38140c8910bc60, 0x6bf5905730907c8c}}, - {{0x0fa778f1e1415b8a, 0x06409ff7bac3a77e, 0x6f52d7b89aa29a50, 0x02521cf67a635a56}}}, -{{{0x513fee0b0a9d5294, 0x8f98e75c0fdf5a66, 0xd4618688bfe107ce, 0x3fa00a7e71382ced}}, - {{0xb1146720772f5ee4, 0xe8f894b196079ace, 0x4af8224d00ac824a, 0x001753d9f7cd6cc4}}, - {{0x3c69232d963ddb34, 0x1dde87dab4973858, 0xaad7d1f9a091f285, 0x12b5fe2fa048edb6}}}, -{{{0x71f0fbc496fce34d, 0x73b9826badf35bed, 0xd2047261ff28c561, 0x749b76f96fb1206f}}, - {{0xdf2b7c26ad6f1e92, 0x4b66d323504b8913, 0x8c409dc0751c8bc3, 0x6f7e93c20796c7b8}}, - {{0x1f5af604aea6ae05, 0xc12351f1bee49c99, 0x61a808b5eeff6b66, 0x0fcec10f01e02151}}}, -{{{0x644d58a649fe1e44, 0x21fcaea231ad777e, 0x02441c5a887fd0d2, 0x4901aa7183c511f3}}, - {{0x3df2d29dc4244e45, 0x2b020e7493d8de0a, 0x6cc8067e820c214d, 0x413779166feab90a}}, - {{0x08b1b7548c1af8f0, 0xce0f7a7c246299b4, 0xf760b0f91e06d939, 0x41bb887b726d1213}}}, -{{{0x9267806c567c49d8, 0x066d04ccca791e6a, 0xa69f5645e3cc394b, 0x5c95b686a0788cd2}}, - {{0x97d980e0aa39f7d2, 0x35d0384252c6b51c, 0x7d43f49307cd55aa, 0x56bd36cfb78ac362}}, - {{0x2ac519c10d14a954, 0xeaf474b494b5fa90, 0xe6af8382a9f87a5a, 0x0dea6db1879be094}}}, -{{{0xaa66bf547344e5ab, 0xda1258888f1b4309, 0x5e87d2b3fd564b2f, 0x5b2c78885483b1dd}}, - {{0x15baeb74d6a8797a, 0x7ef55cf1fac41732, 0x29001f5a3c8b05c5, 0x0ad7cc8752eaccfb}}, - {{0x52151362793408cf, 0xeb0f170319963d94, 0xa833b2fa883d9466, 0x093a7fa775003c78}}}, -{{{0xe5107de63a16d7be, 0xa377ffdc9af332cf, 0x70d5bf18440b677f, 0x6a252b19a4a31403}}, - {{0xb8e9604460a91286, 0x7f3fd8047778d3de, 0x67d01e31bf8a5e2d, 0x7b038a06c27b653e}}, - {{0x9ed919d5d36990f3, 0x5213aebbdb4eb9f2, 0xc708ea054cb99135, 0x58ded57f72260e56}}}, -{{{0x78e79dade9413d77, 0xf257f9d59729e67d, 0x59db910ee37aa7e6, 0x6aa11b5bbb9e039c}}, - {{0xda6d53265b0fd48b, 0x8960823193bfa988, 0xd78ac93261d57e28, 0x79f2942d3a5c8143}}, - {{0x97da2f25b6c88de9, 0x251ba7eaacf20169, 0x09b44f87ef4eb4e4, 0x7d90ab1bbc6a7da5}}}, -{{{0x9acca683a7016bfe, 0x90505f4df2c50b6d, 0x6b610d5fcce435aa, 0x19a10d446198ff96}}, - {{0x1a07a3f496b3c397, 0x11ceaa188f4e2532, 0x7d9498d5a7751bf0, 0x19ed161f508dd8a0}}, - {{0x560a2cd687dce6ca, 0x7f3568c48664cf4d, 0x8741e95222803a38, 0x483bdab1595653fc}}}, -{{{0xfa780f148734fa49, 0x106f0b70360534e0, 0x2210776fe3e307bd, 0x3286c109dde6a0fe}}, - {{0xd6cf4d0ab4da80f6, 0x82483e45f8307fe0, 0x05005269ae6f9da4, 0x1c7052909cf7877a}}, - {{0x32ee7de2874e98d4, 0x14c362e9b97e0c60, 0x5781dcde6a60a38a, 0x217dd5eaaa7aa840}}}, -{{{0x9db7c4d0248e1eb0, 0xe07697e14d74bf52, 0x1e6a9b173c562354, 0x7fa7c21f795a4965}}, - {{0x8bdf1fb9be8c0ec8, 0x00bae7f8e30a0282, 0x4963991dad6c4f6c, 0x07058a6e5df6f60a}}, - {{0xe9eb02c4db31f67f, 0xed25fd8910bcfb2b, 0x46c8131f5c5cddb4, 0x33b21c13a0cb9bce}}}, -{{{0x360692f8087d8e31, 0xf4dcc637d27163f7, 0x25a4e62065ea5963, 0x659bf72e5ac160d9}}, - {{0x9aafb9b05ee38c5b, 0xbf9d2d4e071a13c7, 0x8eee6e6de933290a, 0x1c3bab17ae109717}}, - {{0x1c9ab216c7cab7b0, 0x7d65d37407bbc3cc, 0x52744750504a58d5, 0x09f2606b131a2990}}}, -{{{0x40e87d44744346be, 0x1d48dad415b52b25, 0x7c3a8a18a13b603e, 0x4eb728c12fcdbdf7}}, - {{0x7e234c597c6691ae, 0x64889d3d0a85b4c8, 0xdae2c90c354afae7, 0x0a871e070c6a9e1d}}, - {{0x3301b5994bbc8989, 0x736bae3a5bdd4260, 0x0d61ade219d59e3c, 0x3ee7300f2685d464}}}, -{{{0xf5d255e49e7dd6b7, 0x8016115c610b1eac, 0x3c99975d92e187ca, 0x13815762979125c2}}, - {{0x43fa7947841e7518, 0xe5c6fa59639c46d7, 0xa1065e1de3052b74, 0x7d47c6a2cfb89030}}, - {{0x3fdad0148ef0d6e0, 0x9d3e749a91546f3c, 0x71ec621026bb8157, 0x148cf58d34c9ec80}}}, -{{{0x46a492f67934f027, 0x469984bef6840aa9, 0x5ca1bc2a89611854, 0x3ff2fa1ebd5dbbd4}}, - {{0xe2572f7d9ae4756d, 0x56c345bb88f3487f, 0x9fd10b6d6960a88d, 0x278febad4eaea1b9}}, - {{0xb1aa681f8c933966, 0x8c21949c20290c98, 0x39115291219d3c52, 0x4104dd02fe9c677b}}}, -{{{0x72b2bf5e1124422a, 0xa1fa0c3398a33ab5, 0x94cb6101fa52b666, 0x2c863b00afaf53d5}}, - {{0x81214e06db096ab8, 0x21a8b6c90ce44f35, 0x6524c12a409e2af5, 0x0165b5a48efca481}}, - {{0xf190a474a0846a76, 0x12eff984cd2f7cc0, 0x695e290658aa2b8f, 0x591b67d9bffec8b8}}}, -{{{0x312f0d1c80b49bfa, 0x5979515eabf3ec8a, 0x727033c09ef01c88, 0x3de02ec7ca8f7bcb}}, - {{0x99b9b3719f18b55d, 0xe465e5faa18c641e, 0x61081136c29f05ed, 0x489b4f867030128b}}, - {{0xd232102d3aeb92ef, 0xe16253b46116a861, 0x3d7eabe7190baa24, 0x49f5fbba496cbebf}}}, -{{{0x30949a108a5bcfd4, 0xdc40dd70bc6473eb, 0x92c294c1307c0d1c, 0x5604a86dcbfa6e74}}, - {{0x155d628c1e9c572e, 0x8a4d86acc5884741, 0x91a352f6515763eb, 0x06a1a6c28867515b}}, - {{0x7288d1d47c1764b6, 0x72541140e0418b51, 0x9f031a6018acf6d1, 0x20989e89fe2742c6}}}, -{{{0x499777fd3a2dcc7f, 0x32857c2ca54fd892, 0xa279d864d207e3a0, 0x0403ed1d0ca67e29}}, - {{0x1674278b85eaec2e, 0x5621dc077acb2bdf, 0x640a4c1661cbf45a, 0x730b9950f70595d3}}, - {{0xc94b2d35874ec552, 0xc5e6c8cf98246f8d, 0xf7cb46fa16c035ce, 0x5bd7454308303dcc}}}, -{{{0x7f9ad19528b24cc2, 0x7f6b54656335c181, 0x66b8b66e4fc07236, 0x133a78007380ad83}}, - {{0x85c4932115e7792a, 0xc64c89a2bdcdddc9, 0x9d1e3da8ada3d762, 0x5bb7db123067f82c}}, - {{0x0961f467c6ca62be, 0x04ec21d6211952ee, 0x182360779bd54770, 0x740dca6d58f0e0d2}}}, -{{{0x50b70bf5d3f0af0b, 0x4feaf48ae32e71f7, 0x60e84ed3a55bbd34, 0x00ed489b3f50d1ed}}, - {{0x3906c72aed261ae5, 0x9ab68fd988e100f7, 0xf5e9059af3360197, 0x0e53dc78bf2b6d47}}, - {{0xb90829bf7971877a, 0x5e4444636d17e631, 0x4d05c52e18276893, 0x27632d9a5a4a4af5}}}, -{{{0xd11ff05154b260ce, 0xd86dc38e72f95270, 0x601fcd0d267cc138, 0x2b67916429e90ccd}}, - {{0xa98285d187eaffdb, 0xa5b4fbbbd8d0a864, 0xb658f27f022663f7, 0x3bbc2b22d99ce282}}, - {{0xb917c952583c0a58, 0x653ff9b80fe4c6f3, 0x9b0da7d7bcdf3c0c, 0x43a0eeb6ab54d60e}}}, -{{{0x396966a46d4a5487, 0xf811a18aac2bb3ba, 0x66e4685b5628b26b, 0x70a477029d929b92}}, - {{0x3ac6322357875fe8, 0xd9d4f4ecf5fbcb8f, 0x8dee8493382bb620, 0x50c5eaa14c799fdc}}, - {{0xdd0edc8bd6f2fb3c, 0x54c63aa79cc7b7a0, 0xae0b032b2c8d9f1a, 0x6f9ce107602967fb}}}, -{{{0xad1054b1cde1c22a, 0xc4a8e90248eb32df, 0x5f3e7b33accdc0ea, 0x72364713fc79963e}}, - {{0x139693063520e0b5, 0x437fcf7c88ea03fe, 0xf7d4c40bd3c959bc, 0x699154d1f893ded9}}, - {{0x315d5c75b4b27526, 0xcccb842d0236daa5, 0x22f0c8a3345fee8e, 0x73975a617d39dbed}}}, -{{{0xe4024df96375da10, 0x78d3251a1830c870, 0x902b1948658cd91c, 0x7e18b10b29b7438a}}, - {{0x6f37f392f4433e46, 0x0e19b9a11f566b18, 0x220fb78a1fd1d662, 0x362a4258a381c94d}}, - {{0x9071d9132b6beb2f, 0x0f26e9ad28418247, 0xeab91ec9bdec925d, 0x4be65bc8f48af2de}}}, -{{{0x78487feba36e7028, 0x5f3f13001dd8ce34, 0x934fb12d4b30c489, 0x056c244d397f0a2b}}, - {{0x1d50fba257c26234, 0x7bd4823adeb0678b, 0xc2b0dc6ea6538af5, 0x5665eec6351da73e}}, - {{0xdb3ee00943bfb210, 0x4972018720800ac2, 0x26ab5d6173bd8667, 0x20b209c2ab204938}}}, -{{{0x549e342ac07fb34b, 0x02d8220821373d93, 0xbc262d70acd1f567, 0x7a92c9fdfbcac784}}, - {{0x1fcca94516bd3289, 0x448d65aa41420428, 0x59c3b7b216a55d62, 0x49992cc64e612cd8}}, - {{0x65bd1bea70f801de, 0x1befb7c0fe49e28a, 0xa86306cdb1b2ae4a, 0x3b7ac0cd265c2a09}}}, -{{{0x822bee438c01bcec, 0x530cb525c0fbc73b, 0x48519034c1953fe9, 0x265cc261e09a0f5b}}, - {{0xf0d54e4f22ed39a7, 0xa2aae91e5608150a, 0xf421b2e9eddae875, 0x31bc531d6b7de992}}, - {{0xdf3d134da980f971, 0x7a4fb8d1221a22a7, 0x3df7d42035aad6d8, 0x2a14edcc6a1a125e}}}, -{{{0xdf48ee0752cfce4e, 0xc3fffaf306ec08b7, 0x05710b2ab95459c4, 0x161d25fa963ea38d}}, - {{0x231a8c570478433c, 0xb7b5270ec281439d, 0xdbaa99eae3d9079f, 0x2c03f5256c2b03d9}}, - {{0x790f18757b53a47d, 0x307b0130cf0c5879, 0x31903d77257ef7f9, 0x699468bdbd96bbaf}}}, -{{{0xbd1f2f46f4dafecf, 0x7cef0114a47fd6f7, 0xd31ffdda4a47b37f, 0x525219a473905785}}, - {{0xd8dd3de66aa91948, 0x485064c22fc0d2cc, 0x9b48246634fdea2f, 0x293e1c4e6c4a2e3a}}, - {{0x376e134b925112e1, 0x703778b5dca15da0, 0xb04589af461c3111, 0x5b605c447f032823}}}, -{{{0xb965805920c47c89, 0xe7f0100c923b8fcc, 0x0001256502e2ef77, 0x24a76dcea8aeb3ee}}, - {{0x3be9fec6f0e7f04c, 0x866a579e75e34962, 0x5542ef161e1de61a, 0x2f12fef4cc5abdd5}}, - {{0x0a4522b2dfc0c740, 0x10d06e7f40c9a407, 0xc6cf144178cff668, 0x5e607b2518a43790}}}, -{{{0x58b31d8f6cdf1818, 0x35cfa74fc36258a2, 0xe1b3ff4f66e61d6e, 0x5067acab6ccdd5f7}}, - {{0xa02c431ca596cf14, 0xe3c42d40aed3e400, 0xd24526802e0f26db, 0x201f33139e457068}}, - {{0xfd527f6b08039d51, 0x18b14964017c0006, 0xd5220eb02e25a4a8, 0x397cba8862460375}}}, -{{{0x30c13093f05959b2, 0xe23aa18de9a97976, 0x222fd491721d5e26, 0x2339d320766e6c3a}}, - {{0x7815c3fbc81379e7, 0xa6619420dde12af1, 0xffa9c0f885a8fdd5, 0x771b4022c1e1c252}}, - {{0xd87dd986513a2fa7, 0xf5ac9b71f9d4cf08, 0xd06bc31b1ea283b3, 0x331a189219971a76}}}, -{{{0xf5166f45fb4f80c6, 0x9c36c7de61c775cf, 0xe3d4e81b9041d91c, 0x31167c6b83bdfe21}}, - {{0x26512f3a9d7572af, 0x5bcbe28868074a9e, 0x84edc1c11180f7c4, 0x1ac9619ff649a67b}}, - {{0xf22b3842524b1068, 0x5068343bee9ce987, 0xfc9d71844a6250c8, 0x612436341f08b111}}}, -{{{0xd99d41db874e898d, 0x09fea5f16c07dc20, 0x793d2c67d00f9bbc, 0x46ebe2309e5eff40}}, - {{0x8b6349e31a2d2638, 0x9ddfb7009bd3fd35, 0x7f8bf1b8a3a06ba4, 0x1522aa3178d90445}}, - {{0x2c382f5369614938, 0xdafe409ab72d6d10, 0xe8c83391b646f227, 0x45fe70f50524306c}}}, -{{{0xda4875a6960c0b8c, 0x5b68d076ef0e2f20, 0x07fb51cf3d0b8fd4, 0x428d1623a0e392d4}}, - {{0x62f24920c8951491, 0x05f007c83f630ca2, 0x6fbb45d2f5c9d4b8, 0x16619f6db57a2245}}, - {{0x084f4a4401a308fd, 0xa82219c376a5caac, 0xdeb8de4643d1bc7d, 0x1d81592d60bd38c6}}}, -{{{0xd833d7beec2a4c38, 0x2c9162830acc20ed, 0xe93a47aa92df7581, 0x702d67a3333c4a81}}, - {{0x3a4a369a2f89c8a1, 0x63137a1d7c8de80d, 0xbcac008a78eda015, 0x2cb8b3a5b483b03f}}, - {{0x36e417cbcb1b90a1, 0x33b3ddaa7f11794e, 0x3f510808885bc607, 0x24141dc0e6a8020d}}}, -{{{0x59f73c773fefee9d, 0xb3f1ef89c1cf989d, 0xe35dfb42e02e545f, 0x5766120b47a1b47c}}, - {{0x91925dccbd83157d, 0x3ca1205322cc8094, 0x28e57f183f90d6e4, 0x1a4714cede2e767b}}, - {{0xdb20ba0fb8b6b7ff, 0xb732c3b677511fa1, 0xa92b51c099f02d89, 0x4f3875ad489ca5f1}}}, -{{{0xc7fc762f4932ab22, 0x7ac0edf72f4c3c1b, 0x5f6b55aa9aa895e8, 0x3680274dad0a0081}}, - {{0x79ed13f6ee73eec0, 0xa5c6526d69110bb1, 0xe48928c38603860c, 0x722a1446fd7059f5}}, - {{0xd0959fe9a8cf8819, 0xd0a995508475a99c, 0x6eac173320b09cc5, 0x628ecf04331b1095}}}, -{{{0x98bcb118a9d0ddbc, 0xee449e3408b4802b, 0x87089226b8a6b104, 0x685f349a45c7915d}}, - {{0x9b41acf85c74ccf1, 0xb673318108265251, 0x99c92aed11adb147, 0x7a47d70d34ecb40f}}, - {{0x60a0c4cbcc43a4f5, 0x775c66ca3677bea9, 0xa17aa1752ff8f5ed, 0x11ded9020e01fdc0}}}, -{{{0x890e7809caefe704, 0x8728296de30e8c6c, 0x4c5cd2a392aeb1c9, 0x194263d15771531f}}, - {{0x471f95b03bea93b7, 0x0552d7d43313abd3, 0xbd9370e2e17e3f7b, 0x7b120f1db20e5bec}}, - {{0x17d2fb3d86502d7a, 0xb564d84450a69352, 0x7da962c8a60ed75d, 0x00d0f85b318736aa}}}, -{{{0x978b142e777c84fd, 0xf402644705a8c062, 0xa67ad51be7e612c7, 0x2f7b459698dd6a33}}, - {{0xa6753c1efd7621c1, 0x69c0b4a7445671f5, 0x971f527405b23c11, 0x387bc74851a8c7cd}}, - {{0x81894b4d4a52a9a8, 0xadd93e12f6b8832f, 0x184d8548b61bd638, 0x3f1c62dbd6c9f6cd}}}, -{{{0x2e8f1f0091910c1f, 0xa4df4fe0bff2e12c, 0x60c6560aee927438, 0x6338283facefc8fa}}, - {{0x3fad3e40148f693d, 0x052656e194eb9a72, 0x2f4dcbfd184f4e2f, 0x406f8db1c482e18b}}, - {{0x9e630d2c7f191ee4, 0x4fbf8301bc3ff670, 0x787d8e4e7afb73c4, 0x50d83d5be8f58fa5}}}, -{{{0x85683916c11a1897, 0x2d69a4efe506d008, 0x39af1378f664bd01, 0x65942131361517c6}}, - {{0xc0accf90b4d3b66d, 0xa7059de561732e60, 0x033d1f7870c6b0ba, 0x584161cd26d946e4}}, - {{0xbbf2b1a072d27ca2, 0xbf393c59fbdec704, 0xe98dbbcee262b81e, 0x02eebd0b3029b589}}}, -{{{0x61368756a60dac5f, 0x17e02f6aebabdc57, 0x7f193f2d4cce0f7d, 0x20234a7789ecdcf0}}, - {{0x8765b69f7b85c5e8, 0x6ff0678bd168bab2, 0x3a70e77c1d330f9b, 0x3a5f6d51b0af8e7c}}, - {{0x76d20db67178b252, 0x071c34f9d51ed160, 0xf62a4a20b3e41170, 0x7cd682353cffe366}}}, -{{{0x0be1a45bd887fab6, 0x2a846a32ba403b6e, 0xd9921012e96e6000, 0x2838c8863bdc0943}}, - {{0xa665cd6068acf4f3, 0x42d92d183cd7e3d3, 0x5759389d336025d9, 0x3ef0253b2b2cd8ff}}, - {{0xd16bb0cf4a465030, 0xfa496b4115c577ab, 0x82cfae8af4ab419d, 0x21dcb8a606a82812}}}, -{{{0x5c6004468c9d9fc8, 0x2540096ed42aa3cb, 0x125b4d4c12ee2f9c, 0x0bc3d08194a31dab}}, - {{0x9a8d00fabe7731ba, 0x8203607e629e1889, 0xb2cc023743f3d97f, 0x5d840dbf6c6f678b}}, - {{0x706e380d309fe18b, 0x6eb02da6b9e165c7, 0x57bbba997dae20ab, 0x3a4276232ac196dd}}}, -{{{0x4b42432c8a7084fa, 0x898a19e3dfb9e545, 0xbe9f00219c58e45d, 0x1ff177cea16debd1}}, - {{0x3bf8c172db447ecb, 0x5fcfc41fc6282dbd, 0x80acffc075aa15fe, 0x0770c9e824e1a9f9}}, - {{0xcf61d99a45b5b5fd, 0x860984e91b3a7924, 0xe7300919303e3e89, 0x39f264fd41500b1e}}}, -{{{0xa7ad3417dbe7e29c, 0xbd94376a2b9c139c, 0xa0e91b8e93597ba9, 0x1712d73468889840}}, - {{0xd19b4aabfe097be1, 0xa46dfce1dfe01929, 0xc3c908942ca6f1ff, 0x65c621272c35f14e}}, - {{0xe72b89f8ce3193dd, 0x4d103356a125c0bb, 0x0419a93d2e1cfe83, 0x22f9800ab19ce272}}}, -{{{0x605a368a3e9ef8cb, 0xe3e9c022a5504715, 0x553d48b05f24248f, 0x13f416cd647626e5}}, - {{0x42029fdd9a6efdac, 0xb912cebe34a54941, 0x640f64b987bdf37b, 0x4171a4d38598cab4}}, - {{0xfa2758aa99c94c8c, 0x23006f6fb000b807, 0xfbd291ddadda5392, 0x508214fa574bd1ab}}}, -{{{0xc20269153ed6fe4b, 0xa65a6739511d77c4, 0xcbde26462c14af94, 0x22f960ec6faba74b}}, - {{0x461a15bb53d003d6, 0xb2102888bcf3c965, 0x27c576756c683a5a, 0x3a7758a4c86cb447}}, - {{0x548111f693ae5076, 0x1dae21df1dfd54a6, 0x12248c90f3115e65, 0x5d9fd15f8de7f494}}}, -{{{0x031408d36d63727f, 0x6a379aefd7c7b533, 0xa9e18fc5ccaee24b, 0x332f35914f8fbed3}}, - {{0x3f244d2aeed7521e, 0x8e3a9028432e9615, 0xe164ba772e9c16d4, 0x3bc187fa47eb98d8}}, - {{0x6d470115ea86c20c, 0x998ab7cb6c46d125, 0xd77832b53a660188, 0x450d81ce906fba03}}}, -{{{0xf8ae4d2ad8453902, 0x7018058ee8db2d1d, 0xaab3995fc7d2c11e, 0x53b16d2324ccca79}}, - {{0x23264d66b2cae0b5, 0x7dbaed33ebca6576, 0x030ebed6f0d24ac8, 0x2a887f78f7635510}}, - {{0x2a23b9e75c012d4f, 0x0c974651cae1f2ea, 0x2fb63273675d70ca, 0x0ba7250b864403f5}}}, -{{{0xbb0d18fd029c6421, 0xbc2d142189298f02, 0x8347f8e68b250e96, 0x7b9f2fe8032d71c9}}, - {{0xdd63589386f86d9c, 0x61699176e13a85a4, 0x2e5111954eaa7d57, 0x32c21b57fb60bdfb}}, - {{0xd87823cd319e0780, 0xefc4cfc1897775c5, 0x4854fb129a0ab3f7, 0x12c49d417238c371}}}, -{{{0x0950b533ffe83769, 0x21861c1d8e1d6bd1, 0xf022d8381302e510, 0x2509200c6391cab4}}, - {{0x09b3a01783799542, 0x626dd08faad5ee3f, 0xba00bceeeb70149f, 0x1421b246a0a444c9}}, - {{0x4aa43a8e8c24a7c7, 0x04c1f540d8f05ef5, 0xadba5e0c0b3eb9dc, 0x2ab5504448a49ce3}}}, -{{{0x2ed227266f0f5dec, 0x9824ee415ed50824, 0x807bec7c9468d415, 0x7093bae1b521e23f}}, - {{0xdc07ac631c5d3afa, 0x58615171f9df8c6c, 0x72a079d89d73e2b0, 0x7301f4ceb4eae15d}}, - {{0x6409e759d6722c41, 0xa674e1cf72bf729b, 0xbc0a24eb3c21e569, 0x390167d24ebacb23}}}, -{{{0x27f58e3bba353f1c, 0x4c47764dbf6a4361, 0xafbbc4e56e562650, 0x07db2ee6aae1a45d}}, - {{0xd7bb054ba2f2120b, 0xe2b9ceaeb10589b7, 0x3fe8bac8f3c0edbe, 0x4cbd40767112cb69}}, - {{0x0b603cc029c58176, 0x5988e3825cb15d61, 0x2bb61413dcf0ad8d, 0x7b8eec6c74183287}}}, -{{{0xe4ca40782cd27cb0, 0xdaf9c323fbe967bd, 0xb29bd34a8ad41e9e, 0x72810497626ede4d}}, - {{0x32fee570fc386b73, 0xda8b0141da3a8cc7, 0x975ffd0ac8968359, 0x6ee809a1b132a855}}, - {{0x9444bb31fcfd863a, 0x2fe3690a3e4e48c5, 0xdc29c867d088fa25, 0x13bd1e38d173292e}}}, -{{{0xd32b4cd8696149b5, 0xe55937d781d8aab7, 0x0bcb2127ae122b94, 0x41e86fcfb14099b0}}, - {{0x223fb5cf1dfac521, 0x325c25316f554450, 0x030b98d7659177ac, 0x1ed018b64f88a4bd}}, - {{0x3630dfa1b802a6b0, 0x880f874742ad3bd5, 0x0af90d6ceec5a4d4, 0x746a247a37cdc5d9}}}, -{{{0xd531b8bd2b7b9af6, 0x5005093537fc5b51, 0x232fcf25c593546d, 0x20a365142bb40f49}}, - {{0x6eccd85278d941ed, 0x2254ae83d22f7843, 0xc522d02e7bbfcdb7, 0x681e3351bff0e4e2}}, - {{0x8b64b59d83034f45, 0x2f8b71f21fa20efb, 0x69249495ba6550e4, 0x539ef98e45d5472b}}}, -{{{0x6e7bb6a1a6205275, 0xaa4f21d7413c8e83, 0x6f56d155e88f5cb2, 0x2de25d4ba6345be1}}, - {{0xd074d8961cae743f, 0xf86d18f5ee1c63ed, 0x97bdc55be7f4ed29, 0x4cbad279663ab108}}, - {{0x80d19024a0d71fcd, 0xc525c20afb288af8, 0xb1a3974b5f3a6419, 0x7d7fbcefe2007233}}}, -{{{0xfaef1e6a266b2801, 0x866c68c4d5739f16, 0xf68a2fbc1b03762c, 0x5975435e87b75a8d}}, - {{0xcd7c5dc5f3c29094, 0xc781a29a2a9105ab, 0x80c61d36421c3058, 0x4f9cd196dcd8d4d7}}, - {{0x199297d86a7b3768, 0xd0d058241ad17a63, 0xba029cad5c1c0c17, 0x7ccdd084387a0307}}}, -{{{0xdca6422c6d260417, 0xae153d50948240bd, 0xa9c0c1b4fb68c677, 0x428bd0ed61d0cf53}}, - {{0x9b0c84186760cc93, 0xcdae007a1ab32a99, 0xa88dec86620bda18, 0x3593ca848190ca44}}, - {{0x9213189a5e849aa7, 0xd4d8c33565d8facd, 0x8c52545b53fdbbd1, 0x27398308da2d63e6}}}, -{{{0x42c38d28435ed413, 0xbd50f3603278ccc9, 0xbb07ab1a79da03ef, 0x269597aebe8c3355}}, - {{0xb9a10e4c0a702453, 0x0fa25866d57d1bde, 0xffb9d9b5cd27daf7, 0x572c2945492c33fd}}, - {{0xc77fc745d6cd30be, 0xe4dfe8d3e3baaefb, 0xa22c8830aa5dda0c, 0x7f985498c05bca80}}}, -{{{0x3849ce889f0be117, 0x8005ad1b7b54a288, 0x3da3c39f23fc921c, 0x76c2ec470a31f304}}, - {{0xd35615520fbf6363, 0x08045a45cf4dfba6, 0xeec24fbc873fa0c2, 0x30f2653cd69b12e7}}, - {{0x8a08c938aac10c85, 0x46179b60db276bcb, 0xa920c01e0e6fac70, 0x2f1273f1596473da}}}, -{{{0x4739fc7c8ae01e11, 0xfd5274904a6aab9f, 0x41d98a8287728f2e, 0x5d9e572ad85b69f2}}, - {{0x30488bd755a70bc0, 0x06d6b5a4f1d442e7, 0xead1a69ebc596162, 0x38ac1997edc5f784}}, - {{0x0666b517a751b13b, 0x747d06867e9b858c, 0xacacc011454dde49, 0x22dfcd9cbfe9e69c}}}, -{{{0x8ddbd2e0c30d0cd9, 0xad8e665facbb4333, 0x8f6b258c322a961f, 0x6b2916c05448c1c7}}, - {{0x56ec59b4103be0a1, 0x2ee3baecd259f969, 0x797cb29413f5cd32, 0x0fe9877824cde472}}, - {{0x7edb34d10aba913b, 0x4ea3cd822e6dac0e, 0x66083dff6578f815, 0x4c303f307ff00a17}}}, -{{{0xd30a3bd617b28c85, 0xc5d377b739773bea, 0xc6c6e78c1e6a5cbf, 0x0d61b8f78b2ab7c4}}, - {{0x29fc03580dd94500, 0xecd27aa46fbbec93, 0x130a155fc2e2a7f8, 0x416b151ab706a1d5}}, - {{0x56a8d7efe9c136b0, 0xbd07e5cd58e44b20, 0xafe62fda1b57e0ab, 0x191a2af74277e8d2}}}, -{{{0xd550095bab6f4985, 0x04f4cd5b4fbfaf1a, 0x9d8e2ed12a0c7540, 0x2bc24e04b2212286}}, - {{0x09d4b60b2fe09a14, 0xc384f0afdbb1747e, 0x58e2ea8978b5fd6e, 0x519ef577b5e09b0a}}, - {{0x1863d7d91124cca9, 0x7ac08145b88a708e, 0x2bcd7309857031f5, 0x62337a6e8ab8fae5}}}, -{{{0x4bcef17f06ffca16, 0xde06e1db692ae16a, 0x0753702d614f42b0, 0x5f6041b45b9212d0}}, - {{0xd1ab324e1b3a1273, 0x18947cf181055340, 0x3b5d9567a98c196e, 0x7fa00425802e1e68}}, - {{0x7d531574028c2705, 0x80317d69db0d75fe, 0x30fface8ef8c8ddd, 0x7e9de97bb6c3e998}}}, -{{{0x1558967b9e6585a3, 0x97c99ce098e98b92, 0x10af149b6eb3adad, 0x42181fe8f4d38cfa}}, - {{0xf004be62a24d40dd, 0xba0659910452d41f, 0x81c45ee162a44234, 0x4cb829d8a22266ef}}, - {{0x1dbcaa8407b86681, 0x081f001e8b26753b, 0x3cd7ce6a84048e81, 0x78af11633f25f22c}}}, -{{{0x8416ebd40b50babc, 0x1508722628208bee, 0xa3148fafb9c1c36d, 0x0d07daacd32d7d5d}}, - {{0x3241c00e7d65318c, 0xe6bee5dcd0e86de7, 0x118b2dc2fbc08c26, 0x680d04a7fc603dc3}}, - {{0xf9c2414a695aa3eb, 0xdaa42c4c05a68f21, 0x7c6c23987f93963e, 0x210e8cd30c3954e3}}}, -{{{0xac4201f210a71c06, 0x6a65e0aef3bfb021, 0xbc42c35c393632f7, 0x56ea8db1865f0742}}, - {{0x2b50f16137fe6c26, 0xe102bcd856e404d8, 0x12b0f1414c561f6b, 0x51b17bc8d028ec91}}, - {{0xfff5fb4bcf535119, 0xf4989d79df1108a0, 0xbdfcea659a3ba325, 0x18a11f1174d1a6f2}}}, -{{{0x407375ab3f6bba29, 0x9ec3b6d8991e482e, 0x99c80e82e55f92e9, 0x307c13b6fb0c0ae1}}, - {{0xfbd63cdad27a5f2c, 0xf00fc4bc8aa106d7, 0x53fb5c1a8e64a430, 0x04eaabe50c1a2e85}}, - {{0x24751021cb8ab5e7, 0xfc2344495c5010eb, 0x5f1e717b4e5610a1, 0x44da5f18c2710cd5}}}, -{{{0x033cc55ff1b82eb5, 0xb15ae36d411cae52, 0xba40b6198ffbacd3, 0x768edce1532e861f}}, - {{0x9156fe6b89d8eacc, 0xe6b79451e23126a1, 0xbd7463d93944eb4e, 0x726373f6767203ae}}, - {{0xe305ca72eb7ef68a, 0x662cf31f70eadb23, 0x18f026fdb4c45b68, 0x513b5384b5d2ecbd}}}, -{{{0x46d46280c729989e, 0x4b93fbd05368a5dd, 0x63df3f81d1765a89, 0x34cebd64b9a0a223}}, - {{0x5e2702878af34ceb, 0x900b0409b946d6ae, 0x6512ebf7dabd8512, 0x61d9b76988258f81}}, - {{0xa6c5a71349b7d94b, 0xa3f3d15823eb9446, 0x0416fbd277484834, 0x69d45e6f2c70812f}}}, -{{{0xce16f74bc53c1431, 0x2b9725ce2072edde, 0xb8b9c36fb5b23ee7, 0x7e2e0e450b5cc908}}, - {{0x9fe62b434f460efb, 0xded303d4a63607d6, 0xf052210eb7a0da24, 0x237e7dbe00545b93}}, - {{0x013575ed6701b430, 0x231094e69f0bfd10, 0x75320f1583e47f22, 0x71afa699b11155e3}}}, -{{{0x65ce6f9b3953b61d, 0xc65839eaafa141e6, 0x0f435ffda9f759fe, 0x021142e9c2b1c28e}}, - {{0xea423c1c473b50d6, 0x51e87a1f3b38ef10, 0x9b84bf5fb2c9be95, 0x00731fbc78f89a1c}}, - {{0xe430c71848f81880, 0xbf960c225ecec119, 0xb6dae0836bba15e3, 0x4c4d6f3347e15808}}}, -{{{0x18f7eccfc17d1fc9, 0x6c75f5a651403c14, 0xdbde712bf7ee0cdf, 0x193fddaaa7e47a22}}, - {{0x2f0cddfc988f1970, 0x6b916227b0b9f51b, 0x6ec7b6c4779176be, 0x38bf9500a88f9fa8}}, - {{0x1fd2c93c37e8876f, 0xa2f61e5a18d1462c, 0x5080f58239241276, 0x6a6fb99ebf0d4969}}}, -{{{0x6a46c1bb560855eb, 0x2416bb38f893f09d, 0xd71d11378f71acc1, 0x75f76914a31896ea}}, - {{0xeeb122b5b6e423c6, 0x939d7010f286ff8e, 0x90a92a831dcf5d8c, 0x136fda9f42c5eb10}}, - {{0xf94cdfb1a305bdd1, 0x0f364b9d9ff82c08, 0x2a87d8a5c3bb588a, 0x022183510be8dcba}}}, -{{{0x4af766385ead2d14, 0xa08ed880ca7c5830, 0x0d13a6e610211e3d, 0x6a071ce17b806c03}}, - {{0x9d5a710143307a7f, 0xb063de9ec47da45f, 0x22bbfe52be927ad3, 0x1387c441fd40426c}}, - {{0xb5d3c3d187978af8, 0x722b5a3d7f0e4413, 0x0d7b4848bb477ca0, 0x3171b26aaf1edc92}}}, -{{{0xa92f319097564ca8, 0xff7bb84c2275e119, 0x4f55fe37a4875150, 0x221fd4873cf0835a}}, - {{0xa60db7d8b28a47d1, 0xa6bf14d61770a4f1, 0xd4a1f89353ddbd58, 0x6c514a63344243e9}}, - {{0x2322204f3a156341, 0xfb73e0e9ba0a032d, 0xfce0dd4c410f030e, 0x48daa596fb924aaa}}}, -{{{0x6eca8e665ca59cc7, 0xa847254b2e38aca0, 0x31afc708d21e17ce, 0x676dd6fccad84af7}}, - {{0x14f61d5dc84c9793, 0x9941f9e3ef418206, 0xcdf5b88f346277ac, 0x58c837fa0e8a79a9}}, - {{0x0cf9688596fc9058, 0x1ddcbbf37b56a01b, 0xdcc2e77d4935d66a, 0x1c4f73f2c6a57f0a}}}, -{{{0x0e7a4fbd305fa0bb, 0x829d4ce054c663ad, 0xf421c3832fe33848, 0x795ac80d1bf64c42}}, - {{0xb36e706efc7c3484, 0x73dfc9b4c3c1cf61, 0xeb1d79c9781cc7e5, 0x70459adb7daf675c}}, - {{0x1b91db4991b42bb3, 0x572696234b02dcca, 0x9fdf9ee51f8c78dc, 0x5fe162848ce21fd3}}}, -{{{0xe2790aae4d077c41, 0x8b938270db7469a3, 0x6eb632dc8abd16a2, 0x720814ecaa064b72}}, - {{0x315c29c795115389, 0xd7e0e507862f74ce, 0x0c4a762185927432, 0x72de6c984a25a1e4}}, - {{0xae9ab553bf6aa310, 0x050a50a9806d6e1b, 0x92bb7403adff5139, 0x0394d27645be618b}}}, -{{{0x4d572251857eedf4, 0xe3724edde19e93c5, 0x8a71420e0b797035, 0x3b3c833687abe743}}, - {{0xf5396425b23545a4, 0x15a7a27e98fbb296, 0xab6c52bc636fdd86, 0x79d995a8419334ee}}, - {{0xcd8a8ea61195dd75, 0xa504d8a81dd9a82f, 0x540dca81a35879b6, 0x60dd16a379c86a8a}}}, -{{{0x35a2c8487381e559, 0x596ffea6d78082cb, 0xcb9771ebdba7b653, 0x5a08b5019b4da685}}, - {{0x3501d6f8153e47b8, 0xb7a9675414a2f60c, 0x112ee8b6455d9523, 0x4e62a3c18112ea8a}}, - {{0xc8d4ac04516ab786, 0x595af3215295b23d, 0xd6edd234db0230c1, 0x0929efe8825b41cc}}}, -{{{0x5f0601d1cbd0f2d3, 0x736e412f6132bb7f, 0x83604432238dde87, 0x1e3a5272f5c0753c}}, - {{0x8b3172b7ad56651d, 0x01581b7a3fabd717, 0x2dc94df6424df6e4, 0x30376e5d2c29284f}}, - {{0xd2918da78159a59c, 0x6bdc1cd93f0713f3, 0x565f7a934acd6590, 0x53daacec4cb4c128}}}, -{{{0x4ca73bd79cc8a7d6, 0x4d4a738f47e9a9b2, 0xf4cbf12942f5fe00, 0x01a13ff9bdbf0752}}, - {{0x99852bc3852cfdb0, 0x2cc12e9559d6ed0b, 0x70f9e2bf9b5ac27b, 0x4f3b8c117959ae99}}, - {{0x55b6c9c82ff26412, 0x1ac4a8c91fb667a8, 0xd527bfcfeb778bf2, 0x303337da7012a3be}}}, -{{{0x955422228c1c9d7c, 0x01fac1371a9b340f, 0x7e8d9177925b48d7, 0x53f8ad5661b3e31b}}, - {{0x976d3ccbfad2fdd1, 0xcb88839737a640a8, 0x2ff00c1d6734cb25, 0x269ff4dc789c2d2b}}, - {{0x0c003fbdc08d678d, 0x4d982fa37ead2b17, 0xc07e6bcdb2e582f1, 0x296c7291df412a44}}}, -{{{0x7903de2b33daf397, 0xd0ff0619c9a624b3, 0x8a1d252b555b3e18, 0x2b6d581c52e0b7c0}}, - {{0xdfb23205dab8b59e, 0x465aeaa0c8092250, 0xd133c1189a725d18, 0x2327370261f117d1}}, - {{0x3d0543d3623e7986, 0x679414c2c278a354, 0xae43f0cc726196f6, 0x7836c41f8245eaba}}}, -{{{0xe7a254db49e95a81, 0x5192d5d008b0ad73, 0x4d20e5b1d00afc07, 0x5d55f8012cf25f38}}, - {{0xca651e848011937c, 0xc6b0c46e6ef41a28, 0xb7021ba75f3f8d52, 0x119dff99ead7b9fd}}, - {{0x43eadfcbf4b31d4d, 0xc6503f7411148892, 0xfeee68c5060d3b17, 0x329293b3dd4a0ac8}}}, -{{{0x4e59214fe194961a, 0x49be7dc70d71cd4f, 0x9300cfd23b50f22d, 0x4789d446fc917232}}, - {{0x2879852d5d7cb208, 0xb8dedd70687df2e7, 0xdc0bffab21687891, 0x2b44c043677daa35}}, - {{0x1a1c87ab074eb78e, 0xfac6d18e99daf467, 0x3eacbbcd484f9067, 0x60c52eef2bb9a4e4}}}, -{{{0x0b5d89bc3bfd8bf1, 0xb06b9237c9f3551a, 0x0e4c16b0d53028f5, 0x10bc9c312ccfcaab}}, - {{0x702bc5c27cae6d11, 0x44c7699b54a48cab, 0xefbc4056ba492eb2, 0x70d77248d9b6676d}}, - {{0xaa8ae84b3ec2a05b, 0x98699ef4ed1781e0, 0x794513e4708e85d1, 0x63755bd3a976f413}}}, -{{{0xb55fa03e2ad10853, 0x356f75909ee63569, 0x9ff9f1fdbe69b890, 0x0d8cc1c48bc16f84}}, - {{0x3dc7101897f1acb7, 0x5dda7d5ec165bbd8, 0x508e5b9c0fa1020f, 0x2763751737c52a56}}, - {{0x029402d36eb419a9, 0xf0b44e7e77b460a5, 0xcfa86230d43c4956, 0x70c2dd8a7ad166e7}}}, -{{{0x656194509f6fec0e, 0xee2e7ea946c6518d, 0x9733c1f367e09b5c, 0x2e0fac6363948495}}, - {{0x91d4967db8ed7e13, 0x74252f0ad776817a, 0xe40982e00d852564, 0x32b8613816a53ce5}}, - {{0x79e7f7bee448cd64, 0x6ac83a67087886d0, 0xf89fd4d9a0e4db2e, 0x4179215c735a4f41}}}, -{{{0x8c7094e7d7dced2a, 0x97fb8ac347d39c70, 0xe13be033a906d902, 0x700344a30cd99d76}}, - {{0xe4ae33b9286bcd34, 0xb7ef7eb6559dd6dc, 0x278b141fb3d38e1f, 0x31fa85662241c286}}, - {{0xaf826c422e3622f4, 0xc12029879833502d, 0x9bc1b7e12b389123, 0x24bb2312a9952489}}}, -{{{0xb1a8ed1732de67c3, 0x3cb49418461b4948, 0x8ebd434376cfbcd2, 0x0fee3e871e188008}}, - {{0x41f80c2af5f85c6b, 0x687284c304fa6794, 0x8945df99a3ba1bad, 0x0d1d2af9ffeb5d16}}, - {{0xa9da8aa132621edf, 0x30b822a159226579, 0x4004197ba79ac193, 0x16acd79718531d76}}}, -{{{0x72df72af2d9b1d3d, 0x63462a36a432245a, 0x3ecea07916b39637, 0x123e0ef6b9302309}}, - {{0xc959c6c57887b6ad, 0x94e19ead5f90feba, 0x16e24e62a342f504, 0x164ed34b18161700}}, - {{0x487ed94c192fe69a, 0x61ae2cea3a911513, 0x877bf6d3b9a4de27, 0x78da0fc61073f3eb}}}, -{{{0x5bf15d28e52bc66a, 0x2c47e31870f01a8e, 0x2419afbc06c28bdd, 0x2d25deeb256b173a}}, - {{0xa29f80f1680c3a94, 0x71f77e151ae9e7e6, 0x1100f15848017973, 0x054aa4b316b38ddd}}, - {{0xdfc8468d19267cb8, 0x0b28789c66e54daf, 0x2aeb1d2a666eec17, 0x134610a6ab7da760}}}, -{{{0xcaf55ec27c59b23f, 0x99aeed3e154d04f2, 0x68441d72e14141f4, 0x140345133932a0a2}}, - {{0xd91430e0dc028c3c, 0x0eb955a85217c771, 0x4b09e1ed2c99a1fa, 0x42881af2bd6a743c}}, - {{0x7bfec69aab5cad3d, 0xc23e8cd34cb2cfad, 0x685dd14bfb37d6a2, 0x0ad6d64415677a18}}}, -{{{0x781a439e417becb5, 0x4ac5938cd10e0266, 0x5da385110692ac24, 0x11b065a2ade31233}}, - {{0x7914892847927e9f, 0x33dad6ef370aa877, 0x1f8f24fa11122703, 0x5265ac2f2adf9592}}, - {{0x405fdd309afcb346, 0xd9723d4428e63f54, 0x94c01df05f65aaae, 0x43e4dc3ae14c0809}}}, -{{{0xbc12c7f1a938a517, 0x473028ab3180b2e1, 0x3f78571efbcd254a, 0x74e534426ff6f90f}}, - {{0xea6f7ac3adc2c6a3, 0xd0e928f6e9717c94, 0xe2d379ead645eaf5, 0x46dd8785c51ffbbe}}, - {{0x709801be375c8898, 0x4b06dab5e3fd8348, 0x75880ced27230714, 0x2b09468fdd2f4c42}}}, -{{{0x97c749eeb701cb96, 0x83f438d4b6a369c3, 0x62962b8b9a402cd9, 0x6976c7509888df7b}}, - {{0x5b97946582ffa02a, 0xda096a51fea8f549, 0xa06351375f77af9b, 0x1bcfde61201d1e76}}, - {{0x4a4a5490246a59a2, 0xd63ebddee87fdd90, 0xd9437c670d2371fa, 0x69e87308d30f8ed6}}}, -{{{0x435a8bb15656beb0, 0xf8fac9ba4f4d5bca, 0xb9b278c41548c075, 0x3eb0ef76e892b622}}, - {{0x0f80bf028bc80303, 0x6aae16b37a18cefb, 0xdd47ea47d72cd6a3, 0x61943588f4ed39aa}}, - {{0xd26e5c3e91039f85, 0xc0e9e77df6f33aa9, 0xe8968c5570066a93, 0x3c34d1881faaaddd}}}, -{{{0x3f9d2b5ea09f9ec0, 0x1dab3b6fb623a890, 0xa09ba3ea72d926c4, 0x374193513fd8b36d}}, - {{0xbd5b0b8f2fffe0d9, 0x6aa254103ed24fb9, 0x2ac7d7bcb26821c4, 0x605b394b60dca36a}}, - {{0xb4e856e45a9d1ed2, 0xefe848766c97a9a2, 0xb104cf641e5eee7d, 0x2f50b81c88a71c8f}}}, -{{{0x31723c61fc6811bb, 0x9cb450486211800f, 0x768933d347995753, 0x3491a53502752fcd}}, - {{0x2b552ca0a7da522a, 0x3230b336449b0250, 0xf2c4c5bca4b99fb9, 0x7b2c674958074a22}}, - {{0xd55165883ed28cdf, 0x12d84fd2d362de39, 0x0a874ad3e3378e4f, 0x000d2b1f7c763e74}}}, -{{{0x3d420811d06d4a67, 0xbefc048590e0ffe3, 0xf870c6b7bd487bde, 0x6e2a7316319afa28}}, - {{0x9624778c3e94a8ab, 0x0ad6f3cee9a78bec, 0x948ac7810d743c4f, 0x76627935aaecfccc}}, - {{0x56a8ac24d6d59a9f, 0xc8db753e3096f006, 0x477f41e68f4c5299, 0x588d851cf6c86114}}}, -{{{0x51138ec78df6b0fe, 0x5397da89e575f51b, 0x09207a1d717af1b9, 0x2102fdba2b20d650}}, - {{0xcd2a65e777d1f515, 0x548991878faa60f1, 0xb1b73bbcdabc06e5, 0x654878cba97cc9fb}}, - {{0x969ee405055ce6a1, 0x36bca7681251ad29, 0x3a1af517aa7da415, 0x0ad725db29ecb2ba}}}, -{{{0xdc4267b1834e2457, 0xb67544b570ce1bc5, 0x1af07a0bf7d15ed7, 0x4aefcffb71a03650}}, - {{0xfec7bc0c9b056f85, 0x537d5268e7f5ffd7, 0x77afc6624312aefa, 0x4f675f5302399fd9}}, - {{0xc32d36360415171e, 0xcd2bef118998483b, 0x870a6eadd0945110, 0x0bccbb72a2a86561}}}, -{{{0x185e962feab1a9c8, 0x86e7e63565147dcd, 0xb092e031bb5b6df2, 0x4024f0ab59d6b73e}}, - {{0x186d5e4c50fe1296, 0xe0397b82fee89f7e, 0x3bc7f6c5507031b0, 0x6678fd69108f37c2}}, - {{0x1586fa31636863c2, 0x07f68c48572d33f2, 0x4f73cc9f789eaefc, 0x2d42e2108ead4701}}}, -{{{0x97f5131594dfd29b, 0x6155985d313f4c6a, 0xeba13f0708455010, 0x676b2608b8d2d322}}, - {{0x21717b0d0f537593, 0x914e690b131e064c, 0x1bb687ae752ae09f, 0x420bf3a79b423c6e}}, - {{0x8138ba651c5b2b47, 0x8671b6ec311b1b80, 0x7bff0cb1bc3135b0, 0x745d2ffa9c0cf1e0}}}, -{{{0xbf525a1e2bc9c8bd, 0xea5b260826479d81, 0xd511c70edf0155db, 0x1ae23ceb960cf5d0}}, - {{0x6036df5721d34e6a, 0xb1db8827997bb3d0, 0xd3c209c3c8756afa, 0x06e15be54c1dc839}}, - {{0x5b725d871932994a, 0x32351cb5ceb1dab0, 0x7dc41549dab7ca05, 0x58ded861278ec1f7}}}, -{{{0xd8173793f266c55c, 0xc8c976c5cc454e49, 0x5ce382f8bc26c3a8, 0x2ff39de85485f6f9}}, - {{0x2dfb5ba8b6c2c9a8, 0x48eeef8ef52c598c, 0x33809107f12d1573, 0x08ba696b531d5bd8}}, - {{0x77ed3eeec3efc57a, 0x04e05517d4ff4811, 0xea3d7a3ff1a671cb, 0x120633b4947cfe54}}}, -{{{0x0b94987891610042, 0x4ee7b13cecebfae8, 0x70be739594f0a4c0, 0x35d30a99b4d59185}}, - {{0x82bd31474912100a, 0xde237b6d7e6fbe06, 0xe11e761911ea79c6, 0x07433be3cb393bde}}, - {{0xff7944c05ce997f4, 0x575d3de4b05c51a3, 0x583381fd5a76847c, 0x2d873ede7af6da9f}}}, -{{{0x157a316443373409, 0xfab8b7eef4aa81d9, 0xb093fee6f5a64806, 0x2e773654707fa7b6}}, - {{0xaa6202e14e5df981, 0xa20d59175015e1f5, 0x18a275d3bae21d6c, 0x0543618a01600253}}, - {{0x0deabdf4974c23c1, 0xaa6f0a259dce4693, 0x04202cb8a29aba2c, 0x4b1443362d07960d}}}, -{{{0x47b837f753242cec, 0x256dc48cc04212f2, 0xe222fbfbe1d928c5, 0x48ea295bad8a2c07}}, - {{0x299b1c3f57c5715e, 0x96cb929e6b686d90, 0x3004806447235ab3, 0x2c435c24a44d9fe1}}, - {{0x0607c97c80f8833f, 0x0e851578ca25ec5b, 0x54f7450b161ebb6f, 0x7bcb4792a0def80e}}}, -{{{0x8487e3d02bc73659, 0x4baf8445059979df, 0xd17c975adcad6fbf, 0x57369f0bdefc96b6}}, - {{0x1cecd0a0045224c2, 0x757f1b1b69e53952, 0x775b7a925289f681, 0x1b6cc62016736148}}, - {{0xf1a9990175638698, 0x353dd1beeeaa60d3, 0x849471334c9ba488, 0x63fa6e6843ade311}}}, -{{{0xd15c20536597c168, 0x9f73740098d28789, 0x18aee7f13257ba1f, 0x3418bfda07346f14}}, - {{0x2195becdd24b5eb7, 0x5e41f18cc0cd44f9, 0xdf28074441ca9ede, 0x07073b98f35b7d67}}, - {{0xd03c676c4ce530d4, 0x0b64c0473b5df9f4, 0x065cef8b19b3a31e, 0x3084d661533102c9}}}, -{{{0xe1f6b79ebf8469ad, 0x15801004e2663135, 0x9a498330af74181b, 0x3ba2504f049b673c}}, - {{0x9a6ce876760321fd, 0x7fe2b5109eb63ad8, 0x00e7d4ae8ac80592, 0x73d86b7abb6f723a}}, - {{0x0b52b5606dba5ab6, 0xa9134f0fbbb1edab, 0x30a9520d9b04a635, 0x6813b8f37973e5db}}}, -{{{0x9854b054334127c1, 0x105d047882fbff25, 0xdb49f7f944186f4f, 0x1768e838bed0b900}}, - {{0xf194ca56f3157e29, 0x136d35705ef528a5, 0xdd4cef778b0599bc, 0x7d5472af24f833ed}}, - {{0xd0ef874daf33da47, 0x00d3be5db6e339f9, 0x3f2a8a2f9c9ceece, 0x5d1aeb792352435a}}}, -{{{0xf59e6bb319cd63ca, 0x670c159221d06839, 0xb06d565b2150cab6, 0x20fb199d104f12a3}}, - {{0x12c7bfaeb61ba775, 0xb84e621fe263bffd, 0x0b47a5c35c840dcf, 0x7e83be0bccaf8634}}, - {{0x61943dee6d99c120, 0x86101f2e460b9fe0, 0x6bb2f1518ee8598d, 0x76b76289fcc475cc}}}, -{{{0x791b4cc1756286fa, 0xdbced317d74a157c, 0x7e732421ea72bde6, 0x01fe18491131c8e9}}, - {{0x4245f1a1522ec0b3, 0x558785b22a75656d, 0x1d485a2548a1b3c0, 0x60959eccd58fe09f}}, - {{0x3ebfeb7ba8ed7a09, 0x49fdc2bbe502789c, 0x44ebce5d3c119428, 0x35e1eb55be947f4a}}}, -{{{0xdbdae701c5738dd3, 0xf9c6f635b26f1bee, 0x61e96a8042f15ef4, 0x3aa1d11faf60a4d8}}, - {{0x14fd6dfa726ccc74, 0x3b084cfe2f53b965, 0xf33ae4f552a2c8b4, 0x59aab07a0d40166a}}, - {{0x77bcec4c925eac25, 0x1848718460137738, 0x5b374337fea9f451, 0x1865e78ec8e6aa46}}}, -{{{0xccc4b7c7b66e1f7a, 0x44157e25f50c2f7e, 0x3ef06dfc713eaf1c, 0x582f446752da63f7}}, - {{0x967c54e91c529ccb, 0x30f6269264c635fb, 0x2747aff478121965, 0x17038418eaf66f5c}}, - {{0xc6317bd320324ce4, 0xa81042e8a4488bc4, 0xb21ef18b4e5a1364, 0x0c2a1c4bcda28dc9}}}, -{{{0xd24dc7d06f1f0447, 0xb2269e3edb87c059, 0xd15b0272fbb2d28f, 0x7c558bd1c6f64877}}, - {{0xedc4814869bd6945, 0x0d6d907dbe1c8d22, 0xc63bd212d55cc5ab, 0x5a6a9b30a314dc83}}, - {{0xd0ec1524d396463d, 0x12bb628ac35a24f0, 0xa50c3a791cbc5fa4, 0x0404a5ca0afbafc3}}}, -{{{0x8c1f40070aa743d6, 0xccbad0cb5b265ee8, 0x574b046b668fd2de, 0x46395bfdcadd9633}}, - {{0x62bc9e1b2a416fd1, 0xb5c6f728e350598b, 0x04343fd83d5d6967, 0x39527516e7f8ee98}}, - {{0x117fdb2d1a5d9a9c, 0x9c7745bcd1005c2a, 0xefd4bef154d56fea, 0x76579a29e822d016}}}, -{{{0x45b68e7e49c02a17, 0x23cd51a2bca9a37f, 0x3ed65f11ec224c1b, 0x43a384dc9e05bdb1}}, - {{0x333cb51352b434f2, 0xd832284993de80e1, 0xb5512887750d35ce, 0x02c514bb2a2777c1}}, - {{0x684bd5da8bf1b645, 0xfb8bd37ef6b54b53, 0x313916d7a9b0d253, 0x1160920961548059}}}, -{{{0xb44d166929dacfaa, 0xda529f4c8413598f, 0xe9ef63ca453d5559, 0x351e125bc5698e0b}}, - {{0x7a385616369b4dcd, 0x75c02ca7655c3563, 0x7dc21bf9d4f18021, 0x2f637d7491e6e042}}, - {{0xd4b49b461af67bbe, 0xd603037ac8ab8961, 0x71dee19ff9a699fb, 0x7f182d06e7ce2a9a}}}, -{{{0x7a7c8e64ab0168ec, 0xcb5a4a5515edc543, 0x095519d347cd0eda, 0x67d4ac8c343e93b0}}, - {{0x09454b728e217522, 0xaa58e8f4d484b8d8, 0xd358254d7f46903c, 0x44acc043241c5217}}, - {{0x1c7d6bbb4f7a5777, 0x8b35fed4918313e1, 0x4adca1c6c96b4684, 0x556d1c8312ad71bd}}}, -{{{0x17ef40e30c8d3982, 0x31f7073e15a3fa34, 0x4f21f3cb0773646e, 0x746c6c6d1d824eff}}, - {{0x81f06756b11be821, 0x0faff82310a3f3dd, 0xf8b2d0556a99465d, 0x097abe38cc8c7f05}}, - {{0x0c49c9877ea52da4, 0x4c4369559bdc1d43, 0x022c3809f7ccebd2, 0x577e14a34bee84bd}}}, -{{{0xf0e268ac61a73b0a, 0xf2fafa103791a5f5, 0xc1e13e826b6d00e9, 0x60fa7ee96fd78f42}}, - {{0x94fecebebd4dd72b, 0xf46a4fda060f2211, 0x124a5977c0c8d1ff, 0x705304b8fb009295}}, - {{0xb63d1d354d296ec6, 0xf3c3053e5fad31d8, 0x670b958cb4bd42ec, 0x21398e0ca16353fd}}}, -{{{0x216ab2ca8da7d2ef, 0x366ad9dd99f42827, 0xae64b9004fdd3c75, 0x403a395b53909e62}}, - {{0x86c5fc16861b7e9a, 0xf6a330476a27c451, 0x01667267a1e93597, 0x05ffb9cd6082dfeb}}, - {{0xa617fa9ff53f6139, 0x60f2b5e513e66cb6, 0xd7a8beefb3448aa4, 0x7a2932856f5ea192}}}, -{{{0x0b39d761b02de888, 0x5f550e7ed2414e1f, 0xa6bfa45822e1a940, 0x050a2f7dfd447b99}}, - {{0xb89c444879639302, 0x4ae4f19350c67f2c, 0xf0b35da8c81af9c6, 0x39d0003546871017}}, - {{0x437c3b33a650db77, 0x6bafe81dbac52bb2, 0xfe99402d2db7d318, 0x2b5b7eec372ba6ce}}}, -{{{0xb3bc4bbd83f50eef, 0x508f0c998c927866, 0x43e76587c8b7e66e, 0x0f7655a3a47f98d9}}, - {{0xa694404d613ac8f4, 0x500c3c2bfa97e72c, 0x874104d21fcec210, 0x1b205fb38604a8ee}}, - {{0x55ecad37d24b133c, 0x441e147d6038c90b, 0x656683a1d62c6fee, 0x0157d5dc87e0ecae}}}, -{{{0xf2a7af510354c13d, 0xd7a0b145aa372b60, 0x2869b96a05a3d470, 0x6528e42d82460173}}, - {{0x95265514d71eb524, 0xe603d8815df14593, 0x147cdf410d4de6b7, 0x5293b1730437c850}}, - {{0x23d0e0814bccf226, 0x92c745cd8196fb93, 0x8b61796c59541e5b, 0x40a44df0c021f978}}}, -{{{0xdaa869894f20ea6a, 0xea14a3d14c620618, 0x6001fccb090bf8be, 0x35f4e822947e9cf0}}, - {{0x86c96e514bc5d095, 0xf20d4098fca6804a, 0x27363d89c826ea5d, 0x39ca36565719cacf}}, - {{0x97506f2f6f87b75c, 0xc624aea0034ae070, 0x1ec856e3aad34dd6, 0x055b0be0e440e58f}}}, -{{{0x6469a17d89735d12, 0xdb6f27d5e662b9f1, 0x9fcba3286a395681, 0x363b8004d269af25}}, - {{0x4d12a04b6ea33da2, 0x57cf4c15e36126dd, 0x90ec9675ee44d967, 0x64ca348d2a985aac}}, - {{0x99588e19e4c4912d, 0xefcc3b4e1ca5ce6b, 0x4522ea60fa5b98d5, 0x7064bbab1de4a819}}}, -{{{0xb919e1515a770641, 0xa9a2e2c74e7f8039, 0x7527250b3df23109, 0x756a7330ac27b78b}}, - {{0xa290c06142542129, 0xf2e2c2aebe8d5b90, 0xcf2458db76abfe1b, 0x02157ade83d626bf}}, - {{0x3e46972a1b9a038b, 0x2e4ee66a7ee03fb4, 0x81a248776edbb4ca, 0x1a944ee88ecd0563}}}, -{{{0xd5a91d1151039372, 0x2ed377b799ca26de, 0xa17202acfd366b6b, 0x0730291bd6901995}}, - {{0xbb40a859182362d6, 0xb99f55778a4d1abb, 0x8d18b427758559f6, 0x26c20fe74d26235a}}, - {{0x648d1d9fe9cc22f5, 0x66bc561928dd577c, 0x47d3ed21652439d1, 0x49d271acedaf8b49}}}, -{{{0x89f5058a382b33f3, 0x5ae2ba0bad48c0b4, 0x8f93b503a53db36e, 0x5aa3ed9d95a232e6}}, - {{0x2798aaf9b4b75601, 0x5eac72135c8dad72, 0xd2ceaa6161b7a023, 0x1bbfb284e98f7d4e}}, - {{0x656777e9c7d96561, 0xcb2b125472c78036, 0x65053299d9506eee, 0x4a07e14e5e8957cc}}}, -{{{0x4ee412cb980df999, 0xa315d76f3c6ec771, 0xbba5edde925c77fd, 0x3f0bac391d313402}}, - {{0x240b58cdc477a49b, 0xfd38dade6447f017, 0x19928d32a7c86aad, 0x50af7aed84afa081}}, - {{0x6e4fde0115f65be5, 0x29982621216109b2, 0x780205810badd6d9, 0x1921a316baebd006}}}, -{{{0x89422f7edfb870fc, 0x2c296beb4f76b3bd, 0x0738f1d436c24df7, 0x6458df41e273aeb0}}, - {{0xd75aad9ad9f3c18b, 0x566a0eef60b1c19c, 0x3e9a0bac255c0ed9, 0x7b049deca062c7f5}}, - {{0xdccbe37a35444483, 0x758879330fedbe93, 0x786004c312c5dd87, 0x6093dccbc2950e64}}}, -{{{0x1ff39a8585e0706d, 0x36d0a5d8b3e73933, 0x43b9f2e1718f453b, 0x57d1ea084827a97c}}, - {{0x6bdeeebe6084034b, 0x3199c2b6780fb854, 0x973376abb62d0695, 0x6e3180c98b647d90}}, - {{0xee7ab6e7a128b071, 0xa4c1596d93a88baa, 0xf7b4de82b2216130, 0x363e999ddd97bd18}}}, -{{{0x96a843c135ee1fc4, 0x976eb35508e4c8cf, 0xb42f6801b58cd330, 0x48ee9b78693a052b}}, - {{0x2f1848dce24baec6, 0x769b7255babcaf60, 0x90cb3c6e3cefe931, 0x231f979bc6f9b355}}, - {{0x5c31de4bcc2af3c6, 0xb04bb030fe208d1f, 0xb78d7009c14fb466, 0x079bfa9b08792413}}}, -{{{0xe3903a51da300df4, 0x843964233da95ab0, 0xed3cf12d0b356480, 0x038c77f684817194}}, - {{0xf3c9ed80a2d54245, 0x0aa08b7877f63952, 0xd76dac63d1085475, 0x1ef4fb159470636b}}, - {{0x854e5ee65b167bec, 0x59590a4296d0cdc2, 0x72b2df3498102199, 0x575ee92a4a0bff56}}}, -{{{0xd4c080908a182fcf, 0x30e170c299489dbd, 0x05babd5752f733de, 0x43d4e7112cd3fd00}}, - {{0x5d46bc450aa4d801, 0xc3af1227a533b9d8, 0x389e3b262b8906c2, 0x200a1e7e382f581b}}, - {{0x518db967eaf93ac5, 0x71bc989b056652c0, 0xfe2b85d9567197f5, 0x050eca52651e4e38}}}, -{{{0xc3431ade453f0c9c, 0xe9f5045eff703b9b, 0xfcd97ac9ed847b3d, 0x4b0ee6c21c58f4c6}}, - {{0x97ac397660e668ea, 0x9b19bbfe153ab497, 0x4cb179b534eca79f, 0x6151c09fa131ae57}}, - {{0x3af55c0dfdf05d96, 0xdd262ee02ab4ee7a, 0x11b2bb8712171709, 0x1fef24fa800f030b}}}, -{{{0xb496123a6b6c6609, 0xa750fe8580ab5938, 0xf471bf39b7c27a5f, 0x507903ce77ac193c}}, - {{0xff91a66a90166220, 0xf22552ae5bf1e009, 0x7dff85d87f90df7c, 0x4f620ffe0c736fb9}}, - {{0x62f90d65dfde3e34, 0xcf28c592b9fa5fad, 0x99c86ef9c6164510, 0x25d448044a256c84}}}, -{{{0xbd68230ec7e9b16f, 0x0eb1b9c1c1c5795d, 0x7943c8c495b6b1ff, 0x2f9faf620bbacf5e}}, - {{0x2c7c4415c9022b55, 0x56a0d241812eb1fe, 0xf02ea1c9d7b65e0d, 0x4180512fd5323b26}}, - {{0xa4ff3e698a48a5db, 0xba6a3806bd95403b, 0x9f7ce1af47d5b65d, 0x15e087e55939d2fb}}}, -{{{0x12207543745c1496, 0xdaff3cfdda38610c, 0xe4e797272c71c34f, 0x39c07b1934bdede9}}, - {{0x8894186efb963f38, 0x48a00e80dc639bd5, 0xa4e8092be96c1c99, 0x5a097d54ca573661}}, - {{0x2d45892b17c9e755, 0xd033fd7289308df8, 0x6c2fe9d9525b8bd9, 0x2edbecf1c11cc079}}}, -{{{0x1616a4e3c715a0d2, 0x53623cb0f8341d4d, 0x96ef5329c7e899cb, 0x3d4e8dbba668baa6}}, - {{0xee0f0fddd087a25f, 0x9c7531555c3e34ee, 0x660c572e8fab3ab5, 0x0854fc44544cd3b2}}, - {{0x61eba0c555edad19, 0x24b533fef0a83de6, 0x3b77042883baa5f8, 0x678f82b898a47e8d}}}, -{{{0xb1491d0bd6900c54, 0x3539722c9d132636, 0x4db928920b362bc9, 0x4d7cd1fea68b69df}}, - {{0x1e09d94057775696, 0xeed1265c3cd951db, 0xfa9dac2b20bce16f, 0x0f7f76e0e8d089f4}}, - {{0x36d9ebc5d485b00c, 0xa2596492e4adb365, 0xc1659480c2119ccd, 0x45306349186e0d5f}}}, -{{{0x94ddd0c1a6cdff1d, 0x55f6f115e84213ae, 0x6c935f85992fcf6a, 0x067ee0f54a37f16f}}, - {{0x96a414ec2b072491, 0x1bb2218127a7b65b, 0x6d2849596e8a4af0, 0x65f3b08ccd27765f}}, - {{0xecb29fff199801f7, 0x9d361d1fa2a0f72f, 0x25f11d2375fd2f49, 0x124cefe80fe10fe2}}}, -{{{0x4c126cf9d18df255, 0xc1d471e9147a63b6, 0x2c6d3c73f3c93b5f, 0x6be3a6a2e3ff86a2}}, - {{0x1518e85b31b16489, 0x8faadcb7db710bfb, 0x39b0bdf4a14ae239, 0x05f4cbea503d20c1}}, - {{0xce040e9ec04145bc, 0xc71ff4e208f6834c, 0xbd546e8dab8847a3, 0x64666aa0a4d2aba5}}}, -{{{0x6841435a7c06d912, 0xca123c21bb3f830b, 0xd4b37b27b1cbe278, 0x1d753b84c76f5046}}, - {{0xb0c53bf73337e94c, 0x7cb5697e11e14f15, 0x4b84abac1930c750, 0x28dd4abfe0640468}}, - {{0x7dc0b64c44cb9f44, 0x18a3e1ace3925dbf, 0x7a3034862d0457c4, 0x4c498bf78a0c892e}}}, -{{{0x37d653fb1aa73196, 0x0f9495303fd76418, 0xad200b09fb3a17b2, 0x544d49292fc8613e}}, - {{0x22d2aff530976b86, 0x8d90b806c2d24604, 0xdca1896c4de5bae5, 0x28005fe6c8340c17}}, - {{0x6aefba9f34528688, 0x5c1bff9425107da1, 0xf75bbbcd66d94b36, 0x72e472930f316dfa}}}, -{{{0x2695208c9781084f, 0xb1502a0b23450ee1, 0xfd9daea603efde02, 0x5a9d2e8c2733a34c}}, - {{0x07f3f635d32a7627, 0x7aaa4d865f6566f0, 0x3c85e79728d04450, 0x1fee7f000fe06438}}, - {{0x765305da03dbf7e5, 0xa4daf2491434cdbd, 0x7b4ad5cdd24a88ec, 0x00f94051ee040543}}}, -{{{0x8d356b23c3d330b2, 0xf21c8b9bb0471b06, 0xb36c316c6e42b83c, 0x07d79c7e8beab10d}}, - {{0xd7ef93bb07af9753, 0x583ed0cf3db766a7, 0xce6998bf6e0b1ec5, 0x47b7ffd25dd40452}}, - {{0x87fbfb9cbc08dd12, 0x8a066b3ae1eec29b, 0x0d57242bdb1fc1bf, 0x1c3520a35ea64bb6}}}, -{{{0x80d253a6bccba34a, 0x3e61c3a13838219b, 0x90c3b6019882e396, 0x1c3d05775d0ee66f}}, - {{0xcda86f40216bc059, 0x1fbb231d12bcd87e, 0xb4956a9e17c70990, 0x38750c3b66d12e55}}, - {{0x692ef1409422e51a, 0xcbc0c73c2b5df671, 0x21014fe7744ce029, 0x0621e2c7d330487c}}}, -{{{0xaf9860cc8259838d, 0x90ea48c1c69f9adc, 0x6526483765581e30, 0x0007d6097bd3a5bc}}, - {{0xb7ae1796b0dbf0f3, 0x54dfafb9e17ce196, 0x25923071e9aaa3b4, 0x5d8e589ca1002e9d}}, - {{0xc0bf1d950842a94b, 0xb2d3c363588f2e3e, 0x0a961438bb51e2ef, 0x1583d7783c1cbf86}}}, -{{{0xeceea2ef5da27ae1, 0x597c3a1455670174, 0xc9a62a126609167a, 0x252a5f2e81ed8f70}}, - {{0x90034704cc9d28c7, 0x1d1b679ef72cc58f, 0x16e12b5fbe5b8726, 0x4958064e83c5580a}}, - {{0x0d2894265066e80d, 0xfcc3f785307c8c6b, 0x1b53da780c1112fd, 0x079c170bd843b388}}}, -{{{0x0506ece464fa6fff, 0xbee3431e6205e523, 0x3579422451b8ea42, 0x6dec05e34ac9fb00}}, - {{0xcdd6cd50c0d5d056, 0x9af7686dbb03573b, 0x3ca6723ff3c3ef48, 0x6768c0d7317b8acc}}, - {{0x94b625e5f155c1b3, 0x417bf3a7997b7b91, 0xc22cbddc6d6b2600, 0x51445e14ddcd52f4}}}, -{{{0x57502b4b3b144951, 0x8e67ff6b444bbcb3, 0xb8bd6927166385db, 0x13186f31e39295c8}}, - {{0x893147ab2bbea455, 0x8c53a24f92079129, 0x4b49f948be30f7a7, 0x12e990086e4fd43d}}, - {{0xf10c96b37fdfbb2e, 0x9f9a935e121ceaf9, 0xdf1136c43a5b983f, 0x77b2e3f05d3e99af}}}, -{{{0xfd0d75879cf12657, 0xe82fef94e53a0e29, 0xcc34a7f05bbb4be7, 0x0b251172a50c38a2}}, - {{0x9532f48fcc5cd29b, 0x2ba851bea3ce3671, 0x32dacaa051122941, 0x478d99d9350004f2}}, - {{0x1d5ad94890bb02c0, 0x50e208b10ec25115, 0xa26a22894ef21702, 0x4dc923343b524805}}}, -{{{0xe3828c400f8086b6, 0x3f77e6f7979f0dc8, 0x7ef6de304df42cb4, 0x5265797cb6abd784}}, - {{0x3ad3e3ebf36c4975, 0xd75d25a537862125, 0xe873943da025a516, 0x6bbc7cb4c411c847}}, - {{0x3c6f9cd1d4a50d56, 0xb6244077c6feab7e, 0x6ff9bf483580972e, 0x00375883b332acfb}}}, -{{{0x0001b2cd28cb0940, 0x63fb51a06f1c24c9, 0xb5ad8691dcd5ca31, 0x67238dbd8c450660}}, - {{0xc98bec856c75c99c, 0xe44184c000e33cf4, 0x0a676b9bba907634, 0x669e2cb571f379d7}}, - {{0xcb116b73a49bd308, 0x025aad6b2392729e, 0xb4793efa3f55d9b1, 0x72a1056140678bb9}}}, -{{{0xa2b6812b1cc9249d, 0x62866eee21211f58, 0x2cb5c5b85df10ece, 0x03a6b259e263ae00}}, - {{0x0d8d2909e2e505b6, 0x98ca78abc0291230, 0x77ef5569a9b12327, 0x7c77897b81439b47}}, - {{0xf1c1b5e2de331cb5, 0x5a9f5d8e15fca420, 0x9fa438f17bd932b1, 0x2a381bf01c6146e7}}}, -{{{0xac9b9879cfc811c1, 0x8b7d29813756e567, 0x50da4e607c70edfc, 0x5dbca62f884400b6}}, - {{0xf7c0be32b534166f, 0x27e6ca6419cf70d4, 0x934df7d7a957a759, 0x5701461dabdec2aa}}, - {{0x2c6747402c915c25, 0x1bdcd1a80b0d340a, 0x5e5601bd07b43f5f, 0x2555b4e05539a242}}}, -{{{0x6fc09f5266ddd216, 0xdce560a7c8e37048, 0xec65939da2df62fd, 0x7a869ae7e52ed192}}, - {{0x78409b1d87e463d4, 0xad4da95acdfb639d, 0xec28773755259b9c, 0x69c806e9c31230ab}}, - {{0x7b48f57414bb3f22, 0x68c7cee4aedccc88, 0xed2f936179ed80be, 0x25d70b885f77bc4b}}}, -{{{0x4151c3d9762bf4de, 0x083f435f2745d82b, 0x29775a2e0d23ddd5, 0x138e3a6269a5db24}}, - {{0x98459d29bb1ae4d4, 0x56b9c4c739f954ec, 0x832743f6c29b4b3e, 0x21ea8e2798b6878a}}, - {{0x87bef4b46a5a7b9c, 0xd2299d1b5fc1d062, 0x82409818dd321648, 0x5c5abeb1e5a2e03d}}}, -{{{0x14722af4b73c2ddb, 0xbc470c5f5a05060d, 0x00943eac2581b02e, 0x0e434b3b1f499c8f}}, - {{0x02cde6de1306a233, 0x7b5a52a2116f8ec7, 0xe1c681f4c1163b5b, 0x241d350660d32643}}, - {{0x6be4404d0ebc52c7, 0xae46233bb1a791f5, 0x2aec170ed25db42b, 0x1d8dfd966645d694}}}, -{{{0x296fa9c59c2ec4de, 0xbc8b61bf4f84f3cb, 0x1c7706d917a8f908, 0x63b795fc7ad3255d}}, - {{0xd598639c12ddb0a4, 0xa5d19f30c024866b, 0xd17c2f0358fce460, 0x07a195152e095e8a}}, - {{0xa8368f02389e5fc8, 0x90433b02cf8de43b, 0xafa1fd5dc5412643, 0x3e8fe83d032f0137}}}, -{{{0x2f8b15b90570a294, 0x94f2427067084549, 0xde1c5ae161bbfd84, 0x75ba3b797fac4007}}, - {{0x08704c8de8efd13c, 0xdfc51a8e33e03731, 0xa59d5da51260cde3, 0x22d60899a6258c86}}, - {{0x6239dbc070cdd196, 0x60fe8a8b6c7d8a9a, 0xb38847bceb401260, 0x0904d07b87779e5e}}}, -{{{0xb4ce1fd4ddba919c, 0xcf31db3ec74c8daa, 0x2c63cc63ad86cc51, 0x43e2143fbc1dde07}}, - {{0xf4322d6648f940b9, 0x06952f0cbd2d0c39, 0x167697ada081f931, 0x6240aacebaf72a6c}}, - {{0xf834749c5ba295a0, 0xd6947c5bca37d25a, 0x66f13ba7e7c9316a, 0x56bdaf238db40cac}}}, -{{{0x362ab9e3f53533eb, 0x338568d56eb93d40, 0x9e0e14521d5a5572, 0x1d24a86d83741318}}, - {{0x1310d36cc19d3bb2, 0x062a6bb7622386b9, 0x7c9b8591d7a14f5c, 0x03aa31507e1e5754}}, - {{0xf4ec7648ffd4ce1f, 0xe045eaf054ac8c1c, 0x88d225821d09357c, 0x43b261dc9aeb4859}}}, -{{{0xe55b1e1988bb79bb, 0xa09ed07dc17a359d, 0xb02c2ee2603dea33, 0x326055cf5b276bc2}}, - {{0x19513d8b6c951364, 0x94fe7126000bf47b, 0x028d10ddd54f9567, 0x02b4d5e242940964}}, - {{0xb4a155cb28d18df2, 0xeacc4646186ce508, 0xc49cf4936c824389, 0x27a6c809ae5d3410}}}, -{{{0x8ba6ebcd1f0db188, 0x37d3d73a675a5be8, 0xf22edfa315f5585a, 0x2cb67174ff60a17e}}, - {{0xcd2c270ac43d6954, 0xdd4a3e576a66cab2, 0x79fa592469d7036c, 0x221503603d8c2599}}, - {{0x59eecdf9390be1d0, 0xa9422044728ce3f1, 0x82891c667a94f0f4, 0x7b1df4b73890f436}}}, -{{{0xe492f2e0b3b2a224, 0x7c6c9e062b551160, 0x15eb8fe20d7f7b0e, 0x61fcef2658fc5992}}, - {{0x5f2e221807f8f58c, 0xe3555c9fd49409d4, 0xb2aaa88d1fb6a630, 0x68698245d352e03d}}, - {{0xdbb15d852a18187a, 0xf3e4aad386ddacd7, 0x44bae2810ff6c482, 0x46cf4c473daf01cf}}}, -{{{0x426525ed9ec4e5f9, 0x0e5eda0116903303, 0x72b1a7f2cbe5cadc, 0x29387bcd14eb5f40}}, - {{0x213c6ea7f1498140, 0x7c1e7ef8392b4854, 0x2488c38c5629ceba, 0x1065aae50d8cc5bb}}, - {{0x1c2c4525df200d57, 0x5c3b2dd6bfca674a, 0x0a07e7b1e1834030, 0x69a198e64f1ce716}}}, -{{{0x7afcd613efa9d697, 0x0cc45aa41c067959, 0xa56fe104c1fada96, 0x3a73b70472e40365}}, - {{0x7b26e56b9e2d4734, 0xc4c7132b81c61675, 0xef5c9525ec9cde7f, 0x39c80b16e71743ad}}, - {{0x0f196e0d1b826c68, 0xf71ff0e24960e3db, 0x6113167023b7436c, 0x0cf0ea5877da7282}}}, -{{{0x196c80a4ddd4ccbd, 0x22e6f55d95f2dd9d, 0xc75e33c740d6c71b, 0x7bb51279cb3c042f}}, - {{0xe332ced43ba6945a, 0xde0b1361e881c05d, 0x1ad40f095e67ed3b, 0x5da8acdab8c63d5d}}, - {{0xc4b6664a3a70159f, 0x76194f0f0a904e14, 0xa5614c39a4096c13, 0x6cd0ff50979feced}}}, -{{{0xc0e067e78f4428ac, 0x14835ab0a61135e3, 0xf21d14f338062935, 0x6390a4c8df04849c}}, - {{0x7fecfabdb04ba18e, 0xd0fc7bfc3bddbcf7, 0xa41d486e057a131c, 0x641a4391f2223a61}}, - {{0xc5c6b95aa606a8db, 0x914b7f9eb06825f1, 0x2a731f6b44fc9eff, 0x30ddf38562705cfc}}}, -{{{0x4e3dcbdad1bff7f9, 0xc9118e8220645717, 0xbacccebc0f189d56, 0x1b4822e9d4467668}}, - {{0x33bef2bd68bcd52c, 0xc649dbb069482ef2, 0xb5b6ee0c41cb1aee, 0x5c294d270212a7e5}}, - {{0xab360a7f25563781, 0x2512228a480f7958, 0xc75d05276114b4e3, 0x222d9625d976fe2a}}}, -{{{0x1c717f85b372ace1, 0x81930e694638bf18, 0x239cad056bc08b58, 0x0b34271c87f8fff4}}, - {{0x0f94be7e0a344f85, 0xeb2faa8c87f22c38, 0x9ce1e75e4ee16f0f, 0x43e64e5418a08dea}}, - {{0x8155e2521a35ce63, 0xbe100d4df912028e, 0xbff80bf8a57ddcec, 0x57342dc96d6bc6e4}}}, -{{{0xefeef065c8ce5998, 0xbf029510b5cbeaa2, 0x8c64a10620b7c458, 0x35134fb231c24855}}, - {{0xf3c3bcb71e707bf6, 0x351d9b8c7291a762, 0x00502e6edad69a33, 0x522f521f1ec8807f}}, - {{0x272c1f46f9a3902b, 0xc91ba3b799657bcc, 0xae614b304f8a1c0e, 0x7afcaad70b99017b}}}, -{{{0xc25ded54a4b8be41, 0x902d13e11bb0e2dd, 0x41f43233cde82ab2, 0x1085faa5c3aae7cb}}, - {{0xa88141ecef842b6b, 0x55e7b14797abe6c5, 0x8c748f9703784ffe, 0x5b50a1f7afcd00b7}}, - {{0x9b840f66f1361315, 0x18462242701003e9, 0x65ed45fae4a25080, 0x0a2862393fda7320}}}, -{{{0x46ab13c8347cbc9d, 0x3849e8d499c12383, 0x4cea314087d64ac9, 0x1f354134b1a29ee7}}, - {{0x960e737b6ecb9d17, 0xfaf24948d67ceae1, 0x37e7a9b4d55e1b89, 0x5cb7173cb46c59eb}}, - {{0x4a89e68b82b7abf0, 0xf41cd9279ba6b7b9, 0x16e6c210e18d876f, 0x7cacdb0f7f1b09c6}}}, -{{{0x9062b2e0d91a78bc, 0x47c9889cc8509667, 0x9df54a66405070b8, 0x7369e6a92493a1bf}}, - {{0xe1014434dcc5caed, 0x47ed5d963c84fb33, 0x70019576ed86a0e7, 0x25b2697bd267f9e4}}, - {{0x9d673ffb13986864, 0x3ca5fbd9415dc7b8, 0xe04ecc3bdf273b5e, 0x1420683db54e4cd2}}}, -{{{0xb478bd1e249dd197, 0x620c35005e58c102, 0xfb02d32fccbaac5c, 0x60b63bebf508a72d}}, - {{0x34eebb6fc1cc5ad0, 0x6a1b0ce99646ac8b, 0xd3b0da49a66bde53, 0x31e83b4161d081c1}}, - {{0x97e8c7129e062b4f, 0x49e48f4f29320ad8, 0x5bece14b6f18683f, 0x55cf1eb62d550317}}}, -{{{0x5879101065c23d58, 0x8b9d086d5094819c, 0xe2402fa912c55fa7, 0x669a6564570891d4}}, - {{0x3076b5e37df58c52, 0xd73ab9dde799cc36, 0xbd831ce34913ee20, 0x1a56fbaa62ba0133}}, - {{0x943e6b505c9dc9ec, 0x302557bba77c371a, 0x9873ae5641347651, 0x13c4836799c58a5c}}}, -{{{0x423a5d465ab3e1b9, 0xfc13c187c7f13f61, 0x19f83664ecb5b9b6, 0x66f80c93a637b607}}, - {{0xc4dcfb6a5d8bd080, 0xdeebc4ec571a4842, 0xd4b2e883b8e55365, 0x50bdc87dc8e5b827}}, - {{0x606d37836edfe111, 0x32353e15f011abd9, 0x64b03ac325b73b96, 0x1dd56444725fd5ae}}}, -{{{0x8fa47ff83362127d, 0xbc9f6ac471cd7c15, 0x6e71454349220c8b, 0x0e645912219f732e}}, - {{0xc297e60008bac89a, 0x7d4cea11eae1c3e0, 0xf3e38be19fe7977c, 0x3a3a450f63a305cd}}, - {{0x078f2f31d8394627, 0x389d3183de94a510, 0xd1e36c6d17996f80, 0x318c8d9393a9a87b}}}, -{{{0xf2745d032afffe19, 0x0c9f3c497f24db66, 0xbc98d3e3ba8598ef, 0x224c7c679a1d5314}}, - {{0x5d669e29ab1dd398, 0xfc921658342d9e3b, 0x55851dfdf35973cd, 0x509a41c325950af6}}, - {{0xbdc06edca6f925e9, 0x793ef3f4641b1f33, 0x82ec12809d833e89, 0x05bff02328a11389}}}, -{{{0x3632137023cae00b, 0x544acf0ad1accf59, 0x96741049d21a1c88, 0x780b8cc3fa2a44a7}}, - {{0x6881a0dd0dc512e4, 0x4fe70dc844a5fafe, 0x1f748e6b8f4a5240, 0x576277cdee01a3ea}}, - {{0x1ef38abc234f305f, 0x9a577fbd1405de08, 0x5e82a51434e62a0d, 0x5ff418726271b7a1}}}, -{{{0x398e080c1789db9d, 0xa7602025f3e778f5, 0xfa98894c06bd035d, 0x106a03dc25a966be}}, - {{0xe5db47e813b69540, 0xf35d2a3b432610e1, 0xac1f26e938781276, 0x29d4db8ca0a0cb69}}, - {{0xd9ad0aaf333353d0, 0x38669da5acd309e5, 0x3c57658ac888f7f0, 0x4ab38a51052cbefa}}}, -{{{0xdfdacbee4324c0e9, 0x054442883f955bb7, 0xdef7aaa8ea31609f, 0x68aee70642287cff}}, - {{0xf68fe2e8809de054, 0xe3bc096a9c82bad1, 0x076353d40aadbf45, 0x7b9b1fb5dea1959e}}, - {{0xf01cc8f17471cc0c, 0x95242e37579082bb, 0x27776093d3e46b5f, 0x2d13d55a28bd85fb}}}, -{{{0xfac5d2065b35b8da, 0xa8da8a9a85624bb7, 0xccd2ca913d21cd0f, 0x6b8341ee8bf90d58}}, - {{0xbf019cce7aee7a52, 0xa8ded2b6e454ead3, 0x3c619f0b87a8bb19, 0x3619b5d7560916d8}}, - {{0x3579f26b0282c4b2, 0x64d592f24fafefae, 0xb7cded7b28c8c7c0, 0x6a927b6b7173a8d7}}}, -{{{0x1f6db24f986e4656, 0x1021c02ed1e9105b, 0xf8ff3fff2cc0a375, 0x1d2a6bf8c6c82592}}, - {{0x8d7040863ece88eb, 0xf0e307a980eec08c, 0xac2250610d788fda, 0x056d92a43a0d478d}}, - {{0x1b05a196fc3da5a1, 0x77d7a8c243b59ed0, 0x06da3d6297d17918, 0x66fbb494f12353f7}}}, -{{{0x751a50b9d85c0fb8, 0xd1afdc258bcf097b, 0x2f16a6a38309a969, 0x14ddff9ee5b00659}}, - {{0xd6d70996f12309d6, 0xdbfb2385e9c3d539, 0x46d602b0f7552411, 0x270a0b0557843e0c}}, - {{0x61ff0640a7862bcc, 0x81cac09a5f11abfe, 0x9047830455d12abb, 0x19a4bde1945ae873}}}, -{{{0x9b9f26f520a6200a, 0x64804443cf13eaf8, 0x8a63673f8631edd3, 0x72bbbce11ed39dc1}}, - {{0x40c709dec076c49f, 0x657bfaf27f3e53f6, 0x40662331eca042c4, 0x14b375487eb4df04}}, - {{0xae853c94ab66dc47, 0xeb62343edf762d6e, 0xf08e0e186fb2f7d1, 0x4f0b1c02700ab37a}}}, -{{{0xe1706787d81951fa, 0xa10a2c8eb290c77b, 0xe7382fa03ed66773, 0x0a4d84710bcc4b54}}, - {{0x79fd21ccc1b2e23f, 0x4ae7c281453df52a, 0xc8172ec9d151486b, 0x68abe9443e0a7534}}, - {{0xda12c6c407831dcb, 0x0da230d74d5c510d, 0x4ab1531e6bd404e1, 0x4106b166bcf440ef}}}, -{{{0x02e57a421cd23668, 0x4ad9fb5d0eaef6fd, 0x954e6727b1244480, 0x7f792f9d2699f331}}, - {{0xa485ccd539e4ecf2, 0x5aa3f3ad0555bab5, 0x145e3439937df82d, 0x1238b51e1214283f}}, - {{0x0b886b925fd4d924, 0x60906f7a3626a80d, 0xecd367b4b98abd12, 0x2876beb1def344cf}}}, -{{{0xdc84e93563144691, 0x632fe8a0d61f23f4, 0x4caa800612a9a8d5, 0x48f9dbfa0e9918d3}}, - {{0xd594b3333a8a85f8, 0x4ea37689e78d7d58, 0x73bf9f455e8e351f, 0x5507d7d2bc41ebb4}}, - {{0x1ceb2903299572fc, 0x7c8ccaa29502d0ee, 0x91bfa43411cce67b, 0x5784481964a831e7}}}, -{{{0xda7c2b256768d593, 0x98c1c0574422ca13, 0xf1a80bd5ca0ace1d, 0x29cdd1adc088a690}}, - {{0xd6cfd1ef5fddc09c, 0xe82b3efdf7575dce, 0x25d56b5d201634c2, 0x3041c6bb04ed2b9b}}, - {{0x0ff2f2f9d956e148, 0xade797759f356b2e, 0x1a4698bb5f6c025c, 0x104bbd6814049a7b}}}, -{{{0x51f0fd3168f1ed67, 0x2c811dcdd86f3bc2, 0x44dc5c4304d2f2de, 0x5be8cc57092a7149}}, - {{0xa95d9a5fd67ff163, 0xe92be69d4cc75681, 0xb7f8024cde20f257, 0x204f2a20fb072df5}}, - {{0xc8143b3d30ebb079, 0x7589155abd652e30, 0x653c3c318f6d5c31, 0x2570fb17c279161f}}}, -{{{0x3efa367f2cb61575, 0xf5f96f761cd6026c, 0xe8c7142a65b52562, 0x3dcb65ea53030acd}}, - {{0x192ea9550bb8245a, 0xc8e6fba88f9050d1, 0x7986ea2d88a4c935, 0x241c5f91de018668}}, - {{0x28d8172940de6caa, 0x8fbf2cf022d9733a, 0x16d7fcdd235b01d1, 0x08420edd5fcdf0e5}}}, -{{{0xcdff20ab8362fa4a, 0x57e118d4e21a3e6e, 0xe3179617fc39e62b, 0x0d9a53efbc1769fd}}, - {{0x0358c34e04f410ce, 0xb6135b5a276e0685, 0x5d9670c7ebb91521, 0x04d654f321db889c}}, - {{0x5e7dc116ddbdb5d5, 0x2954deb68da5dd2d, 0x1cb608173334a292, 0x4a7a4f2618991ad7}}}, -{{{0xf4a718025fb15f95, 0x3df65f346b5c1b8f, 0xcdfcf08500e01112, 0x11b50c4cddd31848}}, - {{0x24c3b291af372a4b, 0x93da8270718147f2, 0xdd84856486899ef2, 0x4a96314223e0ee33}}, - {{0xa6e8274408a4ffd6, 0x738e177e9c1576d9, 0x773348b63d02b3f2, 0x4f4bce4dce6bcc51}}}, -{{{0xa71fce5ae2242584, 0x26ea725692f58a9e, 0xd21a09d71cea3cf4, 0x73fcdd14b71c01e6}}, - {{0x30e2616ec49d0b6f, 0xe456718fcaec2317, 0x48eb409bf26b4fa6, 0x3042cee561595f37}}, - {{0x427e7079449bac41, 0x855ae36dbce2310a, 0x4cae76215f841a7c, 0x389e740c9a9ce1d6}}}, -{{{0x64fcb3ae34dcb9ce, 0x97500323e348d0ad, 0x45b3f07d62c6381b, 0x61545379465a6788}}, - {{0xc9bd78f6570eac28, 0xe55b0b3227919ce1, 0x65fc3eaba19b91ed, 0x25c425e5d6263690}}, - {{0x3f3e06a6f1d7de6e, 0x3ef976278e062308, 0x8c14f6264e8a6c77, 0x6539a08915484759}}}, -{{{0xe9d21f74c3d2f773, 0xc150544125c46845, 0x624e5ce8f9b99e33, 0x11c5e4aac5cd186c}}, - {{0xddc4dbd414bb4a19, 0x19b2bc3c98424f8e, 0x48a89fd736ca7169, 0x0f65320ef019bd90}}, - {{0xd486d1b1cafde0c6, 0x4f3fe6e3163b5181, 0x59a8af0dfaf2939a, 0x4cabc7bdec33072a}}}, -{{{0x16faa8fb532f7428, 0xdbd42ea046a4e272, 0x5337653b8b9ea480, 0x4065947223973f03}}, - {{0xf7c0a19c1a54a044, 0x4a1c5e2477bd9fbb, 0xa6e3ca115af22972, 0x1819bb953f2e9e0d}}, - {{0x498fbb795e042e84, 0x7d0dd89a7698b714, 0x8bfb0ba427fe6295, 0x36ba82e721200524}}}, -{{{0xd60ecbb74245ec41, 0xfd9be89e34348716, 0xc9240afee42284de, 0x4472f648d0531db4}}, - {{0xc8d69d0a57274ed5, 0x45ba803260804b17, 0xdf3cda102255dfac, 0x77d221232709b339}}, - {{0x498a6d7064ad94d8, 0xa5b5c8fd9af62263, 0x8ca8ed0545c141f4, 0x2c63bec3662d358c}}}, -{{{0x7fe60d8bea787955, 0xb9dc117eb5f401b7, 0x91c7c09a19355cce, 0x22692ef59442bedf}}, - {{0x9a518b3a8586f8bf, 0x9ee71af6cbb196f0, 0xaa0625e6a2385cf2, 0x1deb2176ddd7c8d1}}, - {{0x8563d19a2066cf6c, 0x401bfd8c4dcc7cd7, 0xd976a6becd0d8f62, 0x67cfd773a278b05e}}}, -{{{0x8dec31faef3ee475, 0x99dbff8a9e22fd92, 0x512d11594e26cab1, 0x0cde561eec4310b9}}, - {{0x2d5fa9855a4e586a, 0x65f8f7a449beab7e, 0xaa074dddf21d33d3, 0x185cba721bcb9dee}}, - {{0x93869da3f4e3cb41, 0xbf0392f540f7977e, 0x026204fcd0463b83, 0x3ec91a769eec6eed}}}, -{{{0x1e9df75bf78166ad, 0x4dfda838eb0cd7af, 0xba002ed8c1eaf988, 0x13fedb3e11f33cfc}}, - {{0x0fad2fb7b0a3402f, 0x46615ecbfb69f4a8, 0xf745bcc8c5f8eaa6, 0x7a5fa8794a94e896}}, - {{0x52958faa13cd67a1, 0x965ee0818bdbb517, 0x16e58daa2e8845b3, 0x357d397d5499da8f}}}, -{{{0x1ebfa05fb0bace6c, 0xc934620c1caf9a1e, 0xcc771cc41d82b61a, 0x2d94a16aa5f74fec}}, - {{0x481dacb4194bfbf8, 0x4d77e3f1bae58299, 0x1ef4612e7d1372a0, 0x3a8d867e70ff69e1}}, - {{0x6f58cd5d55aff958, 0xba3eaa5c75567721, 0x75c123999165227d, 0x69be1343c2f2b35e}}}, -{{{0x0e091d5ee197c92a, 0x4f51019f2945119f, 0x143679b9f034e99c, 0x7d88112e4d24c696}}, - {{0x82bbbdac684b8de3, 0xa2f4c7d03fca0718, 0x337f92fbe096aaa8, 0x200d4d8c63587376}}, - {{0x208aed4b4893b32b, 0x3efbf23ebe59b964, 0xd762deb0dba5e507, 0x69607bd681bd9d94}}}, -{{{0xf6be021068de1ce1, 0xe8d518e70edcbc1f, 0xe3effdd01b5505a5, 0x35f63353d3ec3fd0}}, - {{0x3b7f3bd49323a902, 0x7c21b5566b2c6e53, 0xe5ba8ff53a7852a7, 0x28bc77a5838ece00}}, - {{0x63ba78a8e25d8036, 0x63651e0094333490, 0x48d82f20288ce532, 0x3a31abfa36b57524}}}, -{{{0x239e9624089c0a2e, 0xc748c4c03afe4738, 0x17dbed2a764fa12a, 0x639b93f0321c8582}}, - {{0xc08f788f3f78d289, 0xfe30a72ca1404d9f, 0xf2778bfccf65cc9d, 0x7ee498165acb2021}}, - {{0x7bd508e39111a1c3, 0x2b2b90d480907489, 0xe7d2aec2ae72fd19, 0x0edf493c85b602a6}}}, -{{{0xaecc8158599b5a68, 0xea574f0febade20e, 0x4fe41d7422b67f07, 0x403b92e3019d4fb4}}, - {{0x6767c4d284764113, 0xa090403ff7f5f835, 0x1c8fcffacae6bede, 0x04c00c54d1dfa369}}, - {{0x4dc22f818b465cf8, 0x71a0f35a1480eff8, 0xaee8bfad04c7d657, 0x355bb12ab26176f4}}}, -{{{0xa71e64cc7493bbf4, 0xe5bd84d9eca3b0c3, 0x0a6bc50cfa05e785, 0x0f9b8132182ec312}}, - {{0xa301dac75a8c7318, 0xed90039db3ceaa11, 0x6f077cbf3bae3f2d, 0x7518eaf8e052ad8e}}, - {{0xa48859c41b7f6c32, 0x0f2d60bcf4383298, 0x1815a929c9b1d1d9, 0x47c3871bbb1755c4}}}, -{{{0x5144539771ec4f48, 0xf805b17dc98c5d6e, 0xf762c11a47c3c66b, 0x00b89b85764699dc}}, - {{0xfbe65d50c85066b0, 0x62ecc4b0b3a299b0, 0xe53754ea441ae8e0, 0x08fea02ce8d48d5f}}, - {{0x824ddd7668deead0, 0xc86445204b685d23, 0xb514cfcd5d89d665, 0x473829a74f75d537}}}, -{{{0x82d2da754679c418, 0xe63bd7d8b2618df0, 0x355eef24ac47eb0a, 0x2078684c4833c6b4}}, - {{0x23d9533aad3902c9, 0x64c2ddceef03588f, 0x15257390cfe12fb4, 0x6c668b4d44e4d390}}, - {{0x3b48cf217a78820c, 0xf76a0ab281273e97, 0xa96c65a78c8eed7b, 0x7411a6054f8a433f}}}, -{{{0x4d659d32b99dc86d, 0x044cdc75603af115, 0xb34c712cdcc2e488, 0x7c136574fb8134ff}}, - {{0x579ae53d18b175b4, 0x68713159f392a102, 0x8455ecba1eef35f5, 0x1ec9a872458c398f}}, - {{0xb8e6a4d400a2509b, 0x9b81d7020bc882b4, 0x57e7cc9bf1957561, 0x3add88a5c7cd6460}}}, -{{{0xab895770b635dcf2, 0x02dfef6cf66c1fbc, 0x85530268beb6d187, 0x249929fccc879e74}}, - {{0x85c298d459393046, 0x8f7e35985ff659ec, 0x1d2ca22af2f66e3a, 0x61ba1131a406a720}}, - {{0xa3d0a0f116959029, 0x023b6b6cba7ebd89, 0x7bf15a3e26783307, 0x5620310cbbd8ece7}}}, -{{{0x528993434934d643, 0xb9dbf806a51222f5, 0x8f6d878fc3f41c22, 0x37676a2a4d9d9730}}, - {{0x6646b5f477e285d6, 0x40e8ff676c8f6193, 0xa6ec7311abb594dd, 0x7ec846f3658cec4d}}, - {{0x9b5e8f3f1da22ec7, 0x130f1d776c01cd13, 0x214c8fcfa2989fb8, 0x6daaf723399b9dd5}}}, -{{{0x591e4a5610628564, 0x2a4bb87ca8b4df34, 0xde2a2572e7a38e43, 0x3cbdabd9fee5046e}}, - {{0x81aebbdd2cd13070, 0x962e4325f85a0e9e, 0xde9391aacadffecb, 0x53177fda52c230e6}}, - {{0xa7bc970650b9de79, 0x3d12a7fbc301b59b, 0x02652e68d36ae38c, 0x79d739835a6199dc}}}, -{{{0xd9354df64131c1bd, 0x758094a186ec5822, 0x4464ee12e459f3c2, 0x6c11fce4cb133282}}, - {{0x21c9d9920d591737, 0x9bea41d2e9b46cd6, 0xe20e84200d89bfca, 0x79d99f946eae5ff8}}, - {{0xf17b483568673205, 0x387deae83caad96c, 0x61b471fd56ffe386, 0x31741195b745a599}}}, -{{{0xe8d10190b77a360b, 0x99b983209995e702, 0xbd4fdff8fa0247aa, 0x2772e344e0d36a87}}, - {{0x17f8ba683b02a047, 0x50212096feefb6c8, 0x70139be21556cbe2, 0x203e44a11d98915b}}, - {{0xd6863eba37b9e39f, 0x105bc169723b5a23, 0x104f6459a65c0762, 0x567951295b4d38d4}}}, -{{{0x535fd60613037524, 0xe210adf6b0fbc26a, 0xac8d0a9b23e990ae, 0x47204d08d72fdbf9}}, - {{0x07242eb30d4b497f, 0x1ef96306b9bccc87, 0x37950934d8116f45, 0x05468d6201405b04}}, - {{0x00f565a9f93267de, 0xcecfd78dc0d58e8a, 0xa215e2dcf318e28e, 0x4599ee919b633352}}}, -{{{0xd3c220ca70e0e76b, 0xb12bea58ea9f3094, 0x294ddec8c3271282, 0x0c3539e1a1d1d028}}, - {{0xac746d6b861ae579, 0x31ab0650f6aea9dc, 0x241d661140256d4c, 0x2f485e853d21a5de}}, - {{0x329744839c0833f3, 0x6fe6257fd2abc484, 0x5327d1814b358817, 0x65712585893fe9bc}}}, -{{{0x9c102fb732a61161, 0xe48e10dd34d520a8, 0x365c63546f9a9176, 0x32f6fe4c046f6006}}, - {{0x81c29f1bd708ee3f, 0xddcb5a05ae6407d0, 0x97aec1d7d2a3eba7, 0x1590521a91d50831}}, - {{0x40a3a11ec7910acc, 0x9013dff8f16d27ae, 0x1a9720d8abb195d4, 0x1bb9fe452ea98463}}}, -{{{0xe9d1d950b3d54f9e, 0x2d5f9cbee00d33c1, 0x51c2c656a04fc6ac, 0x65c091ee3c1cbcc9}}, - {{0xcf5e6c95cc36747c, 0x294201536b0bc30d, 0x453ac67cee797af0, 0x5eae6ab32a8bb3c9}}, - {{0x7083661114f118ea, 0x2b37b87b94349cad, 0x7273f51cb4e99f40, 0x78a2a95823d75698}}}, -{{{0xa2b072e95c8c2ace, 0x69cffc96651e9c4b, 0x44328ef842e7b42b, 0x5dd996c122aadeb3}}, - {{0xb4f23c425ef83207, 0xabf894d3c9a934b5, 0xd0708c1339fd87f7, 0x1876789117166130}}, - {{0x925b5ef0670c507c, 0x819bc842b93c33bf, 0x10792e9a70dd003f, 0x59ad4b7a6e28dc74}}}, -{{{0x5f3a7562eb3dbe47, 0xf7ea38548ebda0b8, 0x00c3e53145747299, 0x1304e9e71627d551}}, - {{0x583b04bfacad8ea2, 0x29b743e8148be884, 0x2b1e583b0810c5db, 0x2b5449e58eb3bbaa}}, - {{0x789814d26adc9cfe, 0x3c1bab3f8b48dd0b, 0xda0fe1fff979c60a, 0x4468de2d7c2dd693}}}, -{{{0x51bb355e9419469e, 0x33e6dc4c23ddc754, 0x93a5b6d6447f9962, 0x6cce7c6ffb44bd63}}, - {{0x4b9ad8c6f86307ce, 0x21113531435d0c28, 0xd4a866c5657a772c, 0x5da6427e63247352}}, - {{0x1a94c688deac22ca, 0xb9066ef7bbae1ff8, 0x88ad8c388d59580f, 0x58f29abfe79f2ca8}}}, -{{{0xe90ecfab8de73e68, 0x54036f9f377e76a5, 0xf0495b0bbe015982, 0x577629c4a7f41e36}}, - {{0x4b5a64bf710ecdf6, 0xb14ce538462c293c, 0x3643d056d50b3ab9, 0x6af93724185b4870}}, - {{0x3220024509c6a888, 0xd2e036134b558973, 0x83e236233c33289f, 0x701f25bb0caec18f}}}, -{{{0xc3a8b0f8e4616ced, 0xf700660e9e25a87d, 0x61e3061ff4bca59c, 0x2e0c92bfbdc40be9}}, - {{0x9d18f6d97cbec113, 0x844a06e674bfdbe4, 0x20f5b522ac4e60d6, 0x720a5bc050955e51}}, - {{0x0c3f09439b805a35, 0xe84e8b376242abfc, 0x691417f35c229346, 0x0e9b9cbb144ef0ec}}}, -{{{0xfbbad48ffb5720ad, 0xee81916bdbf90d0e, 0xd4813152635543bf, 0x221104eb3f337bd8}}, - {{0x8dee9bd55db1beee, 0xc9c3ab370a723fb9, 0x44a8f1bf1c68d791, 0x366d44191cfd3cde}}, - {{0x9e3c1743f2bc8c14, 0x2eda26fcb5856c3b, 0xccb82f0e68a7fb97, 0x4167a4e6bc593244}}}, -{{{0x643b9d2876f62700, 0x5d1d9d400e7668eb, 0x1b4b430321fc0684, 0x7938bb7e2255246a}}, - {{0xc2be2665f8ce8fee, 0xe967ff14e880d62c, 0xf12e6e7e2f364eee, 0x34b33370cb7ed2f6}}, - {{0xcdc591ee8681d6cc, 0xce02109ced85a753, 0xed7485c158808883, 0x1176fc6e2dfe65e4}}}, -{{{0xb4af6cd05b9c619b, 0x2ddfc9f4b2a58480, 0x3d4fa502ebe94dc4, 0x08fc3a4c677d5f34}}, - {{0xdb90e28949770eb8, 0x98fbcc2aacf440a3, 0x21354ffeded7879b, 0x1f6a3e54f26906b6}}, - {{0x60a4c199d30734ea, 0x40c085b631165cd6, 0xe2333e23f7598295, 0x4f2fad0116b900d1}}}, -{{{0x44beb24194ae4e54, 0x5f541c511857ef6c, 0xa61e6b2d368d0498, 0x445484a4972ef7ab}}, - {{0x962cd91db73bb638, 0xe60577aafc129c08, 0x6f619b39f3b61689, 0x3451995f2944ee81}}, - {{0x9152fcd09fea7d7c, 0x4a816c94b0935cf6, 0x258e9aaa47285c40, 0x10b89ca6042893b7}}}, -{{{0x9b2a426e3b646025, 0x32127190385ce4cf, 0xa25cffc2dd6dea45, 0x06409010bea8de75}}, - {{0xd67cded679d34aa0, 0xcc0b9ec0cc4db39f, 0xa535a456e35d190f, 0x2e05d9eaf61f6fef}}, - {{0xc447901ad61beb59, 0x661f19bce5dc880a, 0x24685482b7ca6827, 0x293c778cefe07f26}}}, -{{{0x86809e7007069096, 0xaad75b15e4e50189, 0x07f35715a21a0147, 0x0487f3f112815d5e}}, - {{0x16c795d6a11ff200, 0xcb70d0e2b15815c9, 0x89f293209b5395b5, 0x50b8c2d031e47b4f}}, - {{0x48350c08068a4962, 0x6ffdd05351092c9a, 0x17af4f4aaf6fc8dd, 0x4b0553b53cdba58b}}}, -{{{0x9c65fcbe1b32ff79, 0xeb75ea9f03b50f9b, 0xfced2a6c6c07e606, 0x35106cd551717908}}, - {{0xbf05211b27c152d4, 0x5ec26849bd1af639, 0x5e0b2caa8e6fab98, 0x054c8bdd50bd0840}}, - {{0x38a0b12f1dcf073d, 0x4b60a8a3b7f6a276, 0xfed5ac25d3404f9a, 0x72e82d5e5505c229}}}, -{{{0x6b0b697ff0d844c8, 0xbb12f85cd979cb49, 0xd2a541c6c1da0f1f, 0x7b7c242958ce7211}}, - {{0x00d9cdfd69771d02, 0x410276cd6cfbf17e, 0x4c45306c1cb12ec7, 0x2857bf1627500861}}, - {{0x9f21903f0101689e, 0xd779dfd3bf861005, 0xa122ee5f3deb0f1b, 0x510df84b485a00d4}}}, -{{{0xa54133bb9277a1fa, 0x74ec3b6263991237, 0x1a3c54dc35d2f15a, 0x2d347144e482ba3a}}, - {{0x24b3c887c70ac15e, 0xb0f3a557fb81b732, 0x9b2cde2fe578cc1b, 0x4cf7ed0703b54f8e}}, - {{0x6bd47c6598fbee0f, 0x9e4733e2ab55be2d, 0x1093f624127610c5, 0x4e05e26ad0a1eaa4}}}, -{{{0xda9b6b624b531f20, 0x429a760e77509abb, 0xdbe9f522e823cb80, 0x618f1856880c8f82}}, - {{0x1833c773e18fe6c0, 0xe3c4711ad3c87265, 0x3bfd3c4f0116b283, 0x1955875eb4cd4db8}}, - {{0x6da6de8f0e399799, 0x7ad61aa440fda178, 0xb32cd8105e3563dd, 0x15f6beae2ae340ae}}}, -{{{0x862bcb0c31ec3a62, 0x810e2b451138f3c2, 0x788ec4b839dac2a4, 0x28f76867ae2a9281}}, - {{0xba9a0f7b9245e215, 0xf368612dd98c0dbb, 0x2e84e4cbf220b020, 0x6ba92fe962d90eda}}, - {{0x3e4df9655884e2aa, 0xbd62fbdbdbd465a5, 0xd7596caa0de9e524, 0x6e8042ccb2b1b3d7}}}, -{{{0xf10d3c29ce28ca6e, 0xbad34540fcb6093d, 0xe7426ed7a2ea2d3f, 0x08af9d4e4ff298b9}}, - {{0x1530653616521f7e, 0x660d06b896203dba, 0x2d3989bc545f0879, 0x4b5303af78ebd7b0}}, - {{0x72f8a6c3bebcbde8, 0x4f0fca4adc3a8e89, 0x6fa9d4e8c7bfdf7a, 0x0dcf2d679b624eb7}}}, -{{{0x3d5947499718289c, 0x12ebf8c524533f26, 0x0262bfcb14c3ef15, 0x20b878d577b7518e}}, - {{0x753941be5a45f06e, 0xd07caeed6d9c5f65, 0x11776b9c72ff51b6, 0x17d2d1d9ef0d4da9}}, - {{0x27f2af18073f3e6a, 0xfd3fe519d7521069, 0x22e3b72c3ca60022, 0x72214f63cc65c6a7}}}, -{{{0xb4e37f405307a693, 0xaba714d72f336795, 0xd6fbd0a773761099, 0x5fdf48c58171cbc9}}, - {{0x1d9db7b9f43b29c9, 0xd605824a4f518f75, 0xf2c072bd312f9dc4, 0x1f24ac855a1545b0}}, - {{0x24d608328e9505aa, 0x4748c1d10c1420ee, 0xc7ffe45c06fb25a2, 0x00ba739e2ae395e6}}}, -{{{0x592e98de5c8790d6, 0xe5bfb7d345c2a2df, 0x115a3b60f9b49922, 0x03283a3e67ad78f3}}, - {{0xae4426f5ea88bb26, 0x360679d984973bfb, 0x5c9f030c26694e50, 0x72297de7d518d226}}, - {{0x48241dc7be0cb939, 0x32f19b4d8b633080, 0xd3dfc90d02289308, 0x05e1296846271945}}}, -{{{0xba82eeb32d9c495a, 0xceefc8fcf12bb97c, 0xb02dabae93b5d1e0, 0x39c00c9c13698d9b}}, - {{0xadbfbbc8242c4550, 0xbcc80cecd03081d9, 0x843566a6f5c8df92, 0x78cf25d38258ce4c}}, - {{0x15ae6b8e31489d68, 0xaa851cab9c2bf087, 0xc9a75a97f04efa05, 0x006b52076b3ff832}}}, -{{{0x29e0cfe19d95781c, 0xb681df18966310e2, 0x57df39d370516b39, 0x4d57e3443bc76122}}, - {{0xf5cb7e16b9ce082d, 0x3407f14c417abc29, 0xd4b36bce2bf4a7ab, 0x7de2e9561a9f75ce}}, - {{0xde70d4f4b6a55ecb, 0x4801527f5d85db99, 0xdbc9c440d3ee9a81, 0x6b2a90af1a6029ed}}}, -{{{0x6923f4fc9ae61e97, 0x5735281de03f5fd1, 0xa764ae43e6edd12d, 0x5fd8f4e9d12d3e4a}}, - {{0x77ebf3245bb2d80a, 0xd8301b472fb9079b, 0xc647e6f24cee7333, 0x465812c8276c2109}}, - {{0x4d43beb22a1062d9, 0x7065fb753831dc16, 0x180d4a7bde2968d7, 0x05b32c2b1cb16790}}}, -{{{0xc8c05eccd24da8fd, 0xa1cf1aac05dfef83, 0xdbbeeff27df9cd61, 0x3b5556a37b471e99}}, - {{0xf7fca42c7ad58195, 0x3214286e4333f3cc, 0xb6c29d0d340b979d, 0x31771a48567307e1}}, - {{0x32b0c524e14dd482, 0xedb351541a2ba4b6, 0xa3d16048282b5af3, 0x4fc079d27a7336eb}}}, -{{{0x51c938b089bf2f7f, 0x2497bd6502dfe9a7, 0xffffc09c7880e453, 0x124567cecaf98e92}}, - {{0xdc348b440c86c50d, 0x1337cbc9cc94e651, 0x6422f74d643e3cb9, 0x241170c2bae3cd08}}, - {{0x3ff9ab860ac473b4, 0xf0911dee0113e435, 0x4ae75060ebc6c4af, 0x3f8612966c87000d}}}, -{{{0x0c9c5303f7957be4, 0xa3c31a20e085c145, 0xb0721d71d0850050, 0x0aba390eab0bf2da}}, - {{0x529fdffe638c7bf3, 0xdf2b9e60388b4995, 0xe027b34f1bad0249, 0x7bc92fc9b9fa74ed}}, - {{0x9f97ef2e801ad9f9, 0x83697d5479afda3a, 0xe906b3ffbd596b50, 0x02672b37dd3fb8e0}}}, -{{{0x48b2ca8b260885e4, 0xa4286bec82b34c1c, 0x937e1a2617f58f74, 0x741d1fcbab2ca2a5}}, - {{0xee9ba729398ca7f5, 0xeb9ca6257a4849db, 0x29eb29ce7ec544e1, 0x232ca21ef736e2c8}}, - {{0xbf61423d253fcb17, 0x08803ceafa39eb14, 0xf18602df9851c7af, 0x0400f3a049e3414b}}}, -{{{0xabce0476ba61c55b, 0x36a3d6d7c4d39716, 0x6eb259d5e8d82d09, 0x0c9176e984d756fb}}, - {{0x2efba412a06e7b06, 0x146785452c8d2560, 0xdf9713ebd67a91c7, 0x32830ac7157eadf3}}, - {{0x0e782a7ab73769e8, 0x04a05d7875b18e2c, 0x29525226ebcceae1, 0x0d794f8383eba820}}}, -{{{0xff35f5cb9e1516f4, 0xee805bcf648aae45, 0xf0d73c2bb93a9ef3, 0x097b0bf22092a6c2}}, - {{0x7be44ce7a7a2e1ac, 0x411fd93efad1b8b7, 0x1734a1d70d5f7c9b, 0x0d6592233127db16}}, - {{0xc48bab1521a9d733, 0xa6c2eaead61abb25, 0x625c6c1cc6cb4305, 0x7fc90fea93eb3a67}}}, -{{{0x0408f1fe1f5c5926, 0x1a8f2f5e3b258bf4, 0x40a951a2fdc71669, 0x6598ee93c98b577e}}, - {{0xc527deb59c7cb23d, 0x955391695328404e, 0xd64392817ccf2c7a, 0x6ce97dabf7d8fa11}}, - {{0x25b5a8e50ef7c48f, 0xeb6034116f2ce532, 0xc5e75173e53de537, 0x73119fa08c12bb03}}}, -{{{0xed30129453f1a4cb, 0xbce621c9c8f53787, 0xfacb2b1338bee7b9, 0x3025798a9ea8428c}}, - {{0x7845b94d21f4774d, 0xbf62f16c7897b727, 0x671857c03c56522b, 0x3cd6a85295621212}}, - {{0x3fecde923aeca999, 0xbdaa5b0062e8c12f, 0x67b99dfc96988ade, 0x3f52c02852661036}}}, -{{{0xffeaa48e2a1351c6, 0x28624754fa7f53d7, 0x0b5ba9e57582ddf1, 0x60c0104ba696ac59}}, - {{0x9258bf99eec416c6, 0xac8a5017a9d2f671, 0x629549ab16dea4ab, 0x05d0e85c99091569}}, - {{0x051de020de9cbe97, 0xfa07fc56b50bcf74, 0x378cec9f0f11df65, 0x36853c69ab96de4d}}}, -{{{0x36d9b8de78f39b2d, 0x7f42ed71a847b9ec, 0x241cd1d679bd3fde, 0x6a704fec92fbce6b}}, - {{0x4433c0b0fac5e7be, 0x724bae854c08dcbe, 0xf1f24cc446978f9b, 0x4a0aff6d62825fc8}}, - {{0xe917fb9e61095301, 0xc102df9402a092f8, 0xbf09e2f5fa66190b, 0x681109bee0dcfe37}}}, -{{{0x559a0cc9782a0dde, 0x551dcdb2ea718385, 0x7f62865b31ef238c, 0x504aa7767973613d}}, - {{0x9c18fcfa36048d13, 0x29159db373899ddd, 0xdc9f350b9f92d0aa, 0x26f57eee878a19d4}}, - {{0x0cab2cd55687efb1, 0x5180d162247af17b, 0x85c15a344f5a2467, 0x4041943d9dba3069}}}, -{{{0xc3c0eeba43ebcc96, 0x8d749c9c26ea9caf, 0xd9fa95ee1c77ccc6, 0x1420a1d97684340f}}, - {{0x4b217743a26caadd, 0x47a6b424648ab7ce, 0xcb1d4f7a03fbc9e3, 0x12d931429800d019}}, - {{0x00c67799d337594f, 0x5e3c5140b23aa47b, 0x44182854e35ff395, 0x1b4f92314359a012}}}, -{{{0x3e5c109d89150951, 0x39cefa912de9696a, 0x20eae43f975f3020, 0x239b572a7f132dae}}, - {{0x33cf3030a49866b1, 0x251f73d2215f4859, 0xab82aa4051def4f6, 0x5ff191d56f9a23f6}}, - {{0x819ed433ac2d9068, 0x2883ab795fc98523, 0xef4572805593eb3d, 0x020c526a758f36cb}}}, -{{{0x779834f89ed8dbbc, 0xc8f2aaf9dc7ca46c, 0xa9524cdca3e1b074, 0x02aacc4615313877}}, - {{0xe931ef59f042cc89, 0x2c589c9d8e124bb6, 0xadc8e18aaec75997, 0x452cfe0a5602c50c}}, - {{0x86a0f7a0647877df, 0xbbc464270e607c9f, 0xab17ea25f1fb11c9, 0x4cfb7d7b304b877b}}}, -{{{0x72b43d6cb89b75fe, 0x54c694d99c6adc80, 0xb8c3aa373ee34c9f, 0x14b4622b39075364}}, - {{0xe28699c29789ef12, 0x2b6ecd71df57190d, 0xc343c857ecc970d0, 0x5b1d4cbc434d3ac5}}, - {{0xb6fb2615cc0a9f26, 0x3a4f0e2bb88dcce5, 0x1301498b3369a705, 0x2f98f71258592dd1}}}, -{{{0x0c94a74cb50f9e56, 0x5b1ff4a98e8e1320, 0x9a2acc2182300f67, 0x3a6ae249d806aaf9}}, - {{0x2e12ae444f54a701, 0xfcfe3ef0a9cbd7de, 0xcebf890d75835de0, 0x1d8062e9e7614554}}, - {{0x657ada85a9907c5a, 0x1a0ea8b591b90f62, 0x8d0e1dfbdf34b4e9, 0x298b8ce8aef25ff3}}}, -{{{0x2a927953eff70cb2, 0x4b89c92a79157076, 0x9418457a30a7cf6a, 0x34b8a8404d5ce485}}, - {{0x837a72ea0a2165de, 0x3fab07b40bcf79f6, 0x521636c77738ae70, 0x6ba6271803a7d7dc}}, - {{0xc26eecb583693335, 0xd5a813df63b5fefd, 0xa293aa9aa4b22573, 0x71d62bdd465e1c6a}}}, -{{{0x6533cc28d378df80, 0xf6db43790a0fa4b4, 0xe3645ff9f701da5a, 0x74d5f317f3172ba4}}, - {{0xcd2db5dab1f75ef5, 0xd77f95cf16b065f5, 0x14571fea3f49f085, 0x1c333621262b2b3d}}, - {{0xa86fe55467d9ca81, 0x398b7c752b298c37, 0xda6d0892e3ac623b, 0x4aebcc4547e9d98c}}}, -{{{0x53175a7205d21a77, 0xb0c04422d3b934d4, 0xadd9f24bdd5deadc, 0x074f46e69f10ff8c}}, - {{0x0de9b204a059a445, 0xe15cb4aa4b17ad0f, 0xe1bbec521f79c557, 0x2633f1b9d071081b}}, - {{0xc1fb4177018b9910, 0xa6ea20dc6c0fe140, 0xd661f3e74354c6ff, 0x5ecb72e6f1a3407a}}}, -{{{0xa515a31b2259fb4e, 0x0960f3972bcac52f, 0xedb52fec8d3454cb, 0x382e2720c476c019}}, - {{0xfeeae106e8e86997, 0x9863337f98d09383, 0x9470480eaa06ebef, 0x038b6898d4c5c2d0}}, - {{0xf391c51d8ace50a6, 0x3142d0b9ae2d2948, 0xdb4d5a1a7f24ca80, 0x21aeba8b59250ea8}}}, -{{{0x24f13b34cf405530, 0x3c44ea4a43088af7, 0x5dd5c5170006a482, 0x118eb8f8890b086d}}, - {{0x53853600f0087f23, 0x4c461879da7d5784, 0x6af303deb41f6860, 0x0a3c16c5c27c18ed}}, - {{0x17e49c17cc947f3d, 0xccc6eda6aac1d27b, 0xdf6092ceb0f08e56, 0x4909b3e22c67c36b}}}, -{{{0x9c9c85ea63fe2e89, 0xbe1baf910e9412ec, 0x8f7baa8a86fbfe7b, 0x0fb17f9fef968b6c}}, - {{0x59a16676706ff64e, 0x10b953dd0d86a53d, 0x5848e1e6ce5c0b96, 0x2d8b78e712780c68}}, - {{0x79d5c62eafc3902b, 0x773a215289e80728, 0xc38ae640e10120b9, 0x09ae23717b2b1a6d}}}, -{{{0xbb6a192a4e4d083c, 0x34ace0630029e192, 0x98245a59aafabaeb, 0x6d9c8a9ada97faac}}, - {{0x10ab8fa1ad32b1d0, 0xe9aced1be2778b24, 0xa8856bc0373de90f, 0x66f35ddddda53996}}, - {{0xd27d9afb24997323, 0x1bb7e07ef6f01d2e, 0x2ba7472df52ecc7f, 0x03019b4f646f9dc8}}}, -{{{0x04a186b5565345cd, 0xeee76610bcc4116a, 0x689c73b478fb2a45, 0x387dcbff65697512}}, - {{0xaf09b214e6b3dc6b, 0x3f7573b5ad7d2f65, 0xd019d988100a23b0, 0x392b63a58b5c35f7}}, - {{0x4093addc9c07c205, 0xc565be15f532c37e, 0x63dbecfd1583402a, 0x61722b4aef2e032e}}}, -{{{0x0012aafeecbd47af, 0x55a266fb1cd46309, 0xf203eb680967c72c, 0x39633944ca3c1429}}, - {{0xd6b07a5581cb0e3c, 0x290ff006d9444969, 0x08680b6a16dcda1f, 0x5568d2b75a06de59}}, - {{0x8d0cb88c1b37cfe1, 0x05b6a5a3053818f3, 0xf2e9bc04b787d959, 0x6beba1249add7f64}}}, -{{{0x1d06005ca5b1b143, 0x6d4c6bb87fd1cda2, 0x6ef5967653fcffe7, 0x097c29e8c1ce1ea5}}, - {{0x5c3cecb943f5a53b, 0x9cc9a61d06c08df2, 0xcfba639a85895447, 0x5a845ae80df09fd5}}, - {{0x4ce97dbe5deb94ca, 0x38d0a4388c709c48, 0xc43eced4a169d097, 0x0a1249fff7e587c3}}}, -{{{0x12f0071b276d01c9, 0xe7b8bac586c48c70, 0x5308129b71d6fba9, 0x5d88fbf95a3db792}}, - {{0x0b408d9e7354b610, 0x806b32535ba85b6e, 0xdbe63a034a58a207, 0x173bd9ddc9a1df2c}}, - {{0x2b500f1efe5872df, 0x58d6582ed43918c1, 0xe6ed278ec9673ae0, 0x06e1cd13b19ea319}}}, -{{{0x40d0ad516f166f23, 0x118e32931fab6abe, 0x3fe35e14a04d088e, 0x3080603526e16266}}, - {{0x472baf629e5b0353, 0x3baa0b90278d0447, 0x0c785f469643bf27, 0x7f3a6a1a8d837b13}}, - {{0xf7e644395d3d800b, 0x95a8d555c901edf6, 0x68cd7830592c6339, 0x30d0fded2e51307e}}}, -{{{0xe0594d1af21233b3, 0x1bdbe78ef0cc4d9c, 0x6965187f8f499a77, 0x0a9214202c099868}}, - {{0x9cb4971e68b84750, 0xa09572296664bbcf, 0x5c8de72672fa412b, 0x4615084351c589d9}}, - {{0xbc9019c0aeb9a02e, 0x55c7110d16034cae, 0x0e6df501659932ec, 0x3bca0d2895ca5dfe}}}, -{{{0x40f031bc3c5d62a4, 0x19fc8b3ecff07a60, 0x98183da2130fb545, 0x5631deddae8f13cd}}, - {{0x9c688eb69ecc01bf, 0xf0bc83ada644896f, 0xca2d955f5f7a9fe2, 0x4ea8b4038df28241}}, - {{0x2aed460af1cad202, 0x46305305a48cee83, 0x9121774549f11a5f, 0x24ce0930542ca463}}}, -{{{0x1fe890f5fd06c106, 0xb5c468355d8810f2, 0x827808fe6e8caf3e, 0x41d4e3c28a06d74b}}, - {{0x3fcfa155fdf30b85, 0xd2f7168e36372ea4, 0xb2e064de6492f844, 0x549928a7324f4280}}, - {{0xf26e32a763ee1a2e, 0xae91e4b7d25ffdea, 0xbc3bd33bd17f4d69, 0x491b66dec0dcff6a}}}, -{{{0x98f5b13dc7ea32a7, 0xe3d5f8cc7e16db98, 0xac0abf52cbf8d947, 0x08f338d0c85ee4ac}}, - {{0x75f04a8ed0da64a1, 0xed222caf67e2284b, 0x8234a3791f7b7ba4, 0x4cf6b8b0b7018b67}}, - {{0xc383a821991a73bd, 0xab27bc01df320c7a, 0xc13d331b84777063, 0x530d4a82eb078a99}}}, -{{{0x004c3630e1f94825, 0x7e2d78268cab535a, 0xc7482323cc84ff8b, 0x65ea753f101770b9}}, - {{0x6d6973456c9abf9e, 0x257fb2fc4900a880, 0x2bacf412c8cfb850, 0x0db3e7e00cbfbd5b}}, - {{0x3d66fc3ee2096363, 0x81d62c7f61b5cb6b, 0x0fbe044213443b1a, 0x02a4ec1921e1a1db}}}, -{{{0x5ce6259a3b24b8a2, 0xb8577acc45afa0b8, 0xcccbe6e88ba07037, 0x3d143c51127809bf}}, - {{0xf5c86162f1cf795f, 0x118c861926ee57f2, 0x172124851c063578, 0x36d12b5dec067fcf}}, - {{0x126d279179154557, 0xd5e48f5cfc783a0a, 0x36bdb6e8df179bac, 0x2ef517885ba82859}}}, -{{{0x88bd438cd11e0d4a, 0x30cb610d43ccf308, 0xe09a0e3791937bcc, 0x4559135b25b1720c}}, - {{0x1ea436837c6da1e9, 0xf9c189af1fb9bdbe, 0x303001fcce5dd155, 0x28a7c99ebc57be52}}, - {{0xb8fd9399e8d19e9d, 0x908191cb962423ff, 0xb2b948d747c742a3, 0x37f33226d7fb44c4}}}, -{{{0x0dae8767b55f6e08, 0x4a43b3b35b203a02, 0xe3725a6e80af8c79, 0x0f7a7fd1705fa7a3}}, - {{0x33912553c821b11d, 0x66ed42c241e301df, 0x066fcc11104222fd, 0x307a3b41c192168f}}, - {{0x8eeb5d076eb55ce0, 0x2fc536bfaa0d925a, 0xbe81830fdcb6c6e8, 0x556c7045827baf52}}}, -{{{0x8e2b517302e9d8b7, 0xe3e52269248714e8, 0xbd4fbd774ca960b5, 0x6f4b4199c5ecada9}}, - {{0xb94b90022bf44406, 0xabd4237eff90b534, 0x7600a960faf86d3a, 0x2f45abdac2322ee3}}, - {{0x61af4912c8ef8a6a, 0xe58fa4fe43fb6e5e, 0xb5afcc5d6fd427cf, 0x6a5393281e1e11eb}}}, -{{{0xf3da5139a5d1ee89, 0x8145457cff936988, 0x3f622fed00e188c4, 0x0f513815db8b5a3d}}, - {{0x0fff04fe149443cf, 0x53cac6d9865cddd7, 0x31385b03531ed1b7, 0x5846a27cacd1039d}}, - {{0x4ff5cdac1eb08717, 0x67e8b29590f2e9bc, 0x44093b5e237afa99, 0x0d414bed8708b8b2}}}, -{{{0xcfb68265fd0e75f6, 0xe45b3e28bb90e707, 0x7242a8de9ff92c7a, 0x685b3201933202dd}}, - {{0x81886a92294ac9e8, 0x23162b45d55547be, 0x94cfbc4403715983, 0x50eb8fdb134bc401}}, - {{0xc0b73ec6d6b330cd, 0x84e44807132faff1, 0x732b7352c4a5dee1, 0x5d7c7cf1aa7cd2d2}}}, -{{{0xaf3b46bf7a4aafa2, 0xb78705ec4d40d411, 0x114f0c6aca7c15e3, 0x3f364faaa9489d4d}}, - {{0x33d1013e9b73a562, 0x925cef5748ec26e1, 0xa7fce614dd468058, 0x78b0fad41e9aa438}}, - {{0xbf56a431ed05b488, 0xa533e66c9c495c7e, 0xe8652baf87f3651a, 0x0241800059d66c33}}}, -{{{0xceb077fea37a5be4, 0xdb642f02e5a5eeb7, 0xc2e6d0c5471270b8, 0x4771b65538e4529c}}, - {{0x28350c7dcf38ea01, 0x7c6cdbc0b2917ab6, 0xace7cfbe857082f7, 0x4d2845aba2d9a1e0}}, - {{0xbb537fe0447070de, 0xcba744436dd557df, 0xd3b5a3473600dbcb, 0x4aeabbe6f9ffd7f8}}}, -{{{0x4630119e40d8f78c, 0xa01a9bc53c710e11, 0x486d2b258910dd79, 0x1e6c47b3db0324e5}}, - {{0x6a2134bcc4a9c8f2, 0xfbf8fd1c8ace2e37, 0x000ae3049911a0ba, 0x046e3a616bc89b9e}}, - {{0x14e65442f03906be, 0x4a019d54e362be2a, 0x68ccdfec8dc230c7, 0x7cfb7e3faf6b861c}}}, -{{{0x4637974e8c58aedc, 0xb9ef22fbabf041a4, 0xe185d956e980718a, 0x2f1b78fab143a8a6}}, - {{0x96eebffb305b2f51, 0xd3f938ad889596b8, 0xf0f52dc746d5dd25, 0x57968290bb3a0095}}, - {{0xf71ab8430a20e101, 0xf393658d24f0ec47, 0xcf7509a86ee2eed1, 0x7dc43e35dc2aa3e1}}}, -{{{0x85966665887dd9c3, 0xc90f9b314bb05355, 0xc6e08df8ef2079b1, 0x7ef72016758cc12f}}, - {{0x5a782a5c273e9718, 0x3576c6995e4efd94, 0x0f2ed8051f237d3e, 0x044fb81d82d50a99}}, - {{0xc1df18c5a907e3d9, 0x57b3371dce4c6359, 0xca704534b201bb49, 0x7f79823f9c30dd2e}}}, -{{{0x8334d239a3b513e8, 0xc13670d4b91fa8d8, 0x12b54136f590bd33, 0x0a4e0373d784d9b4}}, - {{0x6a9c1ff068f587ba, 0x0827894e0050c8de, 0x3cbf99557ded5be7, 0x64a9b0431c06d6f0}}, - {{0x2eb3d6a15b7d2919, 0xb0b4f6a0d53a8235, 0x7156ce4389a45d47, 0x071a7d0ace18346c}}}, -{{{0xd3072daac887ba0b, 0x01262905bfa562ee, 0xcf543002c0ef768b, 0x2c3bcc7146ea7e9c}}, - {{0xcc0c355220e14431, 0x0d65950709b15141, 0x9af5621b209d5f36, 0x7c69bcf7617755d3}}, - {{0x07f0d7eb04e8295f, 0x10db18252f50f37d, 0xe951a9a3171798d7, 0x6f5a9a7322aca51d}}}, -{{{0x8ba1000c2f41c6c5, 0xc49f79c10cfefb9b, 0x4efa47703cc51c9f, 0x494e21a2e147afca}}, - {{0xe729d4eba3d944be, 0x8d9e09408078af9e, 0x4525567a47869c03, 0x02ab9680ee8d3b24}}, - {{0xefa48a85dde50d9a, 0x219a224e0fb9a249, 0xfa091f1dd91ef6d9, 0x6b5d76cbea46bb34}}}, -{{{0x8857556cec0cd994, 0x6472dc6f5cd01dba, 0xaf0169148f42b477, 0x0ae333f685277354}}, - {{0xe0f941171e782522, 0xf1e6ae74036936d3, 0x408b3ea2d0fcc746, 0x16fb869c03dd313e}}, - {{0x288e199733b60962, 0x24fc72b4d8abe133, 0x4811f7ed0991d03e, 0x3f81e38b8f70d075}}}, -{{{0x7f910fcc7ed9affe, 0x545cb8a12465874b, 0xa8397ed24b0c4704, 0x50510fc104f50993}}, - {{0x0adb7f355f17c824, 0x74b923c3d74299a4, 0xd57c3e8bcbf8eaf7, 0x0ad3e2d34cdedc3d}}, - {{0x6f0c0fc5336e249d, 0x745ede19c331cfd9, 0xf2d6fd0009eefe1c, 0x127c158bf0fa1ebe}}}, -{{{0xf6197c422e9879a2, 0xa44addd452ca3647, 0x9b413fc14b4eaccb, 0x354ef87d07ef4f68}}, - {{0xdea28fc4ae51b974, 0x1d9973d3744dfe96, 0x6240680b873848a8, 0x4ed82479d167df95}}, - {{0xfee3b52260c5d975, 0x50352efceb41b0b8, 0x8808ac30a9f6653c, 0x302d92d20539236d}}}, -{{{0x4c59023fcb3efb7c, 0x6c2fcb99c63c2a94, 0xba4190e2c3c7e084, 0x0e545daea51874d9}}, - {{0x957b8b8b0df53c30, 0x2a1c770a8e60f098, 0xbbc7a670345796de, 0x22a48f9a90c99bc9}}, - {{0x6b7dc0dc8d3fac58, 0x5497cd6ce6e42bfd, 0x542f7d1bf400d305, 0x4159f47f048d9136}}}, -{{{0x20ad660839e31e32, 0xf81e1bd58405be50, 0xf8064056f4dabc69, 0x14d23dd4ce71b975}}, - {{0x748515a8bbd24839, 0x77128347afb02b55, 0x50ba2ac649a2a17f, 0x060525513ad730f1}}, - {{0xf2398e098aa27f82, 0x6d7982bb89a1b024, 0xfa694084214dd24c, 0x71ab966fa32301c3}}}, -{{{0x2dcbd8e34ded02fc, 0x1151f3ec596f22aa, 0xbca255434e0328da, 0x35768fbe92411b22}}, - {{0xb1088a0702809955, 0x43b273ea0b43c391, 0xca9b67aefe0686ed, 0x605eecbf8335f4ed}}, - {{0x83200a656c340431, 0x9fcd71678ee59c2f, 0x75d4613f71300f8a, 0x7a912faf60f542f9}}}, -{{{0xb204585e5edc1a43, 0x9f0e16ee5897c73c, 0x5b82c0ae4e70483c, 0x624a170e2bddf9be}}, - {{0x253f4f8dfa2d5597, 0x25e49c405477130c, 0x00c052e5996b1102, 0x33cb966e33bb6c4a}}, - {{0x597028047f116909, 0x828ac41c1e564467, 0x70417dbde6217387, 0x721627aefbac4384}}}, -{{{0x97d03bc38736add5, 0x2f1422afc532b130, 0x3aa68a057101bbc4, 0x4c946cf7e74f9fa7}}, - {{0xfd3097bc410b2f22, 0xf1a05da7b5cfa844, 0x61289a1def57ca74, 0x245ea199bb821902}}, - {{0xaedca66978d477f8, 0x1898ba3c29117fe1, 0xcf73f983720cbd58, 0x67da12e6b8b56351}}}, -{{{0x7067e187b4bd6e07, 0x6e8f0203c7d1fe74, 0x93c6aa2f38c85a30, 0x76297d1f3d75a78a}}, - {{0x2b7ef3d38ec8308c, 0x828fd7ec71eb94ab, 0x807c3b36c5062abd, 0x0cb64cb831a94141}}, - {{0x3030fc33534c6378, 0xb9635c5ce541e861, 0x15d9a9bed9b2c728, 0x49233ea3f3775dcb}}}, -{{{0x629398fa8dbffc3a, 0xe12fe52dd54db455, 0xf3be11dfdaf25295, 0x628b140dce5e7b51}}, - {{0x7b3985fe1c9f249b, 0x4fd6b2d5a1233293, 0xceb345941adf4d62, 0x6987ff6f542de50c}}, - {{0x47e241428f83753c, 0x6317bebc866af997, 0xdabb5b433d1a9829, 0x074d8d245287fb2d}}}, -{{{0x8337d9cd440bfc31, 0x729d2ca1af318fd7, 0xa040a4a4772c2070, 0x46002ef03a7349be}}, - {{0x481875c6c0e31488, 0x219429b2e22034b4, 0x7223c98a31283b65, 0x3420d60b342277f9}}, - {{0xfaa23adeaffe65f7, 0x78261ed45be0764c, 0x441c0a1e2f164403, 0x5aea8e567a87d395}}}, -{{{0x7813c1a2bca4283d, 0xed62f091a1863dd9, 0xaec7bcb8c268fa86, 0x10e5d3b76f1cae4c}}, - {{0x2dbc6fb6e4e0f177, 0x04e1bf29a4bd6a93, 0x5e1966d4787af6e8, 0x0edc5f5eb426d060}}, - {{0x5453bfd653da8e67, 0xe9dc1eec24a9f641, 0xbf87263b03578a23, 0x45b46c51361cba72}}}, -{{{0xa9402abf314f7fa1, 0xe257f1dc8e8cf450, 0x1dbbd54b23a8be84, 0x2177bfa36dcb713b}}, - {{0xce9d4ddd8a7fe3e4, 0xab13645676620e30, 0x4b594f7bb30e9958, 0x5c1c0aef321229df}}, - {{0x37081bbcfa79db8f, 0x6048811ec25f59b3, 0x087a76659c832487, 0x4ae619387d8ab5bb}}}, -{{{0x8ddbf6aa5344a32e, 0x7d88eab4b41b4078, 0x5eb0eb974a130d60, 0x1a00d91b17bf3e03}}, - {{0x61117e44985bfb83, 0xfce0462a71963136, 0x83ac3448d425904b, 0x75685abe5ba43d64}}, - {{0x6e960933eb61f2b2, 0x543d0fa8c9ff4952, 0xdf7275107af66569, 0x135529b623b0e6aa}}}, -{{{0x18f0dbd7add1d518, 0x979f7888cfc11f11, 0x8732e1f07114759b, 0x79b5b81a65ca3a01}}, - {{0xf5c716bce22e83fe, 0xb42beb19e80985c1, 0xec9da63714254aae, 0x5972ea051590a613}}, - {{0x0fd4ac20dc8f7811, 0x9a9ad294ac4d4fa8, 0xc01b2d64b3360434, 0x4f7e9c95905f3bdb}}}, -{{{0x62674bbc5781302e, 0xd8520f3989addc0f, 0x8c2999ae53fbd9c6, 0x31993ad92e638e4c}}, - {{0x71c8443d355299fe, 0x8bcd3b1cdbebead7, 0x8092499ef1a49466, 0x1942eec4a144adc8}}, - {{0x7dac5319ae234992, 0x2c1b3d910cea3e92, 0x553ce494253c1122, 0x2a0a65314ef9ca75}}}, -{{{0x2db7937ff7f927c2, 0xdb741f0617d0a635, 0x5982f3a21155af76, 0x4cf6e218647c2ded}}, - {{0xcf361acd3c1c793a, 0x2f9ebcac5a35bc3b, 0x60e860e9a8cda6ab, 0x055dc39b6dea1a13}}, - {{0xb119227cc28d5bb6, 0x07e24ebc774dffab, 0xa83c78cee4a32c89, 0x121a307710aa24b6}}}, -{{{0xe4db5d5e9f034a97, 0xe153fc093034bc2d, 0x460546919551d3b1, 0x333fc76c7a40e52d}}, - {{0xd659713ec77483c9, 0x88bfe077b82b96af, 0x289e28231097bcd3, 0x527bb94a6ced3a9b}}, - {{0x563d992a995b482e, 0x3405d07c6e383801, 0x485035de2f64d8e5, 0x6b89069b20a7a9f7}}}, -{{{0x812aa0416270220d, 0x995a89faf9245b4e, 0xffadc4ce5072ef05, 0x23bc2103aa73eb73}}, - {{0x4082fa8cb5c7db77, 0x068686f8c734c155, 0x29e6c8d9f6e7a57e, 0x0473d308a7639bcf}}, - {{0xcaee792603589e05, 0x2b4b421246dcc492, 0x02a1ef74e601a94f, 0x102f73bfde04341a}}}, -{{{0xb5a2d50c7ec20d3e, 0xc64bdd6ea0c97263, 0x56e89052c1ff734d, 0x4929c6f72b2ffaba}}, - {{0x358ecba293a36247, 0xaf8f9862b268fd65, 0x412f7e9968a01c89, 0x5786f312cd754524}}, - {{0x337788ffca14032c, 0xf3921028447f1ee3, 0x8b14071f231bccad, 0x4c817b4bf2344783}}}, -{{{0x0ff853852871b96e, 0xe13e9fab60c3f1bb, 0xeefd595325344402, 0x0a37c37075b7744b}}, - {{0x413ba057a40b4484, 0xba4c2e1a4f5f6a43, 0x614ba0a5aee1d61c, 0x78a1531a8b05dc53}}, - {{0x6cbdf1703ad0562b, 0x8ecf4830c92521a3, 0xdaebd303fd8424e7, 0x72ad82a42e5ec56f}}}, -{{{0x3f9e8e35bafb65f6, 0x39d69ec8f27293a1, 0x6cb8cd958cf6a3d0, 0x1734778173adae6d}}, - {{0xc368939167024bc3, 0x8e69d16d49502fda, 0xfcf2ec3ce45f4b29, 0x065f669ea3b4cbc4}}, - {{0x8a00aec75532db4d, 0xb869a4e443e31bb1, 0x4a0f8552d3a7f515, 0x19adeb7c303d7c08}}}, -{{{0xc720cb6153ead9a3, 0x55b2c97f512b636e, 0xb1e35b5fd40290b1, 0x2fd9ccf13b530ee2}}, - {{0x9d05ba7d43c31794, 0x2470c8ff93322526, 0x8323dec816197438, 0x2852709881569b53}}, - {{0x07bd475b47f796b8, 0xd2c7b013542c8f54, 0x2dbd23f43b24f87e, 0x6551afd77b0901d6}}}, -{{{0x4546baaf54aac27f, 0xf6f66fecb2a45a28, 0x582d1b5b562bcfe8, 0x44b123f3920f785f}}, - {{0x68a24ce3a1d5c9ac, 0xbb77a33d10ff6461, 0x0f86ce4425d3166e, 0x56507c0950b9623b}}, - {{0x1206f0b7d1713e63, 0x353fe3d915bafc74, 0x194ceb970ad9d94d, 0x62fadd7cf9d03ad3}}}, -{{{0xc6b5967b5598a074, 0x5efe91ce8e493e25, 0xd4b72c4549280888, 0x20ef1149a26740c2}}, - {{0x3cd7bc61e7ce4594, 0xcd6b35a9b7dd267e, 0xa080abc84366ef27, 0x6ec7c46f59c79711}}, - {{0x2f07ad636f09a8a2, 0x8697e6ce24205e7d, 0xc0aefc05ee35a139, 0x15e80958b5f9d897}}}, -{{{0x25a5ef7d0c3e235b, 0x6c39c17fbe134ee7, 0xc774e1342dc5c327, 0x021354b892021f39}}, - {{0x4dd1ed355bb061c4, 0x42dc0cef941c0700, 0x61305dc1fd86340e, 0x56b2cc930e55a443}}, - {{0x1df79da6a6bfc5a2, 0x02f3a2749fde4369, 0xb323d9f2cda390a7, 0x7be0847b8774d363}}}, -{{{0x8c99cc5a8b3f55c3, 0x0611d7253fded2a0, 0xed2995ff36b70a36, 0x1f699a54d78a2619}}, - {{0x1466f5af5307fa11, 0x817fcc7ded6c0af2, 0x0a6de44ec3a4a3fb, 0x74071475bc927d0b}}, - {{0xe77292f373e7ea8a, 0x296537d2cb045a31, 0x1bd0653ed3274fde, 0x2f9a2c4476bd2966}}}, -{{{0xeb18b9ab7f5745c6, 0x023a8aee5787c690, 0xb72712da2df7afa9, 0x36597d25ea5c013d}}, - {{0xa2b4dae0b5511c9a, 0x7ac860292bffff06, 0x981f375df5504234, 0x3f6bd725da4ea12d}}, - {{0x734d8d7b106058ac, 0xd940579e6fc6905f, 0x6466f8f99202932d, 0x7b7ecc19da60d6d0}}}, -{{{0x78c2373c695c690d, 0xdd252e660642906e, 0x951d44444ae12bd2, 0x4235ad7601743956}}, - {{0x6dae4a51a77cfa9b, 0x82263654e7a38650, 0x09bbffcd8f2d82db, 0x03bedc661bf5caba}}, - {{0x6258cb0d078975f5, 0x492942549189f298, 0xa0cab423e2e36ee4, 0x0e7ce2b0cdf066a1}}}, -{{{0xc494643ac48c85a3, 0xfd361df43c6139ad, 0x09db17dd3ae94d48, 0x666e0a5d8fb4674a}}, - {{0xfea6fedfd94b70f9, 0xf130c051c1fcba2d, 0x4882d47e7f2fab89, 0x615256138aeceeb5}}, - {{0x2abbf64e4870cb0d, 0xcd65bcf0aa458b6b, 0x9abe4eba75e8985d, 0x7f0bc810d514dee4}}}, -{{{0xb9006ba426f4136f, 0x8d67369e57e03035, 0xcbc8dfd94f463c28, 0x0d1f8dbcf8eedbf5}}, - {{0x83ac9dad737213a0, 0x9ff6f8ba2ef72e98, 0x311e2edd43ec6957, 0x1d3a907ddec5ab75}}, - {{0xba1693313ed081dc, 0x29329fad851b3480, 0x0128013c030321cb, 0x00011b44a31bfde3}}}, -{{{0x3fdfa06c3fc66c0c, 0x5d40e38e4dd60dd2, 0x7ae38b38268e4d71, 0x3ac48d916e8357e1}}, - {{0x16561f696a0aa75c, 0xc1bf725c5852bd6a, 0x11a8dd7f9a7966ad, 0x63d988a2d2851026}}, - {{0x00120753afbd232e, 0xe92bceb8fdd8f683, 0xf81669b384e72b91, 0x33fad52b2368a066}}}, -{{{0x540649c6c5e41e16, 0x0af86430333f7735, 0xb2acfcd2f305e746, 0x16c0f429a256dca7}}, - {{0x8d2cc8d0c422cfe8, 0x072b4f7b05a13acb, 0xa3feb6e6ecf6a56f, 0x3cc355ccb90a71e2}}, - {{0xe9b69443903e9131, 0xb8a494cb7a5637ce, 0xc87cd1a4baba9244, 0x631eaf426bae7568}}}, -{{{0xb3e90410da66fe9f, 0x85dd4b526c16e5a6, 0xbc3d97611ef9bf83, 0x5599648b1ea919b5}}, - {{0x47d975b9a3700de8, 0x7280c5fbe2f80552, 0x53658f2732e45de1, 0x431f2c7f665f80b5}}, - {{0xd6026344858f7b19, 0x14ab352fa1ea514a, 0x8900441a2090a9d7, 0x7b04715f91253b26}}}, -{{{0x83edbd28acf6ae43, 0x86357c8b7d5c7ab4, 0xc0404769b7eb2c44, 0x59b37bf5c2f6583f}}, - {{0xb376c280c4e6bac6, 0x970ed3dd6d1d9b0b, 0xb09a9558450bf944, 0x48d0acfa57cde223}}, - {{0xb60f26e47dabe671, 0xf1d1a197622f3a37, 0x4208ce7ee9960394, 0x16234191336d3bdb}}}, -{{{0xf19aeac733a63aef, 0x2c7fba5d4442454e, 0x5da87aa04795e441, 0x413051e1a4e0b0f5}}, - {{0x852dd1fd3d578bbe, 0x2b65ce72c3286108, 0x658c07f4eace2273, 0x0933f804ec38ab40}}, - {{0xa7ab69798d496476, 0x8121aadefcb5abc8, 0xa5dc12ef7b539472, 0x07fd47065e45351a}}}, -{{{0xc8583c3d258d2bcd, 0x17029a4daf60b73f, 0xfa0fc9d6416a3781, 0x1c1e5fba38b3fb23}}, - {{0x304211559ae8e7c3, 0xf281b229944882a5, 0x8a13ac2e378250e4, 0x014afa0954ba48f4}}, - {{0xcb3197001bb3666c, 0x330060524bffecb9, 0x293711991a88233c, 0x291884363d4ed364}}}, -{{{0x033c6805dc4babfa, 0x2c15bf5e5596ecc1, 0x1bc70624b59b1d3b, 0x3ede9850a19f0ec5}}, - {{0xfb9d37c3bc1ab6eb, 0x02be14534d57a240, 0xf4d73415f8a5e1f6, 0x5964f4300ccc8188}}, - {{0xe44a23152d096800, 0x5c08c55970866996, 0xdf2db60a46affb6e, 0x579155c1f856fd89}}}, -{{{0x96324edd12e0c9ef, 0x468b878df2420297, 0x199a3776a4f573be, 0x1e7fbcf18e91e92a}}, - {{0xb5f16b630817e7a6, 0x808c69233c351026, 0x324a983b54cef201, 0x53c092084a485345}}, - {{0xd2d41481f1cbafbf, 0x231d2db6716174e5, 0x0b7d7656e2a55c98, 0x3e955cd82aa495f6}}}, -{{{0xe48f535e3ed15433, 0xd075692a0d7270a3, 0x40fbd21daade6387, 0x14264887cf4495f5}}, - {{0xab39f3ef61bb3a3f, 0x8eb400652eb9193e, 0xb5de6ecc38c11f74, 0x654d7e9626f3c49f}}, - {{0xe564cfdd5c7d2ceb, 0x82eeafded737ccb9, 0x6107db62d1f9b0ab, 0x0b6baac3b4358dbb}}}, -{{{0x7ae62bcb8622fe98, 0x47762256ceb891af, 0x1a5a92bcf2e406b4, 0x7d29401784e41501}}, - {{0x204abad63700a93b, 0xbe0023d3da779373, 0xd85f0346633ab709, 0x00496dc490820412}}, - {{0x1c74b88dc27e6360, 0x074854268d14850c, 0xa145fb7b3e0dcb30, 0x10843f1b43803b23}}}, -{{{0xc5f90455376276dd, 0xce59158dd7645cd9, 0x92f65d511d366b39, 0x11574b6e526996c4}}, - {{0xd56f672de324689b, 0xd1da8aedb394a981, 0xdd7b58fe9168cfed, 0x7ce246cd4d56c1e8}}, - {{0xb8f4308e7f80be53, 0x5f3cb8cb34a9d397, 0x18a961bd33cc2b2c, 0x710045fb3a9af671}}}, -{{{0x73f93d36101b95eb, 0xfaef33794f6f4486, 0x5651735f8f15e562, 0x7fa3f19058b40da1}}, - {{0xa03fc862059d699e, 0x2370cfa19a619e69, 0xc4fe3b122f823deb, 0x1d1b056fa7f0844e}}, - {{0x1bc64631e56bf61f, 0xd379ab106e5382a3, 0x4d58c57e0540168d, 0x566256628442d8e4}}}, -{{{0xb9e499def6267ff6, 0x7772ca7b742c0843, 0x23a0153fe9a4f2b1, 0x2cdfdfecd5d05006}}, - {{0xdd499cd61ff38640, 0x29cd9bc3063625a0, 0x51e2d8023dd73dc3, 0x4a25707a203b9231}}, - {{0x2ab7668a53f6ed6a, 0x304242581dd170a1, 0x4000144c3ae20161, 0x5721896d248e49fc}}}, -{{{0x0b6e5517fd181bae, 0x9022629f2bb963b4, 0x5509bce932064625, 0x578edd74f63c13da}}, - {{0x285d5091a1d0da4e, 0x4baa6fa7b5fe3e08, 0x63e5177ce19393b3, 0x03c935afc4b030fd}}, - {{0x997276c6492b0c3d, 0x47ccc2c4dfe205fc, 0xdcd29b84dd623a3c, 0x3ec2ab590288c7a2}}}, -{{{0xa1a0d27be4d87bb9, 0xa98b4deb61391aed, 0x99a0ddd073cb9b83, 0x2dd5c25a200fcace}}, - {{0xa7213a09ae32d1cb, 0x0f2b87df40f5c2d5, 0x0baea4c6e81eab29, 0x0e1bf66c6adbac5e}}, - {{0xe2abd5e9792c887e, 0x1a020018cb926d5d, 0xbfba69cdbaae5f1e, 0x730548b35ae88f5f}}}, -{{{0xc43551a3cba8b8ee, 0x65a26f1db2115f16, 0x760f4f52ab8c3850, 0x3043443b411db8ca}}, - {{0x805b094ba1d6e334, 0xbf3ef17709353f19, 0x423f06cb0622702b, 0x585a2277d87845dd}}, - {{0xa18a5f8233d48962, 0x6698c4b5ec78257f, 0xa78e6fa5373e41ff, 0x7656278950ef981f}}}, -{{{0x38c3cf59d51fc8c0, 0x9bedd2fd0506b6f2, 0x26bf109fab570e8f, 0x3f4160a8c1b846a6}}, - {{0xe17073a3ea86cf9d, 0x3a8cfbb707155fdc, 0x4853e7fc31838a8e, 0x28bbf484b613f616}}, - {{0xf2612f5c6f136c7c, 0xafead107f6dd11be, 0x527e9ad213de6f33, 0x1e79cb358188f75d}}}, -{{{0x013436c3eef7e3f1, 0x828b6a7ffe9e10f8, 0x7ff908e5bcf9defc, 0x65d7951b3a3b3831}}, - {{0x77e953d8f5e08181, 0x84a50c44299dded9, 0xdc6c2d0c864525e5, 0x478ab52d39d1f2f4}}, - {{0x66a6a4d39252d159, 0xe5dde1bc871ac807, 0xb82c6b40a6c1c96f, 0x16d87a411a212214}}}, -{{{0xb3bd7e5a42066215, 0x879be3cd0c5a24c1, 0x57c05db1d6f994b7, 0x28f87c8165f38ca6}}, - {{0xfba4d5e2d54e0583, 0xe21fafd72ebd99fa, 0x497ac2736ee9778f, 0x1f990b577a5a6dde}}, - {{0xa3344ead1be8f7d6, 0x7d1e50ebacea798f, 0x77c6569e520de052, 0x45882fe1534d6d3e}}}, -{{{0x6669345d757983d6, 0x62b6ed1117aa11a6, 0x7ddd1857985e128f, 0x688fe5b8f626f6dd}}, - {{0xd8ac9929943c6fe4, 0xb5f9f161a38392a2, 0x2699db13bec89af3, 0x7dcf843ce405f074}}, - {{0x6c90d6484a4732c0, 0xd52143fdca563299, 0xb3be28c3915dc6e1, 0x6739687e7327191b}}}, -{{{0x9f65c5ea200814cf, 0x840536e169a31740, 0x8b0ed13925c8b4ad, 0x0080dbafe936361d}}, - {{0x8ce5aad0c9cb971f, 0x1156aaa99fd54a29, 0x41f7247015af9b78, 0x1fe8cca8420f49aa}}, - {{0x72a1848f3c0cc82a, 0x38c560c2877c9e54, 0x5004e228ce554140, 0x042418a103429d71}}}, -{{{0x899dea51abf3ff5f, 0x9b93a8672fc2d8ba, 0x2c38cb97be6ebd5c, 0x114d578497263b5d}}, - {{0x58e84c6f20816247, 0x8db2b2b6e36fd793, 0x977182561d484d85, 0x0822024f8632abd7}}, - {{0xb301bb7c6b1beca3, 0x55393f6dc6eb1375, 0x910d281097b6e4eb, 0x1ad4548d9d479ea3}}}, -{{{0xcd5a7da0389a48fd, 0xb38fa4aa9a78371e, 0xc6d9761b2cdb8e6c, 0x35cf51dbc97e1443}}, - {{0xa06fe66d0fe9fed3, 0xa8733a401c587909, 0x30d14d800df98953, 0x41ce5876c7b30258}}, - {{0x59ac3bc5d670c022, 0xeae67c109b119406, 0x9798bdf0b3782fda, 0x651e3201fd074092}}}, -{{{0xd63d8483ef30c5cf, 0x4cd4b4962361cc0c, 0xee90e500a48426ac, 0x0af51d7d18c14eeb}}, - {{0xa57ba4a01efcae9e, 0x769f4beedc308a94, 0xd1f10eeb3603cb2e, 0x4099ce5e7e441278}}, - {{0x1ac98e4f8a5121e9, 0x7dae9544dbfa2fe0, 0x8320aa0dd6430df9, 0x667282652c4a2fb5}}}, -{{{0x874621f4d86bc9ab, 0xb54c7bbe56fe6fea, 0x077a24257fadc22c, 0x1ab53be419b90d39}}, - {{0xada8b6e02946db23, 0x1c0ce51a7b253ab7, 0x8448c85a66dd485b, 0x7f1fc025d0675adf}}, - {{0xd8ee1b18319ea6aa, 0x004d88083a21f0da, 0x3bd6aa1d883a4f4b, 0x4db9a3a6dfd9fd14}}}, -{{{0x8ce7b23bb99c0755, 0x35c5d6edc4f50f7a, 0x7e1e2ed2ed9b50c3, 0x36305f16e8934da1}}, - {{0xd95b00bbcbb77c68, 0xddbc846a91f17849, 0x7cf700aebe28d9b3, 0x5ce1285c85d31f3e}}, - {{0x31b6972d98b0bde8, 0x7d920706aca6de5b, 0xe67310f8908a659f, 0x50fac2a6efdf0235}}}, -{{{0xf3d3a9f35b880f5a, 0xedec050cdb03e7c2, 0xa896981ff9f0b1a2, 0x49a4ae2bac5e34a4}}, - {{0x295b1c86f6f449bc, 0x51b2e84a1f0ab4dd, 0xc001cb30aa8e551d, 0x6a28d35944f43662}}, - {{0x28bb12ee04a740e0, 0x14313bbd9bce8174, 0x72f5b5e4e8c10c40, 0x7cbfb19936adcd5b}}}, -{{{0xa311ddc26b89792d, 0x1b30b4c6da512664, 0x0ca77b4ccf150859, 0x1de443df1b009408}}, - {{0x8e793a7acc36e6e0, 0xf9fab7a37d586eed, 0x3a4f9692bae1f4e4, 0x1c14b03eff5f447e}}, - {{0x19647bd114a85291, 0x57b76cb21034d3af, 0x6329db440f9d6dfa, 0x5ef43e586a571493}}}, -{{{0xef782014385675a6, 0xa2649f30aafda9e8, 0x4cd1eb505cdfa8cb, 0x46115aba1d4dc0b3}}, - {{0xa66dcc9dc80c1ac0, 0x97a05cf41b38a436, 0xa7ebf3be95dbd7c6, 0x7da0b8f68d7e7dab}}, - {{0xd40f1953c3b5da76, 0x1dac6f7321119e9b, 0x03cc6021feb25960, 0x5a5f887e83674b4b}}}, -{{{0x8f6301cf70a13d11, 0xcfceb815350dd0c4, 0xf70297d4a4bca47e, 0x3669b656e44d1434}}, - {{0x9e9628d3a0a643b9, 0xb5c3cb00e6c32064, 0x9b5302897c2dec32, 0x43e37ae2d5d1c70c}}, - {{0x387e3f06eda6e133, 0x67301d5199a13ac0, 0xbd5ad8f836263811, 0x6a21e6cd4fd5e9be}}}, -{{{0xf1c6170a3046e65f, 0x58712a2a00d23524, 0x69dbbd3c8c82b755, 0x586bf9f1a195ff57}}, - {{0xef4129126699b2e3, 0x71d30847708d1301, 0x325432d01182b0bd, 0x45371b07001e8b36}}, - {{0xa6db088d5ef8790b, 0x5278f0dc610937e5, 0xac0349d261a16eb8, 0x0eafb03790e52179}}}, -{{{0x960555c13748042f, 0x219a41e6820baa11, 0x1c81f73873486d0c, 0x309acc675a02c661}}, - {{0x5140805e0f75ae1d, 0xec02fbe32662cc30, 0x2cebdf1eea92396d, 0x44ae3344c5435bb3}}, - {{0x9cf289b9bba543ee, 0xf3760e9d5ac97142, 0x1d82e5c64f9360aa, 0x62d5221b7f94678f}}}, -{{{0x524c299c18d0936d, 0xc86bb56c8a0c1a0c, 0xa375052edb4a8631, 0x5c0efde4bc754562}}, - {{0x7585d4263af77a3c, 0xdfae7b11fee9144d, 0xa506708059f7193d, 0x14f29a5383922037}}, - {{0xdf717edc25b2d7f5, 0x21f970db99b53040, 0xda9234b7c3ed4c62, 0x5e72365c7bee093e}}}, -{{{0x575bfc074571217f, 0x3779675d0694d95b, 0x9a0a37bbf4191e33, 0x77f1104c47b4eabc}}, - {{0x7d9339062f08b33e, 0x5b9659e5df9f32be, 0xacff3dad1f9ebdfd, 0x70b20555cb7349b7}}, - {{0xbe5113c555112c4c, 0x6688423a9a881fcd, 0x446677855e503b47, 0x0e34398f4a06404a}}}, -{{{0xb67d22d93ecebde8, 0x09b3e84127822f07, 0x743fa61fb05b6d8d, 0x5e5405368a362372}}, - {{0x18930b093e4b1928, 0x7de3e10e73f3f640, 0xf43217da73395d6f, 0x6f8aded6ca379c3e}}, - {{0xe340123dfdb7b29a, 0x487b97e1a21ab291, 0xf9967d02fde6949e, 0x780de72ec8d3de97}}}, -{{{0x0ae28545089ae7bc, 0x388ddecf1c7f4d06, 0x38ac15510a4811b8, 0x0eb28bf671928ce4}}, - {{0x671feaf300f42772, 0x8f72eb2a2a8c41aa, 0x29a17fd797373292, 0x1defc6ad32b587a6}}, - {{0xaf5bbe1aef5195a7, 0x148c1277917b15ed, 0x2991f7fb7ae5da2e, 0x467d201bf8dd2867}}}, -{{{0x7906ee72f7bd2e6b, 0x05d270d6109abf4e, 0x8d5cfe45b941a8a4, 0x44c218671c974287}}, - {{0x745f9d56296bc318, 0x993580d4d8152e65, 0xb0e5b13f5839e9ce, 0x51fc2b28d43921c0}}, - {{0x1b8fd11795e2a98c, 0x1c4e5ee12b6b6291, 0x5b30e7107424b572, 0x6e6b9de84c4f4ac6}}}, -{{{0xdff25fce4b1de151, 0xd841c0c7e11c4025, 0x2554b3c854749c87, 0x2d292459908e0df9}}, - {{0x6b7c5f10f80cb088, 0x736b54dc56e42151, 0xc2b620a5c6ef99c4, 0x5f4c802cc3a06f42}}, - {{0x9b65c8f17d0752da, 0x881ce338c77ee800, 0xc3b514f05b62f9e3, 0x66ed5dd5bec10d48}}}, -{{{0x7d38a1c20bb2089d, 0x808334e196ccd412, 0xc4a70b8c6c97d313, 0x2eacf8bc03007f20}}, - {{0xf0adf3c9cbca047d, 0x81c3b2cbf4552f6b, 0xcfda112d44735f93, 0x1f23a0c77e20048c}}, - {{0xf235467be5bc1570, 0x03d2d9020dbab38c, 0x27529aa2fcf9e09e, 0x0840bef29d34bc50}}}, -{{{0x796dfb35dc10b287, 0x27176bcd5c7ff29d, 0x7f3d43e8c7b24905, 0x0304f5a191c54276}}, - {{0xcd54e06b7f37e4eb, 0x8cc15f87f5e96cca, 0xb8248bb0d3597dce, 0x246affa06074400c}}, - {{0x37d88e68fbe45321, 0x86097548c0d75032, 0x4e9b13ef894a0d35, 0x25a83cac5753d325}}}, -{{{0x10222f48eed8165e, 0x623fc1234b8bcf3a, 0x1e145c09c221e8f0, 0x7ccfa59fca782630}}, - {{0x9f0f66293952b6e2, 0x33db5e0e0934267b, 0xff45252bd609fedc, 0x06be10f5c506e0c9}}, - {{0x1a9615a9b62a345f, 0x22050c564a52fecc, 0xa7a2788528bc0dfe, 0x5e82770a1a1ee71d}}}, -{{{0x35425183ad896a5c, 0xe8673afbe78d52f6, 0x2c66f25f92a35f64, 0x09d04f3b3b86b102}}, - {{0xe802e80a42339c74, 0x34175166a7fffae5, 0x34865d1f1c408cae, 0x2cca982c605bc5ee}}, - {{0xfd2d5d35197dbe6e, 0x207c2eea8be4ffa3, 0x2613d8db325ae918, 0x7a325d1727741d3e}}}, -{{{0xd036b9bbd16dfde2, 0xa2055757c497a829, 0x8e6cc966a7f12667, 0x4d3b1a791239c180}}, - {{0xecd27d017e2a076a, 0xd788689f1636495e, 0x52a61af0919233e5, 0x2a479df17bb1ae64}}, - {{0x9e5eee8e33db2710, 0x189854ded6c43ca5, 0xa41c22c592718138, 0x27ad5538a43a5e9b}}}, -{{{0x2746dd4b15350d61, 0xd03fcbc8ee9521b7, 0xe86e365a138672ca, 0x510e987f7e7d89e2}}, - {{0xcb5a7d638e47077c, 0x8db7536120a1c059, 0x549e1e4d8bedfdcc, 0x080153b7503b179d}}, - {{0xdda69d930a3ed3e3, 0x3d386ef1cd60a722, 0xc817ad58bdaa4ee6, 0x23be8d554fe7372a}}}, -{{{0x95fe919a74ef4fad, 0x3a827becf6a308a2, 0x964e01d309a47b01, 0x71c43c4f5ba3c797}}, - {{0xbc1ef4bd567ae7a9, 0x3f624cb2d64498bd, 0xe41064d22c1f4ec8, 0x2ef9c5a5ba384001}}, - {{0xb6fd6df6fa9e74cd, 0xf18278bce4af267a, 0x8255b3d0f1ef990e, 0x5a758ca390c5f293}}}, -{{{0xa2b72710d9462495, 0x3aa8c6d2d57d5003, 0xe3d400bfa0b487ca, 0x2dbae244b3eb72ec}}, - {{0x8ce0918b1d61dc94, 0x8ded36469a813066, 0xd4e6a829afe8aad3, 0x0a738027f639d43f}}, - {{0x980f4a2f57ffe1cc, 0x00670d0de1839843, 0x105c3f4a49fb15fd, 0x2698ca635126a69c}}}, -{{{0xe765318832b0ba78, 0x381831f7925cff8b, 0x08a81b91a0291fcc, 0x1fb43dcc49caeb07}}, - {{0x2e3d702f5e3dd90e, 0x9e3f0918e4d25386, 0x5e773ef6024da96a, 0x3c004b0c4afa3332}}, - {{0x9aa946ac06f4b82b, 0x1ca284a5a806c4f3, 0x3ed3265fc6cd4787, 0x6b43fd01cd1fd217}}}, -{{{0xc7a75d4b4697c544, 0x15fdf848df0fffbf, 0x2868b9ebaa46785a, 0x5a68d7105b52f714}}, - {{0xb5c742583e760ef3, 0x75dc52b9ee0ab990, 0xbf1427c2072b923f, 0x73420b2d6ff0d9f0}}, - {{0xaf2cf6cb9e851e06, 0x8f593913c62238c4, 0xda8ab89699fbf373, 0x3db5632fea34bc9e}}}, -{{{0xf46eee2bf75dd9d8, 0x0d17b1f6396759a5, 0x1bf2d131499e7273, 0x04321adf49d75f13}}, - {{0x2e4990b1829825d5, 0xedeaeb873e9a8991, 0xeef03d394c704af8, 0x59197ea495df2b0e}}, - {{0x04e16019e4e55aae, 0xe77b437a7e2f92e9, 0xc7ce2dc16f159aa4, 0x45eafdc1f4d70cc0}}}, -{{{0x698401858045d72b, 0x4c22faa2cf2f0651, 0x941a36656b222dc6, 0x5a5eebc80362dade}}, - {{0xb60e4624cfccb1ed, 0x59dbc292bd5c0395, 0x31a09d1ddc0481c9, 0x3f73ceea5d56d940}}, - {{0xb7a7bfd10a4e8dc6, 0xbe57007e44c9b339, 0x60c1207f1557aefa, 0x26058891266218db}}}, -{{{0x59f704a68360ff04, 0xc3d93fde7661e6f4, 0x831b2a7312873551, 0x54ad0c2e4e615d57}}, - {{0x4c818e3cc676e542, 0x5e422c9303ceccad, 0xec07cccab4129f08, 0x0dedfa10b24443b8}}, - {{0xee3b67d5b82b522a, 0x36f163469fa5c1eb, 0xa5b4d2f26ec19fd3, 0x62ecb2baa77a9408}}}, -{{{0xe5ed795261152b3d, 0x4962357d0eddd7d1, 0x7482c8d0b96b4c71, 0x2e59f919a966d8be}}, - {{0x92072836afb62874, 0x5fcd5e8579e104a5, 0x5aad01adc630a14a, 0x61913d5075663f98}}, - {{0x0dc62d361a3231da, 0xfa47583294200270, 0x02d801513f9594ce, 0x3ddbc2a131c05d5c}}}, -{{{0x3f50a50a4ffb81ef, 0xb1e035093bf420bf, 0x9baa8e1cc6aa2cd0, 0x32239861fa237a40}}, - {{0xfb735ac2004a35d1, 0x31de0f433a6607c3, 0x7b8591bfc528d599, 0x55be9a25f5bb050c}}, - {{0x0d005acd33db3dbf, 0x0111b37c80ac35e2, 0x4892d66c6f88ebeb, 0x770eadb16508fbcd}}}, -{{{0x8451f9e05e4e89dd, 0xc06302ffbc793937, 0x5d22749556a6495c, 0x09a6755ca05603fb}}, - {{0xf1d3b681a05071b9, 0x2207659a3592ff3a, 0x5f0169297881e40e, 0x16bedd0e86ba374e}}, - {{0x5ecccc4f2c2737b5, 0x43b79e0c2dccb703, 0x33e008bc4ec43df3, 0x06c1b840f07566c0}}}, -{{{0x7688a5c6a388f877, 0x02a96c14deb2b6ac, 0x64c9f3431b8c2af8, 0x3628435554a1eed6}}, - {{0x69ee9e7f9b02805c, 0xcbff828a547d1640, 0x3d93a869b2430968, 0x46b7b8cd3fe26972}}, - {{0xe9812086fe7eebe0, 0x4cba6be72f515437, 0x1d04168b516efae9, 0x5ea1391043982cb9}}}, -{{{0x49125c9cf4702ee1, 0x4520b71f8b25b32d, 0x33193026501fef7e, 0x656d8997c8d2eb2b}}, - {{0x6f2b3be4d5d3b002, 0xafec33d96a09c880, 0x035f73a4a8bcc4cc, 0x22c5b9284662198b}}, - {{0xcb58c8fe433d8939, 0x89a0cb2e6a8d7e50, 0x79ca955309fbbe5a, 0x0c626616cd7fc106}}}, -{{{0x1ffeb80a4879b61f, 0x6396726e4ada21ed, 0x33c7b093368025ba, 0x471aa0c6f3c31788}}, - {{0x8fdfc379fbf454b1, 0x45a5a970f1a4b771, 0xac921ef7bad35915, 0x42d088dca81c2192}}, - {{0x8fda0f37a0165199, 0x0adadb77c8a0e343, 0x20fbfdfcc875e820, 0x1cf2bea80c2206e7}}}, -{{{0xc2ddf1deb36202ac, 0x92a5fe09d2e27aa5, 0x7d1648f6fc09f1d3, 0x74c2cc0513bc4959}}, - {{0x982d6e1a02c0412f, 0x90fa4c83db58e8fe, 0x01c2f5bcdcb18bc0, 0x686e0c90216abc66}}, - {{0x1fadbadba54395a7, 0xb41a02a0ae0da66a, 0xbf19f598bba37c07, 0x6a12b8acde48430d}}}, -{{{0xf8daea1f39d495d9, 0x592c190e525f1dfc, 0xdb8cbd04c9991d1b, 0x11f7fda3d88f0cb7}}, - {{0x793bdd801aaeeb5f, 0x00a2a0aac1518871, 0xe8a373a31f2136b4, 0x48aab888fc91ef19}}, - {{0x041f7e925830f40e, 0x002d6ca979661c06, 0x86dc9ff92b046a2e, 0x760360928b0493d1}}}, -{{{0x21bb41c6120cf9c6, 0xeab2aa12decda59b, 0xc1a72d020aa48b34, 0x215d4d27e87d3b68}}, - {{0xb43108e5695a0b05, 0x6cb00ee8ad37a38b, 0x5edad6eea3537381, 0x3f2602d4b6dc3224}}, - {{0xc8b247b65bcaf19c, 0x49779dc3b1b2c652, 0x89a180bbd5ece2e2, 0x13f098a3cec8e039}}}, -{{{0x9adc0ff9ce5ec54b, 0x039c2a6b8c2f130d, 0x028007c7f0f89515, 0x78968314ac04b36b}}, - {{0xf3aa57a22796bb14, 0x883abab79b07da21, 0xe54be21831a0391c, 0x5ee7fb38d83205f9}}, - {{0x538dfdcb41446a8e, 0xa5acfda9434937f9, 0x46af908d263c8c78, 0x61d0633c9bca0d09}}}, -{{{0x63744935ffdb2566, 0xc5bd6b89780b68bb, 0x6f1b3280553eec03, 0x6e965fd847aed7f5}}, - {{0xada328bcf8fc73df, 0xee84695da6f037fc, 0x637fb4db38c2a909, 0x5b23ac2df8067bdc}}, - {{0x9ad2b953ee80527b, 0xe88f19aafade6d8d, 0x0e711704150e82cf, 0x79b9bbb9dd95dedc}}}, -{{{0xebb355406a3126c2, 0xd26383a868c8c393, 0x6c0c6429e5b97a82, 0x5065f158c9fd2147}}, - {{0xd1997dae8e9f7374, 0xa032a2f8cfbb0816, 0xcd6cba126d445f0a, 0x1ba811460accb834}}, - {{0x708169fb0c429954, 0xe14600acd76ecf67, 0x2eaab98a70e645ba, 0x3981f39e58a4faf2}}}, -{{{0x18fb8a7559230a93, 0x1d168f6960e6f45d, 0x3a85a94514a93cb5, 0x38dc083705acd0fd}}, - {{0xc845dfa56de66fde, 0xe152a5002c40483a, 0xe9d2e163c7b4f632, 0x30f4452edcbc1b65}}, - {{0x856d2782c5759740, 0xfa134569f99cbecc, 0x8844fc73c0ea4e71, 0x632d9a1a593f2469}}}, -{{{0xf6bb6b15b807cba6, 0x1823c7dfbc54f0d7, 0xbb1d97036e29670b, 0x0b24f48847ed4a57}}, - {{0xbf09fd11ed0c84a7, 0x63f071810d9f693a, 0x21908c2d57cf8779, 0x3a5a7df28af64ba2}}, - {{0xdcdad4be511beac7, 0xa4538075ed26ccf2, 0xe19cff9f005f9a65, 0x34fcf74475481f63}}}, -{{{0xc197e04c789767ca, 0xb8714dcb38d9467d, 0x55de888283f95fa8, 0x3d3bdc164dfa63f7}}, - {{0xa5bb1dab78cfaa98, 0x5ceda267190b72f2, 0x9309c9110a92608e, 0x0119a3042fb374b0}}, - {{0x67a2d89ce8c2177d, 0x669da5f66895d0c1, 0xf56598e5b282a2b0, 0x56c088f1ede20a73}}}, -{{{0x336d3d1110a86e17, 0xd7f388320b75b2fa, 0xf915337625072988, 0x09674c6b99108b87}}, - {{0x581b5fac24f38f02, 0xa90be9febae30cbd, 0x9a2169028acf92f0, 0x038b7ea48359038f}}, - {{0x9f4ef82199316ff8, 0x2f49d282eaa78d4f, 0x0971a5ab5aef3174, 0x6e5e31025969eb65}}}, -{{{0xb16c62f587e593fb, 0x4999eddeca5d3e71, 0xb491c1e014cc3e6d, 0x08f5114789a8dba8}}, - {{0x3304fb0e63066222, 0xfb35068987acba3f, 0xbd1924778c1061a3, 0x3058ad43d1838620}}, - {{0x323c0ffde57663d0, 0x05c3df38a22ea610, 0xbdc78abdac994f9a, 0x26549fa4efe3dc99}}}, -{{{0x738b38d787ce8f89, 0xb62658e24179a88d, 0x30738c9cf151316d, 0x49128c7f727275c9}}, - {{0x04dbbc17f75396b9, 0x69e6a2d7d2f86746, 0xc6409d99f53eabc6, 0x606175f6332e25d2}}, - {{0x4021370ef540e7dd, 0x0910d6f5a1f1d0a5, 0x4634aacd5b06b807, 0x6a39e6356944f235}}}, -{{{0x96cd5640df90f3e7, 0x6c3a760edbfa25ea, 0x24f3ef0959e33cc4, 0x42889e7e530d2e58}}, - {{0x1da1965774049e9d, 0xfbcd6ea198fe352b, 0xb1cbcd50cc5236a6, 0x1f5ec83d3f9846e2}}, - {{0x8efb23c3328ccb75, 0xaf42a207dd876ee9, 0x20fbdadc5dfae796, 0x241e246b06bf9f51}}}, -{{{0x29e68e57ad6e98f6, 0x4c9260c80b462065, 0x3f00862ea51ebb4b, 0x5bc2c77fb38d9097}}, - {{0x7eaafc9a6280bbb8, 0x22a70f12f403d809, 0x31ce40bb1bfc8d20, 0x2bc65635e8bd53ee}}, - {{0xe8d5dc9fa96bad93, 0xe58fb17dde1947dc, 0x681532ea65185fa3, 0x1fdd6c3b034a7830}}}, -{{{0x0a64e28c55dc18fe, 0xe3df9e993399ebdd, 0x79ac432370e2e652, 0x35ff7fc33ae4cc0e}}, - {{0x9c13a6a52dd8f7a9, 0x2dbb1f8c3efdcabf, 0x961e32405e08f7b5, 0x48c8a121bbe6c9e5}}, - {{0xfc415a7c59646445, 0xd224b2d7c128b615, 0x6035c9c905fbb912, 0x42d7a91274429fab}}}, -{{{0x4e6213e3eaf72ed3, 0x6794981a43acd4e7, 0xff547cde6eb508cb, 0x6fed19dd10fcb532}}, - {{0xa9a48947933da5bc, 0x4a58920ec2e979ec, 0x96d8800013e5ac4c, 0x453692d74b48b147}}, - {{0xdd775d99a8559c6f, 0xf42a2140df003e24, 0x5223e229da928a66, 0x063f46ba6d38f22c}}}, -{{{0xd2d242895f536694, 0xca33a2c542939b2c, 0x986fada6c7ddb95c, 0x5a152c042f712d5d}}, - {{0x39843cb737346921, 0xa747fb0738c89447, 0xcb8d8031a245307e, 0x67810f8e6d82f068}}, - {{0x3eeb8fbcd2287db4, 0x72c7d3a301a03e93, 0x5473e88cbd98265a, 0x7324aa515921b403}}}, -{{{0x857942f46c3cbe8e, 0xa1d364b14730c046, 0x1c8ed914d23c41bf, 0x0838e161eef6d5d2}}, - {{0xad23f6dae82354cb, 0x6962502ab6571a6d, 0x9b651636e38e37d1, 0x5cac5005d1a3312f}}, - {{0x8cc154cce9e39904, 0x5b3a040b84de6846, 0xc4d8a61cb1be5d6e, 0x40fb897bd8861f02}}}, -{{{0x84c5aa9062de37a1, 0x421da5000d1d96e1, 0x788286306a9242d9, 0x3c5e464a690d10da}}, - {{0xe57ed8475ab10761, 0x71435e206fd13746, 0x342f824ecd025632, 0x4b16281ea8791e7b}}, - {{0xd1c101d50b813381, 0xdee60f1176ee6828, 0x0cb68893383f6409, 0x6183c565f6ff484a}}}, -{{{0x741d5a461e6bf9d6, 0x2305b3fc7777a581, 0xd45574a26474d3d9, 0x1926e1dc6401e0ff}}, - {{0xdb468549af3f666e, 0xd77fcf04f14a0ea5, 0x3df23ff7a4ba0c47, 0x3a10dfe132ce3c85}}, - {{0xe07f4e8aea17cea0, 0x2fd515463a1fc1fd, 0x175322fd31f2c0f1, 0x1fa1d01d861e5d15}}}, -{{{0xcc8055947d599832, 0x1e4656da37f15520, 0x99f6f7744e059320, 0x773563bc6a75cf33}}, - {{0x38dcac00d1df94ab, 0x2e712bddd1080de9, 0x7f13e93efdd5e262, 0x73fced18ee9a01e5}}, - {{0x06b1e90863139cb3, 0xa493da67c5a03ecd, 0x8d77cec8ad638932, 0x1f426b701b864f44}}}, -{{{0xefc9264c41911c01, 0xf1a3b7b817a22c25, 0x5875da6bf30f1447, 0x4e1af5271d31b090}}, - {{0xf17e35c891a12552, 0xb76b8153575e9c76, 0xfa83406f0d9b723e, 0x0b76bb1b3fa7e438}}, - {{0x08b8c1f97f92939b, 0xbe6771cbd444ab6e, 0x22e5646399bb8017, 0x7b6dd61eb772a955}}}, -{{{0xb7adc1e850f33d92, 0x7998fa4f608cd5cf, 0xad962dbd8dfc5bdb, 0x703e9bceaf1d2f4f}}, - {{0x5730abf9ab01d2c7, 0x16fb76dc40143b18, 0x866cbe65a0cbb281, 0x53fa9b659bff6afe}}, - {{0x6c14c8e994885455, 0x843a5d6665aed4e5, 0x181bb73ebcd65af1, 0x398d93e5c4c61f50}}}, -{{{0x1c4bd16733e248f3, 0xbd9e128715bf0a5f, 0xd43f8cf0a10b0376, 0x53b09b5ddf191b13}}, - {{0xc3877c60d2e7e3f2, 0x3b34aaa030828bb1, 0x283e26e7739ef138, 0x699c9c9002c30577}}, - {{0xf306a7235946f1cc, 0x921718b5cce5d97d, 0x28cdd24781b4e975, 0x51caf30c6fcdd907}}}, -{{{0xa60ba7427674e00a, 0x630e8570a17a7bf3, 0x3758563dcf3324cc, 0x5504aa292383fdaa}}, - {{0x737af99a18ac54c7, 0x903378dcc51cb30f, 0x2b89bc334ce10cc7, 0x12ae29c189f8e99a}}, - {{0xa99ec0cb1f0d01cf, 0x0dd1efcc3a34f7ae, 0x55ca7521d09c4e22, 0x5fd14fe958eba5ea}}}, -{{{0xb5dc2ddf2845ab2c, 0x069491b10a7fe993, 0x4daaf3d64002e346, 0x093ff26e586474d1}}, - {{0x3c42fe5ebf93cb8e, 0xbedfa85136d4565f, 0xe0f0859e884220e8, 0x7dd73f960725d128}}, - {{0xb10d24fe68059829, 0x75730672dbaf23e5, 0x1367253ab457ac29, 0x2f59bcbc86b470a4}}}, -{{{0x83847d429917135f, 0xad1b911f567d03d7, 0x7e7748d9be77aad1, 0x5458b42e2e51af4a}}, - {{0x7041d560b691c301, 0x85201b3fadd7e71e, 0x16c2e16311335585, 0x2aa55e3d010828b1}}, - {{0xed5192e60c07444f, 0x42c54e2d74421d10, 0x352b4c82fdb5c864, 0x13e9004a8a768664}}}, -{{{0xcbb5b5556c032bff, 0xdf7191b729297a3a, 0xc1ff7326aded81bb, 0x71ade8bb68be03f5}}, - {{0x1e6284c5806b467c, 0xc5f6997be75d607b, 0x8b67d958b378d262, 0x3d88d66a81cd8b70}}, - {{0x8b767a93204ed789, 0x762fcacb9fa0ae2a, 0x771febcc6dce4887, 0x343062158ff05fb3}}}, -{{{0xe05da1a7e1f5bf49, 0x26457d6dd4736092, 0x77dcb07773cc32f6, 0x0a5d94969cdd5fcd}}, - {{0xfce219072a7b31b4, 0x4d7adc75aa578016, 0x0ec276a687479324, 0x6d6d9d5d1fda4beb}}, - {{0x22b1a58ae9b08183, 0xfd95d071c15c388b, 0xa9812376850a0517, 0x33384cbabb7f335e}}}, -{{{0x3c6fa2680ca2c7b5, 0x1b5082046fb64fda, 0xeb53349c5431d6de, 0x5278b38f6b879c89}}, - {{0x33bc627a26218b8d, 0xea80b21fc7a80c61, 0x9458b12b173e9ee6, 0x076247be0e2f3059}}, - {{0x52e105f61416375a, 0xec97af3685abeba4, 0x26e6b50623a67c36, 0x5cf0e856f3d4fb01}}}, -{{{0xf6c968731ae8cab4, 0x5e20741ecb4f92c5, 0x2da53be58ccdbc3e, 0x2dddfea269970df7}}, - {{0xbeaece313db342a8, 0xcba3635b842db7ee, 0xe88c6620817f13ef, 0x1b9438aa4e76d5c6}}, - {{0x8a50777e166f031a, 0x067b39f10fb7a328, 0x1925c9a6010fbd76, 0x6df9b575cc740905}}}, -{{{0x42c1192927f6bdcf, 0x8f91917a403d61ca, 0xdc1c5a668b9e1f61, 0x1596047804ec0f8d}}, - {{0xecdfc35b48cade41, 0x6a88471fb2328270, 0x740a4a2440a01b6a, 0x471e5796003b5f29}}, - {{0xda96bbb3aced37ac, 0x7a2423b5e9208cea, 0x24cc5c3038aebae2, 0x50c356afdc5dae2f}}}, -{{{0x09dcbf4341c30318, 0xeeba061183181dce, 0xc179c0cedc1e29a1, 0x1dbf7b89073f35b0}}, - {{0xcfed9cdf1b31b964, 0xf486a9858ca51af3, 0x14897265ea8c1f84, 0x784a53dd932acc00}}, - {{0x2d99f9df14fc4920, 0x76ccb60cc4499fe5, 0xa4132cbbe5cf0003, 0x3f93d82354f000ea}}}, -{{{0x8183e7689e04ce85, 0x678fb71e04465341, 0xad92058f6688edac, 0x5da350d3532b099a}}, - {{0xeaac12d179e14978, 0xff923ff3bbebff5e, 0x4af663e40663ce27, 0x0fd381a811a5f5ff}}, - {{0xf256aceca436df54, 0x108b6168ae69d6e8, 0x20d986cb6b5d036c, 0x655957b9fee2af50}}}, -{{{0xaea8b07fa902030f, 0xf88c766af463d143, 0x15b083663c787a60, 0x08eab1148267a4a8}}, - {{0xbdc1409bd002d0ac, 0x66660245b5ccd9a6, 0x82317dc4fade85ec, 0x02fe934b6ad7df0d}}, - {{0xef5cf100cfb7ea74, 0x22897633a1cb42ac, 0xd4ce0c54cef285e2, 0x30408c048a146a55}}}, -{{{0x739d8845832fcedb, 0xfa38d6c9ae6bf863, 0x32bc0dcab74ffef7, 0x73937e8814bce45e}}, - {{0xbb2e00c9193b877f, 0xece3a890e0dc506b, 0xecf3b7c036de649f, 0x5f46040898de9e1a}}, - {{0xb9037116297bf48d, 0xa9d13b22d4f06834, 0xe19715574696bdc6, 0x2cf8a4e891d5e835}}}, -{{{0x6d93fd8707110f67, 0xdd4c09d37c38b549, 0x7cb16a4cc2736a86, 0x2049bd6e58252a09}}, - {{0x2cb5487e17d06ba2, 0x24d2381c3950196b, 0xd7659c8185978a30, 0x7a6f7f2891d6a4f6}}, - {{0x7d09fd8d6a9aef49, 0xf0ee60be5b3db90b, 0x4c21b52c519ebfd4, 0x6011aadfc545941d}}}, -{{{0x5f67926dcf95f83c, 0x7c7e856171289071, 0xd6a1e7f3998f7a5b, 0x6fc5cc1b0b62f9e0}}, - {{0x63ded0c802cbf890, 0xfbd098ca0dff6aaa, 0x624d0afdb9b6ed99, 0x69ce18b779340b1e}}, - {{0xd1ef5528b29879cb, 0xdd1aae3cd47e9092, 0x127e0442189f2352, 0x15596b3ae57101f1}}}, -{{{0x462739d23f9179a2, 0xff83123197d6ddcf, 0x1307deb553f2148a, 0x0d2237687b5f4dda}}, - {{0x09ff31167e5124ca, 0x0be4158bd9c745df, 0x292b7d227ef556e5, 0x3aa4e241afb6d138}}, - {{0x2cc138bf2a3305f5, 0x48583f8fa2e926c3, 0x083ab1a25549d2eb, 0x32fcaa6e4687a36c}}}, -{{{0x7bc56e8dc57d9af5, 0x3e0bd2ed9df0bdf2, 0xaac014de22efe4a3, 0x4627e9cefebd6a5c}}, - {{0x3207a4732787ccdf, 0x17e31908f213e3f8, 0xd5b2ecd7f60d964e, 0x746f6336c2600be9}}, - {{0x3f4af345ab6c971c, 0xe288eb729943731f, 0x33596a8a0344186d, 0x7b4917007ed66293}}}, -{{{0x2d85fb5cab84b064, 0x497810d289f3bc14, 0x476adc447b15ce0c, 0x122ba376f844fd7b}}, - {{0x54341b28dd53a2dd, 0xaa17905bdf42fc3f, 0x0ff592d94dd2f8f4, 0x1d03620fe08cd37d}}, - {{0xc20232cda2b4e554, 0x9ed0fd42115d187f, 0x2eabb4be7dd479d9, 0x02c70bf52b68ec4c}}}, -{{{0xa287ec4b5d0b2fbb, 0x415c5790074882ca, 0xe044a61ec1d0815c, 0x26334f0a409ef5e0}}, - {{0xace532bf458d72e1, 0x5be768e07cb73cb5, 0x56cf7d94ee8bbde7, 0x6b0697e3feb43a03}}, - {{0xb6c8f04adf62a3c0, 0x3ef000ef076da45d, 0x9c9cb95849f0d2a9, 0x1cc37f43441b2fae}}}, -{{{0x508f565a5cc7324f, 0xd061c4c0e506a922, 0xfb18abdb5c45ac19, 0x6c6809c10380314a}}, - {{0xd76656f1c9ceaeb9, 0x1c5b15f818e5656a, 0x26e72832844c2334, 0x3a346f772f196838}}, - {{0xd2d55112e2da6ac8, 0xe9bd0331b1e851ed, 0x960746dd8ec67262, 0x05911b9f6ef7c5d0}}}, -{{{0xe9dcd756b637ff2d, 0xec4c348fc987f0c4, 0xced59285f3fbc7b7, 0x3305354793e1ea87}}, - {{0x01c18980c5fe9f94, 0xcd656769716fd5c8, 0x816045c3d195a086, 0x6e2b7f3266cc7982}}, - {{0xcc802468f7c3568f, 0x9de9ba8219974cb3, 0xabb7229cb5b81360, 0x44e2017a6fbeba62}}}, -{{{0xc4c2a74354dab774, 0x8e5d4c3c4eaf031a, 0xb76c23d242838f17, 0x749a098f68dce4ea}}, - {{0x87f82cf3b6ca6ecd, 0x580f893e18f4a0c2, 0x058930072604e557, 0x6cab6ac256d19c1d}}, - {{0xdcdfe0a02cc1de60, 0x032665ff51c5575b, 0x2c0c32f1073abeeb, 0x6a882014cd7b8606}}}, -{{{0xa52a92fea4747fb5, 0xdc12a4491fa5ab89, 0xd82da94bb847a4ce, 0x4d77edce9512cc4e}}, - {{0xd111d17caf4feb6e, 0x050bba42b33aa4a3, 0x17514c3ceeb46c30, 0x54bedb8b1bc27d75}}, - {{0x77c8e14577e2189c, 0xa3e46f6aff99c445, 0x3144dfc86d335343, 0x3a96559e7c4216a9}}}, -{{{0x12550d37f42ad2ee, 0x8b78e00498a1fbf5, 0x5d53078233894cb2, 0x02c84e4e3e498d0c}}, - {{0x4493896880baaa52, 0x4c98afc4f285940e, 0xef4aa79ba45448b6, 0x5278c510a57aae7f}}, - {{0xa54dd074294c0b94, 0xf55d46b8df18ffb6, 0xf06fecc58dae8366, 0x588657668190d165}}}, -{{{0xd47712311aef7117, 0x50343101229e92c7, 0x7a95e1849d159b97, 0x2449959b8b5d29c9}}, - {{0xbf5834f03de25cc3, 0xb887c8aed6815496, 0x5105221a9481e892, 0x6760ed19f7723f93}}, - {{0x669ba3b7ac35e160, 0x2eccf73fba842056, 0x1aec1f17c0804f07, 0x0d96bc031856f4e7}}}, -{{{0x3318be7775c52d82, 0x4cb764b554d0aab9, 0xabcf3d27cc773d91, 0x3bf4d1848123288a}}, - {{0xb1d534b0cc7505e1, 0x32cd003416c35288, 0xcb36a5800762c29d, 0x5bfe69b9237a0bf8}}, - {{0x183eab7e78a151ab, 0xbbe990c999093763, 0xff717d6e4ac7e335, 0x4c5cddb325f39f88}}}, -{{{0xc0f6b74d6190a6eb, 0x20ea81a42db8f4e4, 0xa8bd6f7d97315760, 0x33b1d60262ac7c21}}, - {{0x57750967e7a9f902, 0x2c37fdfc4f5b467e, 0xb261663a3177ba46, 0x3a375e78dc2d532b}}, - {{0x8141e72f2d4dddea, 0xe6eafe9862c607c8, 0x23c28458573cafd0, 0x46b9476f4ff97346}}}, -{{{0x0c1ffea44f901e5c, 0x2b0b6fb72184b782, 0xe587ff910114db88, 0x37130f364785a142}}, - {{0x1215505c0d58359f, 0x2a2013c7fc28c46b, 0x24a0a1af89ea664e, 0x4400b638a1130e1f}}, - {{0x3a01b76496ed19c3, 0x31e00ab0ed327230, 0x520a885783ca15b1, 0x06aab9875accbec7}}}, -{{{0xc1339983f5df0ebb, 0xc0f3758f512c4cac, 0x2cf1130a0bb398e1, 0x6b3cecf9aa270c62}}, - {{0x5349acf3512eeaef, 0x20c141d31cc1cb49, 0x24180c07a99a688d, 0x555ef9d1c64b2d17}}, - {{0x36a770ba3b73bd08, 0x624aef08a3afbf0c, 0x5737ff98b40946f2, 0x675f4de13381749d}}}, -{{{0x0e2c52036b1782fc, 0x64816c816cad83b4, 0xd0dcbdd96964073e, 0x13d99df70164c520}}, - {{0xa12ff6d93bdab31d, 0x0725d80f9d652dfe, 0x019c4ff39abe9487, 0x60f450b882cd3c43}}, - {{0x014b5ec321e5c0ca, 0x4fcb69c9d719bfa2, 0x4e5f1c18750023a0, 0x1c06de9e55edac80}}}, -{{{0x990f7ad6a33ec4e2, 0x6608f938be2ee08e, 0x9ca143c563284515, 0x4cf38a1fec2db60d}}, - {{0xffd52b40ff6d69aa, 0x34530b18dc4049bb, 0x5e4a5c2fa34d9897, 0x78096f8e7d32ba2d}}, - {{0xa0aaaa650dfa5ce7, 0xf9c49e2a48b5478c, 0x4f09cc7d7003725b, 0x373cad3a26091abe}}}, -{{{0xb294634d82c9f57c, 0x1fcbfde124934536, 0x9e9c4db3418cdb5a, 0x0040f3d9454419fc}}, - {{0xf1bea8fb89ddbbad, 0x3bcb2cbc61aeaecb, 0x8f58a7bb1f9b8d9d, 0x21547eda5112a686}}, - {{0xdefde939fd5986d3, 0xf4272c89510a380c, 0xb72ba407bb3119b9, 0x63550a334a254df4}}}, -{{{0x6507d6edb569cf37, 0x178429b00ca52ee1, 0xea7c0090eb6bd65d, 0x3eea62c7daf78f51}}, - {{0x9bba584572547b49, 0xf305c6fae2c408e0, 0x60e8fa69c734f18d, 0x39a92bafaa7d767a}}, - {{0x9d24c713e693274e, 0x5f63857768dbd375, 0x70525560eb8ab39a, 0x68436a0665c9c4cd}}}, -{{{0xbc0235e8202f3f27, 0xc75c00e264f975b0, 0x91a4e9d5a38c2416, 0x17b6e7f68ab789f9}}, - {{0x1e56d317e820107c, 0xc5266844840ae965, 0xc1e0a1c6320ffc7a, 0x5373669c91611472}}, - {{0x5d2814ab9a0e5257, 0x908f2084c9cab3fc, 0xafcaf5885b2d1eca, 0x1cb4b5a678f87d11}}}, -{{{0xb664c06b394afc6c, 0x0c88de2498da5fb1, 0x4f8d03164bcad834, 0x330bca78de7434a2}}, - {{0x6b74aa62a2a007e7, 0xf311e0b0f071c7b1, 0x5707e438000be223, 0x2dc0fd2d82ef6eac}}, - {{0x982eff841119744e, 0xf9695e962b074724, 0xc58ac14fbfc953fb, 0x3c31be1b369f1cf5}}}, -{{{0xb0f4864d08948aee, 0x07dc19ee91ba1c6f, 0x7975cdaea6aca158, 0x330b61134262d4bb}}, - {{0xc168bc93f9cb4272, 0xaeb8711fc7cedb98, 0x7f0e52aa34ac8d7a, 0x41cec1097e7d55bb}}, - {{0xf79619d7a26d808a, 0xbb1fd49e1d9e156d, 0x73d7c36cdba1df27, 0x26b44cd91f28777d}}}, -{{{0x300a9035393aa6d8, 0x2b501131a12bb1cd, 0x7b1ff677f093c222, 0x4309c1f8cab82bad}}, - {{0xaf44842db0285f37, 0x8753189047efc8df, 0x9574e091f820979a, 0x0e378d6069615579}}, - {{0xd9fa917183075a55, 0x4bdb5ad26b009fdc, 0x7829ad2cd63def0e, 0x078fc54975fd3877}}}, -{{{0x87dfbd1428878f2d, 0x134636dd1e9421a1, 0x4f17c951257341a3, 0x5df98d4bad296cb8}}, - {{0xe2004b5bb833a98a, 0x44775dec2d4c3330, 0x3aa244067eace913, 0x272630e3d58e00a9}}, - {{0xf3678fd0ecc90b54, 0xf001459b12043599, 0x26725fbc3758b89b, 0x4325e4aa73a719ae}}}, -{{{0x657dc6ef433c3493, 0x65375e9f80dbf8c3, 0x47fd2d465b372dae, 0x4966ab79796e7947}}, - {{0xed24629acf69f59d, 0x2a4a1ccedd5abbf4, 0x3535ca1f56b2d67b, 0x5d8c68d043b1b42d}}, - {{0xee332d4de3b42b0a, 0xd84e5a2b16a4601c, 0x78243877078ba3e4, 0x77ed1eb4184ee437}}}, -{{{0xbfd4e13f201839a0, 0xaeefffe23e3df161, 0xb65b04f06b5d1fe3, 0x52e085fb2b62fbc0}}, - {{0x185d43f89e92ed1a, 0xb04a1eeafe4719c6, 0x499fbe88a6f03f4f, 0x5d8b0d2f3c859bdd}}, - {{0x124079eaa54cf2ba, 0xd72465eb001b26e7, 0x6843bcfdc97af7fd, 0x0524b42b55eacd02}}}, -{{{0xfd0d5dbee45447b0, 0x6cec351a092005ee, 0x99a47844567579cb, 0x59d242a216e7fa45}}, - {{0xbc18dcad9b829eac, 0x23ae7d28b5f579d0, 0xc346122a69384233, 0x1a6110b2e7d4ac89}}, - {{0x4f833f6ae66997ac, 0x6849762a361839a4, 0x6985dec1970ab525, 0x53045e89dcb1f546}}}, -{{{0xcb8bb346d75353db, 0xfcfcb24bae511e22, 0xcba48d40d50ae6ef, 0x26e3bae5f4f7cb5d}}, - {{0x84da3cde8d45fe12, 0xbd42c218e444e2d2, 0xa85196781f7e3598, 0x7642c93f5616e2b2}}, - {{0x2323daa74595f8e4, 0xde688c8b857abeb4, 0x3fc48e961c59326e, 0x0b2e73ca15c9b8ba}}}, -{{{0xd6bb4428c17f5026, 0x9eb27223fb5a9ca7, 0xe37ba5031919c644, 0x21ce380db59a6602}}, - {{0x0e3fbfaf79c03a55, 0x3077af054cbb5acf, 0xd5c55245db3de39f, 0x015e68c1476a4af7}}, - {{0xc1d5285220066a38, 0x95603e523570aef3, 0x832659a7226b8a4d, 0x5dd689091f8eedc9}}}, -{{{0xcbac84debfd3c856, 0x1624c348b35ff244, 0xb7f88dca5d9cad07, 0x3b0e574da2c2ebe8}}, - {{0x1d022591a5313084, 0xca2d4aaed6270872, 0x86a12b852f0bfd20, 0x56e6c439ad7da748}}, - {{0xc704ff4942bdbae6, 0x5e21ade2b2de1f79, 0xe95db3f35652fad8, 0x0822b5378f08ebc1}}}, -{{{0x51f048478f387475, 0xb25dbcf49cbecb3c, 0x9aab1244d99f2055, 0x2c709e6c1c10a5d6}}, - {{0xe1b7f29362730383, 0x4b5279ffebca8a2c, 0xdafc778abfd41314, 0x7deb10149c72610f}}, - {{0xcb62af6a8766ee7a, 0x66cbec045553cd0e, 0x588001380f0be4b5, 0x08e68e9ff62ce2ea}}}, -{{{0x34ad500a4bc130ad, 0x8d38db493d0bd49c, 0xa25c3d98500a89be, 0x2f1f3f87eeba3b09}}, - {{0x2f2d09d50ab8f2f9, 0xacb9218dc55923df, 0x4a8f342673766cb9, 0x4cb13bd738f719f5}}, - {{0xf7848c75e515b64a, 0xa59501badb4a9038, 0xc20d313f3f751b50, 0x19a1e353c0ae2ee8}}}, -{{{0x7d1c7560bafa05c3, 0xb3e1a0a0c6e55e61, 0xe3529718c0d66473, 0x41546b11c20c3486}}, - {{0xb42172cdd596bdbd, 0x93e0454398eefc40, 0x9fb15347b44109b5, 0x736bd3990266ae34}}, - {{0x85532d509334b3b4, 0x46fd114b60816573, 0xcc5f5f30425c8375, 0x412295a2b87fab5c}}}, -{{{0x19c99b88f57ed6e9, 0x5393cb266df8c825, 0x5cee3213b30ad273, 0x14e153ebb52d2e34}}, - {{0x2e655261e293eac6, 0x845a92032133acdb, 0x460975cb7900996b, 0x0760bb8d195add80}}, - {{0x413e1a17cde6818a, 0x57156da9ed69a084, 0x2cbf268f46caccb1, 0x6b34be9bc33ac5f2}}}, -{{{0xf3df2f643a78c0b2, 0x4c3e971ef22e027c, 0xec7d1c5e49c1b5a3, 0x2012c18f0922dd2d}}, - {{0x11fc69656571f2d3, 0xc6c9e845530e737a, 0xe33ae7a2d4fe5035, 0x01b9c7b62e6dd30b}}, - {{0x880b55e55ac89d29, 0x1483241f45a0a763, 0x3d36efdfc2e76c1f, 0x08af5b784e4bade8}}}, -{{{0x283499dc881f2533, 0x9d0525da779323b6, 0x897addfb673441f4, 0x32b79d71163a168d}}, - {{0xe27314d289cc2c4b, 0x4be4bd11a287178d, 0x18d528d6fa3364ce, 0x6423c1d5afd9826e}}, - {{0xcc85f8d9edfcb36a, 0x22bcc28f3746e5f9, 0xe49de338f9e5d3cd, 0x480a5efbc13e2dcc}}}, -{{{0x0b51e70b01622071, 0x06b505cf8b1dafc5, 0x2c6bb061ef5aabcd, 0x47aa27600cb7bf31}}, - {{0xb6614ce442ce221f, 0x6e199dcc4c053928, 0x663fb4a4dc1cbe03, 0x24b31d47691c8e06}}, - {{0x2a541eedc015f8c3, 0x11a4fe7e7c693f7c, 0xf0af66134ea278d6, 0x545b585d14dda094}}}, -{{{0x67bf275ea0d43a0f, 0xade68e34089beebe, 0x4289134cd479e72e, 0x0f62f9c332ba5454}}, - {{0x6204e4d0e3b321e1, 0x3baa637a28ff1e95, 0x0b0ccffd5b99bd9e, 0x4d22dc3e64c8d071}}, - {{0xfcb46589d63b5f39, 0x5cae6a3f57cbcf61, 0xfebac2d2953afa05, 0x1c0fa01a36371436}}}, -{{{0xe7547449bc7cd692, 0x0f9abeaae6f73ddf, 0x4af01ca700837e29, 0x63ab1b5d3f1bc183}}, - {{0xc11ee5e854c53fae, 0x6a0b06c12b4f3ff4, 0x33540f80e0b67a72, 0x15f18fc3cd07e3ef}}, - {{0x32750763b028f48c, 0x06020740556a065f, 0xd53bd812c3495b58, 0x08706c9b865f508d}}}, -{{{0xf37ca2ab3d343dff, 0x1a8c6a2d80abc617, 0x8e49e035d4ccffca, 0x48b46beebaa1d1b9}}, - {{0xcc991b4138b41246, 0x243b9c526f9ac26b, 0xb9ef494db7cbabbd, 0x5fba433dd082ed00}}, - {{0x9c49e355c9941ad0, 0xb9734ade74498f84, 0x41c3fed066663e5c, 0x0ecfedf8e8e710b3}}}, -{{{0x76430f9f9cd470d9, 0xb62acc9ba42f6008, 0x1898297c59adad5e, 0x7789dd2db78c5080}}, - {{0x744f7463e9403762, 0xf79a8dee8dfcc9c9, 0x163a649655e4cde3, 0x3b61788db284f435}}, - {{0xb22228190d6ef6b2, 0xa94a66b246ce4bfa, 0x46c1a77a4f0b6cc7, 0x4236ccffeb7338cf}}}, -{{{0x8497404d0d55e274, 0x6c6663d9c4ad2b53, 0xec2fb0d9ada95734, 0x2617e120cdb8f73c}}, - {{0x3bd82dbfda777df6, 0x71b177cc0b98369e, 0x1d0e8463850c3699, 0x5a71945b48e2d1f1}}, - {{0x6f203dd5405b4b42, 0x327ec60410b24509, 0x9c347230ac2a8846, 0x77de29fc11ffeb6a}}}, -{{{0xb0ac57c983b778a8, 0x53cdcca9d7fe912c, 0x61c2b854ff1f59dc, 0x3a1a2cf0f0de7dac}}, - {{0x835e138fecced2ca, 0x8c9eaf13ea963b9a, 0xc95fbfc0b2160ea6, 0x575e66f3ad877892}}, - {{0x99803a27c88fcb3a, 0x345a6789275ec0b0, 0x459789d0ff6c2be5, 0x62f882651e70a8b2}}}, -{{{0x085ae2c759ff1be4, 0x149145c93b0e40b7, 0xc467e7fa7ff27379, 0x4eeecf0ad5c73a95}}, - {{0x6d822986698a19e0, 0xdc9821e174d78a71, 0x41a85f31f6cb1f47, 0x352721c2bcda9c51}}, - {{0x48329952213fc985, 0x1087cf0d368a1746, 0x8e5261b166c15aa5, 0x2d5b2d842ed24c21}}}, -{{{0x02cfebd9ebd3ded1, 0xd45b217739021974, 0x7576f813fe30a1b7, 0x5691b6f9a34ef6c2}}, - {{0x5eb7d13d196ac533, 0x377234ecdb80be2b, 0xe144cffc7cf5ae24, 0x5226bcf9c441acec}}, - {{0x79ee6c7223e5b547, 0x6f5f50768330d679, 0xed73e1e96d8adce9, 0x27c3da1e1d8ccc03}}}, -{{{0x7eb9efb23fe24c74, 0x3e50f49f1651be01, 0x3ea732dc21858dea, 0x17377bd75bb810f9}}, - {{0x28302e71630ef9f6, 0xc2d4a2032b64cee0, 0x090820304b6292be, 0x5fca747aa82adf18}}, - {{0x232a03c35c258ea5, 0x86f23a2c6bcb0cf1, 0x3dad8d0d2e442166, 0x04a8933cab76862b}}}, -{{{0xd2c604b622943dff, 0xbc8cbece44cfb3a0, 0x5d254ff397808678, 0x0fa3614f3b1ca6bf}}, - {{0x69082b0e8c936a50, 0xf9c9a035c1dac5b6, 0x6fb73e54c4dfb634, 0x4005419b1d2bc140}}, - {{0xa003febdb9be82f0, 0x2089c1af3a44ac90, 0xf8499f911954fa8e, 0x1fba218aef40ab42}}}, -{{{0xab549448fac8f53e, 0x81f6e89a7ba63741, 0x74fd6c7d6c2b5e01, 0x392e3acaa8c86e42}}, - {{0x4f3e57043e7b0194, 0xa81d3eee08daaf7f, 0xc839c6ab99dcdef1, 0x6c535d13ff7761d5}}, - {{0x4cbd34e93e8a35af, 0x2e0781445887e816, 0x19319c76f29ab0ab, 0x25e17fe4d50ac13b}}}, -{{{0x0a289bd71e04f676, 0x208e1c52d6420f95, 0x5186d8b034691fab, 0x255751442a9fb351}}, - {{0x915f7ff576f121a7, 0xc34a32272fcd87e3, 0xccba2fde4d1be526, 0x6bba828f8969899b}}, - {{0xe2d1bc6690fe3901, 0x4cb54a18a0997ad5, 0x971d6914af8460d4, 0x559d504f7f6b7be4}}}, -{{{0xa7738378b3eb54d5, 0x1d69d366a5553c7c, 0x0a26cf62f92800ba, 0x01ab12d5807e3217}}, - {{0x9c4891e7f6d266fd, 0x0744a19b0307781b, 0x88388f1d6061e23b, 0x123ea6a3354bd50e}}, - {{0x118d189041e32d96, 0xb9ede3c2d8315848, 0x1eab4271d83245d9, 0x4a3961e2c918a154}}}, -{{{0x71dc3be0f8e6bba0, 0xd6cef8347effe30a, 0xa992425fe13a476a, 0x2cd6bce3fb1db763}}, - {{0x0327d644f3233f1e, 0x499a260e34fcf016, 0x83b5a716f2dab979, 0x68aceead9bd4111f}}, - {{0x38b4c90ef3d7c210, 0x308e6e24b7ad040c, 0x3860d9f1b7e73e23, 0x595760d5b508f597}}}, -{{{0x6129bfe104aa6397, 0x8f960008a4a7fccb, 0x3f8bc0897d909458, 0x709fa43edcb291a9}}, - {{0x882acbebfd022790, 0x89af3305c4115760, 0x65f492e37d3473f4, 0x2cb2c5df54515a2b}}, - {{0xeb0a5d8c63fd2aca, 0xd22bc1662e694eff, 0x2723f36ef8cbb03a, 0x70f029ecf0c8131f}}}, -{{{0x461307b32eed3e33, 0xae042f33a45581e7, 0xc94449d3195f0366, 0x0b7d5d8a6c314858}}, - {{0x2a6aafaa5e10b0b9, 0x78f0a370ef041aa9, 0x773efb77aa3ad61f, 0x44eca5a2a74bd9e1}}, - {{0x25d448327b95d543, 0x70d38300a3340f1d, 0xde1c531c60e1c52b, 0x272224512c7de9e4}}}, -{{{0x1abc92af49c5342e, 0xffeed811b2e6fad0, 0xefa28c8dfcc84e29, 0x11b5df18a44cc543}}, - {{0xbf7bbb8a42a975fc, 0x8c5c397796ada358, 0xe27fc76fcdedaa48, 0x19735fd7f6bc20a6}}, - {{0xe3ab90d042c84266, 0xeb848e0f7f19547e, 0x2503a1d065a497b9, 0x0fef911191df895f}}}, -{{{0xb1507ca1ab1c6eb9, 0xbd448f3e16b687b3, 0x3455fb7f2c7a91ab, 0x7579229e2f2adec1}}, - {{0x6ab5dcb85b1c16b7, 0x94c0fce83c7b27a5, 0xa4b11c1a735517be, 0x499238d0ba0eafaa}}, - {{0xecf46e527aba8b57, 0x15a08c478bd1647b, 0x7af1c6a65f706fef, 0x6345fa78f03a30d5}}}, -{{{0xdf02f95f1015e7a1, 0x790ec41da9b40263, 0x4d3a0ea133ea1107, 0x54f70be7e33af8c9}}, - {{0x93d3cbe9bdd8f0a4, 0xdb152c1bfd177302, 0x7dbddc6d7f17a875, 0x3e1a71cc8f426efe}}, - {{0xc83ca3e390babd62, 0x80ede3670291c833, 0xc88038ccd37900c4, 0x2c5fc0231ec31fa1}}}, -{{{0xfeba911717038b4f, 0xe5123721c9deef81, 0x1c97e4e75d0d8834, 0x68afae7a23dc3bc6}}, - {{0xc422e4d102456e65, 0x87414ac1cad47b91, 0x1592e2bba2b6ffdd, 0x75d9d2bff5c2100f}}, - {{0x5bd9b4763626e81c, 0x89966936bca02edd, 0x0a41193d61f077b3, 0x3097a24200ce5471}}}, -{{{0x57427734c7f8b84c, 0xf141a13e01b270e9, 0x02d1adfeb4e564a6, 0x4bb23d92ce83bd48}}, - {{0xa162e7246695c486, 0x131d633435a89607, 0x30521561a0d12a37, 0x56704bada6afb363}}, - {{0xaf6c4aa752f912b9, 0x5e665f6cd86770c8, 0x4c35ac83a3c8cd58, 0x2b7a29c010a58a7e}}}, -{{{0xc4007f77d0c1cec3, 0x8d1020b6bac492f8, 0x32ec29d57e69daaf, 0x599408759d95fce0}}, - {{0x33810a23bf00086e, 0xafce925ee736ff7c, 0x3d60e670e24922d4, 0x11ce9e714f96061b}}, - {{0x219ef713d815bac1, 0xf141465d485be25c, 0x6d5447cc4e513c51, 0x174926be5ef44393}}}, -{{{0xb5deb2f9fc5bd5bb, 0x92daa72ae1d810e1, 0xafc4cfdcb72a1c59, 0x497d78813fc22a24}}, - {{0x3ef5d41593ea022e, 0x5cbcc1a20ed0eed6, 0x8fd24ecf07382c8c, 0x6fa42ead06d8e1ad}}, - {{0xe276824a1f73371f, 0x7f7cf01c4f5b6736, 0x7e201fe304fa46e7, 0x785a36a357808c96}}}, -{{{0x825fbdfd63014d2b, 0xc852369c6ca7578b, 0x5b2fcd285c0b5df0, 0x12ab214c58048c8f}}, - {{0x070442985d517bc3, 0x6acd56c7ae653678, 0x00a27983985a7763, 0x5167effae512662b}}, - {{0xbd4ea9e10f53c4b6, 0x1673dc5f8ac91a14, 0xa8f81a4e2acc1aba, 0x33a92a7924332a25}}}, -{{{0x9dd1f49927996c02, 0x0cb3b058e04d1752, 0x1f7e88967fd02c3e, 0x2f964268cb8b3eb1}}, - {{0x7ba95ba0218f2ada, 0xcff42287330fb9ca, 0xdada496d56c6d907, 0x5380c296f4beee54}}, - {{0x9d4f270466898d0a, 0x3d0987990aff3f7a, 0xd09ef36267daba45, 0x7761455e7b1c669c}}} \ No newline at end of file diff --git a/ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data b/ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data deleted file mode 100644 index a31f6f2f..00000000 --- a/ext/ed25519-amd64-asm/ge25519_base_niels_smalltables.data +++ /dev/null @@ -1,768 +0,0 @@ -{{{0x9d103905d740913e, 0xfd399f05d140beb3, 0xa5c18434688f8a09, 0x44fd2f9298f81267}}, - {{0x2fbc93c6f58c3b85, 0xcf932dc6fb8c0e19, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65}}, - {{0xdbbd15674b6fbb59, 0x41e13f00eea2a5ea, 0xcdd49d1cc957c6fa, 0x4f0ebe1faf16ecca}}}, -{{{0x8a99a56042b4d5a8, 0x8f2b810c4e60acf6, 0xe09e236bb16e37aa, 0x6bb595a669c92555}}, - {{0x9224e7fc933c71d7, 0x9f469d967a0ff5b5, 0x5aa69a65e1d60702, 0x590c063fa87d2e2e}}, - {{0x6e347eaadad36802, 0xbaf3599383ee4805, 0x3bcabe10e6076826, 0x49314f0a165ed1b8}}}, -{{{0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, 0x8131f31a214bd6bd, 0x2ab91587555bda62}}, - {{0xaf25b0a84cee9730, 0x025a8430e8864b8a, 0xc11b50029f016732, 0x7a164e1b9a80f8f4}}, - {{0x9bf211f4f1674834, 0xb84e6b17f62df895, 0xd7de6f075b722a4e, 0x549a04b963bb2a21}}}, -{{{0x95fe050a056818bf, 0x327e89715660faa9, 0xc3e8e3cd06a05073, 0x27933f4c7445a49a}}, - {{0x287351b98efc099f, 0x6765c6f47dfd2538, 0xca348d3dfb0a9265, 0x680e910321e58727}}, - {{0xbf1e45ece51426b0, 0xe32bc63d6dba0f94, 0xe42974d58cf852c0, 0x44f079b1b0e64c18}}}, -{{{0x7f9182c3a447d6ba, 0xd50014d14b2729b7, 0xe33cf11cb864a087, 0x154a7e73eb1b55f3}}, - {{0xa212bc4408a5bb33, 0x8d5048c3c75eed02, 0xdd1beb0c5abfec44, 0x2945ccf146e206eb}}, - {{0xc832a179e7d003b3, 0x5f729d0a00124d7e, 0x62c1d4a10e6d8ff3, 0x68b8ac5938b27a98}}}, -{{{0x499806b67b7d8ca4, 0x575be28427d22739, 0xbb085ce7204553b9, 0x38b64c41ae417884}}, - {{0x3a0ceeeb77157131, 0x9b27158900c8af88, 0x8065b668da59a736, 0x51e57bb6a2cc38bd}}, - {{0x8f9dad91689de3a4, 0x175f2428f8fb9137, 0x050ab5329fcfb988, 0x7865dfa21354c09f}}}, -{{{0xba6f2c9aaa3221b1, 0x6ca021533bba23a7, 0x9dea764f92192c3a, 0x1d6edd5d2e5317e0}}, - {{0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e}}, - {{0x217a8aacab0fda36, 0xa528c6543d3549c8, 0x37d05b8b13ab7568, 0x233cef623a2cbc37}}}, -{{{0xe2a75dedf39234d9, 0x963d7680e1b558f9, 0x2c2741ac6e3c23fb, 0x3a9024a1320e01c3}}, - {{0x59b7596604dd3e8f, 0x6cb30377e288702c, 0xb1339c665ed9c323, 0x0915e76061bce52f}}, - {{0xdf7de835a834a37e, 0x8be19cda689857ea, 0x2c1185367167b326, 0x589eb3d9dbefd5c2}}}, -{{{0xed5b635449aa515e, 0xa865c49f0bc6823a, 0x850c1fe95b42d1c4, 0x30d76d6f03d315b9}}, - {{0x2eccdd0e632f9c1d, 0x51d0b69676893115, 0x52dfb76ba8637a58, 0x6dd37d49a00eef39}}, - {{0x6c4444172106e4c7, 0xfb53d680928d7f69, 0xb4739ea4694d3f26, 0x10c697112e864bb0}}}, -{{{0x6493c4277dbe5fde, 0x265d4fad19ad7ea2, 0x0e00dfc846304590, 0x25e61cabed66fe09}}, - {{0x0ca62aa08358c805, 0x6a3d4ae37a204247, 0x7464d3a63b11eddc, 0x03bf9baf550806ef}}, - {{0x3f13e128cc586604, 0x6f5873ecb459747e, 0xa0b63dedcc1268f5, 0x566d78634586e22c}}}, -{{{0x1637a49f9cc10834, 0xbc8e56d5a89bc451, 0x1cb5ec0f7f7fd2db, 0x33975bca5ecc35d9}}, - {{0xa1054285c65a2fd0, 0x6c64112af31667c3, 0x680ae240731aee58, 0x14fba5f34793b22a}}, - {{0x3cd746166985f7d4, 0x593e5e84c9c80057, 0x2fc3f2b67b61131e, 0x14829cea83fc526c}}}, -{{{0xff437b8497dd95c2, 0x6c744e30aa4eb5a7, 0x9e0c5d613c85e88b, 0x2fd9c71e5f758173}}, - {{0x21e70b2f4e71ecb8, 0xe656ddb940a477e3, 0xbf6556cece1d4f80, 0x05fc3bc4535d7b7e}}, - {{0x24b8b3ae52afdedd, 0x3495638ced3b30cf, 0x33a4bc83a9be8195, 0x373767475c651f04}}}, -{{{0x2fba99fd40d1add9, 0xb307166f96f4d027, 0x4363f05215f03bae, 0x1fbea56c3b18f999}}, - {{0x634095cb14246590, 0xef12144016c15535, 0x9e38140c8910bc60, 0x6bf5905730907c8c}}, - {{0x0fa778f1e1415b8a, 0x06409ff7bac3a77e, 0x6f52d7b89aa29a50, 0x02521cf67a635a56}}}, -{{{0x513fee0b0a9d5294, 0x8f98e75c0fdf5a66, 0xd4618688bfe107ce, 0x3fa00a7e71382ced}}, - {{0xb1146720772f5ee4, 0xe8f894b196079ace, 0x4af8224d00ac824a, 0x001753d9f7cd6cc4}}, - {{0x3c69232d963ddb34, 0x1dde87dab4973858, 0xaad7d1f9a091f285, 0x12b5fe2fa048edb6}}}, -{{{0x71f0fbc496fce34d, 0x73b9826badf35bed, 0xd2047261ff28c561, 0x749b76f96fb1206f}}, - {{0xdf2b7c26ad6f1e92, 0x4b66d323504b8913, 0x8c409dc0751c8bc3, 0x6f7e93c20796c7b8}}, - {{0x1f5af604aea6ae05, 0xc12351f1bee49c99, 0x61a808b5eeff6b66, 0x0fcec10f01e02151}}}, -{{{0x644d58a649fe1e44, 0x21fcaea231ad777e, 0x02441c5a887fd0d2, 0x4901aa7183c511f3}}, - {{0x3df2d29dc4244e45, 0x2b020e7493d8de0a, 0x6cc8067e820c214d, 0x413779166feab90a}}, - {{0x08b1b7548c1af8f0, 0xce0f7a7c246299b4, 0xf760b0f91e06d939, 0x41bb887b726d1213}}}, -{{{0x40e87d44744346be, 0x1d48dad415b52b25, 0x7c3a8a18a13b603e, 0x4eb728c12fcdbdf7}}, - {{0x7e234c597c6691ae, 0x64889d3d0a85b4c8, 0xdae2c90c354afae7, 0x0a871e070c6a9e1d}}, - {{0x3301b5994bbc8989, 0x736bae3a5bdd4260, 0x0d61ade219d59e3c, 0x3ee7300f2685d464}}}, -{{{0xf5d255e49e7dd6b7, 0x8016115c610b1eac, 0x3c99975d92e187ca, 0x13815762979125c2}}, - {{0x43fa7947841e7518, 0xe5c6fa59639c46d7, 0xa1065e1de3052b74, 0x7d47c6a2cfb89030}}, - {{0x3fdad0148ef0d6e0, 0x9d3e749a91546f3c, 0x71ec621026bb8157, 0x148cf58d34c9ec80}}}, -{{{0x46a492f67934f027, 0x469984bef6840aa9, 0x5ca1bc2a89611854, 0x3ff2fa1ebd5dbbd4}}, - {{0xe2572f7d9ae4756d, 0x56c345bb88f3487f, 0x9fd10b6d6960a88d, 0x278febad4eaea1b9}}, - {{0xb1aa681f8c933966, 0x8c21949c20290c98, 0x39115291219d3c52, 0x4104dd02fe9c677b}}}, -{{{0x72b2bf5e1124422a, 0xa1fa0c3398a33ab5, 0x94cb6101fa52b666, 0x2c863b00afaf53d5}}, - {{0x81214e06db096ab8, 0x21a8b6c90ce44f35, 0x6524c12a409e2af5, 0x0165b5a48efca481}}, - {{0xf190a474a0846a76, 0x12eff984cd2f7cc0, 0x695e290658aa2b8f, 0x591b67d9bffec8b8}}}, -{{{0x312f0d1c80b49bfa, 0x5979515eabf3ec8a, 0x727033c09ef01c88, 0x3de02ec7ca8f7bcb}}, - {{0x99b9b3719f18b55d, 0xe465e5faa18c641e, 0x61081136c29f05ed, 0x489b4f867030128b}}, - {{0xd232102d3aeb92ef, 0xe16253b46116a861, 0x3d7eabe7190baa24, 0x49f5fbba496cbebf}}}, -{{{0x30949a108a5bcfd4, 0xdc40dd70bc6473eb, 0x92c294c1307c0d1c, 0x5604a86dcbfa6e74}}, - {{0x155d628c1e9c572e, 0x8a4d86acc5884741, 0x91a352f6515763eb, 0x06a1a6c28867515b}}, - {{0x7288d1d47c1764b6, 0x72541140e0418b51, 0x9f031a6018acf6d1, 0x20989e89fe2742c6}}}, -{{{0x499777fd3a2dcc7f, 0x32857c2ca54fd892, 0xa279d864d207e3a0, 0x0403ed1d0ca67e29}}, - {{0x1674278b85eaec2e, 0x5621dc077acb2bdf, 0x640a4c1661cbf45a, 0x730b9950f70595d3}}, - {{0xc94b2d35874ec552, 0xc5e6c8cf98246f8d, 0xf7cb46fa16c035ce, 0x5bd7454308303dcc}}}, -{{{0x7f9ad19528b24cc2, 0x7f6b54656335c181, 0x66b8b66e4fc07236, 0x133a78007380ad83}}, - {{0x85c4932115e7792a, 0xc64c89a2bdcdddc9, 0x9d1e3da8ada3d762, 0x5bb7db123067f82c}}, - {{0x0961f467c6ca62be, 0x04ec21d6211952ee, 0x182360779bd54770, 0x740dca6d58f0e0d2}}}, -{{{0xdf48ee0752cfce4e, 0xc3fffaf306ec08b7, 0x05710b2ab95459c4, 0x161d25fa963ea38d}}, - {{0x231a8c570478433c, 0xb7b5270ec281439d, 0xdbaa99eae3d9079f, 0x2c03f5256c2b03d9}}, - {{0x790f18757b53a47d, 0x307b0130cf0c5879, 0x31903d77257ef7f9, 0x699468bdbd96bbaf}}}, -{{{0xbd1f2f46f4dafecf, 0x7cef0114a47fd6f7, 0xd31ffdda4a47b37f, 0x525219a473905785}}, - {{0xd8dd3de66aa91948, 0x485064c22fc0d2cc, 0x9b48246634fdea2f, 0x293e1c4e6c4a2e3a}}, - {{0x376e134b925112e1, 0x703778b5dca15da0, 0xb04589af461c3111, 0x5b605c447f032823}}}, -{{{0xb965805920c47c89, 0xe7f0100c923b8fcc, 0x0001256502e2ef77, 0x24a76dcea8aeb3ee}}, - {{0x3be9fec6f0e7f04c, 0x866a579e75e34962, 0x5542ef161e1de61a, 0x2f12fef4cc5abdd5}}, - {{0x0a4522b2dfc0c740, 0x10d06e7f40c9a407, 0xc6cf144178cff668, 0x5e607b2518a43790}}}, -{{{0x58b31d8f6cdf1818, 0x35cfa74fc36258a2, 0xe1b3ff4f66e61d6e, 0x5067acab6ccdd5f7}}, - {{0xa02c431ca596cf14, 0xe3c42d40aed3e400, 0xd24526802e0f26db, 0x201f33139e457068}}, - {{0xfd527f6b08039d51, 0x18b14964017c0006, 0xd5220eb02e25a4a8, 0x397cba8862460375}}}, -{{{0x30c13093f05959b2, 0xe23aa18de9a97976, 0x222fd491721d5e26, 0x2339d320766e6c3a}}, - {{0x7815c3fbc81379e7, 0xa6619420dde12af1, 0xffa9c0f885a8fdd5, 0x771b4022c1e1c252}}, - {{0xd87dd986513a2fa7, 0xf5ac9b71f9d4cf08, 0xd06bc31b1ea283b3, 0x331a189219971a76}}}, -{{{0xf5166f45fb4f80c6, 0x9c36c7de61c775cf, 0xe3d4e81b9041d91c, 0x31167c6b83bdfe21}}, - {{0x26512f3a9d7572af, 0x5bcbe28868074a9e, 0x84edc1c11180f7c4, 0x1ac9619ff649a67b}}, - {{0xf22b3842524b1068, 0x5068343bee9ce987, 0xfc9d71844a6250c8, 0x612436341f08b111}}}, -{{{0xd99d41db874e898d, 0x09fea5f16c07dc20, 0x793d2c67d00f9bbc, 0x46ebe2309e5eff40}}, - {{0x8b6349e31a2d2638, 0x9ddfb7009bd3fd35, 0x7f8bf1b8a3a06ba4, 0x1522aa3178d90445}}, - {{0x2c382f5369614938, 0xdafe409ab72d6d10, 0xe8c83391b646f227, 0x45fe70f50524306c}}}, -{{{0xda4875a6960c0b8c, 0x5b68d076ef0e2f20, 0x07fb51cf3d0b8fd4, 0x428d1623a0e392d4}}, - {{0x62f24920c8951491, 0x05f007c83f630ca2, 0x6fbb45d2f5c9d4b8, 0x16619f6db57a2245}}, - {{0x084f4a4401a308fd, 0xa82219c376a5caac, 0xdeb8de4643d1bc7d, 0x1d81592d60bd38c6}}}, -{{{0x61368756a60dac5f, 0x17e02f6aebabdc57, 0x7f193f2d4cce0f7d, 0x20234a7789ecdcf0}}, - {{0x8765b69f7b85c5e8, 0x6ff0678bd168bab2, 0x3a70e77c1d330f9b, 0x3a5f6d51b0af8e7c}}, - {{0x76d20db67178b252, 0x071c34f9d51ed160, 0xf62a4a20b3e41170, 0x7cd682353cffe366}}}, -{{{0x0be1a45bd887fab6, 0x2a846a32ba403b6e, 0xd9921012e96e6000, 0x2838c8863bdc0943}}, - {{0xa665cd6068acf4f3, 0x42d92d183cd7e3d3, 0x5759389d336025d9, 0x3ef0253b2b2cd8ff}}, - {{0xd16bb0cf4a465030, 0xfa496b4115c577ab, 0x82cfae8af4ab419d, 0x21dcb8a606a82812}}}, -{{{0x5c6004468c9d9fc8, 0x2540096ed42aa3cb, 0x125b4d4c12ee2f9c, 0x0bc3d08194a31dab}}, - {{0x9a8d00fabe7731ba, 0x8203607e629e1889, 0xb2cc023743f3d97f, 0x5d840dbf6c6f678b}}, - {{0x706e380d309fe18b, 0x6eb02da6b9e165c7, 0x57bbba997dae20ab, 0x3a4276232ac196dd}}}, -{{{0x4b42432c8a7084fa, 0x898a19e3dfb9e545, 0xbe9f00219c58e45d, 0x1ff177cea16debd1}}, - {{0x3bf8c172db447ecb, 0x5fcfc41fc6282dbd, 0x80acffc075aa15fe, 0x0770c9e824e1a9f9}}, - {{0xcf61d99a45b5b5fd, 0x860984e91b3a7924, 0xe7300919303e3e89, 0x39f264fd41500b1e}}}, -{{{0xa7ad3417dbe7e29c, 0xbd94376a2b9c139c, 0xa0e91b8e93597ba9, 0x1712d73468889840}}, - {{0xd19b4aabfe097be1, 0xa46dfce1dfe01929, 0xc3c908942ca6f1ff, 0x65c621272c35f14e}}, - {{0xe72b89f8ce3193dd, 0x4d103356a125c0bb, 0x0419a93d2e1cfe83, 0x22f9800ab19ce272}}}, -{{{0x605a368a3e9ef8cb, 0xe3e9c022a5504715, 0x553d48b05f24248f, 0x13f416cd647626e5}}, - {{0x42029fdd9a6efdac, 0xb912cebe34a54941, 0x640f64b987bdf37b, 0x4171a4d38598cab4}}, - {{0xfa2758aa99c94c8c, 0x23006f6fb000b807, 0xfbd291ddadda5392, 0x508214fa574bd1ab}}}, -{{{0xc20269153ed6fe4b, 0xa65a6739511d77c4, 0xcbde26462c14af94, 0x22f960ec6faba74b}}, - {{0x461a15bb53d003d6, 0xb2102888bcf3c965, 0x27c576756c683a5a, 0x3a7758a4c86cb447}}, - {{0x548111f693ae5076, 0x1dae21df1dfd54a6, 0x12248c90f3115e65, 0x5d9fd15f8de7f494}}}, -{{{0x031408d36d63727f, 0x6a379aefd7c7b533, 0xa9e18fc5ccaee24b, 0x332f35914f8fbed3}}, - {{0x3f244d2aeed7521e, 0x8e3a9028432e9615, 0xe164ba772e9c16d4, 0x3bc187fa47eb98d8}}, - {{0x6d470115ea86c20c, 0x998ab7cb6c46d125, 0xd77832b53a660188, 0x450d81ce906fba03}}}, -{{{0x6e7bb6a1a6205275, 0xaa4f21d7413c8e83, 0x6f56d155e88f5cb2, 0x2de25d4ba6345be1}}, - {{0xd074d8961cae743f, 0xf86d18f5ee1c63ed, 0x97bdc55be7f4ed29, 0x4cbad279663ab108}}, - {{0x80d19024a0d71fcd, 0xc525c20afb288af8, 0xb1a3974b5f3a6419, 0x7d7fbcefe2007233}}}, -{{{0xfaef1e6a266b2801, 0x866c68c4d5739f16, 0xf68a2fbc1b03762c, 0x5975435e87b75a8d}}, - {{0xcd7c5dc5f3c29094, 0xc781a29a2a9105ab, 0x80c61d36421c3058, 0x4f9cd196dcd8d4d7}}, - {{0x199297d86a7b3768, 0xd0d058241ad17a63, 0xba029cad5c1c0c17, 0x7ccdd084387a0307}}}, -{{{0xdca6422c6d260417, 0xae153d50948240bd, 0xa9c0c1b4fb68c677, 0x428bd0ed61d0cf53}}, - {{0x9b0c84186760cc93, 0xcdae007a1ab32a99, 0xa88dec86620bda18, 0x3593ca848190ca44}}, - {{0x9213189a5e849aa7, 0xd4d8c33565d8facd, 0x8c52545b53fdbbd1, 0x27398308da2d63e6}}}, -{{{0x42c38d28435ed413, 0xbd50f3603278ccc9, 0xbb07ab1a79da03ef, 0x269597aebe8c3355}}, - {{0xb9a10e4c0a702453, 0x0fa25866d57d1bde, 0xffb9d9b5cd27daf7, 0x572c2945492c33fd}}, - {{0xc77fc745d6cd30be, 0xe4dfe8d3e3baaefb, 0xa22c8830aa5dda0c, 0x7f985498c05bca80}}}, -{{{0x3849ce889f0be117, 0x8005ad1b7b54a288, 0x3da3c39f23fc921c, 0x76c2ec470a31f304}}, - {{0xd35615520fbf6363, 0x08045a45cf4dfba6, 0xeec24fbc873fa0c2, 0x30f2653cd69b12e7}}, - {{0x8a08c938aac10c85, 0x46179b60db276bcb, 0xa920c01e0e6fac70, 0x2f1273f1596473da}}}, -{{{0x4739fc7c8ae01e11, 0xfd5274904a6aab9f, 0x41d98a8287728f2e, 0x5d9e572ad85b69f2}}, - {{0x30488bd755a70bc0, 0x06d6b5a4f1d442e7, 0xead1a69ebc596162, 0x38ac1997edc5f784}}, - {{0x0666b517a751b13b, 0x747d06867e9b858c, 0xacacc011454dde49, 0x22dfcd9cbfe9e69c}}}, -{{{0x8ddbd2e0c30d0cd9, 0xad8e665facbb4333, 0x8f6b258c322a961f, 0x6b2916c05448c1c7}}, - {{0x56ec59b4103be0a1, 0x2ee3baecd259f969, 0x797cb29413f5cd32, 0x0fe9877824cde472}}, - {{0x7edb34d10aba913b, 0x4ea3cd822e6dac0e, 0x66083dff6578f815, 0x4c303f307ff00a17}}}, -{{{0xd30a3bd617b28c85, 0xc5d377b739773bea, 0xc6c6e78c1e6a5cbf, 0x0d61b8f78b2ab7c4}}, - {{0x29fc03580dd94500, 0xecd27aa46fbbec93, 0x130a155fc2e2a7f8, 0x416b151ab706a1d5}}, - {{0x56a8d7efe9c136b0, 0xbd07e5cd58e44b20, 0xafe62fda1b57e0ab, 0x191a2af74277e8d2}}}, -{{{0xce16f74bc53c1431, 0x2b9725ce2072edde, 0xb8b9c36fb5b23ee7, 0x7e2e0e450b5cc908}}, - {{0x9fe62b434f460efb, 0xded303d4a63607d6, 0xf052210eb7a0da24, 0x237e7dbe00545b93}}, - {{0x013575ed6701b430, 0x231094e69f0bfd10, 0x75320f1583e47f22, 0x71afa699b11155e3}}}, -{{{0x65ce6f9b3953b61d, 0xc65839eaafa141e6, 0x0f435ffda9f759fe, 0x021142e9c2b1c28e}}, - {{0xea423c1c473b50d6, 0x51e87a1f3b38ef10, 0x9b84bf5fb2c9be95, 0x00731fbc78f89a1c}}, - {{0xe430c71848f81880, 0xbf960c225ecec119, 0xb6dae0836bba15e3, 0x4c4d6f3347e15808}}}, -{{{0x18f7eccfc17d1fc9, 0x6c75f5a651403c14, 0xdbde712bf7ee0cdf, 0x193fddaaa7e47a22}}, - {{0x2f0cddfc988f1970, 0x6b916227b0b9f51b, 0x6ec7b6c4779176be, 0x38bf9500a88f9fa8}}, - {{0x1fd2c93c37e8876f, 0xa2f61e5a18d1462c, 0x5080f58239241276, 0x6a6fb99ebf0d4969}}}, -{{{0x6a46c1bb560855eb, 0x2416bb38f893f09d, 0xd71d11378f71acc1, 0x75f76914a31896ea}}, - {{0xeeb122b5b6e423c6, 0x939d7010f286ff8e, 0x90a92a831dcf5d8c, 0x136fda9f42c5eb10}}, - {{0xf94cdfb1a305bdd1, 0x0f364b9d9ff82c08, 0x2a87d8a5c3bb588a, 0x022183510be8dcba}}}, -{{{0x4af766385ead2d14, 0xa08ed880ca7c5830, 0x0d13a6e610211e3d, 0x6a071ce17b806c03}}, - {{0x9d5a710143307a7f, 0xb063de9ec47da45f, 0x22bbfe52be927ad3, 0x1387c441fd40426c}}, - {{0xb5d3c3d187978af8, 0x722b5a3d7f0e4413, 0x0d7b4848bb477ca0, 0x3171b26aaf1edc92}}}, -{{{0xa92f319097564ca8, 0xff7bb84c2275e119, 0x4f55fe37a4875150, 0x221fd4873cf0835a}}, - {{0xa60db7d8b28a47d1, 0xa6bf14d61770a4f1, 0xd4a1f89353ddbd58, 0x6c514a63344243e9}}, - {{0x2322204f3a156341, 0xfb73e0e9ba0a032d, 0xfce0dd4c410f030e, 0x48daa596fb924aaa}}}, -{{{0x6eca8e665ca59cc7, 0xa847254b2e38aca0, 0x31afc708d21e17ce, 0x676dd6fccad84af7}}, - {{0x14f61d5dc84c9793, 0x9941f9e3ef418206, 0xcdf5b88f346277ac, 0x58c837fa0e8a79a9}}, - {{0x0cf9688596fc9058, 0x1ddcbbf37b56a01b, 0xdcc2e77d4935d66a, 0x1c4f73f2c6a57f0a}}}, -{{{0x0e7a4fbd305fa0bb, 0x829d4ce054c663ad, 0xf421c3832fe33848, 0x795ac80d1bf64c42}}, - {{0xb36e706efc7c3484, 0x73dfc9b4c3c1cf61, 0xeb1d79c9781cc7e5, 0x70459adb7daf675c}}, - {{0x1b91db4991b42bb3, 0x572696234b02dcca, 0x9fdf9ee51f8c78dc, 0x5fe162848ce21fd3}}}, -{{{0x4e59214fe194961a, 0x49be7dc70d71cd4f, 0x9300cfd23b50f22d, 0x4789d446fc917232}}, - {{0x2879852d5d7cb208, 0xb8dedd70687df2e7, 0xdc0bffab21687891, 0x2b44c043677daa35}}, - {{0x1a1c87ab074eb78e, 0xfac6d18e99daf467, 0x3eacbbcd484f9067, 0x60c52eef2bb9a4e4}}}, -{{{0x0b5d89bc3bfd8bf1, 0xb06b9237c9f3551a, 0x0e4c16b0d53028f5, 0x10bc9c312ccfcaab}}, - {{0x702bc5c27cae6d11, 0x44c7699b54a48cab, 0xefbc4056ba492eb2, 0x70d77248d9b6676d}}, - {{0xaa8ae84b3ec2a05b, 0x98699ef4ed1781e0, 0x794513e4708e85d1, 0x63755bd3a976f413}}}, -{{{0xb55fa03e2ad10853, 0x356f75909ee63569, 0x9ff9f1fdbe69b890, 0x0d8cc1c48bc16f84}}, - {{0x3dc7101897f1acb7, 0x5dda7d5ec165bbd8, 0x508e5b9c0fa1020f, 0x2763751737c52a56}}, - {{0x029402d36eb419a9, 0xf0b44e7e77b460a5, 0xcfa86230d43c4956, 0x70c2dd8a7ad166e7}}}, -{{{0x656194509f6fec0e, 0xee2e7ea946c6518d, 0x9733c1f367e09b5c, 0x2e0fac6363948495}}, - {{0x91d4967db8ed7e13, 0x74252f0ad776817a, 0xe40982e00d852564, 0x32b8613816a53ce5}}, - {{0x79e7f7bee448cd64, 0x6ac83a67087886d0, 0xf89fd4d9a0e4db2e, 0x4179215c735a4f41}}}, -{{{0x8c7094e7d7dced2a, 0x97fb8ac347d39c70, 0xe13be033a906d902, 0x700344a30cd99d76}}, - {{0xe4ae33b9286bcd34, 0xb7ef7eb6559dd6dc, 0x278b141fb3d38e1f, 0x31fa85662241c286}}, - {{0xaf826c422e3622f4, 0xc12029879833502d, 0x9bc1b7e12b389123, 0x24bb2312a9952489}}}, -{{{0xb1a8ed1732de67c3, 0x3cb49418461b4948, 0x8ebd434376cfbcd2, 0x0fee3e871e188008}}, - {{0x41f80c2af5f85c6b, 0x687284c304fa6794, 0x8945df99a3ba1bad, 0x0d1d2af9ffeb5d16}}, - {{0xa9da8aa132621edf, 0x30b822a159226579, 0x4004197ba79ac193, 0x16acd79718531d76}}}, -{{{0x72df72af2d9b1d3d, 0x63462a36a432245a, 0x3ecea07916b39637, 0x123e0ef6b9302309}}, - {{0xc959c6c57887b6ad, 0x94e19ead5f90feba, 0x16e24e62a342f504, 0x164ed34b18161700}}, - {{0x487ed94c192fe69a, 0x61ae2cea3a911513, 0x877bf6d3b9a4de27, 0x78da0fc61073f3eb}}}, -{{{0x5bf15d28e52bc66a, 0x2c47e31870f01a8e, 0x2419afbc06c28bdd, 0x2d25deeb256b173a}}, - {{0xa29f80f1680c3a94, 0x71f77e151ae9e7e6, 0x1100f15848017973, 0x054aa4b316b38ddd}}, - {{0xdfc8468d19267cb8, 0x0b28789c66e54daf, 0x2aeb1d2a666eec17, 0x134610a6ab7da760}}}, -{{{0x51138ec78df6b0fe, 0x5397da89e575f51b, 0x09207a1d717af1b9, 0x2102fdba2b20d650}}, - {{0xcd2a65e777d1f515, 0x548991878faa60f1, 0xb1b73bbcdabc06e5, 0x654878cba97cc9fb}}, - {{0x969ee405055ce6a1, 0x36bca7681251ad29, 0x3a1af517aa7da415, 0x0ad725db29ecb2ba}}}, -{{{0xdc4267b1834e2457, 0xb67544b570ce1bc5, 0x1af07a0bf7d15ed7, 0x4aefcffb71a03650}}, - {{0xfec7bc0c9b056f85, 0x537d5268e7f5ffd7, 0x77afc6624312aefa, 0x4f675f5302399fd9}}, - {{0xc32d36360415171e, 0xcd2bef118998483b, 0x870a6eadd0945110, 0x0bccbb72a2a86561}}}, -{{{0x185e962feab1a9c8, 0x86e7e63565147dcd, 0xb092e031bb5b6df2, 0x4024f0ab59d6b73e}}, - {{0x186d5e4c50fe1296, 0xe0397b82fee89f7e, 0x3bc7f6c5507031b0, 0x6678fd69108f37c2}}, - {{0x1586fa31636863c2, 0x07f68c48572d33f2, 0x4f73cc9f789eaefc, 0x2d42e2108ead4701}}}, -{{{0x97f5131594dfd29b, 0x6155985d313f4c6a, 0xeba13f0708455010, 0x676b2608b8d2d322}}, - {{0x21717b0d0f537593, 0x914e690b131e064c, 0x1bb687ae752ae09f, 0x420bf3a79b423c6e}}, - {{0x8138ba651c5b2b47, 0x8671b6ec311b1b80, 0x7bff0cb1bc3135b0, 0x745d2ffa9c0cf1e0}}}, -{{{0xbf525a1e2bc9c8bd, 0xea5b260826479d81, 0xd511c70edf0155db, 0x1ae23ceb960cf5d0}}, - {{0x6036df5721d34e6a, 0xb1db8827997bb3d0, 0xd3c209c3c8756afa, 0x06e15be54c1dc839}}, - {{0x5b725d871932994a, 0x32351cb5ceb1dab0, 0x7dc41549dab7ca05, 0x58ded861278ec1f7}}}, -{{{0xd8173793f266c55c, 0xc8c976c5cc454e49, 0x5ce382f8bc26c3a8, 0x2ff39de85485f6f9}}, - {{0x2dfb5ba8b6c2c9a8, 0x48eeef8ef52c598c, 0x33809107f12d1573, 0x08ba696b531d5bd8}}, - {{0x77ed3eeec3efc57a, 0x04e05517d4ff4811, 0xea3d7a3ff1a671cb, 0x120633b4947cfe54}}}, -{{{0x0b94987891610042, 0x4ee7b13cecebfae8, 0x70be739594f0a4c0, 0x35d30a99b4d59185}}, - {{0x82bd31474912100a, 0xde237b6d7e6fbe06, 0xe11e761911ea79c6, 0x07433be3cb393bde}}, - {{0xff7944c05ce997f4, 0x575d3de4b05c51a3, 0x583381fd5a76847c, 0x2d873ede7af6da9f}}}, -{{{0x157a316443373409, 0xfab8b7eef4aa81d9, 0xb093fee6f5a64806, 0x2e773654707fa7b6}}, - {{0xaa6202e14e5df981, 0xa20d59175015e1f5, 0x18a275d3bae21d6c, 0x0543618a01600253}}, - {{0x0deabdf4974c23c1, 0xaa6f0a259dce4693, 0x04202cb8a29aba2c, 0x4b1443362d07960d}}}, -{{{0xccc4b7c7b66e1f7a, 0x44157e25f50c2f7e, 0x3ef06dfc713eaf1c, 0x582f446752da63f7}}, - {{0x967c54e91c529ccb, 0x30f6269264c635fb, 0x2747aff478121965, 0x17038418eaf66f5c}}, - {{0xc6317bd320324ce4, 0xa81042e8a4488bc4, 0xb21ef18b4e5a1364, 0x0c2a1c4bcda28dc9}}}, -{{{0xd24dc7d06f1f0447, 0xb2269e3edb87c059, 0xd15b0272fbb2d28f, 0x7c558bd1c6f64877}}, - {{0xedc4814869bd6945, 0x0d6d907dbe1c8d22, 0xc63bd212d55cc5ab, 0x5a6a9b30a314dc83}}, - {{0xd0ec1524d396463d, 0x12bb628ac35a24f0, 0xa50c3a791cbc5fa4, 0x0404a5ca0afbafc3}}}, -{{{0x8c1f40070aa743d6, 0xccbad0cb5b265ee8, 0x574b046b668fd2de, 0x46395bfdcadd9633}}, - {{0x62bc9e1b2a416fd1, 0xb5c6f728e350598b, 0x04343fd83d5d6967, 0x39527516e7f8ee98}}, - {{0x117fdb2d1a5d9a9c, 0x9c7745bcd1005c2a, 0xefd4bef154d56fea, 0x76579a29e822d016}}}, -{{{0x45b68e7e49c02a17, 0x23cd51a2bca9a37f, 0x3ed65f11ec224c1b, 0x43a384dc9e05bdb1}}, - {{0x333cb51352b434f2, 0xd832284993de80e1, 0xb5512887750d35ce, 0x02c514bb2a2777c1}}, - {{0x684bd5da8bf1b645, 0xfb8bd37ef6b54b53, 0x313916d7a9b0d253, 0x1160920961548059}}}, -{{{0xb44d166929dacfaa, 0xda529f4c8413598f, 0xe9ef63ca453d5559, 0x351e125bc5698e0b}}, - {{0x7a385616369b4dcd, 0x75c02ca7655c3563, 0x7dc21bf9d4f18021, 0x2f637d7491e6e042}}, - {{0xd4b49b461af67bbe, 0xd603037ac8ab8961, 0x71dee19ff9a699fb, 0x7f182d06e7ce2a9a}}}, -{{{0x7a7c8e64ab0168ec, 0xcb5a4a5515edc543, 0x095519d347cd0eda, 0x67d4ac8c343e93b0}}, - {{0x09454b728e217522, 0xaa58e8f4d484b8d8, 0xd358254d7f46903c, 0x44acc043241c5217}}, - {{0x1c7d6bbb4f7a5777, 0x8b35fed4918313e1, 0x4adca1c6c96b4684, 0x556d1c8312ad71bd}}}, -{{{0x17ef40e30c8d3982, 0x31f7073e15a3fa34, 0x4f21f3cb0773646e, 0x746c6c6d1d824eff}}, - {{0x81f06756b11be821, 0x0faff82310a3f3dd, 0xf8b2d0556a99465d, 0x097abe38cc8c7f05}}, - {{0x0c49c9877ea52da4, 0x4c4369559bdc1d43, 0x022c3809f7ccebd2, 0x577e14a34bee84bd}}}, -{{{0xf0e268ac61a73b0a, 0xf2fafa103791a5f5, 0xc1e13e826b6d00e9, 0x60fa7ee96fd78f42}}, - {{0x94fecebebd4dd72b, 0xf46a4fda060f2211, 0x124a5977c0c8d1ff, 0x705304b8fb009295}}, - {{0xb63d1d354d296ec6, 0xf3c3053e5fad31d8, 0x670b958cb4bd42ec, 0x21398e0ca16353fd}}}, -{{{0x89f5058a382b33f3, 0x5ae2ba0bad48c0b4, 0x8f93b503a53db36e, 0x5aa3ed9d95a232e6}}, - {{0x2798aaf9b4b75601, 0x5eac72135c8dad72, 0xd2ceaa6161b7a023, 0x1bbfb284e98f7d4e}}, - {{0x656777e9c7d96561, 0xcb2b125472c78036, 0x65053299d9506eee, 0x4a07e14e5e8957cc}}}, -{{{0x4ee412cb980df999, 0xa315d76f3c6ec771, 0xbba5edde925c77fd, 0x3f0bac391d313402}}, - {{0x240b58cdc477a49b, 0xfd38dade6447f017, 0x19928d32a7c86aad, 0x50af7aed84afa081}}, - {{0x6e4fde0115f65be5, 0x29982621216109b2, 0x780205810badd6d9, 0x1921a316baebd006}}}, -{{{0x89422f7edfb870fc, 0x2c296beb4f76b3bd, 0x0738f1d436c24df7, 0x6458df41e273aeb0}}, - {{0xd75aad9ad9f3c18b, 0x566a0eef60b1c19c, 0x3e9a0bac255c0ed9, 0x7b049deca062c7f5}}, - {{0xdccbe37a35444483, 0x758879330fedbe93, 0x786004c312c5dd87, 0x6093dccbc2950e64}}}, -{{{0x1ff39a8585e0706d, 0x36d0a5d8b3e73933, 0x43b9f2e1718f453b, 0x57d1ea084827a97c}}, - {{0x6bdeeebe6084034b, 0x3199c2b6780fb854, 0x973376abb62d0695, 0x6e3180c98b647d90}}, - {{0xee7ab6e7a128b071, 0xa4c1596d93a88baa, 0xf7b4de82b2216130, 0x363e999ddd97bd18}}}, -{{{0x96a843c135ee1fc4, 0x976eb35508e4c8cf, 0xb42f6801b58cd330, 0x48ee9b78693a052b}}, - {{0x2f1848dce24baec6, 0x769b7255babcaf60, 0x90cb3c6e3cefe931, 0x231f979bc6f9b355}}, - {{0x5c31de4bcc2af3c6, 0xb04bb030fe208d1f, 0xb78d7009c14fb466, 0x079bfa9b08792413}}}, -{{{0xe3903a51da300df4, 0x843964233da95ab0, 0xed3cf12d0b356480, 0x038c77f684817194}}, - {{0xf3c9ed80a2d54245, 0x0aa08b7877f63952, 0xd76dac63d1085475, 0x1ef4fb159470636b}}, - {{0x854e5ee65b167bec, 0x59590a4296d0cdc2, 0x72b2df3498102199, 0x575ee92a4a0bff56}}}, -{{{0xd4c080908a182fcf, 0x30e170c299489dbd, 0x05babd5752f733de, 0x43d4e7112cd3fd00}}, - {{0x5d46bc450aa4d801, 0xc3af1227a533b9d8, 0x389e3b262b8906c2, 0x200a1e7e382f581b}}, - {{0x518db967eaf93ac5, 0x71bc989b056652c0, 0xfe2b85d9567197f5, 0x050eca52651e4e38}}}, -{{{0xc3431ade453f0c9c, 0xe9f5045eff703b9b, 0xfcd97ac9ed847b3d, 0x4b0ee6c21c58f4c6}}, - {{0x97ac397660e668ea, 0x9b19bbfe153ab497, 0x4cb179b534eca79f, 0x6151c09fa131ae57}}, - {{0x3af55c0dfdf05d96, 0xdd262ee02ab4ee7a, 0x11b2bb8712171709, 0x1fef24fa800f030b}}}, -{{{0x37d653fb1aa73196, 0x0f9495303fd76418, 0xad200b09fb3a17b2, 0x544d49292fc8613e}}, - {{0x22d2aff530976b86, 0x8d90b806c2d24604, 0xdca1896c4de5bae5, 0x28005fe6c8340c17}}, - {{0x6aefba9f34528688, 0x5c1bff9425107da1, 0xf75bbbcd66d94b36, 0x72e472930f316dfa}}}, -{{{0x2695208c9781084f, 0xb1502a0b23450ee1, 0xfd9daea603efde02, 0x5a9d2e8c2733a34c}}, - {{0x07f3f635d32a7627, 0x7aaa4d865f6566f0, 0x3c85e79728d04450, 0x1fee7f000fe06438}}, - {{0x765305da03dbf7e5, 0xa4daf2491434cdbd, 0x7b4ad5cdd24a88ec, 0x00f94051ee040543}}}, -{{{0x8d356b23c3d330b2, 0xf21c8b9bb0471b06, 0xb36c316c6e42b83c, 0x07d79c7e8beab10d}}, - {{0xd7ef93bb07af9753, 0x583ed0cf3db766a7, 0xce6998bf6e0b1ec5, 0x47b7ffd25dd40452}}, - {{0x87fbfb9cbc08dd12, 0x8a066b3ae1eec29b, 0x0d57242bdb1fc1bf, 0x1c3520a35ea64bb6}}}, -{{{0x80d253a6bccba34a, 0x3e61c3a13838219b, 0x90c3b6019882e396, 0x1c3d05775d0ee66f}}, - {{0xcda86f40216bc059, 0x1fbb231d12bcd87e, 0xb4956a9e17c70990, 0x38750c3b66d12e55}}, - {{0x692ef1409422e51a, 0xcbc0c73c2b5df671, 0x21014fe7744ce029, 0x0621e2c7d330487c}}}, -{{{0xaf9860cc8259838d, 0x90ea48c1c69f9adc, 0x6526483765581e30, 0x0007d6097bd3a5bc}}, - {{0xb7ae1796b0dbf0f3, 0x54dfafb9e17ce196, 0x25923071e9aaa3b4, 0x5d8e589ca1002e9d}}, - {{0xc0bf1d950842a94b, 0xb2d3c363588f2e3e, 0x0a961438bb51e2ef, 0x1583d7783c1cbf86}}}, -{{{0xeceea2ef5da27ae1, 0x597c3a1455670174, 0xc9a62a126609167a, 0x252a5f2e81ed8f70}}, - {{0x90034704cc9d28c7, 0x1d1b679ef72cc58f, 0x16e12b5fbe5b8726, 0x4958064e83c5580a}}, - {{0x0d2894265066e80d, 0xfcc3f785307c8c6b, 0x1b53da780c1112fd, 0x079c170bd843b388}}}, -{{{0x0506ece464fa6fff, 0xbee3431e6205e523, 0x3579422451b8ea42, 0x6dec05e34ac9fb00}}, - {{0xcdd6cd50c0d5d056, 0x9af7686dbb03573b, 0x3ca6723ff3c3ef48, 0x6768c0d7317b8acc}}, - {{0x94b625e5f155c1b3, 0x417bf3a7997b7b91, 0xc22cbddc6d6b2600, 0x51445e14ddcd52f4}}}, -{{{0x57502b4b3b144951, 0x8e67ff6b444bbcb3, 0xb8bd6927166385db, 0x13186f31e39295c8}}, - {{0x893147ab2bbea455, 0x8c53a24f92079129, 0x4b49f948be30f7a7, 0x12e990086e4fd43d}}, - {{0xf10c96b37fdfbb2e, 0x9f9a935e121ceaf9, 0xdf1136c43a5b983f, 0x77b2e3f05d3e99af}}}, -{{{0x296fa9c59c2ec4de, 0xbc8b61bf4f84f3cb, 0x1c7706d917a8f908, 0x63b795fc7ad3255d}}, - {{0xd598639c12ddb0a4, 0xa5d19f30c024866b, 0xd17c2f0358fce460, 0x07a195152e095e8a}}, - {{0xa8368f02389e5fc8, 0x90433b02cf8de43b, 0xafa1fd5dc5412643, 0x3e8fe83d032f0137}}}, -{{{0x2f8b15b90570a294, 0x94f2427067084549, 0xde1c5ae161bbfd84, 0x75ba3b797fac4007}}, - {{0x08704c8de8efd13c, 0xdfc51a8e33e03731, 0xa59d5da51260cde3, 0x22d60899a6258c86}}, - {{0x6239dbc070cdd196, 0x60fe8a8b6c7d8a9a, 0xb38847bceb401260, 0x0904d07b87779e5e}}}, -{{{0xb4ce1fd4ddba919c, 0xcf31db3ec74c8daa, 0x2c63cc63ad86cc51, 0x43e2143fbc1dde07}}, - {{0xf4322d6648f940b9, 0x06952f0cbd2d0c39, 0x167697ada081f931, 0x6240aacebaf72a6c}}, - {{0xf834749c5ba295a0, 0xd6947c5bca37d25a, 0x66f13ba7e7c9316a, 0x56bdaf238db40cac}}}, -{{{0x362ab9e3f53533eb, 0x338568d56eb93d40, 0x9e0e14521d5a5572, 0x1d24a86d83741318}}, - {{0x1310d36cc19d3bb2, 0x062a6bb7622386b9, 0x7c9b8591d7a14f5c, 0x03aa31507e1e5754}}, - {{0xf4ec7648ffd4ce1f, 0xe045eaf054ac8c1c, 0x88d225821d09357c, 0x43b261dc9aeb4859}}}, -{{{0xe55b1e1988bb79bb, 0xa09ed07dc17a359d, 0xb02c2ee2603dea33, 0x326055cf5b276bc2}}, - {{0x19513d8b6c951364, 0x94fe7126000bf47b, 0x028d10ddd54f9567, 0x02b4d5e242940964}}, - {{0xb4a155cb28d18df2, 0xeacc4646186ce508, 0xc49cf4936c824389, 0x27a6c809ae5d3410}}}, -{{{0x8ba6ebcd1f0db188, 0x37d3d73a675a5be8, 0xf22edfa315f5585a, 0x2cb67174ff60a17e}}, - {{0xcd2c270ac43d6954, 0xdd4a3e576a66cab2, 0x79fa592469d7036c, 0x221503603d8c2599}}, - {{0x59eecdf9390be1d0, 0xa9422044728ce3f1, 0x82891c667a94f0f4, 0x7b1df4b73890f436}}}, -{{{0xe492f2e0b3b2a224, 0x7c6c9e062b551160, 0x15eb8fe20d7f7b0e, 0x61fcef2658fc5992}}, - {{0x5f2e221807f8f58c, 0xe3555c9fd49409d4, 0xb2aaa88d1fb6a630, 0x68698245d352e03d}}, - {{0xdbb15d852a18187a, 0xf3e4aad386ddacd7, 0x44bae2810ff6c482, 0x46cf4c473daf01cf}}}, -{{{0x426525ed9ec4e5f9, 0x0e5eda0116903303, 0x72b1a7f2cbe5cadc, 0x29387bcd14eb5f40}}, - {{0x213c6ea7f1498140, 0x7c1e7ef8392b4854, 0x2488c38c5629ceba, 0x1065aae50d8cc5bb}}, - {{0x1c2c4525df200d57, 0x5c3b2dd6bfca674a, 0x0a07e7b1e1834030, 0x69a198e64f1ce716}}}, -{{{0x9062b2e0d91a78bc, 0x47c9889cc8509667, 0x9df54a66405070b8, 0x7369e6a92493a1bf}}, - {{0xe1014434dcc5caed, 0x47ed5d963c84fb33, 0x70019576ed86a0e7, 0x25b2697bd267f9e4}}, - {{0x9d673ffb13986864, 0x3ca5fbd9415dc7b8, 0xe04ecc3bdf273b5e, 0x1420683db54e4cd2}}}, -{{{0xb478bd1e249dd197, 0x620c35005e58c102, 0xfb02d32fccbaac5c, 0x60b63bebf508a72d}}, - {{0x34eebb6fc1cc5ad0, 0x6a1b0ce99646ac8b, 0xd3b0da49a66bde53, 0x31e83b4161d081c1}}, - {{0x97e8c7129e062b4f, 0x49e48f4f29320ad8, 0x5bece14b6f18683f, 0x55cf1eb62d550317}}}, -{{{0x5879101065c23d58, 0x8b9d086d5094819c, 0xe2402fa912c55fa7, 0x669a6564570891d4}}, - {{0x3076b5e37df58c52, 0xd73ab9dde799cc36, 0xbd831ce34913ee20, 0x1a56fbaa62ba0133}}, - {{0x943e6b505c9dc9ec, 0x302557bba77c371a, 0x9873ae5641347651, 0x13c4836799c58a5c}}}, -{{{0x423a5d465ab3e1b9, 0xfc13c187c7f13f61, 0x19f83664ecb5b9b6, 0x66f80c93a637b607}}, - {{0xc4dcfb6a5d8bd080, 0xdeebc4ec571a4842, 0xd4b2e883b8e55365, 0x50bdc87dc8e5b827}}, - {{0x606d37836edfe111, 0x32353e15f011abd9, 0x64b03ac325b73b96, 0x1dd56444725fd5ae}}}, -{{{0x8fa47ff83362127d, 0xbc9f6ac471cd7c15, 0x6e71454349220c8b, 0x0e645912219f732e}}, - {{0xc297e60008bac89a, 0x7d4cea11eae1c3e0, 0xf3e38be19fe7977c, 0x3a3a450f63a305cd}}, - {{0x078f2f31d8394627, 0x389d3183de94a510, 0xd1e36c6d17996f80, 0x318c8d9393a9a87b}}}, -{{{0xf2745d032afffe19, 0x0c9f3c497f24db66, 0xbc98d3e3ba8598ef, 0x224c7c679a1d5314}}, - {{0x5d669e29ab1dd398, 0xfc921658342d9e3b, 0x55851dfdf35973cd, 0x509a41c325950af6}}, - {{0xbdc06edca6f925e9, 0x793ef3f4641b1f33, 0x82ec12809d833e89, 0x05bff02328a11389}}}, -{{{0x3632137023cae00b, 0x544acf0ad1accf59, 0x96741049d21a1c88, 0x780b8cc3fa2a44a7}}, - {{0x6881a0dd0dc512e4, 0x4fe70dc844a5fafe, 0x1f748e6b8f4a5240, 0x576277cdee01a3ea}}, - {{0x1ef38abc234f305f, 0x9a577fbd1405de08, 0x5e82a51434e62a0d, 0x5ff418726271b7a1}}}, -{{{0x398e080c1789db9d, 0xa7602025f3e778f5, 0xfa98894c06bd035d, 0x106a03dc25a966be}}, - {{0xe5db47e813b69540, 0xf35d2a3b432610e1, 0xac1f26e938781276, 0x29d4db8ca0a0cb69}}, - {{0xd9ad0aaf333353d0, 0x38669da5acd309e5, 0x3c57658ac888f7f0, 0x4ab38a51052cbefa}}}, -{{{0xda7c2b256768d593, 0x98c1c0574422ca13, 0xf1a80bd5ca0ace1d, 0x29cdd1adc088a690}}, - {{0xd6cfd1ef5fddc09c, 0xe82b3efdf7575dce, 0x25d56b5d201634c2, 0x3041c6bb04ed2b9b}}, - {{0x0ff2f2f9d956e148, 0xade797759f356b2e, 0x1a4698bb5f6c025c, 0x104bbd6814049a7b}}}, -{{{0x51f0fd3168f1ed67, 0x2c811dcdd86f3bc2, 0x44dc5c4304d2f2de, 0x5be8cc57092a7149}}, - {{0xa95d9a5fd67ff163, 0xe92be69d4cc75681, 0xb7f8024cde20f257, 0x204f2a20fb072df5}}, - {{0xc8143b3d30ebb079, 0x7589155abd652e30, 0x653c3c318f6d5c31, 0x2570fb17c279161f}}}, -{{{0x3efa367f2cb61575, 0xf5f96f761cd6026c, 0xe8c7142a65b52562, 0x3dcb65ea53030acd}}, - {{0x192ea9550bb8245a, 0xc8e6fba88f9050d1, 0x7986ea2d88a4c935, 0x241c5f91de018668}}, - {{0x28d8172940de6caa, 0x8fbf2cf022d9733a, 0x16d7fcdd235b01d1, 0x08420edd5fcdf0e5}}}, -{{{0xcdff20ab8362fa4a, 0x57e118d4e21a3e6e, 0xe3179617fc39e62b, 0x0d9a53efbc1769fd}}, - {{0x0358c34e04f410ce, 0xb6135b5a276e0685, 0x5d9670c7ebb91521, 0x04d654f321db889c}}, - {{0x5e7dc116ddbdb5d5, 0x2954deb68da5dd2d, 0x1cb608173334a292, 0x4a7a4f2618991ad7}}}, -{{{0xf4a718025fb15f95, 0x3df65f346b5c1b8f, 0xcdfcf08500e01112, 0x11b50c4cddd31848}}, - {{0x24c3b291af372a4b, 0x93da8270718147f2, 0xdd84856486899ef2, 0x4a96314223e0ee33}}, - {{0xa6e8274408a4ffd6, 0x738e177e9c1576d9, 0x773348b63d02b3f2, 0x4f4bce4dce6bcc51}}}, -{{{0xa71fce5ae2242584, 0x26ea725692f58a9e, 0xd21a09d71cea3cf4, 0x73fcdd14b71c01e6}}, - {{0x30e2616ec49d0b6f, 0xe456718fcaec2317, 0x48eb409bf26b4fa6, 0x3042cee561595f37}}, - {{0x427e7079449bac41, 0x855ae36dbce2310a, 0x4cae76215f841a7c, 0x389e740c9a9ce1d6}}}, -{{{0x64fcb3ae34dcb9ce, 0x97500323e348d0ad, 0x45b3f07d62c6381b, 0x61545379465a6788}}, - {{0xc9bd78f6570eac28, 0xe55b0b3227919ce1, 0x65fc3eaba19b91ed, 0x25c425e5d6263690}}, - {{0x3f3e06a6f1d7de6e, 0x3ef976278e062308, 0x8c14f6264e8a6c77, 0x6539a08915484759}}}, -{{{0xe9d21f74c3d2f773, 0xc150544125c46845, 0x624e5ce8f9b99e33, 0x11c5e4aac5cd186c}}, - {{0xddc4dbd414bb4a19, 0x19b2bc3c98424f8e, 0x48a89fd736ca7169, 0x0f65320ef019bd90}}, - {{0xd486d1b1cafde0c6, 0x4f3fe6e3163b5181, 0x59a8af0dfaf2939a, 0x4cabc7bdec33072a}}}, -{{{0x239e9624089c0a2e, 0xc748c4c03afe4738, 0x17dbed2a764fa12a, 0x639b93f0321c8582}}, - {{0xc08f788f3f78d289, 0xfe30a72ca1404d9f, 0xf2778bfccf65cc9d, 0x7ee498165acb2021}}, - {{0x7bd508e39111a1c3, 0x2b2b90d480907489, 0xe7d2aec2ae72fd19, 0x0edf493c85b602a6}}}, -{{{0xaecc8158599b5a68, 0xea574f0febade20e, 0x4fe41d7422b67f07, 0x403b92e3019d4fb4}}, - {{0x6767c4d284764113, 0xa090403ff7f5f835, 0x1c8fcffacae6bede, 0x04c00c54d1dfa369}}, - {{0x4dc22f818b465cf8, 0x71a0f35a1480eff8, 0xaee8bfad04c7d657, 0x355bb12ab26176f4}}}, -{{{0xa71e64cc7493bbf4, 0xe5bd84d9eca3b0c3, 0x0a6bc50cfa05e785, 0x0f9b8132182ec312}}, - {{0xa301dac75a8c7318, 0xed90039db3ceaa11, 0x6f077cbf3bae3f2d, 0x7518eaf8e052ad8e}}, - {{0xa48859c41b7f6c32, 0x0f2d60bcf4383298, 0x1815a929c9b1d1d9, 0x47c3871bbb1755c4}}}, -{{{0x5144539771ec4f48, 0xf805b17dc98c5d6e, 0xf762c11a47c3c66b, 0x00b89b85764699dc}}, - {{0xfbe65d50c85066b0, 0x62ecc4b0b3a299b0, 0xe53754ea441ae8e0, 0x08fea02ce8d48d5f}}, - {{0x824ddd7668deead0, 0xc86445204b685d23, 0xb514cfcd5d89d665, 0x473829a74f75d537}}}, -{{{0x82d2da754679c418, 0xe63bd7d8b2618df0, 0x355eef24ac47eb0a, 0x2078684c4833c6b4}}, - {{0x23d9533aad3902c9, 0x64c2ddceef03588f, 0x15257390cfe12fb4, 0x6c668b4d44e4d390}}, - {{0x3b48cf217a78820c, 0xf76a0ab281273e97, 0xa96c65a78c8eed7b, 0x7411a6054f8a433f}}}, -{{{0x4d659d32b99dc86d, 0x044cdc75603af115, 0xb34c712cdcc2e488, 0x7c136574fb8134ff}}, - {{0x579ae53d18b175b4, 0x68713159f392a102, 0x8455ecba1eef35f5, 0x1ec9a872458c398f}}, - {{0xb8e6a4d400a2509b, 0x9b81d7020bc882b4, 0x57e7cc9bf1957561, 0x3add88a5c7cd6460}}}, -{{{0xab895770b635dcf2, 0x02dfef6cf66c1fbc, 0x85530268beb6d187, 0x249929fccc879e74}}, - {{0x85c298d459393046, 0x8f7e35985ff659ec, 0x1d2ca22af2f66e3a, 0x61ba1131a406a720}}, - {{0xa3d0a0f116959029, 0x023b6b6cba7ebd89, 0x7bf15a3e26783307, 0x5620310cbbd8ece7}}}, -{{{0x528993434934d643, 0xb9dbf806a51222f5, 0x8f6d878fc3f41c22, 0x37676a2a4d9d9730}}, - {{0x6646b5f477e285d6, 0x40e8ff676c8f6193, 0xa6ec7311abb594dd, 0x7ec846f3658cec4d}}, - {{0x9b5e8f3f1da22ec7, 0x130f1d776c01cd13, 0x214c8fcfa2989fb8, 0x6daaf723399b9dd5}}}, -{{{0x5f3a7562eb3dbe47, 0xf7ea38548ebda0b8, 0x00c3e53145747299, 0x1304e9e71627d551}}, - {{0x583b04bfacad8ea2, 0x29b743e8148be884, 0x2b1e583b0810c5db, 0x2b5449e58eb3bbaa}}, - {{0x789814d26adc9cfe, 0x3c1bab3f8b48dd0b, 0xda0fe1fff979c60a, 0x4468de2d7c2dd693}}}, -{{{0x51bb355e9419469e, 0x33e6dc4c23ddc754, 0x93a5b6d6447f9962, 0x6cce7c6ffb44bd63}}, - {{0x4b9ad8c6f86307ce, 0x21113531435d0c28, 0xd4a866c5657a772c, 0x5da6427e63247352}}, - {{0x1a94c688deac22ca, 0xb9066ef7bbae1ff8, 0x88ad8c388d59580f, 0x58f29abfe79f2ca8}}}, -{{{0xe90ecfab8de73e68, 0x54036f9f377e76a5, 0xf0495b0bbe015982, 0x577629c4a7f41e36}}, - {{0x4b5a64bf710ecdf6, 0xb14ce538462c293c, 0x3643d056d50b3ab9, 0x6af93724185b4870}}, - {{0x3220024509c6a888, 0xd2e036134b558973, 0x83e236233c33289f, 0x701f25bb0caec18f}}}, -{{{0xc3a8b0f8e4616ced, 0xf700660e9e25a87d, 0x61e3061ff4bca59c, 0x2e0c92bfbdc40be9}}, - {{0x9d18f6d97cbec113, 0x844a06e674bfdbe4, 0x20f5b522ac4e60d6, 0x720a5bc050955e51}}, - {{0x0c3f09439b805a35, 0xe84e8b376242abfc, 0x691417f35c229346, 0x0e9b9cbb144ef0ec}}}, -{{{0xfbbad48ffb5720ad, 0xee81916bdbf90d0e, 0xd4813152635543bf, 0x221104eb3f337bd8}}, - {{0x8dee9bd55db1beee, 0xc9c3ab370a723fb9, 0x44a8f1bf1c68d791, 0x366d44191cfd3cde}}, - {{0x9e3c1743f2bc8c14, 0x2eda26fcb5856c3b, 0xccb82f0e68a7fb97, 0x4167a4e6bc593244}}}, -{{{0x643b9d2876f62700, 0x5d1d9d400e7668eb, 0x1b4b430321fc0684, 0x7938bb7e2255246a}}, - {{0xc2be2665f8ce8fee, 0xe967ff14e880d62c, 0xf12e6e7e2f364eee, 0x34b33370cb7ed2f6}}, - {{0xcdc591ee8681d6cc, 0xce02109ced85a753, 0xed7485c158808883, 0x1176fc6e2dfe65e4}}}, -{{{0xb4af6cd05b9c619b, 0x2ddfc9f4b2a58480, 0x3d4fa502ebe94dc4, 0x08fc3a4c677d5f34}}, - {{0xdb90e28949770eb8, 0x98fbcc2aacf440a3, 0x21354ffeded7879b, 0x1f6a3e54f26906b6}}, - {{0x60a4c199d30734ea, 0x40c085b631165cd6, 0xe2333e23f7598295, 0x4f2fad0116b900d1}}}, -{{{0x44beb24194ae4e54, 0x5f541c511857ef6c, 0xa61e6b2d368d0498, 0x445484a4972ef7ab}}, - {{0x962cd91db73bb638, 0xe60577aafc129c08, 0x6f619b39f3b61689, 0x3451995f2944ee81}}, - {{0x9152fcd09fea7d7c, 0x4a816c94b0935cf6, 0x258e9aaa47285c40, 0x10b89ca6042893b7}}}, -{{{0x3d5947499718289c, 0x12ebf8c524533f26, 0x0262bfcb14c3ef15, 0x20b878d577b7518e}}, - {{0x753941be5a45f06e, 0xd07caeed6d9c5f65, 0x11776b9c72ff51b6, 0x17d2d1d9ef0d4da9}}, - {{0x27f2af18073f3e6a, 0xfd3fe519d7521069, 0x22e3b72c3ca60022, 0x72214f63cc65c6a7}}}, -{{{0xb4e37f405307a693, 0xaba714d72f336795, 0xd6fbd0a773761099, 0x5fdf48c58171cbc9}}, - {{0x1d9db7b9f43b29c9, 0xd605824a4f518f75, 0xf2c072bd312f9dc4, 0x1f24ac855a1545b0}}, - {{0x24d608328e9505aa, 0x4748c1d10c1420ee, 0xc7ffe45c06fb25a2, 0x00ba739e2ae395e6}}}, -{{{0x592e98de5c8790d6, 0xe5bfb7d345c2a2df, 0x115a3b60f9b49922, 0x03283a3e67ad78f3}}, - {{0xae4426f5ea88bb26, 0x360679d984973bfb, 0x5c9f030c26694e50, 0x72297de7d518d226}}, - {{0x48241dc7be0cb939, 0x32f19b4d8b633080, 0xd3dfc90d02289308, 0x05e1296846271945}}}, -{{{0xba82eeb32d9c495a, 0xceefc8fcf12bb97c, 0xb02dabae93b5d1e0, 0x39c00c9c13698d9b}}, - {{0xadbfbbc8242c4550, 0xbcc80cecd03081d9, 0x843566a6f5c8df92, 0x78cf25d38258ce4c}}, - {{0x15ae6b8e31489d68, 0xaa851cab9c2bf087, 0xc9a75a97f04efa05, 0x006b52076b3ff832}}}, -{{{0x29e0cfe19d95781c, 0xb681df18966310e2, 0x57df39d370516b39, 0x4d57e3443bc76122}}, - {{0xf5cb7e16b9ce082d, 0x3407f14c417abc29, 0xd4b36bce2bf4a7ab, 0x7de2e9561a9f75ce}}, - {{0xde70d4f4b6a55ecb, 0x4801527f5d85db99, 0xdbc9c440d3ee9a81, 0x6b2a90af1a6029ed}}}, -{{{0x6923f4fc9ae61e97, 0x5735281de03f5fd1, 0xa764ae43e6edd12d, 0x5fd8f4e9d12d3e4a}}, - {{0x77ebf3245bb2d80a, 0xd8301b472fb9079b, 0xc647e6f24cee7333, 0x465812c8276c2109}}, - {{0x4d43beb22a1062d9, 0x7065fb753831dc16, 0x180d4a7bde2968d7, 0x05b32c2b1cb16790}}}, -{{{0xc8c05eccd24da8fd, 0xa1cf1aac05dfef83, 0xdbbeeff27df9cd61, 0x3b5556a37b471e99}}, - {{0xf7fca42c7ad58195, 0x3214286e4333f3cc, 0xb6c29d0d340b979d, 0x31771a48567307e1}}, - {{0x32b0c524e14dd482, 0xedb351541a2ba4b6, 0xa3d16048282b5af3, 0x4fc079d27a7336eb}}}, -{{{0x51c938b089bf2f7f, 0x2497bd6502dfe9a7, 0xffffc09c7880e453, 0x124567cecaf98e92}}, - {{0xdc348b440c86c50d, 0x1337cbc9cc94e651, 0x6422f74d643e3cb9, 0x241170c2bae3cd08}}, - {{0x3ff9ab860ac473b4, 0xf0911dee0113e435, 0x4ae75060ebc6c4af, 0x3f8612966c87000d}}}, -{{{0x559a0cc9782a0dde, 0x551dcdb2ea718385, 0x7f62865b31ef238c, 0x504aa7767973613d}}, - {{0x9c18fcfa36048d13, 0x29159db373899ddd, 0xdc9f350b9f92d0aa, 0x26f57eee878a19d4}}, - {{0x0cab2cd55687efb1, 0x5180d162247af17b, 0x85c15a344f5a2467, 0x4041943d9dba3069}}}, -{{{0xc3c0eeba43ebcc96, 0x8d749c9c26ea9caf, 0xd9fa95ee1c77ccc6, 0x1420a1d97684340f}}, - {{0x4b217743a26caadd, 0x47a6b424648ab7ce, 0xcb1d4f7a03fbc9e3, 0x12d931429800d019}}, - {{0x00c67799d337594f, 0x5e3c5140b23aa47b, 0x44182854e35ff395, 0x1b4f92314359a012}}}, -{{{0x3e5c109d89150951, 0x39cefa912de9696a, 0x20eae43f975f3020, 0x239b572a7f132dae}}, - {{0x33cf3030a49866b1, 0x251f73d2215f4859, 0xab82aa4051def4f6, 0x5ff191d56f9a23f6}}, - {{0x819ed433ac2d9068, 0x2883ab795fc98523, 0xef4572805593eb3d, 0x020c526a758f36cb}}}, -{{{0x779834f89ed8dbbc, 0xc8f2aaf9dc7ca46c, 0xa9524cdca3e1b074, 0x02aacc4615313877}}, - {{0xe931ef59f042cc89, 0x2c589c9d8e124bb6, 0xadc8e18aaec75997, 0x452cfe0a5602c50c}}, - {{0x86a0f7a0647877df, 0xbbc464270e607c9f, 0xab17ea25f1fb11c9, 0x4cfb7d7b304b877b}}}, -{{{0x72b43d6cb89b75fe, 0x54c694d99c6adc80, 0xb8c3aa373ee34c9f, 0x14b4622b39075364}}, - {{0xe28699c29789ef12, 0x2b6ecd71df57190d, 0xc343c857ecc970d0, 0x5b1d4cbc434d3ac5}}, - {{0xb6fb2615cc0a9f26, 0x3a4f0e2bb88dcce5, 0x1301498b3369a705, 0x2f98f71258592dd1}}}, -{{{0x0c94a74cb50f9e56, 0x5b1ff4a98e8e1320, 0x9a2acc2182300f67, 0x3a6ae249d806aaf9}}, - {{0x2e12ae444f54a701, 0xfcfe3ef0a9cbd7de, 0xcebf890d75835de0, 0x1d8062e9e7614554}}, - {{0x657ada85a9907c5a, 0x1a0ea8b591b90f62, 0x8d0e1dfbdf34b4e9, 0x298b8ce8aef25ff3}}}, -{{{0x2a927953eff70cb2, 0x4b89c92a79157076, 0x9418457a30a7cf6a, 0x34b8a8404d5ce485}}, - {{0x837a72ea0a2165de, 0x3fab07b40bcf79f6, 0x521636c77738ae70, 0x6ba6271803a7d7dc}}, - {{0xc26eecb583693335, 0xd5a813df63b5fefd, 0xa293aa9aa4b22573, 0x71d62bdd465e1c6a}}}, -{{{0x6533cc28d378df80, 0xf6db43790a0fa4b4, 0xe3645ff9f701da5a, 0x74d5f317f3172ba4}}, - {{0xcd2db5dab1f75ef5, 0xd77f95cf16b065f5, 0x14571fea3f49f085, 0x1c333621262b2b3d}}, - {{0xa86fe55467d9ca81, 0x398b7c752b298c37, 0xda6d0892e3ac623b, 0x4aebcc4547e9d98c}}}, -{{{0x12f0071b276d01c9, 0xe7b8bac586c48c70, 0x5308129b71d6fba9, 0x5d88fbf95a3db792}}, - {{0x0b408d9e7354b610, 0x806b32535ba85b6e, 0xdbe63a034a58a207, 0x173bd9ddc9a1df2c}}, - {{0x2b500f1efe5872df, 0x58d6582ed43918c1, 0xe6ed278ec9673ae0, 0x06e1cd13b19ea319}}}, -{{{0x40d0ad516f166f23, 0x118e32931fab6abe, 0x3fe35e14a04d088e, 0x3080603526e16266}}, - {{0x472baf629e5b0353, 0x3baa0b90278d0447, 0x0c785f469643bf27, 0x7f3a6a1a8d837b13}}, - {{0xf7e644395d3d800b, 0x95a8d555c901edf6, 0x68cd7830592c6339, 0x30d0fded2e51307e}}}, -{{{0xe0594d1af21233b3, 0x1bdbe78ef0cc4d9c, 0x6965187f8f499a77, 0x0a9214202c099868}}, - {{0x9cb4971e68b84750, 0xa09572296664bbcf, 0x5c8de72672fa412b, 0x4615084351c589d9}}, - {{0xbc9019c0aeb9a02e, 0x55c7110d16034cae, 0x0e6df501659932ec, 0x3bca0d2895ca5dfe}}}, -{{{0x40f031bc3c5d62a4, 0x19fc8b3ecff07a60, 0x98183da2130fb545, 0x5631deddae8f13cd}}, - {{0x9c688eb69ecc01bf, 0xf0bc83ada644896f, 0xca2d955f5f7a9fe2, 0x4ea8b4038df28241}}, - {{0x2aed460af1cad202, 0x46305305a48cee83, 0x9121774549f11a5f, 0x24ce0930542ca463}}}, -{{{0x1fe890f5fd06c106, 0xb5c468355d8810f2, 0x827808fe6e8caf3e, 0x41d4e3c28a06d74b}}, - {{0x3fcfa155fdf30b85, 0xd2f7168e36372ea4, 0xb2e064de6492f844, 0x549928a7324f4280}}, - {{0xf26e32a763ee1a2e, 0xae91e4b7d25ffdea, 0xbc3bd33bd17f4d69, 0x491b66dec0dcff6a}}}, -{{{0x98f5b13dc7ea32a7, 0xe3d5f8cc7e16db98, 0xac0abf52cbf8d947, 0x08f338d0c85ee4ac}}, - {{0x75f04a8ed0da64a1, 0xed222caf67e2284b, 0x8234a3791f7b7ba4, 0x4cf6b8b0b7018b67}}, - {{0xc383a821991a73bd, 0xab27bc01df320c7a, 0xc13d331b84777063, 0x530d4a82eb078a99}}}, -{{{0x004c3630e1f94825, 0x7e2d78268cab535a, 0xc7482323cc84ff8b, 0x65ea753f101770b9}}, - {{0x6d6973456c9abf9e, 0x257fb2fc4900a880, 0x2bacf412c8cfb850, 0x0db3e7e00cbfbd5b}}, - {{0x3d66fc3ee2096363, 0x81d62c7f61b5cb6b, 0x0fbe044213443b1a, 0x02a4ec1921e1a1db}}}, -{{{0x5ce6259a3b24b8a2, 0xb8577acc45afa0b8, 0xcccbe6e88ba07037, 0x3d143c51127809bf}}, - {{0xf5c86162f1cf795f, 0x118c861926ee57f2, 0x172124851c063578, 0x36d12b5dec067fcf}}, - {{0x126d279179154557, 0xd5e48f5cfc783a0a, 0x36bdb6e8df179bac, 0x2ef517885ba82859}}}, -{{{0x4637974e8c58aedc, 0xb9ef22fbabf041a4, 0xe185d956e980718a, 0x2f1b78fab143a8a6}}, - {{0x96eebffb305b2f51, 0xd3f938ad889596b8, 0xf0f52dc746d5dd25, 0x57968290bb3a0095}}, - {{0xf71ab8430a20e101, 0xf393658d24f0ec47, 0xcf7509a86ee2eed1, 0x7dc43e35dc2aa3e1}}}, -{{{0x85966665887dd9c3, 0xc90f9b314bb05355, 0xc6e08df8ef2079b1, 0x7ef72016758cc12f}}, - {{0x5a782a5c273e9718, 0x3576c6995e4efd94, 0x0f2ed8051f237d3e, 0x044fb81d82d50a99}}, - {{0xc1df18c5a907e3d9, 0x57b3371dce4c6359, 0xca704534b201bb49, 0x7f79823f9c30dd2e}}}, -{{{0x8334d239a3b513e8, 0xc13670d4b91fa8d8, 0x12b54136f590bd33, 0x0a4e0373d784d9b4}}, - {{0x6a9c1ff068f587ba, 0x0827894e0050c8de, 0x3cbf99557ded5be7, 0x64a9b0431c06d6f0}}, - {{0x2eb3d6a15b7d2919, 0xb0b4f6a0d53a8235, 0x7156ce4389a45d47, 0x071a7d0ace18346c}}}, -{{{0xd3072daac887ba0b, 0x01262905bfa562ee, 0xcf543002c0ef768b, 0x2c3bcc7146ea7e9c}}, - {{0xcc0c355220e14431, 0x0d65950709b15141, 0x9af5621b209d5f36, 0x7c69bcf7617755d3}}, - {{0x07f0d7eb04e8295f, 0x10db18252f50f37d, 0xe951a9a3171798d7, 0x6f5a9a7322aca51d}}}, -{{{0x8ba1000c2f41c6c5, 0xc49f79c10cfefb9b, 0x4efa47703cc51c9f, 0x494e21a2e147afca}}, - {{0xe729d4eba3d944be, 0x8d9e09408078af9e, 0x4525567a47869c03, 0x02ab9680ee8d3b24}}, - {{0xefa48a85dde50d9a, 0x219a224e0fb9a249, 0xfa091f1dd91ef6d9, 0x6b5d76cbea46bb34}}}, -{{{0x8857556cec0cd994, 0x6472dc6f5cd01dba, 0xaf0169148f42b477, 0x0ae333f685277354}}, - {{0xe0f941171e782522, 0xf1e6ae74036936d3, 0x408b3ea2d0fcc746, 0x16fb869c03dd313e}}, - {{0x288e199733b60962, 0x24fc72b4d8abe133, 0x4811f7ed0991d03e, 0x3f81e38b8f70d075}}}, -{{{0x7f910fcc7ed9affe, 0x545cb8a12465874b, 0xa8397ed24b0c4704, 0x50510fc104f50993}}, - {{0x0adb7f355f17c824, 0x74b923c3d74299a4, 0xd57c3e8bcbf8eaf7, 0x0ad3e2d34cdedc3d}}, - {{0x6f0c0fc5336e249d, 0x745ede19c331cfd9, 0xf2d6fd0009eefe1c, 0x127c158bf0fa1ebe}}}, -{{{0xf6197c422e9879a2, 0xa44addd452ca3647, 0x9b413fc14b4eaccb, 0x354ef87d07ef4f68}}, - {{0xdea28fc4ae51b974, 0x1d9973d3744dfe96, 0x6240680b873848a8, 0x4ed82479d167df95}}, - {{0xfee3b52260c5d975, 0x50352efceb41b0b8, 0x8808ac30a9f6653c, 0x302d92d20539236d}}}, -{{{0x7813c1a2bca4283d, 0xed62f091a1863dd9, 0xaec7bcb8c268fa86, 0x10e5d3b76f1cae4c}}, - {{0x2dbc6fb6e4e0f177, 0x04e1bf29a4bd6a93, 0x5e1966d4787af6e8, 0x0edc5f5eb426d060}}, - {{0x5453bfd653da8e67, 0xe9dc1eec24a9f641, 0xbf87263b03578a23, 0x45b46c51361cba72}}}, -{{{0xa9402abf314f7fa1, 0xe257f1dc8e8cf450, 0x1dbbd54b23a8be84, 0x2177bfa36dcb713b}}, - {{0xce9d4ddd8a7fe3e4, 0xab13645676620e30, 0x4b594f7bb30e9958, 0x5c1c0aef321229df}}, - {{0x37081bbcfa79db8f, 0x6048811ec25f59b3, 0x087a76659c832487, 0x4ae619387d8ab5bb}}}, -{{{0x8ddbf6aa5344a32e, 0x7d88eab4b41b4078, 0x5eb0eb974a130d60, 0x1a00d91b17bf3e03}}, - {{0x61117e44985bfb83, 0xfce0462a71963136, 0x83ac3448d425904b, 0x75685abe5ba43d64}}, - {{0x6e960933eb61f2b2, 0x543d0fa8c9ff4952, 0xdf7275107af66569, 0x135529b623b0e6aa}}}, -{{{0x18f0dbd7add1d518, 0x979f7888cfc11f11, 0x8732e1f07114759b, 0x79b5b81a65ca3a01}}, - {{0xf5c716bce22e83fe, 0xb42beb19e80985c1, 0xec9da63714254aae, 0x5972ea051590a613}}, - {{0x0fd4ac20dc8f7811, 0x9a9ad294ac4d4fa8, 0xc01b2d64b3360434, 0x4f7e9c95905f3bdb}}}, -{{{0x62674bbc5781302e, 0xd8520f3989addc0f, 0x8c2999ae53fbd9c6, 0x31993ad92e638e4c}}, - {{0x71c8443d355299fe, 0x8bcd3b1cdbebead7, 0x8092499ef1a49466, 0x1942eec4a144adc8}}, - {{0x7dac5319ae234992, 0x2c1b3d910cea3e92, 0x553ce494253c1122, 0x2a0a65314ef9ca75}}}, -{{{0x2db7937ff7f927c2, 0xdb741f0617d0a635, 0x5982f3a21155af76, 0x4cf6e218647c2ded}}, - {{0xcf361acd3c1c793a, 0x2f9ebcac5a35bc3b, 0x60e860e9a8cda6ab, 0x055dc39b6dea1a13}}, - {{0xb119227cc28d5bb6, 0x07e24ebc774dffab, 0xa83c78cee4a32c89, 0x121a307710aa24b6}}}, -{{{0xe4db5d5e9f034a97, 0xe153fc093034bc2d, 0x460546919551d3b1, 0x333fc76c7a40e52d}}, - {{0xd659713ec77483c9, 0x88bfe077b82b96af, 0x289e28231097bcd3, 0x527bb94a6ced3a9b}}, - {{0x563d992a995b482e, 0x3405d07c6e383801, 0x485035de2f64d8e5, 0x6b89069b20a7a9f7}}}, -{{{0x812aa0416270220d, 0x995a89faf9245b4e, 0xffadc4ce5072ef05, 0x23bc2103aa73eb73}}, - {{0x4082fa8cb5c7db77, 0x068686f8c734c155, 0x29e6c8d9f6e7a57e, 0x0473d308a7639bcf}}, - {{0xcaee792603589e05, 0x2b4b421246dcc492, 0x02a1ef74e601a94f, 0x102f73bfde04341a}}}, -{{{0xeb18b9ab7f5745c6, 0x023a8aee5787c690, 0xb72712da2df7afa9, 0x36597d25ea5c013d}}, - {{0xa2b4dae0b5511c9a, 0x7ac860292bffff06, 0x981f375df5504234, 0x3f6bd725da4ea12d}}, - {{0x734d8d7b106058ac, 0xd940579e6fc6905f, 0x6466f8f99202932d, 0x7b7ecc19da60d6d0}}}, -{{{0x78c2373c695c690d, 0xdd252e660642906e, 0x951d44444ae12bd2, 0x4235ad7601743956}}, - {{0x6dae4a51a77cfa9b, 0x82263654e7a38650, 0x09bbffcd8f2d82db, 0x03bedc661bf5caba}}, - {{0x6258cb0d078975f5, 0x492942549189f298, 0xa0cab423e2e36ee4, 0x0e7ce2b0cdf066a1}}}, -{{{0xc494643ac48c85a3, 0xfd361df43c6139ad, 0x09db17dd3ae94d48, 0x666e0a5d8fb4674a}}, - {{0xfea6fedfd94b70f9, 0xf130c051c1fcba2d, 0x4882d47e7f2fab89, 0x615256138aeceeb5}}, - {{0x2abbf64e4870cb0d, 0xcd65bcf0aa458b6b, 0x9abe4eba75e8985d, 0x7f0bc810d514dee4}}}, -{{{0xb9006ba426f4136f, 0x8d67369e57e03035, 0xcbc8dfd94f463c28, 0x0d1f8dbcf8eedbf5}}, - {{0x83ac9dad737213a0, 0x9ff6f8ba2ef72e98, 0x311e2edd43ec6957, 0x1d3a907ddec5ab75}}, - {{0xba1693313ed081dc, 0x29329fad851b3480, 0x0128013c030321cb, 0x00011b44a31bfde3}}}, -{{{0x3fdfa06c3fc66c0c, 0x5d40e38e4dd60dd2, 0x7ae38b38268e4d71, 0x3ac48d916e8357e1}}, - {{0x16561f696a0aa75c, 0xc1bf725c5852bd6a, 0x11a8dd7f9a7966ad, 0x63d988a2d2851026}}, - {{0x00120753afbd232e, 0xe92bceb8fdd8f683, 0xf81669b384e72b91, 0x33fad52b2368a066}}}, -{{{0x540649c6c5e41e16, 0x0af86430333f7735, 0xb2acfcd2f305e746, 0x16c0f429a256dca7}}, - {{0x8d2cc8d0c422cfe8, 0x072b4f7b05a13acb, 0xa3feb6e6ecf6a56f, 0x3cc355ccb90a71e2}}, - {{0xe9b69443903e9131, 0xb8a494cb7a5637ce, 0xc87cd1a4baba9244, 0x631eaf426bae7568}}}, -{{{0xb3e90410da66fe9f, 0x85dd4b526c16e5a6, 0xbc3d97611ef9bf83, 0x5599648b1ea919b5}}, - {{0x47d975b9a3700de8, 0x7280c5fbe2f80552, 0x53658f2732e45de1, 0x431f2c7f665f80b5}}, - {{0xd6026344858f7b19, 0x14ab352fa1ea514a, 0x8900441a2090a9d7, 0x7b04715f91253b26}}}, -{{{0x83edbd28acf6ae43, 0x86357c8b7d5c7ab4, 0xc0404769b7eb2c44, 0x59b37bf5c2f6583f}}, - {{0xb376c280c4e6bac6, 0x970ed3dd6d1d9b0b, 0xb09a9558450bf944, 0x48d0acfa57cde223}}, - {{0xb60f26e47dabe671, 0xf1d1a197622f3a37, 0x4208ce7ee9960394, 0x16234191336d3bdb}}}, -{{{0xb9e499def6267ff6, 0x7772ca7b742c0843, 0x23a0153fe9a4f2b1, 0x2cdfdfecd5d05006}}, - {{0xdd499cd61ff38640, 0x29cd9bc3063625a0, 0x51e2d8023dd73dc3, 0x4a25707a203b9231}}, - {{0x2ab7668a53f6ed6a, 0x304242581dd170a1, 0x4000144c3ae20161, 0x5721896d248e49fc}}}, -{{{0x0b6e5517fd181bae, 0x9022629f2bb963b4, 0x5509bce932064625, 0x578edd74f63c13da}}, - {{0x285d5091a1d0da4e, 0x4baa6fa7b5fe3e08, 0x63e5177ce19393b3, 0x03c935afc4b030fd}}, - {{0x997276c6492b0c3d, 0x47ccc2c4dfe205fc, 0xdcd29b84dd623a3c, 0x3ec2ab590288c7a2}}}, -{{{0xa1a0d27be4d87bb9, 0xa98b4deb61391aed, 0x99a0ddd073cb9b83, 0x2dd5c25a200fcace}}, - {{0xa7213a09ae32d1cb, 0x0f2b87df40f5c2d5, 0x0baea4c6e81eab29, 0x0e1bf66c6adbac5e}}, - {{0xe2abd5e9792c887e, 0x1a020018cb926d5d, 0xbfba69cdbaae5f1e, 0x730548b35ae88f5f}}}, -{{{0xc43551a3cba8b8ee, 0x65a26f1db2115f16, 0x760f4f52ab8c3850, 0x3043443b411db8ca}}, - {{0x805b094ba1d6e334, 0xbf3ef17709353f19, 0x423f06cb0622702b, 0x585a2277d87845dd}}, - {{0xa18a5f8233d48962, 0x6698c4b5ec78257f, 0xa78e6fa5373e41ff, 0x7656278950ef981f}}}, -{{{0x38c3cf59d51fc8c0, 0x9bedd2fd0506b6f2, 0x26bf109fab570e8f, 0x3f4160a8c1b846a6}}, - {{0xe17073a3ea86cf9d, 0x3a8cfbb707155fdc, 0x4853e7fc31838a8e, 0x28bbf484b613f616}}, - {{0xf2612f5c6f136c7c, 0xafead107f6dd11be, 0x527e9ad213de6f33, 0x1e79cb358188f75d}}}, -{{{0x013436c3eef7e3f1, 0x828b6a7ffe9e10f8, 0x7ff908e5bcf9defc, 0x65d7951b3a3b3831}}, - {{0x77e953d8f5e08181, 0x84a50c44299dded9, 0xdc6c2d0c864525e5, 0x478ab52d39d1f2f4}}, - {{0x66a6a4d39252d159, 0xe5dde1bc871ac807, 0xb82c6b40a6c1c96f, 0x16d87a411a212214}}}, -{{{0xb3bd7e5a42066215, 0x879be3cd0c5a24c1, 0x57c05db1d6f994b7, 0x28f87c8165f38ca6}}, - {{0xfba4d5e2d54e0583, 0xe21fafd72ebd99fa, 0x497ac2736ee9778f, 0x1f990b577a5a6dde}}, - {{0xa3344ead1be8f7d6, 0x7d1e50ebacea798f, 0x77c6569e520de052, 0x45882fe1534d6d3e}}}, -{{{0x6669345d757983d6, 0x62b6ed1117aa11a6, 0x7ddd1857985e128f, 0x688fe5b8f626f6dd}}, - {{0xd8ac9929943c6fe4, 0xb5f9f161a38392a2, 0x2699db13bec89af3, 0x7dcf843ce405f074}}, - {{0x6c90d6484a4732c0, 0xd52143fdca563299, 0xb3be28c3915dc6e1, 0x6739687e7327191b}}}, -{{{0xef782014385675a6, 0xa2649f30aafda9e8, 0x4cd1eb505cdfa8cb, 0x46115aba1d4dc0b3}}, - {{0xa66dcc9dc80c1ac0, 0x97a05cf41b38a436, 0xa7ebf3be95dbd7c6, 0x7da0b8f68d7e7dab}}, - {{0xd40f1953c3b5da76, 0x1dac6f7321119e9b, 0x03cc6021feb25960, 0x5a5f887e83674b4b}}}, -{{{0x8f6301cf70a13d11, 0xcfceb815350dd0c4, 0xf70297d4a4bca47e, 0x3669b656e44d1434}}, - {{0x9e9628d3a0a643b9, 0xb5c3cb00e6c32064, 0x9b5302897c2dec32, 0x43e37ae2d5d1c70c}}, - {{0x387e3f06eda6e133, 0x67301d5199a13ac0, 0xbd5ad8f836263811, 0x6a21e6cd4fd5e9be}}}, -{{{0xf1c6170a3046e65f, 0x58712a2a00d23524, 0x69dbbd3c8c82b755, 0x586bf9f1a195ff57}}, - {{0xef4129126699b2e3, 0x71d30847708d1301, 0x325432d01182b0bd, 0x45371b07001e8b36}}, - {{0xa6db088d5ef8790b, 0x5278f0dc610937e5, 0xac0349d261a16eb8, 0x0eafb03790e52179}}}, -{{{0x960555c13748042f, 0x219a41e6820baa11, 0x1c81f73873486d0c, 0x309acc675a02c661}}, - {{0x5140805e0f75ae1d, 0xec02fbe32662cc30, 0x2cebdf1eea92396d, 0x44ae3344c5435bb3}}, - {{0x9cf289b9bba543ee, 0xf3760e9d5ac97142, 0x1d82e5c64f9360aa, 0x62d5221b7f94678f}}}, -{{{0x524c299c18d0936d, 0xc86bb56c8a0c1a0c, 0xa375052edb4a8631, 0x5c0efde4bc754562}}, - {{0x7585d4263af77a3c, 0xdfae7b11fee9144d, 0xa506708059f7193d, 0x14f29a5383922037}}, - {{0xdf717edc25b2d7f5, 0x21f970db99b53040, 0xda9234b7c3ed4c62, 0x5e72365c7bee093e}}}, -{{{0x575bfc074571217f, 0x3779675d0694d95b, 0x9a0a37bbf4191e33, 0x77f1104c47b4eabc}}, - {{0x7d9339062f08b33e, 0x5b9659e5df9f32be, 0xacff3dad1f9ebdfd, 0x70b20555cb7349b7}}, - {{0xbe5113c555112c4c, 0x6688423a9a881fcd, 0x446677855e503b47, 0x0e34398f4a06404a}}}, -{{{0xb67d22d93ecebde8, 0x09b3e84127822f07, 0x743fa61fb05b6d8d, 0x5e5405368a362372}}, - {{0x18930b093e4b1928, 0x7de3e10e73f3f640, 0xf43217da73395d6f, 0x6f8aded6ca379c3e}}, - {{0xe340123dfdb7b29a, 0x487b97e1a21ab291, 0xf9967d02fde6949e, 0x780de72ec8d3de97}}}, -{{{0x0ae28545089ae7bc, 0x388ddecf1c7f4d06, 0x38ac15510a4811b8, 0x0eb28bf671928ce4}}, - {{0x671feaf300f42772, 0x8f72eb2a2a8c41aa, 0x29a17fd797373292, 0x1defc6ad32b587a6}}, - {{0xaf5bbe1aef5195a7, 0x148c1277917b15ed, 0x2991f7fb7ae5da2e, 0x467d201bf8dd2867}}}, -{{{0x95fe919a74ef4fad, 0x3a827becf6a308a2, 0x964e01d309a47b01, 0x71c43c4f5ba3c797}}, - {{0xbc1ef4bd567ae7a9, 0x3f624cb2d64498bd, 0xe41064d22c1f4ec8, 0x2ef9c5a5ba384001}}, - {{0xb6fd6df6fa9e74cd, 0xf18278bce4af267a, 0x8255b3d0f1ef990e, 0x5a758ca390c5f293}}}, -{{{0xa2b72710d9462495, 0x3aa8c6d2d57d5003, 0xe3d400bfa0b487ca, 0x2dbae244b3eb72ec}}, - {{0x8ce0918b1d61dc94, 0x8ded36469a813066, 0xd4e6a829afe8aad3, 0x0a738027f639d43f}}, - {{0x980f4a2f57ffe1cc, 0x00670d0de1839843, 0x105c3f4a49fb15fd, 0x2698ca635126a69c}}}, -{{{0xe765318832b0ba78, 0x381831f7925cff8b, 0x08a81b91a0291fcc, 0x1fb43dcc49caeb07}}, - {{0x2e3d702f5e3dd90e, 0x9e3f0918e4d25386, 0x5e773ef6024da96a, 0x3c004b0c4afa3332}}, - {{0x9aa946ac06f4b82b, 0x1ca284a5a806c4f3, 0x3ed3265fc6cd4787, 0x6b43fd01cd1fd217}}}, -{{{0xc7a75d4b4697c544, 0x15fdf848df0fffbf, 0x2868b9ebaa46785a, 0x5a68d7105b52f714}}, - {{0xb5c742583e760ef3, 0x75dc52b9ee0ab990, 0xbf1427c2072b923f, 0x73420b2d6ff0d9f0}}, - {{0xaf2cf6cb9e851e06, 0x8f593913c62238c4, 0xda8ab89699fbf373, 0x3db5632fea34bc9e}}}, -{{{0xf46eee2bf75dd9d8, 0x0d17b1f6396759a5, 0x1bf2d131499e7273, 0x04321adf49d75f13}}, - {{0x2e4990b1829825d5, 0xedeaeb873e9a8991, 0xeef03d394c704af8, 0x59197ea495df2b0e}}, - {{0x04e16019e4e55aae, 0xe77b437a7e2f92e9, 0xc7ce2dc16f159aa4, 0x45eafdc1f4d70cc0}}}, -{{{0x698401858045d72b, 0x4c22faa2cf2f0651, 0x941a36656b222dc6, 0x5a5eebc80362dade}}, - {{0xb60e4624cfccb1ed, 0x59dbc292bd5c0395, 0x31a09d1ddc0481c9, 0x3f73ceea5d56d940}}, - {{0xb7a7bfd10a4e8dc6, 0xbe57007e44c9b339, 0x60c1207f1557aefa, 0x26058891266218db}}}, -{{{0x59f704a68360ff04, 0xc3d93fde7661e6f4, 0x831b2a7312873551, 0x54ad0c2e4e615d57}}, - {{0x4c818e3cc676e542, 0x5e422c9303ceccad, 0xec07cccab4129f08, 0x0dedfa10b24443b8}}, - {{0xee3b67d5b82b522a, 0x36f163469fa5c1eb, 0xa5b4d2f26ec19fd3, 0x62ecb2baa77a9408}}}, -{{{0xe5ed795261152b3d, 0x4962357d0eddd7d1, 0x7482c8d0b96b4c71, 0x2e59f919a966d8be}}, - {{0x92072836afb62874, 0x5fcd5e8579e104a5, 0x5aad01adc630a14a, 0x61913d5075663f98}}, - {{0x0dc62d361a3231da, 0xfa47583294200270, 0x02d801513f9594ce, 0x3ddbc2a131c05d5c}}}, -{{{0x9adc0ff9ce5ec54b, 0x039c2a6b8c2f130d, 0x028007c7f0f89515, 0x78968314ac04b36b}}, - {{0xf3aa57a22796bb14, 0x883abab79b07da21, 0xe54be21831a0391c, 0x5ee7fb38d83205f9}}, - {{0x538dfdcb41446a8e, 0xa5acfda9434937f9, 0x46af908d263c8c78, 0x61d0633c9bca0d09}}}, -{{{0x63744935ffdb2566, 0xc5bd6b89780b68bb, 0x6f1b3280553eec03, 0x6e965fd847aed7f5}}, - {{0xada328bcf8fc73df, 0xee84695da6f037fc, 0x637fb4db38c2a909, 0x5b23ac2df8067bdc}}, - {{0x9ad2b953ee80527b, 0xe88f19aafade6d8d, 0x0e711704150e82cf, 0x79b9bbb9dd95dedc}}}, -{{{0xebb355406a3126c2, 0xd26383a868c8c393, 0x6c0c6429e5b97a82, 0x5065f158c9fd2147}}, - {{0xd1997dae8e9f7374, 0xa032a2f8cfbb0816, 0xcd6cba126d445f0a, 0x1ba811460accb834}}, - {{0x708169fb0c429954, 0xe14600acd76ecf67, 0x2eaab98a70e645ba, 0x3981f39e58a4faf2}}}, -{{{0x18fb8a7559230a93, 0x1d168f6960e6f45d, 0x3a85a94514a93cb5, 0x38dc083705acd0fd}}, - {{0xc845dfa56de66fde, 0xe152a5002c40483a, 0xe9d2e163c7b4f632, 0x30f4452edcbc1b65}}, - {{0x856d2782c5759740, 0xfa134569f99cbecc, 0x8844fc73c0ea4e71, 0x632d9a1a593f2469}}}, -{{{0xf6bb6b15b807cba6, 0x1823c7dfbc54f0d7, 0xbb1d97036e29670b, 0x0b24f48847ed4a57}}, - {{0xbf09fd11ed0c84a7, 0x63f071810d9f693a, 0x21908c2d57cf8779, 0x3a5a7df28af64ba2}}, - {{0xdcdad4be511beac7, 0xa4538075ed26ccf2, 0xe19cff9f005f9a65, 0x34fcf74475481f63}}}, -{{{0xc197e04c789767ca, 0xb8714dcb38d9467d, 0x55de888283f95fa8, 0x3d3bdc164dfa63f7}}, - {{0xa5bb1dab78cfaa98, 0x5ceda267190b72f2, 0x9309c9110a92608e, 0x0119a3042fb374b0}}, - {{0x67a2d89ce8c2177d, 0x669da5f66895d0c1, 0xf56598e5b282a2b0, 0x56c088f1ede20a73}}}, -{{{0x336d3d1110a86e17, 0xd7f388320b75b2fa, 0xf915337625072988, 0x09674c6b99108b87}}, - {{0x581b5fac24f38f02, 0xa90be9febae30cbd, 0x9a2169028acf92f0, 0x038b7ea48359038f}}, - {{0x9f4ef82199316ff8, 0x2f49d282eaa78d4f, 0x0971a5ab5aef3174, 0x6e5e31025969eb65}}}, -{{{0xb16c62f587e593fb, 0x4999eddeca5d3e71, 0xb491c1e014cc3e6d, 0x08f5114789a8dba8}}, - {{0x3304fb0e63066222, 0xfb35068987acba3f, 0xbd1924778c1061a3, 0x3058ad43d1838620}}, - {{0x323c0ffde57663d0, 0x05c3df38a22ea610, 0xbdc78abdac994f9a, 0x26549fa4efe3dc99}}}, -{{{0x741d5a461e6bf9d6, 0x2305b3fc7777a581, 0xd45574a26474d3d9, 0x1926e1dc6401e0ff}}, - {{0xdb468549af3f666e, 0xd77fcf04f14a0ea5, 0x3df23ff7a4ba0c47, 0x3a10dfe132ce3c85}}, - {{0xe07f4e8aea17cea0, 0x2fd515463a1fc1fd, 0x175322fd31f2c0f1, 0x1fa1d01d861e5d15}}}, -{{{0xcc8055947d599832, 0x1e4656da37f15520, 0x99f6f7744e059320, 0x773563bc6a75cf33}}, - {{0x38dcac00d1df94ab, 0x2e712bddd1080de9, 0x7f13e93efdd5e262, 0x73fced18ee9a01e5}}, - {{0x06b1e90863139cb3, 0xa493da67c5a03ecd, 0x8d77cec8ad638932, 0x1f426b701b864f44}}}, -{{{0xefc9264c41911c01, 0xf1a3b7b817a22c25, 0x5875da6bf30f1447, 0x4e1af5271d31b090}}, - {{0xf17e35c891a12552, 0xb76b8153575e9c76, 0xfa83406f0d9b723e, 0x0b76bb1b3fa7e438}}, - {{0x08b8c1f97f92939b, 0xbe6771cbd444ab6e, 0x22e5646399bb8017, 0x7b6dd61eb772a955}}}, -{{{0xb7adc1e850f33d92, 0x7998fa4f608cd5cf, 0xad962dbd8dfc5bdb, 0x703e9bceaf1d2f4f}}, - {{0x5730abf9ab01d2c7, 0x16fb76dc40143b18, 0x866cbe65a0cbb281, 0x53fa9b659bff6afe}}, - {{0x6c14c8e994885455, 0x843a5d6665aed4e5, 0x181bb73ebcd65af1, 0x398d93e5c4c61f50}}}, -{{{0x1c4bd16733e248f3, 0xbd9e128715bf0a5f, 0xd43f8cf0a10b0376, 0x53b09b5ddf191b13}}, - {{0xc3877c60d2e7e3f2, 0x3b34aaa030828bb1, 0x283e26e7739ef138, 0x699c9c9002c30577}}, - {{0xf306a7235946f1cc, 0x921718b5cce5d97d, 0x28cdd24781b4e975, 0x51caf30c6fcdd907}}}, -{{{0xa60ba7427674e00a, 0x630e8570a17a7bf3, 0x3758563dcf3324cc, 0x5504aa292383fdaa}}, - {{0x737af99a18ac54c7, 0x903378dcc51cb30f, 0x2b89bc334ce10cc7, 0x12ae29c189f8e99a}}, - {{0xa99ec0cb1f0d01cf, 0x0dd1efcc3a34f7ae, 0x55ca7521d09c4e22, 0x5fd14fe958eba5ea}}}, -{{{0xb5dc2ddf2845ab2c, 0x069491b10a7fe993, 0x4daaf3d64002e346, 0x093ff26e586474d1}}, - {{0x3c42fe5ebf93cb8e, 0xbedfa85136d4565f, 0xe0f0859e884220e8, 0x7dd73f960725d128}}, - {{0xb10d24fe68059829, 0x75730672dbaf23e5, 0x1367253ab457ac29, 0x2f59bcbc86b470a4}}}, -{{{0x83847d429917135f, 0xad1b911f567d03d7, 0x7e7748d9be77aad1, 0x5458b42e2e51af4a}}, - {{0x7041d560b691c301, 0x85201b3fadd7e71e, 0x16c2e16311335585, 0x2aa55e3d010828b1}}, - {{0xed5192e60c07444f, 0x42c54e2d74421d10, 0x352b4c82fdb5c864, 0x13e9004a8a768664}}}, -{{{0x739d8845832fcedb, 0xfa38d6c9ae6bf863, 0x32bc0dcab74ffef7, 0x73937e8814bce45e}}, - {{0xbb2e00c9193b877f, 0xece3a890e0dc506b, 0xecf3b7c036de649f, 0x5f46040898de9e1a}}, - {{0xb9037116297bf48d, 0xa9d13b22d4f06834, 0xe19715574696bdc6, 0x2cf8a4e891d5e835}}}, -{{{0x6d93fd8707110f67, 0xdd4c09d37c38b549, 0x7cb16a4cc2736a86, 0x2049bd6e58252a09}}, - {{0x2cb5487e17d06ba2, 0x24d2381c3950196b, 0xd7659c8185978a30, 0x7a6f7f2891d6a4f6}}, - {{0x7d09fd8d6a9aef49, 0xf0ee60be5b3db90b, 0x4c21b52c519ebfd4, 0x6011aadfc545941d}}}, -{{{0x5f67926dcf95f83c, 0x7c7e856171289071, 0xd6a1e7f3998f7a5b, 0x6fc5cc1b0b62f9e0}}, - {{0x63ded0c802cbf890, 0xfbd098ca0dff6aaa, 0x624d0afdb9b6ed99, 0x69ce18b779340b1e}}, - {{0xd1ef5528b29879cb, 0xdd1aae3cd47e9092, 0x127e0442189f2352, 0x15596b3ae57101f1}}}, -{{{0x462739d23f9179a2, 0xff83123197d6ddcf, 0x1307deb553f2148a, 0x0d2237687b5f4dda}}, - {{0x09ff31167e5124ca, 0x0be4158bd9c745df, 0x292b7d227ef556e5, 0x3aa4e241afb6d138}}, - {{0x2cc138bf2a3305f5, 0x48583f8fa2e926c3, 0x083ab1a25549d2eb, 0x32fcaa6e4687a36c}}}, -{{{0x7bc56e8dc57d9af5, 0x3e0bd2ed9df0bdf2, 0xaac014de22efe4a3, 0x4627e9cefebd6a5c}}, - {{0x3207a4732787ccdf, 0x17e31908f213e3f8, 0xd5b2ecd7f60d964e, 0x746f6336c2600be9}}, - {{0x3f4af345ab6c971c, 0xe288eb729943731f, 0x33596a8a0344186d, 0x7b4917007ed66293}}}, -{{{0x2d85fb5cab84b064, 0x497810d289f3bc14, 0x476adc447b15ce0c, 0x122ba376f844fd7b}}, - {{0x54341b28dd53a2dd, 0xaa17905bdf42fc3f, 0x0ff592d94dd2f8f4, 0x1d03620fe08cd37d}}, - {{0xc20232cda2b4e554, 0x9ed0fd42115d187f, 0x2eabb4be7dd479d9, 0x02c70bf52b68ec4c}}}, -{{{0xa287ec4b5d0b2fbb, 0x415c5790074882ca, 0xe044a61ec1d0815c, 0x26334f0a409ef5e0}}, - {{0xace532bf458d72e1, 0x5be768e07cb73cb5, 0x56cf7d94ee8bbde7, 0x6b0697e3feb43a03}}, - {{0xb6c8f04adf62a3c0, 0x3ef000ef076da45d, 0x9c9cb95849f0d2a9, 0x1cc37f43441b2fae}}}, -{{{0x508f565a5cc7324f, 0xd061c4c0e506a922, 0xfb18abdb5c45ac19, 0x6c6809c10380314a}}, - {{0xd76656f1c9ceaeb9, 0x1c5b15f818e5656a, 0x26e72832844c2334, 0x3a346f772f196838}}, - {{0xd2d55112e2da6ac8, 0xe9bd0331b1e851ed, 0x960746dd8ec67262, 0x05911b9f6ef7c5d0}}}, -{{{0xc1339983f5df0ebb, 0xc0f3758f512c4cac, 0x2cf1130a0bb398e1, 0x6b3cecf9aa270c62}}, - {{0x5349acf3512eeaef, 0x20c141d31cc1cb49, 0x24180c07a99a688d, 0x555ef9d1c64b2d17}}, - {{0x36a770ba3b73bd08, 0x624aef08a3afbf0c, 0x5737ff98b40946f2, 0x675f4de13381749d}}}, -{{{0x0e2c52036b1782fc, 0x64816c816cad83b4, 0xd0dcbdd96964073e, 0x13d99df70164c520}}, - {{0xa12ff6d93bdab31d, 0x0725d80f9d652dfe, 0x019c4ff39abe9487, 0x60f450b882cd3c43}}, - {{0x014b5ec321e5c0ca, 0x4fcb69c9d719bfa2, 0x4e5f1c18750023a0, 0x1c06de9e55edac80}}}, -{{{0x990f7ad6a33ec4e2, 0x6608f938be2ee08e, 0x9ca143c563284515, 0x4cf38a1fec2db60d}}, - {{0xffd52b40ff6d69aa, 0x34530b18dc4049bb, 0x5e4a5c2fa34d9897, 0x78096f8e7d32ba2d}}, - {{0xa0aaaa650dfa5ce7, 0xf9c49e2a48b5478c, 0x4f09cc7d7003725b, 0x373cad3a26091abe}}}, -{{{0xb294634d82c9f57c, 0x1fcbfde124934536, 0x9e9c4db3418cdb5a, 0x0040f3d9454419fc}}, - {{0xf1bea8fb89ddbbad, 0x3bcb2cbc61aeaecb, 0x8f58a7bb1f9b8d9d, 0x21547eda5112a686}}, - {{0xdefde939fd5986d3, 0xf4272c89510a380c, 0xb72ba407bb3119b9, 0x63550a334a254df4}}}, -{{{0x6507d6edb569cf37, 0x178429b00ca52ee1, 0xea7c0090eb6bd65d, 0x3eea62c7daf78f51}}, - {{0x9bba584572547b49, 0xf305c6fae2c408e0, 0x60e8fa69c734f18d, 0x39a92bafaa7d767a}}, - {{0x9d24c713e693274e, 0x5f63857768dbd375, 0x70525560eb8ab39a, 0x68436a0665c9c4cd}}}, -{{{0xbc0235e8202f3f27, 0xc75c00e264f975b0, 0x91a4e9d5a38c2416, 0x17b6e7f68ab789f9}}, - {{0x1e56d317e820107c, 0xc5266844840ae965, 0xc1e0a1c6320ffc7a, 0x5373669c91611472}}, - {{0x5d2814ab9a0e5257, 0x908f2084c9cab3fc, 0xafcaf5885b2d1eca, 0x1cb4b5a678f87d11}}}, -{{{0xb664c06b394afc6c, 0x0c88de2498da5fb1, 0x4f8d03164bcad834, 0x330bca78de7434a2}}, - {{0x6b74aa62a2a007e7, 0xf311e0b0f071c7b1, 0x5707e438000be223, 0x2dc0fd2d82ef6eac}}, - {{0x982eff841119744e, 0xf9695e962b074724, 0xc58ac14fbfc953fb, 0x3c31be1b369f1cf5}}}, -{{{0xb0f4864d08948aee, 0x07dc19ee91ba1c6f, 0x7975cdaea6aca158, 0x330b61134262d4bb}}, - {{0xc168bc93f9cb4272, 0xaeb8711fc7cedb98, 0x7f0e52aa34ac8d7a, 0x41cec1097e7d55bb}}, - {{0xf79619d7a26d808a, 0xbb1fd49e1d9e156d, 0x73d7c36cdba1df27, 0x26b44cd91f28777d}}}, -{{{0x51f048478f387475, 0xb25dbcf49cbecb3c, 0x9aab1244d99f2055, 0x2c709e6c1c10a5d6}}, - {{0xe1b7f29362730383, 0x4b5279ffebca8a2c, 0xdafc778abfd41314, 0x7deb10149c72610f}}, - {{0xcb62af6a8766ee7a, 0x66cbec045553cd0e, 0x588001380f0be4b5, 0x08e68e9ff62ce2ea}}}, -{{{0x34ad500a4bc130ad, 0x8d38db493d0bd49c, 0xa25c3d98500a89be, 0x2f1f3f87eeba3b09}}, - {{0x2f2d09d50ab8f2f9, 0xacb9218dc55923df, 0x4a8f342673766cb9, 0x4cb13bd738f719f5}}, - {{0xf7848c75e515b64a, 0xa59501badb4a9038, 0xc20d313f3f751b50, 0x19a1e353c0ae2ee8}}}, -{{{0x7d1c7560bafa05c3, 0xb3e1a0a0c6e55e61, 0xe3529718c0d66473, 0x41546b11c20c3486}}, - {{0xb42172cdd596bdbd, 0x93e0454398eefc40, 0x9fb15347b44109b5, 0x736bd3990266ae34}}, - {{0x85532d509334b3b4, 0x46fd114b60816573, 0xcc5f5f30425c8375, 0x412295a2b87fab5c}}}, -{{{0x19c99b88f57ed6e9, 0x5393cb266df8c825, 0x5cee3213b30ad273, 0x14e153ebb52d2e34}}, - {{0x2e655261e293eac6, 0x845a92032133acdb, 0x460975cb7900996b, 0x0760bb8d195add80}}, - {{0x413e1a17cde6818a, 0x57156da9ed69a084, 0x2cbf268f46caccb1, 0x6b34be9bc33ac5f2}}}, -{{{0xf3df2f643a78c0b2, 0x4c3e971ef22e027c, 0xec7d1c5e49c1b5a3, 0x2012c18f0922dd2d}}, - {{0x11fc69656571f2d3, 0xc6c9e845530e737a, 0xe33ae7a2d4fe5035, 0x01b9c7b62e6dd30b}}, - {{0x880b55e55ac89d29, 0x1483241f45a0a763, 0x3d36efdfc2e76c1f, 0x08af5b784e4bade8}}}, -{{{0x283499dc881f2533, 0x9d0525da779323b6, 0x897addfb673441f4, 0x32b79d71163a168d}}, - {{0xe27314d289cc2c4b, 0x4be4bd11a287178d, 0x18d528d6fa3364ce, 0x6423c1d5afd9826e}}, - {{0xcc85f8d9edfcb36a, 0x22bcc28f3746e5f9, 0xe49de338f9e5d3cd, 0x480a5efbc13e2dcc}}}, -{{{0x0b51e70b01622071, 0x06b505cf8b1dafc5, 0x2c6bb061ef5aabcd, 0x47aa27600cb7bf31}}, - {{0xb6614ce442ce221f, 0x6e199dcc4c053928, 0x663fb4a4dc1cbe03, 0x24b31d47691c8e06}}, - {{0x2a541eedc015f8c3, 0x11a4fe7e7c693f7c, 0xf0af66134ea278d6, 0x545b585d14dda094}}}, -{{{0x67bf275ea0d43a0f, 0xade68e34089beebe, 0x4289134cd479e72e, 0x0f62f9c332ba5454}}, - {{0x6204e4d0e3b321e1, 0x3baa637a28ff1e95, 0x0b0ccffd5b99bd9e, 0x4d22dc3e64c8d071}}, - {{0xfcb46589d63b5f39, 0x5cae6a3f57cbcf61, 0xfebac2d2953afa05, 0x1c0fa01a36371436}}}, -{{{0xd2c604b622943dff, 0xbc8cbece44cfb3a0, 0x5d254ff397808678, 0x0fa3614f3b1ca6bf}}, - {{0x69082b0e8c936a50, 0xf9c9a035c1dac5b6, 0x6fb73e54c4dfb634, 0x4005419b1d2bc140}}, - {{0xa003febdb9be82f0, 0x2089c1af3a44ac90, 0xf8499f911954fa8e, 0x1fba218aef40ab42}}}, -{{{0xab549448fac8f53e, 0x81f6e89a7ba63741, 0x74fd6c7d6c2b5e01, 0x392e3acaa8c86e42}}, - {{0x4f3e57043e7b0194, 0xa81d3eee08daaf7f, 0xc839c6ab99dcdef1, 0x6c535d13ff7761d5}}, - {{0x4cbd34e93e8a35af, 0x2e0781445887e816, 0x19319c76f29ab0ab, 0x25e17fe4d50ac13b}}}, -{{{0x0a289bd71e04f676, 0x208e1c52d6420f95, 0x5186d8b034691fab, 0x255751442a9fb351}}, - {{0x915f7ff576f121a7, 0xc34a32272fcd87e3, 0xccba2fde4d1be526, 0x6bba828f8969899b}}, - {{0xe2d1bc6690fe3901, 0x4cb54a18a0997ad5, 0x971d6914af8460d4, 0x559d504f7f6b7be4}}}, -{{{0xa7738378b3eb54d5, 0x1d69d366a5553c7c, 0x0a26cf62f92800ba, 0x01ab12d5807e3217}}, - {{0x9c4891e7f6d266fd, 0x0744a19b0307781b, 0x88388f1d6061e23b, 0x123ea6a3354bd50e}}, - {{0x118d189041e32d96, 0xb9ede3c2d8315848, 0x1eab4271d83245d9, 0x4a3961e2c918a154}}}, -{{{0x71dc3be0f8e6bba0, 0xd6cef8347effe30a, 0xa992425fe13a476a, 0x2cd6bce3fb1db763}}, - {{0x0327d644f3233f1e, 0x499a260e34fcf016, 0x83b5a716f2dab979, 0x68aceead9bd4111f}}, - {{0x38b4c90ef3d7c210, 0x308e6e24b7ad040c, 0x3860d9f1b7e73e23, 0x595760d5b508f597}}}, -{{{0x6129bfe104aa6397, 0x8f960008a4a7fccb, 0x3f8bc0897d909458, 0x709fa43edcb291a9}}, - {{0x882acbebfd022790, 0x89af3305c4115760, 0x65f492e37d3473f4, 0x2cb2c5df54515a2b}}, - {{0xeb0a5d8c63fd2aca, 0xd22bc1662e694eff, 0x2723f36ef8cbb03a, 0x70f029ecf0c8131f}}}, -{{{0x461307b32eed3e33, 0xae042f33a45581e7, 0xc94449d3195f0366, 0x0b7d5d8a6c314858}}, - {{0x2a6aafaa5e10b0b9, 0x78f0a370ef041aa9, 0x773efb77aa3ad61f, 0x44eca5a2a74bd9e1}}, - {{0x25d448327b95d543, 0x70d38300a3340f1d, 0xde1c531c60e1c52b, 0x272224512c7de9e4}}}, -{{{0x1abc92af49c5342e, 0xffeed811b2e6fad0, 0xefa28c8dfcc84e29, 0x11b5df18a44cc543}}, - {{0xbf7bbb8a42a975fc, 0x8c5c397796ada358, 0xe27fc76fcdedaa48, 0x19735fd7f6bc20a6}}, - {{0xe3ab90d042c84266, 0xeb848e0f7f19547e, 0x2503a1d065a497b9, 0x0fef911191df895f}}} \ No newline at end of file diff --git a/ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data b/ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data deleted file mode 100644 index 32a5d474..00000000 --- a/ext/ed25519-amd64-asm/ge25519_base_slide_multiples.data +++ /dev/null @@ -1,96 +0,0 @@ -{{{0x9d103905d740913e, 0xfd399f05d140beb3, 0xa5c18434688f8a09, 0x44fd2f9298f81267}}, - {{0x2fbc93c6f58c3b85, 0xcf932dc6fb8c0e19, 0x270b4898643d42c2, 0x07cf9d3a33d4ba65}}, - {{0xabc91205877aaa68, 0x26d9e823ccaac49e, 0x5a1b7dcbdd43598c, 0x6f117b689f0c65a8}}}, -{{{0x56611fe8a4fcd265, 0x3bd353fde5c1ba7d, 0x8131f31a214bd6bd, 0x2ab91587555bda62}}, - {{0xaf25b0a84cee9730, 0x025a8430e8864b8a, 0xc11b50029f016732, 0x7a164e1b9a80f8f4}}, - {{0x14ae933f0dd0d889, 0x589423221c35da62, 0xd170e5458cf2db4c, 0x5a2826af12b9b4c6}}}, -{{{0x7f9182c3a447d6ba, 0xd50014d14b2729b7, 0xe33cf11cb864a087, 0x154a7e73eb1b55f3}}, - {{0xa212bc4408a5bb33, 0x8d5048c3c75eed02, 0xdd1beb0c5abfec44, 0x2945ccf146e206eb}}, - {{0xbcbbdbf1812a8285, 0x270e0807d0bdd1fc, 0xb41b670b1bbda72d, 0x43aabe696b3bb69a}}}, -{{{0xba6f2c9aaa3221b1, 0x6ca021533bba23a7, 0x9dea764f92192c3a, 0x1d6edd5d2e5317e0}}, - {{0x6b1a5cd0944ea3bf, 0x7470353ab39dc0d2, 0x71b2528228542e49, 0x461bea69283c927e}}, - {{0xf1836dc801b8b3a2, 0xb3035f47053ea49a, 0x529c41ba5877adf3, 0x7a9fbb1c6a0f90a7}}}, -{{{0xf36e217e039d8064, 0x98a081b6f520419b, 0x96cbc608e75eb044, 0x49c05a51fadc9c8f}}, - {{0x9b2e678aa6a8632f, 0xa6509e6f51bc46c5, 0xceb233c9c686f5b5, 0x34b9ed338add7f59}}, - {{0x06b4e8bf9045af1b, 0xe2ff83e8a719d22f, 0xaaf6fc2993d4cf16, 0x73c172021b008b06}}}, -{{{0x315f5b0249864348, 0x3ed6b36977088381, 0xa3a075556a8deb95, 0x18ab598029d5c77f}}, - {{0x2fbf00848a802ade, 0xe5d9fecf02302e27, 0x113e847117703406, 0x4275aae2546d8faf}}, - {{0xd82b2cc5fd6089e9, 0x031eb4a13282e4a4, 0x44311199b51a8622, 0x3dc65522b53df948}}}, -{{{0x506f013b327fbf93, 0xaefcebc99b776f6b, 0x9d12b232aaad5968, 0x0267882d176024a7}}, - {{0xbf70c222a2007f6d, 0xbf84b39ab5bcdedb, 0x537a0e12fb07ba07, 0x234fd7eec346f241}}, - {{0x5360a119732ea378, 0x2437e6b1df8dd471, 0xa2ef37f891a7e533, 0x497ba6fdaa097863}}}, -{{{0x040bcd86468ccf0b, 0xd3829ba42a9910d6, 0x7508300807b25192, 0x43b5cd4218d05ebf}}, - {{0x24cecc0313cfeaa0, 0x8648c28d189c246d, 0x2dbdbdfac1f2d4d0, 0x61e22917f12de72b}}, - {{0x5d9a762f9bd0b516, 0xeb38af4e373fdeee, 0x032e5a7d93d64270, 0x511d61210ae4d842}}}, -{{{0x081386484420de87, 0x8a1cf016b592edb4, 0x39fa4e2729942d25, 0x71a7fe6fe2482810}}, - {{0x92c676ef950e9d81, 0xa54620cdc0d7044f, 0xaa9b36646f8f1248, 0x6d325924ddb855e3}}, - {{0x6c7182b8a5c8c854, 0x33fd1479fe5f2a03, 0x72cf591883778d0c, 0x4746c4b6559eeaa9}}}, -{{{0x348546c864741147, 0x7d35aedd0efcc849, 0xff939a760672a332, 0x219663497db5e6d6}}, - {{0xd3777b3c6dc69a2b, 0xdefab2276f89f617, 0x45651cf7b53a16b5, 0x5c9a51de34fe9fb7}}, - {{0xf510f1cf79f10e67, 0xffdddaa1e658515b, 0x09c3a71710142277, 0x4804503c608223bb}}}, -{{{0x3b6821d23a36d175, 0xbbb40aa7e99b9e32, 0x5d9e5ce420838a47, 0x771e098858de4c5e}}, - {{0xc4249ed02ca37fc7, 0xa059a0e3a615acab, 0x88a96ed7c96e0e23, 0x553398a51650696d}}, - {{0x9a12f5d278451edf, 0x3ada5d7985899ccb, 0x477f4a2d9fa59508, 0x5a5ed1d68ff5a611}}}, -{{{0xbae5e0c558527359, 0x392e5c19cadb9d7e, 0x28653c1eda1cabe9, 0x019b60135fefdc44}}, - {{0x1195122afe150e83, 0xcf209a257e4b35d8, 0x7387f8291e711e20, 0x44acb897d8bf92f0}}, - {{0x1e6068145e134b83, 0xc4f5e64f24304c16, 0x506e88a8fc1a3ed7, 0x150c49fde6ad2f92}}}, -{{{0xb849863c9cdca868, 0xc83f44dbb8714ad0, 0xfe3ee3560c36168d, 0x78a6d7791e05fbc1}}, - {{0x8e7bf29509471138, 0x5d6fef394f75a651, 0x10af79c425a708ad, 0x6b2b5a075bb99922}}, - {{0x58bf704b47a0b976, 0xa601b355741748d5, 0xaa2b1fb1d542f590, 0x725c7ffc4ad55d00}}}, -{{{0x91802bf71cd098c0, 0xfe416ca4ed5e6366, 0xdf585d714902994c, 0x4cd54625f855fae7}}, - {{0xe4426715d1cf99b2, 0x7352d51102a20d34, 0x23d1157b8b12109f, 0x794cc9277cb1f3a3}}, - {{0x4af6c426c2ac5053, 0xbc9aedad32f67258, 0x2ad032f10a311021, 0x7008357b6fcc8e85}}}, -{{{0xd01b9fbb82584a34, 0x47ab6463d2b4792b, 0xb631639c48536202, 0x13a92a3669d6d428}}, - {{0x0b88672738773f01, 0xb8ccc8fa95fbccfb, 0x8d2dd5a3b9ad29b6, 0x06ef7e9851ad0f6a}}, - {{0xca93771cc0577de5, 0x7540e41e5035dc5c, 0x24680f01d802e071, 0x3c296ddf8a2af86a}}}, -{{{0xfceb4d2ebb1f2541, 0xb89510c740adb91f, 0xfc71a37dd0a1ad05, 0x0a892c700747717b}}, - {{0xaead15f9d914a713, 0xa92f7bf98c8ff912, 0xaff823179f53d730, 0x7a99d393490c77ba}}, - {{0x8f52ed2436bda3e8, 0x77a8c84157e80794, 0xa5a96563262f9ce0, 0x286762d28302f7d2}}}, -{{{0x7c558e2bce2ef5bd, 0xe4986cb46747bc63, 0x154a179f3bbb89b8, 0x7686f2a3d6f1767a}}, - {{0x4e7836093ce35b25, 0x82e1181db26baa97, 0x0cc192d3cbc7b83f, 0x32f1da046a9d9d3a}}, - {{0xaa8d12a66d597c6a, 0x8f11930304d3852b, 0x3f91dc73c209b022, 0x561305f8a9ad28a6}}}, -{{{0x6722cc28e7b0c0d5, 0x709de9bbdb075c53, 0xcaf68da7d7010a61, 0x030a1aef2c57cc6c}}, - {{0x100c978dec92aed1, 0xca43d5434d6d73e5, 0x83131b22d847ba48, 0x00aaec53e35d4d2c}}, - {{0x7bb1f773003ad2aa, 0x0b3f29802b216608, 0x7821dc86520ed23e, 0x20be9c1c24065480}}}, -{{{0x20e0e44ae2025e60, 0xb03b3b2fcbdcb938, 0x105d639cf95a0d1c, 0x69764c545067e311}}, - {{0xe15387d8249673a6, 0x5943bc2df546e493, 0x1c7f9a81c36f63b5, 0x750ab3361f0ac1de}}, - {{0x1e8a3283a2f81037, 0x6f2eda23bd7fcbf1, 0xb72fd15bac2e2563, 0x54f96b3fb7075040}}}, -{{{0x177dafc616b11ecd, 0x89764b9cfa576479, 0xb7a8a110e6ece785, 0x78e6839fbe85dbf0}}, - {{0x0fadf20429669279, 0x3adda2047d7d724a, 0x6f3d94828c5760f1, 0x3d7fe9c52bb7539e}}, - {{0x70332df737b8856b, 0x75d05d43041a178a, 0x320ff74aa0e59e22, 0x70f268f350088242}}}, -{{{0x2324112070dcf355, 0x380cc97ee7fce117, 0xb31ddeed3552b698, 0x404e56c039b8c4b9}}, - {{0x66864583b1805f47, 0xf535c5d160dd7c19, 0xe9874eb71e4cb006, 0x7c0d345cfad889d9}}, - {{0x591f1f4b8c78338a, 0xa0366ab167e0b5e1, 0x5cbc4152b45f3d44, 0x20d754762aaec777}}}, -{{{0x9d74feb135b9f543, 0x84b37df1de8c956c, 0xe9322b0757138ba9, 0x38b8ada8790b4ce1}}, - {{0x5e8fc36fc73bb758, 0xace543a5363cbb9a, 0xa9934a7d903bc922, 0x2b8f1e46f3ceec62}}, - {{0xb5c04a9cdf51f95d, 0x2b3952aecb1fdeac, 0x1d106d8b328b66da, 0x049aeb32ceba1953}}}, -{{{0xd7767d3c63dcfe7e, 0x209c594897856e40, 0xb6676861e14f7c13, 0x51c665e0c8d625fc}}, - {{0xaa507d0b75fc7931, 0x0fef924b7a6725d3, 0x1d82542b396b3930, 0x795ee17530f674fc}}, - {{0x254a5b0a52ecbd81, 0x5d411f6ee034afe7, 0xe6a24d0dcaee4a31, 0x6cd19bf49dc54477}}}, -{{{0x7e87619052179ca3, 0x571d0a060b2c9f85, 0x80a2baa88499711e, 0x7520f3db40b2e638}}, - {{0x1ffe612165afc386, 0x082a2a88b8d51b10, 0x76f6627e20990baa, 0x5e01b3a7429e43e7}}, - {{0x3db50be3d39357a1, 0x967b6cdd599e94a5, 0x1a309a64df311e6e, 0x71092c9ccef3c986}}}, -{{{0x53d8523f0364918c, 0xa2b404f43fab6b1c, 0x080b4a9e6681e5a4, 0x0ea15b03d0257ba7}}, - {{0x856bd8ac74051dcf, 0x03f6a40855b7aa1e, 0x3a4ae7cbc9743ceb, 0x4173a5bb7137abde}}, - {{0x17c56e31f0f9218a, 0x5a696e2b1afc4708, 0xf7931668f4b2f176, 0x5fc565614a4e3a67}}}, -{{{0x136e570dc46d7ae5, 0x0fd0aacc54f8dc8f, 0x59549f03310dad86, 0x62711c414c454aa1}}, - {{0x4892e1e67790988e, 0x01d5950f1c5cd722, 0xe3b0819ae5923eed, 0x3214c7409d46651b}}, - {{0x1329827406651770, 0x3ba4a0668a279436, 0xd9b6b8ec185d223c, 0x5bea94073ecb833c}}}, -{{{0x641dbf0912c89be4, 0xacf38b317d6e579c, 0xabfe9e02f697b065, 0x3aacd5c148f61eec}}, - {{0xb470ce63f343d2f8, 0x0067ba8f0543e8f1, 0x35da51a1a2117b6f, 0x4ad0785944f1bd2f}}, - {{0x858e3b34c3318301, 0xdc99c04707316826, 0x34085b2ed39da88c, 0x3aff0cb1d902853d}}}, -{{{0x87c5c7eb3a20405e, 0x8ee311efedad56c9, 0x29252e48ad29d5f9, 0x110e7e86f4cd251d}}, - {{0x9226430bf4c53505, 0x68e49c13261f2283, 0x09ef33788fd327c6, 0x2ccf9f732bd99e7f}}, - {{0x57c0d89ed603f5e4, 0x12888628f0b0200c, 0x53172709a02e3bb7, 0x05c557e0b9693a37}}}, -{{{0xd8f9ce311fc97e6f, 0x7a3f263011f9fdae, 0xe15b7ea08bed25dd, 0x6e154c178fe9875a}}, - {{0xf776bbb089c20eb0, 0x61f85bf6fa0fd85c, 0xb6b93f4e634421fb, 0x289fef0841861205}}, - {{0xcf616336fed69abf, 0x9b16e4e78335c94f, 0x13789765753a7fe7, 0x6afbf642a95ca319}}}, -{{{0x7da8de0c62f5d2c1, 0x98fc3da4b00e7b9a, 0x7deb6ada0dad70e0, 0x0db4b851b95038c4}}, - {{0x5de55070f913a8cc, 0x7d1d167b2b0cf561, 0xda2956b690ead489, 0x12c093cedb801ed9}}, - {{0xfc147f9308b8190f, 0x06969da0a11ae310, 0xcee75572dac7d7fd, 0x33aa8799c6635ce6}}}, -{{{0xaf0ff51ebd085cf2, 0x78f51a8967d33f1f, 0x6ec2bfe15060033c, 0x233c6f29e8e21a86}}, - {{0x8348f588fc156cb1, 0x6da2ba9b1a0a6d27, 0xe2262d5c87ca5ab6, 0x212cd0c1c8d589a6}}, - {{0xd2f4d5107f18c781, 0x122ecdf2527e9d28, 0xa70a862a3d3d3341, 0x1db7778911914ce3}}}, -{{{0xddf352397c6bc26f, 0x7a97e2cc53d50113, 0x7c74f43abf79a330, 0x31ad97ad26e2adfc}}, - {{0xb3394769dd701ab6, 0xe2b8ded419cf8da5, 0x15df4161fd2ac852, 0x7ae2ca8a017d24be}}, - {{0xb7e817ed0920b962, 0x1e8518cc3f19da9d, 0xe491c14f25560a64, 0x1ed1fc53a6622c83}}} \ No newline at end of file diff --git a/ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s b/ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s deleted file mode 100644 index 265daf09..00000000 --- a/ext/ed25519-amd64-asm/ge25519_dbl_p1p1.s +++ /dev/null @@ -1,2975 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 pp - -# qhasm: input rp - -# qhasm: input pp - -# qhasm: int64 a0 - -# qhasm: int64 a1 - -# qhasm: int64 a2 - -# qhasm: int64 a3 - -# qhasm: stack64 a0_stack - -# qhasm: stack64 a1_stack - -# qhasm: stack64 a2_stack - -# qhasm: stack64 a3_stack - -# qhasm: int64 b0 - -# qhasm: int64 b1 - -# qhasm: int64 b2 - -# qhasm: int64 b3 - -# qhasm: stack64 b0_stack - -# qhasm: stack64 b1_stack - -# qhasm: stack64 b2_stack - -# qhasm: stack64 b3_stack - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: stack64 c0_stack - -# qhasm: stack64 c1_stack - -# qhasm: stack64 c2_stack - -# qhasm: stack64 c3_stack - -# qhasm: int64 d0 - -# qhasm: int64 d1 - -# qhasm: int64 d2 - -# qhasm: int64 d3 - -# qhasm: stack64 d0_stack - -# qhasm: stack64 d1_stack - -# qhasm: stack64 d2_stack - -# qhasm: stack64 d3_stack - -# qhasm: int64 e0 - -# qhasm: int64 e1 - -# qhasm: int64 e2 - -# qhasm: int64 e3 - -# qhasm: stack64 e0_stack - -# qhasm: stack64 e1_stack - -# qhasm: stack64 e2_stack - -# qhasm: stack64 e3_stack - -# qhasm: int64 rx0 - -# qhasm: int64 rx1 - -# qhasm: int64 rx2 - -# qhasm: int64 rx3 - -# qhasm: stack64 rx0_stack - -# qhasm: stack64 rx1_stack - -# qhasm: stack64 rx2_stack - -# qhasm: stack64 rx3_stack - -# qhasm: int64 ry0 - -# qhasm: int64 ry1 - -# qhasm: int64 ry2 - -# qhasm: int64 ry3 - -# qhasm: int64 ry4 - -# qhasm: int64 rz0 - -# qhasm: int64 rz1 - -# qhasm: int64 rz2 - -# qhasm: int64 rz3 - -# qhasm: int64 rt0 - -# qhasm: int64 rt1 - -# qhasm: int64 rt2 - -# qhasm: int64 rt3 - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: int64 squarer4 - -# qhasm: int64 squarer5 - -# qhasm: int64 squarer6 - -# qhasm: int64 squarer7 - -# qhasm: int64 squarer8 - -# qhasm: int64 squarerax - -# qhasm: int64 squarerdx - -# qhasm: int64 squaret1 - -# qhasm: int64 squaret2 - -# qhasm: int64 squaret3 - -# qhasm: int64 squarec - -# qhasm: int64 squarezero - -# qhasm: int64 squarei38 - -# qhasm: int64 addt0 - -# qhasm: int64 addt1 - -# qhasm: int64 subt0 - -# qhasm: int64 subt1 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 -.globl crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1 -_crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1: -crypto_sign_ed25519_amd64_64_ge25519_dbl_p1p1: -mov %rsp,%r11 -and $31,%r11 -add $192,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarerax = *(uint64 *)(pp + 8) -# asm 1: movq 8(squarerax=int64#7 -# asm 2: movq 8(squarerax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) -# asm 1: mulq 0(a1=int64#5 -# asm 2: mov a1=%r8 -mov %rax,%r8 - -# qhasm: a2 = squarerdx -# asm 1: mov a2=int64#6 -# asm 2: mov a2=%r9 -mov %rdx,%r9 - -# qhasm: squarerax = *(uint64 *)(pp + 16) -# asm 1: movq 16(squarerax=int64#7 -# asm 2: movq 16(squarerax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 8) -# asm 1: mulq 8(a3=int64#8 -# asm 2: mov a3=%r10 -mov %rax,%r10 - -# qhasm: squarer4 = squarerdx -# asm 1: mov squarer4=int64#9 -# asm 2: mov squarer4=%r11 -mov %rdx,%r11 - -# qhasm: squarerax = *(uint64 *)(pp + 24) -# asm 1: movq 24(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 16) -# asm 1: mulq 16(squarer5=int64#10 -# asm 2: mov squarer5=%r12 -mov %rax,%r12 - -# qhasm: squarer6 = squarerdx -# asm 1: mov squarer6=int64#11 -# asm 2: mov squarer6=%r13 -mov %rdx,%r13 - -# qhasm: squarerax = *(uint64 *)(pp + 16) -# asm 1: movq 16(squarerax=int64#7 -# asm 2: movq 16(squarerax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) -# asm 1: mulq 0(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 8) -# asm 1: mulq 8(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) -# asm 1: mulq 0(squarerax=int64#7 -# asm 2: movq 0(squarerax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 0) -# asm 1: mulq 0(a0=int64#12 -# asm 2: mov a0=%r14 -mov %rax,%r14 - -# qhasm: squaret1 = squarerdx -# asm 1: mov squaret1=int64#13 -# asm 2: mov squaret1=%r15 -mov %rdx,%r15 - -# qhasm: squarerax = *(uint64 *)(pp + 8) -# asm 1: movq 8(squarerax=int64#7 -# asm 2: movq 8(squarerax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 8) -# asm 1: mulq 8(squaret2=int64#14 -# asm 2: mov squaret2=%rbx -mov %rax,%rbx - -# qhasm: squaret3 = squarerdx -# asm 1: mov squaret3=int64#15 -# asm 2: mov squaret3=%rbp -mov %rdx,%rbp - -# qhasm: squarerax = *(uint64 *)(pp + 16) -# asm 1: movq 16(squarerax=int64#7 -# asm 2: movq 16(squarerax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 16) -# asm 1: mulq 16(squarerax=int64#7 -# asm 2: movq 24(squarerax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 24) -# asm 1: mulq 24(squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r11,%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: squarer4 = squarerax -# asm 1: mov squarer4=int64#9 -# asm 2: mov squarer4=%r11 -mov %rax,%r11 - -# qhasm: squarerax = squarer5 -# asm 1: mov squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r12,%rax - -# qhasm: squarer5 = squarerdx -# asm 1: mov squarer5=int64#10 -# asm 2: mov squarer5=%r12 -mov %rdx,%r12 - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? squarer5 += squarerax -# asm 1: add squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r13,%rax - -# qhasm: squarer6 = 0 -# asm 1: mov $0,>squarer6=int64#11 -# asm 2: mov $0,>squarer6=%r13 -mov $0,%r13 - -# qhasm: squarer6 += squarerdx + carry -# asm 1: adc squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %rcx,%rax - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarer7 += squarerdx + carry -# asm 1: adc squarer8=int64#7 -# asm 2: mov $0,>squarer8=%rax -mov $0,%rax - -# qhasm: squarer8 += squarerdx + carry -# asm 1: adc squarezero=int64#3 -# asm 2: mov $0,>squarezero=%rdx -mov $0,%rdx - -# qhasm: squarer8 += squarezero + carry -# asm 1: adc squarer8=int64#4 -# asm 2: imulq $38,squarer8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? a0 += squarer8 -# asm 1: add squarezero=int64#3 -# asm 2: imulq $38,squarezero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: a0 += squarezero -# asm 1: add a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %r14,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r8,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r9,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %r10,80(%rsp) - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarerax = *(uint64 *)(pp + 40) -# asm 1: movq 40(squarerax=int64#7 -# asm 2: movq 40(squarerax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) -# asm 1: mulq 32(b1=int64#5 -# asm 2: mov b1=%r8 -mov %rax,%r8 - -# qhasm: b2 = squarerdx -# asm 1: mov b2=int64#6 -# asm 2: mov b2=%r9 -mov %rdx,%r9 - -# qhasm: squarerax = *(uint64 *)(pp + 48) -# asm 1: movq 48(squarerax=int64#7 -# asm 2: movq 48(squarerax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 40) -# asm 1: mulq 40(b3=int64#8 -# asm 2: mov b3=%r10 -mov %rax,%r10 - -# qhasm: squarer4 = squarerdx -# asm 1: mov squarer4=int64#9 -# asm 2: mov squarer4=%r11 -mov %rdx,%r11 - -# qhasm: squarerax = *(uint64 *)(pp + 56) -# asm 1: movq 56(squarerax=int64#7 -# asm 2: movq 56(squarerax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 48) -# asm 1: mulq 48(squarer5=int64#10 -# asm 2: mov squarer5=%r12 -mov %rax,%r12 - -# qhasm: squarer6 = squarerdx -# asm 1: mov squarer6=int64#11 -# asm 2: mov squarer6=%r13 -mov %rdx,%r13 - -# qhasm: squarerax = *(uint64 *)(pp + 48) -# asm 1: movq 48(squarerax=int64#7 -# asm 2: movq 48(squarerax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) -# asm 1: mulq 32(squarerax=int64#7 -# asm 2: movq 56(squarerax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 40) -# asm 1: mulq 40(squarerax=int64#7 -# asm 2: movq 56(squarerax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) -# asm 1: mulq 32(squarerax=int64#7 -# asm 2: movq 32(squarerax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 32) -# asm 1: mulq 32(b0=int64#12 -# asm 2: mov b0=%r14 -mov %rax,%r14 - -# qhasm: squaret1 = squarerdx -# asm 1: mov squaret1=int64#13 -# asm 2: mov squaret1=%r15 -mov %rdx,%r15 - -# qhasm: squarerax = *(uint64 *)(pp + 40) -# asm 1: movq 40(squarerax=int64#7 -# asm 2: movq 40(squarerax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 40) -# asm 1: mulq 40(squaret2=int64#14 -# asm 2: mov squaret2=%rbx -mov %rax,%rbx - -# qhasm: squaret3 = squarerdx -# asm 1: mov squaret3=int64#15 -# asm 2: mov squaret3=%rbp -mov %rdx,%rbp - -# qhasm: squarerax = *(uint64 *)(pp + 48) -# asm 1: movq 48(squarerax=int64#7 -# asm 2: movq 48(squarerax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 48) -# asm 1: mulq 48(squarerax=int64#7 -# asm 2: movq 56(squarerax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 56) -# asm 1: mulq 56(squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r11,%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: squarer4 = squarerax -# asm 1: mov squarer4=int64#9 -# asm 2: mov squarer4=%r11 -mov %rax,%r11 - -# qhasm: squarerax = squarer5 -# asm 1: mov squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r12,%rax - -# qhasm: squarer5 = squarerdx -# asm 1: mov squarer5=int64#10 -# asm 2: mov squarer5=%r12 -mov %rdx,%r12 - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? squarer5 += squarerax -# asm 1: add squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r13,%rax - -# qhasm: squarer6 = 0 -# asm 1: mov $0,>squarer6=int64#11 -# asm 2: mov $0,>squarer6=%r13 -mov $0,%r13 - -# qhasm: squarer6 += squarerdx + carry -# asm 1: adc squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %rcx,%rax - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarer7 += squarerdx + carry -# asm 1: adc squarer8=int64#7 -# asm 2: mov $0,>squarer8=%rax -mov $0,%rax - -# qhasm: squarer8 += squarerdx + carry -# asm 1: adc squarezero=int64#3 -# asm 2: mov $0,>squarezero=%rdx -mov $0,%rdx - -# qhasm: squarer8 += squarezero + carry -# asm 1: adc squarer8=int64#4 -# asm 2: imulq $38,squarer8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? b0 += squarer8 -# asm 1: add squarezero=int64#3 -# asm 2: imulq $38,squarezero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: b0 += squarezero -# asm 1: add b0_stack=stack64#12 -# asm 2: movq b0_stack=88(%rsp) -movq %r14,88(%rsp) - -# qhasm: b1_stack = b1 -# asm 1: movq b1_stack=stack64#13 -# asm 2: movq b1_stack=96(%rsp) -movq %r8,96(%rsp) - -# qhasm: b2_stack = b2 -# asm 1: movq b2_stack=stack64#14 -# asm 2: movq b2_stack=104(%rsp) -movq %r9,104(%rsp) - -# qhasm: b3_stack = b3 -# asm 1: movq b3_stack=stack64#15 -# asm 2: movq b3_stack=112(%rsp) -movq %r10,112(%rsp) - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarerax = *(uint64 *)(pp + 72) -# asm 1: movq 72(squarerax=int64#7 -# asm 2: movq 72(squarerax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) -# asm 1: mulq 64(c1=int64#5 -# asm 2: mov c1=%r8 -mov %rax,%r8 - -# qhasm: c2 = squarerdx -# asm 1: mov c2=int64#6 -# asm 2: mov c2=%r9 -mov %rdx,%r9 - -# qhasm: squarerax = *(uint64 *)(pp + 80) -# asm 1: movq 80(squarerax=int64#7 -# asm 2: movq 80(squarerax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 72) -# asm 1: mulq 72(c3=int64#8 -# asm 2: mov c3=%r10 -mov %rax,%r10 - -# qhasm: squarer4 = squarerdx -# asm 1: mov squarer4=int64#9 -# asm 2: mov squarer4=%r11 -mov %rdx,%r11 - -# qhasm: squarerax = *(uint64 *)(pp + 88) -# asm 1: movq 88(squarerax=int64#7 -# asm 2: movq 88(squarerax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 80) -# asm 1: mulq 80(squarer5=int64#10 -# asm 2: mov squarer5=%r12 -mov %rax,%r12 - -# qhasm: squarer6 = squarerdx -# asm 1: mov squarer6=int64#11 -# asm 2: mov squarer6=%r13 -mov %rdx,%r13 - -# qhasm: squarerax = *(uint64 *)(pp + 80) -# asm 1: movq 80(squarerax=int64#7 -# asm 2: movq 80(squarerax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) -# asm 1: mulq 64(squarerax=int64#7 -# asm 2: movq 88(squarerax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 72) -# asm 1: mulq 72(squarerax=int64#7 -# asm 2: movq 88(squarerax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) -# asm 1: mulq 64(squarerax=int64#7 -# asm 2: movq 64(squarerax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 64) -# asm 1: mulq 64(c0=int64#12 -# asm 2: mov c0=%r14 -mov %rax,%r14 - -# qhasm: squaret1 = squarerdx -# asm 1: mov squaret1=int64#13 -# asm 2: mov squaret1=%r15 -mov %rdx,%r15 - -# qhasm: squarerax = *(uint64 *)(pp + 72) -# asm 1: movq 72(squarerax=int64#7 -# asm 2: movq 72(squarerax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 72) -# asm 1: mulq 72(squaret2=int64#14 -# asm 2: mov squaret2=%rbx -mov %rax,%rbx - -# qhasm: squaret3 = squarerdx -# asm 1: mov squaret3=int64#15 -# asm 2: mov squaret3=%rbp -mov %rdx,%rbp - -# qhasm: squarerax = *(uint64 *)(pp + 80) -# asm 1: movq 80(squarerax=int64#7 -# asm 2: movq 80(squarerax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 80) -# asm 1: mulq 80(squarerax=int64#7 -# asm 2: movq 88(squarerax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)(pp + 88) -# asm 1: mulq 88(squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r11,%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: squarer4 = squarerax -# asm 1: mov squarer4=int64#9 -# asm 2: mov squarer4=%r11 -mov %rax,%r11 - -# qhasm: squarerax = squarer5 -# asm 1: mov squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r12,%rax - -# qhasm: squarer5 = squarerdx -# asm 1: mov squarer5=int64#10 -# asm 2: mov squarer5=%r12 -mov %rdx,%r12 - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? squarer5 += squarerax -# asm 1: add squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r13,%rax - -# qhasm: squarer6 = 0 -# asm 1: mov $0,>squarer6=int64#11 -# asm 2: mov $0,>squarer6=%r13 -mov $0,%r13 - -# qhasm: squarer6 += squarerdx + carry -# asm 1: adc squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %rcx,%rax - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#4 -# asm 2: mov $0,>squarer7=%rcx -mov $0,%rcx - -# qhasm: squarer7 += squarerdx + carry -# asm 1: adc squarer8=int64#7 -# asm 2: mov $0,>squarer8=%rax -mov $0,%rax - -# qhasm: squarer8 += squarerdx + carry -# asm 1: adc squarezero=int64#3 -# asm 2: mov $0,>squarezero=%rdx -mov $0,%rdx - -# qhasm: squarer8 += squarezero + carry -# asm 1: adc squarer8=int64#4 -# asm 2: imulq $38,squarer8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? c0 += squarer8 -# asm 1: add squarezero=int64#3 -# asm 2: imulq $38,squarezero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: c0 += squarezero -# asm 1: add addt0=int64#3 -# asm 2: mov $0,>addt0=%rdx -mov $0,%rdx - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#4 -# asm 2: mov $38,>addt1=%rcx -mov $38,%rcx - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae c0_stack=stack64#16 -# asm 2: movq c0_stack=120(%rsp) -movq %r14,120(%rsp) - -# qhasm: c1_stack = c1 -# asm 1: movq c1_stack=stack64#17 -# asm 2: movq c1_stack=128(%rsp) -movq %r8,128(%rsp) - -# qhasm: c2_stack = c2 -# asm 1: movq c2_stack=stack64#18 -# asm 2: movq c2_stack=136(%rsp) -movq %r9,136(%rsp) - -# qhasm: c3_stack = c3 -# asm 1: movq c3_stack=stack64#19 -# asm 2: movq c3_stack=144(%rsp) -movq %r10,144(%rsp) - -# qhasm: d0 = 0 -# asm 1: mov $0,>d0=int64#3 -# asm 2: mov $0,>d0=%rdx -mov $0,%rdx - -# qhasm: d1 = 0 -# asm 1: mov $0,>d1=int64#4 -# asm 2: mov $0,>d1=%rcx -mov $0,%rcx - -# qhasm: d2 = 0 -# asm 1: mov $0,>d2=int64#5 -# asm 2: mov $0,>d2=%r8 -mov $0,%r8 - -# qhasm: d3 = 0 -# asm 1: mov $0,>d3=int64#6 -# asm 2: mov $0,>d3=%r9 -mov $0,%r9 - -# qhasm: carry? d0 -= a0_stack -# asm 1: subq subt0=int64#7 -# asm 2: mov $0,>subt0=%rax -mov $0,%rax - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#8 -# asm 2: mov $38,>subt1=%r10 -mov $38,%r10 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae d0_stack=stack64#8 -# asm 2: movq d0_stack=56(%rsp) -movq %rdx,56(%rsp) - -# qhasm: d1_stack = d1 -# asm 1: movq d1_stack=stack64#9 -# asm 2: movq d1_stack=64(%rsp) -movq %rcx,64(%rsp) - -# qhasm: d2_stack = d2 -# asm 1: movq d2_stack=stack64#10 -# asm 2: movq d2_stack=72(%rsp) -movq %r8,72(%rsp) - -# qhasm: d3_stack = d3 -# asm 1: movq d3_stack=stack64#11 -# asm 2: movq d3_stack=80(%rsp) -movq %r9,80(%rsp) - -# qhasm: e0 = 0 -# asm 1: mov $0,>e0=int64#7 -# asm 2: mov $0,>e0=%rax -mov $0,%rax - -# qhasm: e1 = 0 -# asm 1: mov $0,>e1=int64#8 -# asm 2: mov $0,>e1=%r10 -mov $0,%r10 - -# qhasm: e2 = 0 -# asm 1: mov $0,>e2=int64#9 -# asm 2: mov $0,>e2=%r11 -mov $0,%r11 - -# qhasm: e3 = 0 -# asm 1: mov $0,>e3=int64#10 -# asm 2: mov $0,>e3=%r12 -mov $0,%r12 - -# qhasm: carry? e0 -= b0_stack -# asm 1: subq subt0=int64#11 -# asm 2: mov $0,>subt0=%r13 -mov $0,%r13 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#12 -# asm 2: mov $38,>subt1=%r14 -mov $38,%r14 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae e0_stack=stack64#20 -# asm 2: movq e0_stack=152(%rsp) -movq %rax,152(%rsp) - -# qhasm: e1_stack = e1 -# asm 1: movq e1_stack=stack64#21 -# asm 2: movq e1_stack=160(%rsp) -movq %r10,160(%rsp) - -# qhasm: e2_stack = e2 -# asm 1: movq e2_stack=stack64#22 -# asm 2: movq e2_stack=168(%rsp) -movq %r11,168(%rsp) - -# qhasm: e3_stack = e3 -# asm 1: movq e3_stack=stack64#23 -# asm 2: movq e3_stack=176(%rsp) -movq %r12,176(%rsp) - -# qhasm: rz0 = d0 -# asm 1: mov rz0=int64#7 -# asm 2: mov rz0=%rax -mov %rdx,%rax - -# qhasm: rz1 = d1 -# asm 1: mov rz1=int64#8 -# asm 2: mov rz1=%r10 -mov %rcx,%r10 - -# qhasm: rz2 = d2 -# asm 1: mov rz2=int64#9 -# asm 2: mov rz2=%r11 -mov %r8,%r11 - -# qhasm: rz3 = d3 -# asm 1: mov rz3=int64#10 -# asm 2: mov rz3=%r12 -mov %r9,%r12 - -# qhasm: carry? rz0 += b0_stack -# asm 1: addq addt0=int64#11 -# asm 2: mov $0,>addt0=%r13 -mov $0,%r13 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#12 -# asm 2: mov $38,>addt1=%r14 -mov $38,%r14 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae subt0=int64#11 -# asm 2: mov $0,>subt0=%r13 -mov $0,%r13 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#12 -# asm 2: mov $38,>subt1=%r14 -mov $38,%r14 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae subt0=int64#3 -# asm 2: mov $0,>subt0=%rdx -mov $0,%rdx - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#4 -# asm 2: mov $38,>subt1=%rcx -mov $38,%rcx - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae rx0=int64#3 -# asm 2: movq 0(rx0=%rdx -movq 0(%rsi),%rdx - -# qhasm: rx1 = *(uint64 *)(pp + 8) -# asm 1: movq 8(rx1=int64#4 -# asm 2: movq 8(rx1=%rcx -movq 8(%rsi),%rcx - -# qhasm: rx2 = *(uint64 *)(pp + 16) -# asm 1: movq 16(rx2=int64#5 -# asm 2: movq 16(rx2=%r8 -movq 16(%rsi),%r8 - -# qhasm: rx3 = *(uint64 *)(pp + 24) -# asm 1: movq 24(rx3=int64#6 -# asm 2: movq 24(rx3=%r9 -movq 24(%rsi),%r9 - -# qhasm: carry? rx0 += *(uint64 *)(pp + 32) -# asm 1: addq 32(addt0=int64#2 -# asm 2: mov $0,>addt0=%rsi -mov $0,%rsi - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#7 -# asm 2: mov $38,>addt1=%rax -mov $38,%rax - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae rx0_stack=stack64#12 -# asm 2: movq rx0_stack=88(%rsp) -movq %rdx,88(%rsp) - -# qhasm: rx1_stack = rx1 -# asm 1: movq rx1_stack=stack64#13 -# asm 2: movq rx1_stack=96(%rsp) -movq %rcx,96(%rsp) - -# qhasm: rx2_stack = rx2 -# asm 1: movq rx2_stack=stack64#14 -# asm 2: movq rx2_stack=104(%rsp) -movq %r8,104(%rsp) - -# qhasm: rx3_stack = rx3 -# asm 1: movq rx3_stack=stack64#15 -# asm 2: movq rx3_stack=112(%rsp) -movq %r9,112(%rsp) - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#2 -# asm 2: mov $0,>squarer7=%rsi -mov $0,%rsi - -# qhasm: squarerax = rx1_stack -# asm 1: movq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 96(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack -# asm 1: mulq rx1=int64#4 -# asm 2: mov rx1=%rcx -mov %rax,%rcx - -# qhasm: rx2 = squarerdx -# asm 1: mov rx2=int64#5 -# asm 2: mov rx2=%r8 -mov %rdx,%r8 - -# qhasm: squarerax = rx2_stack -# asm 1: movq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 104(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx1_stack -# asm 1: mulq rx3=int64#6 -# asm 2: mov rx3=%r9 -mov %rax,%r9 - -# qhasm: squarer4 = squarerdx -# asm 1: mov squarer4=int64#8 -# asm 2: mov squarer4=%r10 -mov %rdx,%r10 - -# qhasm: squarerax = rx3_stack -# asm 1: movq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 112(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx2_stack -# asm 1: mulq squarer5=int64#9 -# asm 2: mov squarer5=%r11 -mov %rax,%r11 - -# qhasm: squarer6 = squarerdx -# asm 1: mov squarer6=int64#10 -# asm 2: mov squarer6=%r12 -mov %rdx,%r12 - -# qhasm: squarerax = rx2_stack -# asm 1: movq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 104(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack -# asm 1: mulq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 112(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx1_stack -# asm 1: mulq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 112(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack -# asm 1: mulq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 88(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx0_stack -# asm 1: mulq rx0=int64#11 -# asm 2: mov rx0=%r13 -mov %rax,%r13 - -# qhasm: squaret1 = squarerdx -# asm 1: mov squaret1=int64#12 -# asm 2: mov squaret1=%r14 -mov %rdx,%r14 - -# qhasm: squarerax = rx1_stack -# asm 1: movq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 96(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx1_stack -# asm 1: mulq squaret2=int64#13 -# asm 2: mov squaret2=%r15 -mov %rax,%r15 - -# qhasm: squaret3 = squarerdx -# asm 1: mov squaret3=int64#14 -# asm 2: mov squaret3=%rbx -mov %rdx,%rbx - -# qhasm: squarerax = rx2_stack -# asm 1: movq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 104(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx2_stack -# asm 1: mulq squarerax=int64#7 -# asm 2: movq squarerax=%rax -movq 112(%rsp),%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * rx3_stack -# asm 1: mulq squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r10,%rax - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: squarer4 = squarerax -# asm 1: mov squarer4=int64#8 -# asm 2: mov squarer4=%r10 -mov %rax,%r10 - -# qhasm: squarerax = squarer5 -# asm 1: mov squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r11,%rax - -# qhasm: squarer5 = squarerdx -# asm 1: mov squarer5=int64#9 -# asm 2: mov squarer5=%r11 -mov %rdx,%r11 - -# qhasm: (uint128) squarerdx squarerax = squarerax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? squarer5 += squarerax -# asm 1: add squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %r12,%rax - -# qhasm: squarer6 = 0 -# asm 1: mov $0,>squarer6=int64#10 -# asm 2: mov $0,>squarer6=%r12 -mov $0,%r12 - -# qhasm: squarer6 += squarerdx + carry -# asm 1: adc squarerax=int64#7 -# asm 2: mov squarerax=%rax -mov %rsi,%rax - -# qhasm: squarer7 = 0 -# asm 1: mov $0,>squarer7=int64#2 -# asm 2: mov $0,>squarer7=%rsi -mov $0,%rsi - -# qhasm: squarer7 += squarerdx + carry -# asm 1: adc squarer8=int64#7 -# asm 2: mov $0,>squarer8=%rax -mov $0,%rax - -# qhasm: squarer8 += squarerdx + carry -# asm 1: adc squarezero=int64#2 -# asm 2: mov $0,>squarezero=%rsi -mov $0,%rsi - -# qhasm: squarer8 += squarezero + carry -# asm 1: adc squarer8=int64#3 -# asm 2: imulq $38,squarer8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rx0 += squarer8 -# asm 1: add squarezero=int64#2 -# asm 2: imulq $38,squarezero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rx0 += squarezero -# asm 1: add addt0=int64#2 -# asm 2: mov $0,>addt0=%rsi -mov $0,%rsi - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#3 -# asm 2: mov $38,>addt1=%rdx -mov $38,%rdx - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae addt0=int64#2 -# asm 2: mov $0,>addt0=%rsi -mov $0,%rsi - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#3 -# asm 2: mov $38,>addt1=%rdx -mov $38,%rdx - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/ge25519_double.c b/ext/ed25519-amd64-asm/ge25519_double.c deleted file mode 100644 index d55e2b4f..00000000 --- a/ext/ed25519-amd64-asm/ge25519_double.c +++ /dev/null @@ -1,8 +0,0 @@ -#include "ge25519.h" - -void ge25519_double(ge25519_p3 *r, const ge25519_p3 *p) -{ - ge25519_p1p1 grp1p1; - ge25519_dbl_p1p1(&grp1p1, (ge25519_p2 *)p); - ge25519_p1p1_to_p3(r, &grp1p1); -} diff --git a/ext/ed25519-amd64-asm/ge25519_double_scalarmult.c b/ext/ed25519-amd64-asm/ge25519_double_scalarmult.c deleted file mode 100644 index 30c922af..00000000 --- a/ext/ed25519-amd64-asm/ge25519_double_scalarmult.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "fe25519.h" -#include "sc25519.h" -#include "ge25519.h" - -#define S1_SWINDOWSIZE 5 -#define PRE1_SIZE (1<<(S1_SWINDOWSIZE-2)) -#define S2_SWINDOWSIZE 7 -#define PRE2_SIZE (1<<(S2_SWINDOWSIZE-2)) - -ge25519_niels pre2[PRE2_SIZE] = { -#include "ge25519_base_slide_multiples.data" -}; - -static const fe25519 ec2d = {{0xEBD69B9426B2F146, 0x00E0149A8283B156, 0x198E80F2EEF3D130, 0xA406D9DC56DFFCE7}}; - -static void setneutral(ge25519 *r) -{ - fe25519_setint(&r->x,0); - fe25519_setint(&r->y,1); - fe25519_setint(&r->z,1); - fe25519_setint(&r->t,0); -} - -/* computes [s1]p1 + [s2]p2 */ -void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const sc25519 *s2) -{ - signed char slide1[256], slide2[256]; - ge25519_pniels pre1[PRE1_SIZE], neg; - ge25519_p3 d1; - ge25519_p1p1 t; - ge25519_niels nneg; - fe25519 d; - int i; - - sc25519_slide(slide1, s1, S1_SWINDOWSIZE); - sc25519_slide(slide2, s2, S2_SWINDOWSIZE); - - /* precomputation */ - pre1[0] = *(ge25519_pniels *)p1; - ge25519_dbl_p1p1(&t,(ge25519_p2 *)pre1); ge25519_p1p1_to_p3(&d1, &t); - /* Convert pre[0] to projective Niels representation */ - d = pre1[0].ysubx; - fe25519_sub(&pre1[0].ysubx, &pre1[0].xaddy, &pre1[0].ysubx); - fe25519_add(&pre1[0].xaddy, &pre1[0].xaddy, &d); - fe25519_mul(&pre1[0].t2d, &pre1[0].t2d, &ec2d); - - for(i=0;i= 0;--i) { - if (slide1[i] || slide2[i]) goto firstbit; - } - - for(;i>=0;i--) - { - firstbit: - - ge25519_dbl_p1p1(&t, (ge25519_p2 *)r); - - if(slide1[i]>0) - { - ge25519_p1p1_to_p3(r, &t); - ge25519_pnielsadd_p1p1(&t, r, &pre1[slide1[i]/2]); - } - else if(slide1[i]<0) - { - ge25519_p1p1_to_p3(r, &t); - neg = pre1[-slide1[i]/2]; - d = neg.ysubx; - neg.ysubx = neg.xaddy; - neg.xaddy = d; - fe25519_neg(&neg.t2d, &neg.t2d); - ge25519_pnielsadd_p1p1(&t, r, &neg); - } - - if(slide2[i]>0) - { - ge25519_p1p1_to_p3(r, &t); - ge25519_nielsadd_p1p1(&t, r, &pre2[slide2[i]/2]); - } - else if(slide2[i]<0) - { - ge25519_p1p1_to_p3(r, &t); - nneg = pre2[-slide2[i]/2]; - d = nneg.ysubx; - nneg.ysubx = nneg.xaddy; - nneg.xaddy = d; - fe25519_neg(&nneg.t2d, &nneg.t2d); - ge25519_nielsadd_p1p1(&t, r, &nneg); - } - - ge25519_p1p1_to_p2((ge25519_p2 *)r, &t); - } -} diff --git a/ext/ed25519-amd64-asm/ge25519_isneutral.c b/ext/ed25519-amd64-asm/ge25519_isneutral.c deleted file mode 100644 index cf566dba..00000000 --- a/ext/ed25519-amd64-asm/ge25519_isneutral.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "fe25519.h" -#include "ge25519.h" - -int ge25519_isneutral_vartime(const ge25519_p3 *p) -{ - if(!fe25519_iszero_vartime(&p->x)) return 0; - if(!fe25519_iseq_vartime(&p->y, &p->z)) return 0; - return 1; -} diff --git a/ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c b/ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c deleted file mode 100644 index afc6aeae..00000000 --- a/ext/ed25519-amd64-asm/ge25519_multi_scalarmult.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "fe25519.h" -#include "sc25519.h" -#include "ge25519.h" -#include "index_heap.h" - -static void setneutral(ge25519 *r) -{ - fe25519_setint(&r->x,0); - fe25519_setint(&r->y,1); - fe25519_setint(&r->z,1); - fe25519_setint(&r->t,0); -} - -static void ge25519_scalarmult_vartime_2limbs(ge25519 *r, ge25519 *p, sc25519 *s) -{ - if (s->v[1] == 0 && s->v[0] == 1) /* This will happen most of the time after Bos-Coster */ - *r = *p; - else if (s->v[1] == 0 && s->v[0] == 0) /* This won't ever happen, except for all scalars == 0 in Bos-Coster */ - setneutral(r); - else - { - ge25519 d; - unsigned long long mask = (1ULL << 63); - int i = 1; - while(!(mask & s->v[1]) && mask != 0) - mask >>= 1; - if(mask == 0) - { - mask = (1ULL << 63); - i = 0; - while(!(mask & s->v[0]) && mask != 0) - mask >>= 1; - } - d = *p; - mask >>= 1; - for(;mask != 0;mask >>= 1) - { - ge25519_double(&d,&d); - if(s->v[i] & mask) - ge25519_add(&d,&d,p); - } - if(i==1) - { - mask = (1ULL << 63); - for(;mask != 0;mask >>= 1) - { - ge25519_double(&d,&d); - if(s->v[0] & mask) - ge25519_add(&d,&d,p); - } - } - *r = d; - } -} - -/* caller's responsibility to ensure npoints >= 5 */ -void ge25519_multi_scalarmult_vartime(ge25519_p3 *r, ge25519_p3 *p, sc25519 *s, const unsigned long long npoints) -{ - unsigned long long pos[npoints]; - unsigned long long hlen=((npoints+1)/2)|1; - unsigned long long max1, max2,i; - - heap_init(pos, hlen, s); - - for(i=0;;i++) - { - heap_get2max(pos, &max1, &max2, s); - if((s[max1].v[3] == 0) || (sc25519_iszero_vartime(&s[max2]))) break; - sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); - ge25519_add(&p[max2],&p[max2],&p[max1]); - heap_rootreplaced(pos, hlen, s); - } - for(;;i++) - { - heap_get2max(pos, &max1, &max2, s); - if((s[max1].v[2] == 0) || (sc25519_iszero_vartime(&s[max2]))) break; - sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); - ge25519_add(&p[max2],&p[max2],&p[max1]); - heap_rootreplaced_3limbs(pos, hlen, s); - } - /* We know that (npoints-1)/2 scalars are only 128-bit scalars */ - heap_extend(pos, hlen, npoints, s); - hlen = npoints; - for(;;i++) - { - heap_get2max(pos, &max1, &max2, s); - if((s[max1].v[1] == 0) || (sc25519_iszero_vartime(&s[max2]))) break; - sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); - ge25519_add(&p[max2],&p[max2],&p[max1]); - heap_rootreplaced_2limbs(pos, hlen, s); - } - for(;;i++) - { - heap_get2max(pos, &max1, &max2, s); - if(sc25519_iszero_vartime(&s[max2])) break; - sc25519_sub_nored(&s[max1],&s[max1],&s[max2]); - ge25519_add(&p[max2],&p[max2],&p[max1]); - heap_rootreplaced_1limb(pos, hlen, s); - } - - ge25519_scalarmult_vartime_2limbs(r, &p[max1], &s[max1]); -} diff --git a/ext/ed25519-amd64-asm/ge25519_nielsadd2.s b/ext/ed25519-amd64-asm/ge25519_nielsadd2.s deleted file mode 100644 index 19d71f11..00000000 --- a/ext/ed25519-amd64-asm/ge25519_nielsadd2.s +++ /dev/null @@ -1,5791 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 qp - -# qhasm: input rp - -# qhasm: input qp - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 a0 - -# qhasm: int64 a1 - -# qhasm: int64 a2 - -# qhasm: int64 a3 - -# qhasm: stack64 a0_stack - -# qhasm: stack64 a1_stack - -# qhasm: stack64 a2_stack - -# qhasm: stack64 a3_stack - -# qhasm: int64 b0 - -# qhasm: int64 b1 - -# qhasm: int64 b2 - -# qhasm: int64 b3 - -# qhasm: stack64 b0_stack - -# qhasm: stack64 b1_stack - -# qhasm: stack64 b2_stack - -# qhasm: stack64 b3_stack - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: stack64 c0_stack - -# qhasm: stack64 c1_stack - -# qhasm: stack64 c2_stack - -# qhasm: stack64 c3_stack - -# qhasm: int64 d0 - -# qhasm: int64 d1 - -# qhasm: int64 d2 - -# qhasm: int64 d3 - -# qhasm: stack64 d0_stack - -# qhasm: stack64 d1_stack - -# qhasm: stack64 d2_stack - -# qhasm: stack64 d3_stack - -# qhasm: int64 e0 - -# qhasm: int64 e1 - -# qhasm: int64 e2 - -# qhasm: int64 e3 - -# qhasm: stack64 e0_stack - -# qhasm: stack64 e1_stack - -# qhasm: stack64 e2_stack - -# qhasm: stack64 e3_stack - -# qhasm: int64 f0 - -# qhasm: int64 f1 - -# qhasm: int64 f2 - -# qhasm: int64 f3 - -# qhasm: stack64 f0_stack - -# qhasm: stack64 f1_stack - -# qhasm: stack64 f2_stack - -# qhasm: stack64 f3_stack - -# qhasm: int64 g0 - -# qhasm: int64 g1 - -# qhasm: int64 g2 - -# qhasm: int64 g3 - -# qhasm: stack64 g0_stack - -# qhasm: stack64 g1_stack - -# qhasm: stack64 g2_stack - -# qhasm: stack64 g3_stack - -# qhasm: int64 h0 - -# qhasm: int64 h1 - -# qhasm: int64 h2 - -# qhasm: int64 h3 - -# qhasm: stack64 h0_stack - -# qhasm: stack64 h1_stack - -# qhasm: stack64 h2_stack - -# qhasm: stack64 h3_stack - -# qhasm: int64 qt0 - -# qhasm: int64 qt1 - -# qhasm: int64 qt2 - -# qhasm: int64 qt3 - -# qhasm: stack64 qt0_stack - -# qhasm: stack64 qt1_stack - -# qhasm: stack64 qt2_stack - -# qhasm: stack64 qt3_stack - -# qhasm: int64 t10 - -# qhasm: int64 t11 - -# qhasm: int64 t12 - -# qhasm: int64 t13 - -# qhasm: stack64 t10_stack - -# qhasm: stack64 t11_stack - -# qhasm: stack64 t12_stack - -# qhasm: stack64 t13_stack - -# qhasm: int64 t20 - -# qhasm: int64 t21 - -# qhasm: int64 t22 - -# qhasm: int64 t23 - -# qhasm: stack64 t20_stack - -# qhasm: stack64 t21_stack - -# qhasm: stack64 t22_stack - -# qhasm: stack64 t23_stack - -# qhasm: int64 rx0 - -# qhasm: int64 rx1 - -# qhasm: int64 rx2 - -# qhasm: int64 rx3 - -# qhasm: int64 ry0 - -# qhasm: int64 ry1 - -# qhasm: int64 ry2 - -# qhasm: int64 ry3 - -# qhasm: int64 rz0 - -# qhasm: int64 rz1 - -# qhasm: int64 rz2 - -# qhasm: int64 rz3 - -# qhasm: int64 rt0 - -# qhasm: int64 rt1 - -# qhasm: int64 rt2 - -# qhasm: int64 rt3 - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: int64 addt0 - -# qhasm: int64 addt1 - -# qhasm: int64 subt0 - -# qhasm: int64 subt1 - -# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 -.globl crypto_sign_ed25519_amd64_64_ge25519_nielsadd2 -_crypto_sign_ed25519_amd64_64_ge25519_nielsadd2: -crypto_sign_ed25519_amd64_64_ge25519_nielsadd2: -mov %rsp,%r11 -and $31,%r11 -add $192,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: a0 = *(uint64 *)(rp + 32) -# asm 1: movq 32(a0=int64#3 -# asm 2: movq 32(a0=%rdx -movq 32(%rdi),%rdx - -# qhasm: a1 = *(uint64 *)(rp + 40) -# asm 1: movq 40(a1=int64#4 -# asm 2: movq 40(a1=%rcx -movq 40(%rdi),%rcx - -# qhasm: a2 = *(uint64 *)(rp + 48) -# asm 1: movq 48(a2=int64#5 -# asm 2: movq 48(a2=%r8 -movq 48(%rdi),%r8 - -# qhasm: a3 = *(uint64 *)(rp + 56) -# asm 1: movq 56(a3=int64#6 -# asm 2: movq 56(a3=%r9 -movq 56(%rdi),%r9 - -# qhasm: b0 = a0 -# asm 1: mov b0=int64#7 -# asm 2: mov b0=%rax -mov %rdx,%rax - -# qhasm: b1 = a1 -# asm 1: mov b1=int64#8 -# asm 2: mov b1=%r10 -mov %rcx,%r10 - -# qhasm: b2 = a2 -# asm 1: mov b2=int64#9 -# asm 2: mov b2=%r11 -mov %r8,%r11 - -# qhasm: b3 = a3 -# asm 1: mov b3=int64#10 -# asm 2: mov b3=%r12 -mov %r9,%r12 - -# qhasm: carry? a0 -= *(uint64 *) (rp + 0) -# asm 1: subq 0(subt0=int64#11 -# asm 2: mov $0,>subt0=%r13 -mov $0,%r13 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#12 -# asm 2: mov $38,>subt1=%r14 -mov $38,%r14 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#11 -# asm 2: mov $0,>addt0=%r13 -mov $0,%r13 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#12 -# asm 2: mov $38,>addt1=%r14 -mov $38,%r14 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %rdx,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %rcx,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r8,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %r9,80(%rsp) - -# qhasm: b0_stack = b0 -# asm 1: movq b0_stack=stack64#12 -# asm 2: movq b0_stack=88(%rsp) -movq %rax,88(%rsp) - -# qhasm: b1_stack = b1 -# asm 1: movq b1_stack=stack64#13 -# asm 2: movq b1_stack=96(%rsp) -movq %r10,96(%rsp) - -# qhasm: b2_stack = b2 -# asm 1: movq b2_stack=stack64#14 -# asm 2: movq b2_stack=104(%rsp) -movq %r11,104(%rsp) - -# qhasm: b3_stack = b3 -# asm 1: movq b3_stack=stack64#15 -# asm 2: movq b3_stack=112(%rsp) -movq %r12,112(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = a0_stack -# asm 1: movq mulx0=int64#9 -# asm 2: movq mulx0=%r11 -movq 56(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a0=int64#10 -# asm 2: mov a0=%r12 -mov %rax,%r12 - -# qhasm: a1 = mulrdx -# asm 1: mov a1=int64#11 -# asm 2: mov a1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(qp + 8) -# asm 1: movq 8(mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a2=int64#12 -# asm 2: mov $0,>a2=%r14 -mov $0,%r14 - -# qhasm: a2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a3=int64#13 -# asm 2: mov $0,>a3=%r15 -mov $0,%r15 - -# qhasm: a3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq mulx1=%r11 -movq 64(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq mulx2=%r11 -movq 72(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq mulx3=%r11 -movq 80(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? a0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: a0 += mulzero -# asm 1: add a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %r12,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r13,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r14,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %r15,80(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = b0_stack -# asm 1: movq mulx0=int64#9 -# asm 2: movq mulx0=%r11 -movq 88(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul e0=int64#10 -# asm 2: mov e0=%r12 -mov %rax,%r12 - -# qhasm: e1 = mulrdx -# asm 1: mov e1=int64#11 -# asm 2: mov e1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(qp + 40) -# asm 1: movq 40(mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul e2=int64#12 -# asm 2: mov $0,>e2=%r14 -mov $0,%r14 - -# qhasm: e2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul e3=int64#13 -# asm 2: mov $0,>e3=%r15 -mov $0,%r15 - -# qhasm: e3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq mulx1=%r11 -movq 96(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq mulx2=%r11 -movq 104(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq mulx3=%r11 -movq 112(%rsp),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? e0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: e0 += mulzero -# asm 1: add h0=int64#3 -# asm 2: mov h0=%rdx -mov %r12,%rdx - -# qhasm: h1 = e1 -# asm 1: mov h1=int64#4 -# asm 2: mov h1=%rcx -mov %r13,%rcx - -# qhasm: h2 = e2 -# asm 1: mov h2=int64#5 -# asm 2: mov h2=%r8 -mov %r14,%r8 - -# qhasm: h3 = e3 -# asm 1: mov h3=int64#6 -# asm 2: mov h3=%r9 -mov %r15,%r9 - -# qhasm: carry? e0 -= a0_stack -# asm 1: subq subt0=int64#7 -# asm 2: mov $0,>subt0=%rax -mov $0,%rax - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#8 -# asm 2: mov $38,>subt1=%r10 -mov $38,%r10 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#7 -# asm 2: mov $0,>addt0=%rax -mov $0,%rax - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#8 -# asm 2: mov $38,>addt1=%r10 -mov $38,%r10 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae h0_stack=stack64#8 -# asm 2: movq h0_stack=56(%rsp) -movq %rdx,56(%rsp) - -# qhasm: h1_stack = h1 -# asm 1: movq h1_stack=stack64#9 -# asm 2: movq h1_stack=64(%rsp) -movq %rcx,64(%rsp) - -# qhasm: h2_stack = h2 -# asm 1: movq h2_stack=stack64#10 -# asm 2: movq h2_stack=72(%rsp) -movq %r8,72(%rsp) - -# qhasm: h3_stack = h3 -# asm 1: movq h3_stack=stack64#11 -# asm 2: movq h3_stack=80(%rsp) -movq %r9,80(%rsp) - -# qhasm: e0_stack = e0 -# asm 1: movq e0_stack=stack64#12 -# asm 2: movq e0_stack=88(%rsp) -movq %r12,88(%rsp) - -# qhasm: e1_stack = e1 -# asm 1: movq e1_stack=stack64#13 -# asm 2: movq e1_stack=96(%rsp) -movq %r13,96(%rsp) - -# qhasm: e2_stack = e2 -# asm 1: movq e2_stack=stack64#14 -# asm 2: movq e2_stack=104(%rsp) -movq %r14,104(%rsp) - -# qhasm: e3_stack = e3 -# asm 1: movq e3_stack=stack64#15 -# asm 2: movq e3_stack=112(%rsp) -movq %r15,112(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(rp + 96) -# asm 1: movq 96(mulx0=int64#9 -# asm 2: movq 96(mulx0=%r11 -movq 96(%rdi),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c0=int64#10 -# asm 2: mov c0=%r12 -mov %rax,%r12 - -# qhasm: c1 = mulrdx -# asm 1: mov c1=int64#11 -# asm 2: mov c1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(qp + 72) -# asm 1: movq 72(mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c2=int64#12 -# asm 2: mov $0,>c2=%r14 -mov $0,%r14 - -# qhasm: c2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c3=int64#13 -# asm 2: mov $0,>c3=%r15 -mov $0,%r15 - -# qhasm: c3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 104(mulx1=%r11 -movq 104(%rdi),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 112(mulx2=%r11 -movq 112(%rdi),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 120(mulx3=%r11 -movq 120(%rdi),%r11 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? c0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: c0 += mulzero -# asm 1: add f0=int64#2 -# asm 2: movq 64(f0=%rsi -movq 64(%rdi),%rsi - -# qhasm: f1 = *(uint64 *)(rp + 72) -# asm 1: movq 72(f1=int64#3 -# asm 2: movq 72(f1=%rdx -movq 72(%rdi),%rdx - -# qhasm: f2 = *(uint64 *)(rp + 80) -# asm 1: movq 80(f2=int64#4 -# asm 2: movq 80(f2=%rcx -movq 80(%rdi),%rcx - -# qhasm: f3 = *(uint64 *)(rp + 88) -# asm 1: movq 88(f3=int64#5 -# asm 2: movq 88(f3=%r8 -movq 88(%rdi),%r8 - -# qhasm: carry? f0 += f0 -# asm 1: add addt0=int64#6 -# asm 2: mov $0,>addt0=%r9 -mov $0,%r9 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#7 -# asm 2: mov $38,>addt1=%rax -mov $38,%rax - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae g0=int64#6 -# asm 2: mov g0=%r9 -mov %rsi,%r9 - -# qhasm: g1 = f1 -# asm 1: mov g1=int64#7 -# asm 2: mov g1=%rax -mov %rdx,%rax - -# qhasm: g2 = f2 -# asm 1: mov g2=int64#8 -# asm 2: mov g2=%r10 -mov %rcx,%r10 - -# qhasm: g3 = f3 -# asm 1: mov g3=int64#9 -# asm 2: mov g3=%r11 -mov %r8,%r11 - -# qhasm: carry? f0 -= c0 -# asm 1: sub subt0=int64#14 -# asm 2: mov $0,>subt0=%rbx -mov $0,%rbx - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#15 -# asm 2: mov $38,>subt1=%rbp -mov $38,%rbp - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#10 -# asm 2: mov $0,>addt0=%r12 -mov $0,%r12 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#11 -# asm 2: mov $38,>addt1=%r13 -mov $38,%r13 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae g0_stack=stack64#16 -# asm 2: movq g0_stack=120(%rsp) -movq %r9,120(%rsp) - -# qhasm: g1_stack = g1 -# asm 1: movq g1_stack=stack64#17 -# asm 2: movq g1_stack=128(%rsp) -movq %rax,128(%rsp) - -# qhasm: g2_stack = g2 -# asm 1: movq g2_stack=stack64#18 -# asm 2: movq g2_stack=136(%rsp) -movq %r10,136(%rsp) - -# qhasm: g3_stack = g3 -# asm 1: movq g3_stack=stack64#19 -# asm 2: movq g3_stack=144(%rsp) -movq %r11,144(%rsp) - -# qhasm: f0_stack = f0 -# asm 1: movq f0_stack=stack64#20 -# asm 2: movq f0_stack=152(%rsp) -movq %rsi,152(%rsp) - -# qhasm: f1_stack = f1 -# asm 1: movq f1_stack=stack64#21 -# asm 2: movq f1_stack=160(%rsp) -movq %rdx,160(%rsp) - -# qhasm: f2_stack = f2 -# asm 1: movq f2_stack=stack64#22 -# asm 2: movq f2_stack=168(%rsp) -movq %rcx,168(%rsp) - -# qhasm: f3_stack = f3 -# asm 1: movq f3_stack=stack64#23 -# asm 2: movq f3_stack=176(%rsp) -movq %r8,176(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#2 -# asm 2: mov $0,>mulr4=%rsi -mov $0,%rsi - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#4 -# asm 2: mov $0,>mulr5=%rcx -mov $0,%rcx - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulx0 = e0_stack -# asm 1: movq mulx0=int64#8 -# asm 2: movq mulx0=%r10 -movq 88(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx0=int64#9 -# asm 2: mov rx0=%r11 -mov %rax,%r11 - -# qhasm: rx1 = mulrdx -# asm 1: mov rx1=int64#10 -# asm 2: mov rx1=%r12 -mov %rdx,%r12 - -# qhasm: mulrax = f1_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx2=int64#11 -# asm 2: mov $0,>rx2=%r13 -mov $0,%r13 - -# qhasm: rx2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx3=int64#12 -# asm 2: mov $0,>rx3=%r14 -mov $0,%r14 - -# qhasm: rx3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#8 -# asm 2: movq mulx1=%r10 -movq 96(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#8 -# asm 2: movq mulx2=%r10 -movq 104(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#8 -# asm 2: movq mulx3=%r10 -movq 112(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rsi,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rx0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rx0 += mulzero -# asm 1: add mulr4=int64#2 -# asm 2: mov $0,>mulr4=%rsi -mov $0,%rsi - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#4 -# asm 2: mov $0,>mulr5=%rcx -mov $0,%rcx - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulx0 = h0_stack -# asm 1: movq mulx0=int64#8 -# asm 2: movq mulx0=%r10 -movq 56(%rsp),%r10 - -# qhasm: mulrax = g0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry0=int64#9 -# asm 2: mov ry0=%r11 -mov %rax,%r11 - -# qhasm: ry1 = mulrdx -# asm 1: mov ry1=int64#10 -# asm 2: mov ry1=%r12 -mov %rdx,%r12 - -# qhasm: mulrax = g1_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry2=int64#11 -# asm 2: mov $0,>ry2=%r13 -mov $0,%r13 - -# qhasm: ry2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry3=int64#12 -# asm 2: mov $0,>ry3=%r14 -mov $0,%r14 - -# qhasm: ry3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#8 -# asm 2: movq mulx1=%r10 -movq 64(%rsp),%r10 - -# qhasm: mulrax = g0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#8 -# asm 2: movq mulx2=%r10 -movq 72(%rsp),%r10 - -# qhasm: mulrax = g0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#8 -# asm 2: movq mulx3=%r10 -movq 80(%rsp),%r10 - -# qhasm: mulrax = g0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 120(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 128(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 136(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 144(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rsi,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? ry0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: ry0 += mulzero -# asm 1: add mulr4=int64#2 -# asm 2: mov $0,>mulr4=%rsi -mov $0,%rsi - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#4 -# asm 2: mov $0,>mulr5=%rcx -mov $0,%rcx - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulx0 = g0_stack -# asm 1: movq mulx0=int64#8 -# asm 2: movq mulx0=%r10 -movq 120(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz0=int64#9 -# asm 2: mov rz0=%r11 -mov %rax,%r11 - -# qhasm: rz1 = mulrdx -# asm 1: mov rz1=int64#10 -# asm 2: mov rz1=%r12 -mov %rdx,%r12 - -# qhasm: mulrax = f1_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz2=int64#11 -# asm 2: mov $0,>rz2=%r13 -mov $0,%r13 - -# qhasm: rz2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz3=int64#12 -# asm 2: mov $0,>rz3=%r14 -mov $0,%r14 - -# qhasm: rz3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#8 -# asm 2: movq mulx1=%r10 -movq 128(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#8 -# asm 2: movq mulx2=%r10 -movq 136(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#8 -# asm 2: movq mulx3=%r10 -movq 144(%rsp),%r10 - -# qhasm: mulrax = f0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 152(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 160(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 168(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 176(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rsi,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rz0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rz0 += mulzero -# asm 1: add mulr4=int64#2 -# asm 2: mov $0,>mulr4=%rsi -mov $0,%rsi - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#4 -# asm 2: mov $0,>mulr5=%rcx -mov $0,%rcx - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulx0 = e0_stack -# asm 1: movq mulx0=int64#8 -# asm 2: movq mulx0=%r10 -movq 88(%rsp),%r10 - -# qhasm: mulrax = h0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt0=int64#9 -# asm 2: mov rt0=%r11 -mov %rax,%r11 - -# qhasm: rt1 = mulrdx -# asm 1: mov rt1=int64#10 -# asm 2: mov rt1=%r12 -mov %rdx,%r12 - -# qhasm: mulrax = h1_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 64(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt2=int64#11 -# asm 2: mov $0,>rt2=%r13 -mov $0,%r13 - -# qhasm: rt2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 72(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt3=int64#12 -# asm 2: mov $0,>rt3=%r14 -mov $0,%r14 - -# qhasm: rt3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 80(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#8 -# asm 2: movq mulx1=%r10 -movq 96(%rsp),%r10 - -# qhasm: mulrax = h0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 64(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 72(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 80(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#8 -# asm 2: movq mulx2=%r10 -movq 104(%rsp),%r10 - -# qhasm: mulrax = h0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 64(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 72(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 80(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#8 -# asm 2: movq mulx3=%r10 -movq 112(%rsp),%r10 - -# qhasm: mulrax = h0_stack -# asm 1: movq mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 64(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 72(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#13 -# asm 2: mov $0,>mulc=%r15 -mov $0,%r15 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq mulrax=%rax -movq 80(%rsp),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rsi,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rt0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rt0 += mulzero -# asm 1: add caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s b/ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s deleted file mode 100644 index b5629462..00000000 --- a/ext/ed25519-amd64-asm/ge25519_nielsadd_p1p1.s +++ /dev/null @@ -1,3072 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 pp - -# qhasm: int64 qp - -# qhasm: input rp - -# qhasm: input pp - -# qhasm: input qp - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 a0 - -# qhasm: int64 a1 - -# qhasm: int64 a2 - -# qhasm: int64 a3 - -# qhasm: stack64 a0_stack - -# qhasm: stack64 a1_stack - -# qhasm: stack64 a2_stack - -# qhasm: stack64 a3_stack - -# qhasm: int64 b0 - -# qhasm: int64 b1 - -# qhasm: int64 b2 - -# qhasm: int64 b3 - -# qhasm: stack64 b0_stack - -# qhasm: stack64 b1_stack - -# qhasm: stack64 b2_stack - -# qhasm: stack64 b3_stack - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: stack64 c0_stack - -# qhasm: stack64 c1_stack - -# qhasm: stack64 c2_stack - -# qhasm: stack64 c3_stack - -# qhasm: int64 d0 - -# qhasm: int64 d1 - -# qhasm: int64 d2 - -# qhasm: int64 d3 - -# qhasm: stack64 d0_stack - -# qhasm: stack64 d1_stack - -# qhasm: stack64 d2_stack - -# qhasm: stack64 d3_stack - -# qhasm: int64 e0 - -# qhasm: int64 e1 - -# qhasm: int64 e2 - -# qhasm: int64 e3 - -# qhasm: stack64 e0_stack - -# qhasm: stack64 e1_stack - -# qhasm: stack64 e2_stack - -# qhasm: stack64 e3_stack - -# qhasm: int64 f0 - -# qhasm: int64 f1 - -# qhasm: int64 f2 - -# qhasm: int64 f3 - -# qhasm: stack64 f0_stack - -# qhasm: stack64 f1_stack - -# qhasm: stack64 f2_stack - -# qhasm: stack64 f3_stack - -# qhasm: int64 g0 - -# qhasm: int64 g1 - -# qhasm: int64 g2 - -# qhasm: int64 g3 - -# qhasm: stack64 g0_stack - -# qhasm: stack64 g1_stack - -# qhasm: stack64 g2_stack - -# qhasm: stack64 g3_stack - -# qhasm: int64 h0 - -# qhasm: int64 h1 - -# qhasm: int64 h2 - -# qhasm: int64 h3 - -# qhasm: stack64 h0_stack - -# qhasm: stack64 h1_stack - -# qhasm: stack64 h2_stack - -# qhasm: stack64 h3_stack - -# qhasm: int64 qt0 - -# qhasm: int64 qt1 - -# qhasm: int64 qt2 - -# qhasm: int64 qt3 - -# qhasm: stack64 qt0_stack - -# qhasm: stack64 qt1_stack - -# qhasm: stack64 qt2_stack - -# qhasm: stack64 qt3_stack - -# qhasm: int64 t10 - -# qhasm: int64 t11 - -# qhasm: int64 t12 - -# qhasm: int64 t13 - -# qhasm: stack64 t10_stack - -# qhasm: stack64 t11_stack - -# qhasm: stack64 t12_stack - -# qhasm: stack64 t13_stack - -# qhasm: int64 t20 - -# qhasm: int64 t21 - -# qhasm: int64 t22 - -# qhasm: int64 t23 - -# qhasm: stack64 t20_stack - -# qhasm: stack64 t21_stack - -# qhasm: stack64 t22_stack - -# qhasm: stack64 t23_stack - -# qhasm: int64 rx0 - -# qhasm: int64 rx1 - -# qhasm: int64 rx2 - -# qhasm: int64 rx3 - -# qhasm: int64 ry0 - -# qhasm: int64 ry1 - -# qhasm: int64 ry2 - -# qhasm: int64 ry3 - -# qhasm: int64 rz0 - -# qhasm: int64 rz1 - -# qhasm: int64 rz2 - -# qhasm: int64 rz3 - -# qhasm: int64 rt0 - -# qhasm: int64 rt1 - -# qhasm: int64 rt2 - -# qhasm: int64 rt3 - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: int64 addt0 - -# qhasm: int64 addt1 - -# qhasm: int64 subt0 - -# qhasm: int64 subt1 - -# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 -.globl crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1 -_crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1: -crypto_sign_ed25519_amd64_64_ge25519_nielsadd_p1p1: -mov %rsp,%r11 -and $31,%r11 -add $128,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: qp = qp -# asm 1: mov qp=int64#4 -# asm 2: mov qp=%rcx -mov %rdx,%rcx - -# qhasm: a0 = *(uint64 *)(pp + 32) -# asm 1: movq 32(a0=int64#3 -# asm 2: movq 32(a0=%rdx -movq 32(%rsi),%rdx - -# qhasm: a1 = *(uint64 *)(pp + 40) -# asm 1: movq 40(a1=int64#5 -# asm 2: movq 40(a1=%r8 -movq 40(%rsi),%r8 - -# qhasm: a2 = *(uint64 *)(pp + 48) -# asm 1: movq 48(a2=int64#6 -# asm 2: movq 48(a2=%r9 -movq 48(%rsi),%r9 - -# qhasm: a3 = *(uint64 *)(pp + 56) -# asm 1: movq 56(a3=int64#7 -# asm 2: movq 56(a3=%rax -movq 56(%rsi),%rax - -# qhasm: b0 = a0 -# asm 1: mov b0=int64#8 -# asm 2: mov b0=%r10 -mov %rdx,%r10 - -# qhasm: b1 = a1 -# asm 1: mov b1=int64#9 -# asm 2: mov b1=%r11 -mov %r8,%r11 - -# qhasm: b2 = a2 -# asm 1: mov b2=int64#10 -# asm 2: mov b2=%r12 -mov %r9,%r12 - -# qhasm: b3 = a3 -# asm 1: mov b3=int64#11 -# asm 2: mov b3=%r13 -mov %rax,%r13 - -# qhasm: carry? a0 -= *(uint64 *) (pp + 0) -# asm 1: subq 0(subt0=int64#12 -# asm 2: mov $0,>subt0=%r14 -mov $0,%r14 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#13 -# asm 2: mov $38,>subt1=%r15 -mov $38,%r15 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#12 -# asm 2: mov $0,>addt0=%r14 -mov $0,%r14 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#13 -# asm 2: mov $38,>addt1=%r15 -mov $38,%r15 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %rdx,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r8,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r9,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %rax,80(%rsp) - -# qhasm: b0_stack = b0 -# asm 1: movq b0_stack=stack64#12 -# asm 2: movq b0_stack=88(%rsp) -movq %r10,88(%rsp) - -# qhasm: b1_stack = b1 -# asm 1: movq b1_stack=stack64#13 -# asm 2: movq b1_stack=96(%rsp) -movq %r11,96(%rsp) - -# qhasm: b2_stack = b2 -# asm 1: movq b2_stack=stack64#14 -# asm 2: movq b2_stack=104(%rsp) -movq %r12,104(%rsp) - -# qhasm: b3_stack = b3 -# asm 1: movq b3_stack=stack64#15 -# asm 2: movq b3_stack=112(%rsp) -movq %r13,112(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = a0_stack -# asm 1: movq mulx0=int64#10 -# asm 2: movq mulx0=%r12 -movq 56(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a0=int64#11 -# asm 2: mov a0=%r13 -mov %rax,%r13 - -# qhasm: a1 = mulrdx -# asm 1: mov a1=int64#12 -# asm 2: mov a1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 8) -# asm 1: movq 8(mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a2=int64#13 -# asm 2: mov $0,>a2=%r15 -mov $0,%r15 - -# qhasm: a2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a3=int64#14 -# asm 2: mov $0,>a3=%rbx -mov $0,%rbx - -# qhasm: a3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq mulx1=%r12 -movq 64(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq mulx2=%r12 -movq 72(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq mulx3=%r12 -movq 80(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? a0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: a0 += mulzero -# asm 1: add a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %r13,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r14,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r15,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %rbx,80(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = b0_stack -# asm 1: movq mulx0=int64#10 -# asm 2: movq mulx0=%r12 -movq 88(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul e0=int64#11 -# asm 2: mov e0=%r13 -mov %rax,%r13 - -# qhasm: e1 = mulrdx -# asm 1: mov e1=int64#12 -# asm 2: mov e1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 40) -# asm 1: movq 40(mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul e2=int64#13 -# asm 2: mov $0,>e2=%r15 -mov $0,%r15 - -# qhasm: e2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul e3=int64#14 -# asm 2: mov $0,>e3=%rbx -mov $0,%rbx - -# qhasm: e3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq mulx1=%r12 -movq 96(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq mulx2=%r12 -movq 104(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq mulx3=%r12 -movq 112(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? e0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: e0 += mulzero -# asm 1: add h0=int64#3 -# asm 2: mov h0=%rdx -mov %r13,%rdx - -# qhasm: h1 = e1 -# asm 1: mov h1=int64#5 -# asm 2: mov h1=%r8 -mov %r14,%r8 - -# qhasm: h2 = e2 -# asm 1: mov h2=int64#6 -# asm 2: mov h2=%r9 -mov %r15,%r9 - -# qhasm: h3 = e3 -# asm 1: mov h3=int64#7 -# asm 2: mov h3=%rax -mov %rbx,%rax - -# qhasm: carry? e0 -= a0_stack -# asm 1: subq subt0=int64#8 -# asm 2: mov $0,>subt0=%r10 -mov $0,%r10 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#9 -# asm 2: mov $38,>subt1=%r11 -mov $38,%r11 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#8 -# asm 2: mov $0,>addt0=%r10 -mov $0,%r10 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#9 -# asm 2: mov $38,>addt1=%r11 -mov $38,%r11 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulx0=int64#10 -# asm 2: movq 96(mulx0=%r12 -movq 96(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c0=int64#11 -# asm 2: mov c0=%r13 -mov %rax,%r13 - -# qhasm: c1 = mulrdx -# asm 1: mov c1=int64#12 -# asm 2: mov c1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 72) -# asm 1: movq 72(mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c2=int64#13 -# asm 2: mov $0,>c2=%r15 -mov $0,%r15 - -# qhasm: c2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c3=int64#14 -# asm 2: mov $0,>c3=%rbx -mov $0,%rbx - -# qhasm: c3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq 104(mulx1=%r12 -movq 104(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq 112(mulx2=%r12 -movq 112(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq 120(mulx3=%r12 -movq 120(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? c0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: c0 += mulzero -# asm 1: add f0=int64#3 -# asm 2: movq 64(f0=%rdx -movq 64(%rsi),%rdx - -# qhasm: f1 = *(uint64 *)(pp + 72) -# asm 1: movq 72(f1=int64#4 -# asm 2: movq 72(f1=%rcx -movq 72(%rsi),%rcx - -# qhasm: f2 = *(uint64 *)(pp + 80) -# asm 1: movq 80(f2=int64#5 -# asm 2: movq 80(f2=%r8 -movq 80(%rsi),%r8 - -# qhasm: f3 = *(uint64 *)(pp + 88) -# asm 1: movq 88(f3=int64#2 -# asm 2: movq 88(f3=%rsi -movq 88(%rsi),%rsi - -# qhasm: carry? f0 += f0 -# asm 1: add addt0=int64#6 -# asm 2: mov $0,>addt0=%r9 -mov $0,%r9 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#7 -# asm 2: mov $38,>addt1=%rax -mov $38,%rax - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae g0=int64#6 -# asm 2: mov g0=%r9 -mov %rdx,%r9 - -# qhasm: g1 = f1 -# asm 1: mov g1=int64#7 -# asm 2: mov g1=%rax -mov %rcx,%rax - -# qhasm: g2 = f2 -# asm 1: mov g2=int64#8 -# asm 2: mov g2=%r10 -mov %r8,%r10 - -# qhasm: g3 = f3 -# asm 1: mov g3=int64#9 -# asm 2: mov g3=%r11 -mov %rsi,%r11 - -# qhasm: carry? f0 -= c0 -# asm 1: sub subt0=int64#10 -# asm 2: mov $0,>subt0=%r12 -mov $0,%r12 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#15 -# asm 2: mov $38,>subt1=%rbp -mov $38,%rbp - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#10 -# asm 2: mov $0,>addt0=%r12 -mov $0,%r12 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#11 -# asm 2: mov $38,>addt1=%r13 -mov $38,%r13 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s b/ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s deleted file mode 100644 index beddbc79..00000000 --- a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p2.s +++ /dev/null @@ -1,2236 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 pp - -# qhasm: input rp - -# qhasm: input pp - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 rx0 - -# qhasm: int64 rx1 - -# qhasm: int64 rx2 - -# qhasm: int64 rx3 - -# qhasm: int64 ry0 - -# qhasm: int64 ry1 - -# qhasm: int64 ry2 - -# qhasm: int64 ry3 - -# qhasm: int64 rz0 - -# qhasm: int64 rz1 - -# qhasm: int64 rz2 - -# qhasm: int64 rz3 - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 -.globl crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2 -_crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2: -crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p2: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(pp + 0) -# asm 1: movq 0(mulx0=int64#9 -# asm 2: movq 0(mulx0=%r11 -movq 0(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx0=int64#10 -# asm 2: mov rx0=%r12 -mov %rax,%r12 - -# qhasm: rx1 = mulrdx -# asm 1: mov rx1=int64#11 -# asm 2: mov rx1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(pp + 104) -# asm 1: movq 104(mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx2=int64#12 -# asm 2: mov $0,>rx2=%r14 -mov $0,%r14 - -# qhasm: rx2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx3=int64#13 -# asm 2: mov $0,>rx3=%r15 -mov $0,%r15 - -# qhasm: rx3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 8(mulx1=%r11 -movq 8(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 16(mulx2=%r11 -movq 16(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 24(mulx3=%r11 -movq 24(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? rx0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: rx0 += mulzero -# asm 1: add mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulx0=int64#9 -# asm 2: movq 64(mulx0=%r11 -movq 64(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry0=int64#10 -# asm 2: mov ry0=%r12 -mov %rax,%r12 - -# qhasm: ry1 = mulrdx -# asm 1: mov ry1=int64#11 -# asm 2: mov ry1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(pp + 40) -# asm 1: movq 40(mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry2=int64#12 -# asm 2: mov $0,>ry2=%r14 -mov $0,%r14 - -# qhasm: ry2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry3=int64#13 -# asm 2: mov $0,>ry3=%r15 -mov $0,%r15 - -# qhasm: ry3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 72(mulx1=%r11 -movq 72(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 80(mulx2=%r11 -movq 80(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 88(mulx3=%r11 -movq 88(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? ry0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: ry0 += mulzero -# asm 1: add mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulx0=int64#9 -# asm 2: movq 32(mulx0=%r11 -movq 32(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz0=int64#10 -# asm 2: mov rz0=%r12 -mov %rax,%r12 - -# qhasm: rz1 = mulrdx -# asm 1: mov rz1=int64#11 -# asm 2: mov rz1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(pp + 104) -# asm 1: movq 104(mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz2=int64#12 -# asm 2: mov $0,>rz2=%r14 -mov $0,%r14 - -# qhasm: rz2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz3=int64#13 -# asm 2: mov $0,>rz3=%r15 -mov $0,%r15 - -# qhasm: rz3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 40(mulx1=%r11 -movq 40(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 48(mulx2=%r11 -movq 48(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 56(mulx3=%r11 -movq 56(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rz0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rz0 += mulzero -# asm 1: add caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s b/ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s deleted file mode 100644 index 82433fba..00000000 --- a/ext/ed25519-amd64-asm/ge25519_p1p1_to_p3.s +++ /dev/null @@ -1,2926 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 pp - -# qhasm: input rp - -# qhasm: input pp - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 rx0 - -# qhasm: int64 rx1 - -# qhasm: int64 rx2 - -# qhasm: int64 rx3 - -# qhasm: int64 ry0 - -# qhasm: int64 ry1 - -# qhasm: int64 ry2 - -# qhasm: int64 ry3 - -# qhasm: int64 rz0 - -# qhasm: int64 rz1 - -# qhasm: int64 rz2 - -# qhasm: int64 rz3 - -# qhasm: int64 rt0 - -# qhasm: int64 rt1 - -# qhasm: int64 rt2 - -# qhasm: int64 rt3 - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 -.globl crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3 -_crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3: -crypto_sign_ed25519_amd64_64_ge25519_p1p1_to_p3: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(pp + 0) -# asm 1: movq 0(mulx0=int64#9 -# asm 2: movq 0(mulx0=%r11 -movq 0(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx0=int64#10 -# asm 2: mov rx0=%r12 -mov %rax,%r12 - -# qhasm: rx1 = mulrdx -# asm 1: mov rx1=int64#11 -# asm 2: mov rx1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(pp + 104) -# asm 1: movq 104(mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx2=int64#12 -# asm 2: mov $0,>rx2=%r14 -mov $0,%r14 - -# qhasm: rx2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx3=int64#13 -# asm 2: mov $0,>rx3=%r15 -mov $0,%r15 - -# qhasm: rx3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 8(mulx1=%r11 -movq 8(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 16(mulx2=%r11 -movq 16(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 24(mulx3=%r11 -movq 24(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? rx0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: rx0 += mulzero -# asm 1: add mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulx0=int64#9 -# asm 2: movq 64(mulx0=%r11 -movq 64(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry0=int64#10 -# asm 2: mov ry0=%r12 -mov %rax,%r12 - -# qhasm: ry1 = mulrdx -# asm 1: mov ry1=int64#11 -# asm 2: mov ry1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(pp + 40) -# asm 1: movq 40(mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry2=int64#12 -# asm 2: mov $0,>ry2=%r14 -mov $0,%r14 - -# qhasm: ry2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul ry3=int64#13 -# asm 2: mov $0,>ry3=%r15 -mov $0,%r15 - -# qhasm: ry3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 72(mulx1=%r11 -movq 72(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 80(mulx2=%r11 -movq 80(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 88(mulx3=%r11 -movq 88(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? ry0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: ry0 += mulzero -# asm 1: add mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(pp + 32) -# asm 1: movq 32(mulx0=int64#9 -# asm 2: movq 32(mulx0=%r11 -movq 32(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz0=int64#10 -# asm 2: mov rz0=%r12 -mov %rax,%r12 - -# qhasm: rz1 = mulrdx -# asm 1: mov rz1=int64#11 -# asm 2: mov rz1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(pp + 104) -# asm 1: movq 104(mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz2=int64#12 -# asm 2: mov $0,>rz2=%r14 -mov $0,%r14 - -# qhasm: rz2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rz3=int64#13 -# asm 2: mov $0,>rz3=%r15 -mov $0,%r15 - -# qhasm: rz3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 40(mulx1=%r11 -movq 40(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 48(mulx2=%r11 -movq 48(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 56(mulx3=%r11 -movq 56(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#4 -# asm 2: mov mulr4=%rcx -mov %rax,%rcx - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#5 -# asm 2: mov mulr5=%r8 -mov %rdx,%r8 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#4 -# asm 2: imulq $38,mulr8=%rcx -imulq $38,%rax,%rcx - -# qhasm: carry? rz0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: rz0 += mulzero -# asm 1: add mulr4=int64#4 -# asm 2: mov $0,>mulr4=%rcx -mov $0,%rcx - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#5 -# asm 2: mov $0,>mulr5=%r8 -mov $0,%r8 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#6 -# asm 2: mov $0,>mulr6=%r9 -mov $0,%r9 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#8 -# asm 2: mov $0,>mulr7=%r10 -mov $0,%r10 - -# qhasm: mulx0 = *(uint64 *)(pp + 0) -# asm 1: movq 0(mulx0=int64#9 -# asm 2: movq 0(mulx0=%r11 -movq 0(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt0=int64#10 -# asm 2: mov rt0=%r12 -mov %rax,%r12 - -# qhasm: rt1 = mulrdx -# asm 1: mov rt1=int64#11 -# asm 2: mov rt1=%r13 -mov %rdx,%r13 - -# qhasm: mulrax = *(uint64 *)(pp + 72) -# asm 1: movq 72(mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt2=int64#12 -# asm 2: mov $0,>rt2=%r14 -mov $0,%r14 - -# qhasm: rt2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt3=int64#13 -# asm 2: mov $0,>rt3=%r15 -mov $0,%r15 - -# qhasm: rt3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#9 -# asm 2: movq 8(mulx1=%r11 -movq 8(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#9 -# asm 2: movq 16(mulx2=%r11 -movq 16(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#9 -# asm 2: movq 24(mulx3=%r11 -movq 24(%rsi),%r11 - -# qhasm: mulrax = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#14 -# asm 2: mov $0,>mulc=%rbx -mov $0,%rbx - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rsi),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %rcx,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rt0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rt0 += mulzero -# asm 1: add caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/ge25519_pack.c b/ext/ed25519-amd64-asm/ge25519_pack.c deleted file mode 100644 index f289fe57..00000000 --- a/ext/ed25519-amd64-asm/ge25519_pack.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "fe25519.h" -#include "sc25519.h" -#include "ge25519.h" - -void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) -{ - fe25519 tx, ty, zi; - fe25519_invert(&zi, &p->z); - fe25519_mul(&tx, &p->x, &zi); - fe25519_mul(&ty, &p->y, &zi); - fe25519_pack(r, &ty); - r[31] ^= fe25519_getparity(&tx) << 7; -} diff --git a/ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s b/ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s deleted file mode 100644 index aff2e75d..00000000 --- a/ext/ed25519-amd64-asm/ge25519_pnielsadd_p1p1.s +++ /dev/null @@ -1,3662 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 pp - -# qhasm: int64 qp - -# qhasm: input rp - -# qhasm: input pp - -# qhasm: input qp - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 a0 - -# qhasm: int64 a1 - -# qhasm: int64 a2 - -# qhasm: int64 a3 - -# qhasm: stack64 a0_stack - -# qhasm: stack64 a1_stack - -# qhasm: stack64 a2_stack - -# qhasm: stack64 a3_stack - -# qhasm: int64 b0 - -# qhasm: int64 b1 - -# qhasm: int64 b2 - -# qhasm: int64 b3 - -# qhasm: stack64 b0_stack - -# qhasm: stack64 b1_stack - -# qhasm: stack64 b2_stack - -# qhasm: stack64 b3_stack - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: stack64 c0_stack - -# qhasm: stack64 c1_stack - -# qhasm: stack64 c2_stack - -# qhasm: stack64 c3_stack - -# qhasm: int64 d0 - -# qhasm: int64 d1 - -# qhasm: int64 d2 - -# qhasm: int64 d3 - -# qhasm: stack64 d0_stack - -# qhasm: stack64 d1_stack - -# qhasm: stack64 d2_stack - -# qhasm: stack64 d3_stack - -# qhasm: int64 t10 - -# qhasm: int64 t11 - -# qhasm: int64 t12 - -# qhasm: int64 t13 - -# qhasm: stack64 t10_stack - -# qhasm: stack64 t11_stack - -# qhasm: stack64 t12_stack - -# qhasm: stack64 t13_stack - -# qhasm: int64 t20 - -# qhasm: int64 t21 - -# qhasm: int64 t22 - -# qhasm: int64 t23 - -# qhasm: stack64 t20_stack - -# qhasm: stack64 t21_stack - -# qhasm: stack64 t22_stack - -# qhasm: stack64 t23_stack - -# qhasm: int64 rx0 - -# qhasm: int64 rx1 - -# qhasm: int64 rx2 - -# qhasm: int64 rx3 - -# qhasm: int64 ry0 - -# qhasm: int64 ry1 - -# qhasm: int64 ry2 - -# qhasm: int64 ry3 - -# qhasm: int64 rz0 - -# qhasm: int64 rz1 - -# qhasm: int64 rz2 - -# qhasm: int64 rz3 - -# qhasm: int64 rt0 - -# qhasm: int64 rt1 - -# qhasm: int64 rt2 - -# qhasm: int64 rt3 - -# qhasm: int64 x0 - -# qhasm: int64 x1 - -# qhasm: int64 x2 - -# qhasm: int64 x3 - -# qhasm: int64 mulr4 - -# qhasm: int64 mulr5 - -# qhasm: int64 mulr6 - -# qhasm: int64 mulr7 - -# qhasm: int64 mulr8 - -# qhasm: int64 mulrax - -# qhasm: int64 mulrdx - -# qhasm: int64 mulx0 - -# qhasm: int64 mulx1 - -# qhasm: int64 mulx2 - -# qhasm: int64 mulx3 - -# qhasm: int64 mulc - -# qhasm: int64 mulzero - -# qhasm: int64 muli38 - -# qhasm: int64 addt0 - -# qhasm: int64 addt1 - -# qhasm: int64 subt0 - -# qhasm: int64 subt1 - -# qhasm: enter crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 -.globl crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1 -_crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1: -crypto_sign_ed25519_amd64_64_ge25519_pnielsadd_p1p1: -mov %rsp,%r11 -and $31,%r11 -add $128,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: qp = qp -# asm 1: mov qp=int64#4 -# asm 2: mov qp=%rcx -mov %rdx,%rcx - -# qhasm: a0 = *(uint64 *)(pp + 32) -# asm 1: movq 32(a0=int64#3 -# asm 2: movq 32(a0=%rdx -movq 32(%rsi),%rdx - -# qhasm: a1 = *(uint64 *)(pp + 40) -# asm 1: movq 40(a1=int64#5 -# asm 2: movq 40(a1=%r8 -movq 40(%rsi),%r8 - -# qhasm: a2 = *(uint64 *)(pp + 48) -# asm 1: movq 48(a2=int64#6 -# asm 2: movq 48(a2=%r9 -movq 48(%rsi),%r9 - -# qhasm: a3 = *(uint64 *)(pp + 56) -# asm 1: movq 56(a3=int64#7 -# asm 2: movq 56(a3=%rax -movq 56(%rsi),%rax - -# qhasm: b0 = a0 -# asm 1: mov b0=int64#8 -# asm 2: mov b0=%r10 -mov %rdx,%r10 - -# qhasm: b1 = a1 -# asm 1: mov b1=int64#9 -# asm 2: mov b1=%r11 -mov %r8,%r11 - -# qhasm: b2 = a2 -# asm 1: mov b2=int64#10 -# asm 2: mov b2=%r12 -mov %r9,%r12 - -# qhasm: b3 = a3 -# asm 1: mov b3=int64#11 -# asm 2: mov b3=%r13 -mov %rax,%r13 - -# qhasm: carry? a0 -= *(uint64 *)(pp + 0) -# asm 1: subq 0(subt0=int64#12 -# asm 2: mov $0,>subt0=%r14 -mov $0,%r14 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#13 -# asm 2: mov $38,>subt1=%r15 -mov $38,%r15 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae addt0=int64#12 -# asm 2: mov $0,>addt0=%r14 -mov $0,%r14 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#13 -# asm 2: mov $38,>addt1=%r15 -mov $38,%r15 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %rdx,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r8,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r9,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %rax,80(%rsp) - -# qhasm: b0_stack = b0 -# asm 1: movq b0_stack=stack64#12 -# asm 2: movq b0_stack=88(%rsp) -movq %r10,88(%rsp) - -# qhasm: b1_stack = b1 -# asm 1: movq b1_stack=stack64#13 -# asm 2: movq b1_stack=96(%rsp) -movq %r11,96(%rsp) - -# qhasm: b2_stack = b2 -# asm 1: movq b2_stack=stack64#14 -# asm 2: movq b2_stack=104(%rsp) -movq %r12,104(%rsp) - -# qhasm: b3_stack = b3 -# asm 1: movq b3_stack=stack64#15 -# asm 2: movq b3_stack=112(%rsp) -movq %r13,112(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = a0_stack -# asm 1: movq mulx0=int64#10 -# asm 2: movq mulx0=%r12 -movq 56(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a0=int64#11 -# asm 2: mov a0=%r13 -mov %rax,%r13 - -# qhasm: a1 = mulrdx -# asm 1: mov a1=int64#12 -# asm 2: mov a1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 8) -# asm 1: movq 8(mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a2=int64#13 -# asm 2: mov $0,>a2=%r15 -mov $0,%r15 - -# qhasm: a2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul a3=int64#14 -# asm 2: mov $0,>a3=%rbx -mov $0,%rbx - -# qhasm: a3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq mulx1=%r12 -movq 64(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq mulx2=%r12 -movq 72(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq mulx3=%r12 -movq 80(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 0) -# asm 1: movq 0(mulrax=int64#7 -# asm 2: movq 0(mulrax=%rax -movq 0(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 8(mulrax=%rax -movq 8(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 16(mulrax=%rax -movq 16(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 24(mulrax=%rax -movq 24(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? a0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: a0 += mulzero -# asm 1: add a0_stack=stack64#8 -# asm 2: movq a0_stack=56(%rsp) -movq %r13,56(%rsp) - -# qhasm: a1_stack = a1 -# asm 1: movq a1_stack=stack64#9 -# asm 2: movq a1_stack=64(%rsp) -movq %r14,64(%rsp) - -# qhasm: a2_stack = a2 -# asm 1: movq a2_stack=stack64#10 -# asm 2: movq a2_stack=72(%rsp) -movq %r15,72(%rsp) - -# qhasm: a3_stack = a3 -# asm 1: movq a3_stack=stack64#11 -# asm 2: movq a3_stack=80(%rsp) -movq %rbx,80(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = b0_stack -# asm 1: movq mulx0=int64#10 -# asm 2: movq mulx0=%r12 -movq 88(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx0=int64#11 -# asm 2: mov rx0=%r13 -mov %rax,%r13 - -# qhasm: rx1 = mulrdx -# asm 1: mov rx1=int64#12 -# asm 2: mov rx1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 40) -# asm 1: movq 40(mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx2=int64#13 -# asm 2: mov $0,>rx2=%r15 -mov $0,%r15 - -# qhasm: rx2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rx3=int64#14 -# asm 2: mov $0,>rx3=%rbx -mov $0,%rbx - -# qhasm: rx3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq mulx1=%r12 -movq 96(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq mulx2=%r12 -movq 104(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq mulx3=%r12 -movq 112(%rsp),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 32) -# asm 1: movq 32(mulrax=int64#7 -# asm 2: movq 32(mulrax=%rax -movq 32(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 40(mulrax=%rax -movq 40(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 48(mulrax=%rax -movq 48(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 56(mulrax=%rax -movq 56(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? rx0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: rx0 += mulzero -# asm 1: add ry0=int64#3 -# asm 2: mov ry0=%rdx -mov %r13,%rdx - -# qhasm: ry1 = rx1 -# asm 1: mov ry1=int64#5 -# asm 2: mov ry1=%r8 -mov %r14,%r8 - -# qhasm: ry2 = rx2 -# asm 1: mov ry2=int64#6 -# asm 2: mov ry2=%r9 -mov %r15,%r9 - -# qhasm: ry3 = rx3 -# asm 1: mov ry3=int64#7 -# asm 2: mov ry3=%rax -mov %rbx,%rax - -# qhasm: carry? ry0 += a0_stack -# asm 1: addq addt0=int64#8 -# asm 2: mov $0,>addt0=%r10 -mov $0,%r10 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#9 -# asm 2: mov $38,>addt1=%r11 -mov $38,%r11 - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae subt0=int64#8 -# asm 2: mov $0,>subt0=%r10 -mov $0,%r10 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#9 -# asm 2: mov $38,>subt1=%r11 -mov $38,%r11 - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = *(uint64 *)(pp + 96) -# asm 1: movq 96(mulx0=int64#10 -# asm 2: movq 96(mulx0=%r12 -movq 96(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c0=int64#11 -# asm 2: mov c0=%r13 -mov %rax,%r13 - -# qhasm: c1 = mulrdx -# asm 1: mov c1=int64#12 -# asm 2: mov c1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 104) -# asm 1: movq 104(mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c2=int64#13 -# asm 2: mov $0,>c2=%r15 -mov $0,%r15 - -# qhasm: c2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul c3=int64#14 -# asm 2: mov $0,>c3=%rbx -mov $0,%rbx - -# qhasm: c3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq 104(mulx1=%r12 -movq 104(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq 112(mulx2=%r12 -movq 112(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#10 -# asm 2: movq 120(mulx3=%r12 -movq 120(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 96) -# asm 1: movq 96(mulrax=int64#7 -# asm 2: movq 96(mulrax=%rax -movq 96(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 104(mulrax=%rax -movq 104(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 112(mulrax=%rax -movq 112(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 120(mulrax=%rax -movq 120(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#5 -# asm 2: mov mulr4=%r8 -mov %rax,%r8 - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#6 -# asm 2: mov mulr5=%r9 -mov %rdx,%r9 - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#3 -# asm 2: mov $0,>mulzero=%rdx -mov $0,%rdx - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#5 -# asm 2: imulq $38,mulr8=%r8 -imulq $38,%rax,%r8 - -# qhasm: carry? c0 += mulr8 -# asm 1: add mulzero=int64#3 -# asm 2: imulq $38,mulzero=%rdx -imulq $38,%rdx,%rdx - -# qhasm: c0 += mulzero -# asm 1: add c0_stack=stack64#8 -# asm 2: movq c0_stack=56(%rsp) -movq %r13,56(%rsp) - -# qhasm: c1_stack = c1 -# asm 1: movq c1_stack=stack64#9 -# asm 2: movq c1_stack=64(%rsp) -movq %r14,64(%rsp) - -# qhasm: c2_stack = c2 -# asm 1: movq c2_stack=stack64#10 -# asm 2: movq c2_stack=72(%rsp) -movq %r15,72(%rsp) - -# qhasm: c3_stack = c3 -# asm 1: movq c3_stack=stack64#11 -# asm 2: movq c3_stack=80(%rsp) -movq %rbx,80(%rsp) - -# qhasm: mulr4 = 0 -# asm 1: mov $0,>mulr4=int64#5 -# asm 2: mov $0,>mulr4=%r8 -mov $0,%r8 - -# qhasm: mulr5 = 0 -# asm 1: mov $0,>mulr5=int64#6 -# asm 2: mov $0,>mulr5=%r9 -mov $0,%r9 - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#8 -# asm 2: mov $0,>mulr6=%r10 -mov $0,%r10 - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#9 -# asm 2: mov $0,>mulr7=%r11 -mov $0,%r11 - -# qhasm: mulx0 = *(uint64 *)(pp + 64) -# asm 1: movq 64(mulx0=int64#10 -# asm 2: movq 64(mulx0=%r12 -movq 64(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt0=int64#11 -# asm 2: mov rt0=%r13 -mov %rax,%r13 - -# qhasm: rt1 = mulrdx -# asm 1: mov rt1=int64#12 -# asm 2: mov rt1=%r14 -mov %rdx,%r14 - -# qhasm: mulrax = *(uint64 *)(qp + 72) -# asm 1: movq 72(mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt2=int64#13 -# asm 2: mov $0,>rt2=%r15 -mov $0,%r15 - -# qhasm: rt2 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul rt3=int64#14 -# asm 2: mov $0,>rt3=%rbx -mov $0,%rbx - -# qhasm: rt3 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx0 -# asm 1: mul mulx1=int64#10 -# asm 2: movq 72(mulx1=%r12 -movq 72(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx1 -# asm 1: mul mulx2=int64#10 -# asm 2: movq 80(mulx2=%r12 -movq 80(%rsi),%r12 - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulc=int64#15 -# asm 2: mov $0,>mulc=%rbp -mov $0,%rbp - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx2 -# asm 1: mul mulx3=int64#2 -# asm 2: movq 88(mulx3=%rsi -movq 88(%rsi),%rsi - -# qhasm: mulrax = *(uint64 *)(qp + 64) -# asm 1: movq 64(mulrax=int64#7 -# asm 2: movq 64(mulrax=%rax -movq 64(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 72(mulrax=%rax -movq 72(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 80(mulrax=%rax -movq 80(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulc=int64#10 -# asm 2: mov $0,>mulc=%r12 -mov $0,%r12 - -# qhasm: mulc += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: movq 88(mulrax=%rax -movq 88(%rcx),%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * mulx3 -# asm 1: mul mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r8,%rax - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: mulr4 = mulrax -# asm 1: mov mulr4=int64#2 -# asm 2: mov mulr4=%rsi -mov %rax,%rsi - -# qhasm: mulrax = mulr5 -# asm 1: mov mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r9,%rax - -# qhasm: mulr5 = mulrdx -# asm 1: mov mulr5=int64#4 -# asm 2: mov mulr5=%rcx -mov %rdx,%rcx - -# qhasm: (uint128) mulrdx mulrax = mulrax * *(uint64 *)&crypto_sign_ed25519_amd64_64_38 -mulq crypto_sign_ed25519_amd64_64_38(%rip) - -# qhasm: carry? mulr5 += mulrax -# asm 1: add mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r10,%rax - -# qhasm: mulr6 = 0 -# asm 1: mov $0,>mulr6=int64#5 -# asm 2: mov $0,>mulr6=%r8 -mov $0,%r8 - -# qhasm: mulr6 += mulrdx + carry -# asm 1: adc mulrax=int64#7 -# asm 2: mov mulrax=%rax -mov %r11,%rax - -# qhasm: mulr7 = 0 -# asm 1: mov $0,>mulr7=int64#6 -# asm 2: mov $0,>mulr7=%r9 -mov $0,%r9 - -# qhasm: mulr7 += mulrdx + carry -# asm 1: adc mulr8=int64#7 -# asm 2: mov $0,>mulr8=%rax -mov $0,%rax - -# qhasm: mulr8 += mulrdx + carry -# asm 1: adc mulzero=int64#2 -# asm 2: mov $0,>mulzero=%rsi -mov $0,%rsi - -# qhasm: mulr8 += mulzero + carry -# asm 1: adc mulr8=int64#3 -# asm 2: imulq $38,mulr8=%rdx -imulq $38,%rax,%rdx - -# qhasm: carry? rt0 += mulr8 -# asm 1: add mulzero=int64#2 -# asm 2: imulq $38,mulzero=%rsi -imulq $38,%rsi,%rsi - -# qhasm: rt0 += mulzero -# asm 1: add addt0=int64#2 -# asm 2: mov $0,>addt0=%rsi -mov $0,%rsi - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#3 -# asm 2: mov $38,>addt1=%rdx -mov $38,%rdx - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae rz0=int64#2 -# asm 2: mov rz0=%rsi -mov %r13,%rsi - -# qhasm: rz1 = rt1 -# asm 1: mov rz1=int64#3 -# asm 2: mov rz1=%rdx -mov %r14,%rdx - -# qhasm: rz2 = rt2 -# asm 1: mov rz2=int64#4 -# asm 2: mov rz2=%rcx -mov %r15,%rcx - -# qhasm: rz3 = rt3 -# asm 1: mov rz3=int64#5 -# asm 2: mov rz3=%r8 -mov %rbx,%r8 - -# qhasm: carry? rz0 += c0_stack -# asm 1: addq addt0=int64#6 -# asm 2: mov $0,>addt0=%r9 -mov $0,%r9 - -# qhasm: addt1 = 38 -# asm 1: mov $38,>addt1=int64#7 -# asm 2: mov $38,>addt1=%rax -mov $38,%rax - -# qhasm: addt1 = addt0 if !carry -# asm 1: cmovae subt0=int64#6 -# asm 2: mov $0,>subt0=%r9 -mov $0,%r9 - -# qhasm: subt1 = 38 -# asm 1: mov $38,>subt1=int64#7 -# asm 2: mov $38,>subt1=%rax -mov $38,%rax - -# qhasm: subt1 = subt0 if !carry -# asm 1: cmovae caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/ge25519_scalarmult_base.c b/ext/ed25519-amd64-asm/ge25519_scalarmult_base.c deleted file mode 100644 index ffa6e2fa..00000000 --- a/ext/ed25519-amd64-asm/ge25519_scalarmult_base.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "fe25519.h" -#include "sc25519.h" -#include "ge25519.h" - -/* Multiples of the base point in Niels' representation */ -static const ge25519_niels ge25519_base_multiples_niels[] = { -#ifdef SMALLTABLES -#include "ge25519_base_niels_smalltables.data" -#else -#include "ge25519_base_niels.data" -#endif -}; - -/* d */ -/*static const fe25519 ecd = {{0x75EB4DCA135978A3, 0x00700A4D4141D8AB, 0x8CC740797779E898, 0x52036CEE2B6FFE73}};*/ - -void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s) -{ - signed char b[64]; - int i; - ge25519_niels t; - fe25519 d; - - sc25519_window4(b,s); - -#ifdef SMALLTABLES - ge25519_p1p1 tp1p1; - choose_t((ge25519_niels *)r, 0, (signed long long) b[1], ge25519_base_multiples_niels); - fe25519_sub(&d, &r->y, &r->x); - fe25519_add(&r->y, &r->y, &r->x); - r->x = d; - r->t = r->z; - fe25519_setint(&r->z,2); - for(i=3;i<64;i+=2) - { - choose_t(&t, (unsigned long long) i/2, (signed long long) b[i], ge25519_base_multiples_niels); - ge25519_nielsadd2(r, &t); - } - ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); - ge25519_p1p1_to_p2((ge25519_p2 *)r, &tp1p1); - ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); - ge25519_p1p1_to_p2((ge25519_p2 *)r, &tp1p1); - ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); - ge25519_p1p1_to_p2((ge25519_p2 *)r, &tp1p1); - ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)r); - ge25519_p1p1_to_p3(r, &tp1p1); - choose_t(&t, (unsigned long long) 0, (signed long long) b[0], ge25519_base_multiples_niels); - fe25519_mul(&t.t2d, &t.t2d, &ecd); - ge25519_nielsadd2(r, &t); - for(i=2;i<64;i+=2) - { - choose_t(&t, (unsigned long long) i/2, (signed long long) b[i], ge25519_base_multiples_niels); - ge25519_nielsadd2(r, &t); - } -#else - choose_t((ge25519_niels *)r, 0, (signed long long) b[0], ge25519_base_multiples_niels); - fe25519_sub(&d, &r->y, &r->x); - fe25519_add(&r->y, &r->y, &r->x); - r->x = d; - r->t = r->z; - fe25519_setint(&r->z,2); - for(i=1;i<64;i++) - { - choose_t(&t, (unsigned long long) i, (signed long long) b[i], ge25519_base_multiples_niels); - ge25519_nielsadd2(r, &t); - } -#endif -} diff --git a/ext/ed25519-amd64-asm/ge25519_unpackneg.c b/ext/ed25519-amd64-asm/ge25519_unpackneg.c deleted file mode 100644 index ff16fd20..00000000 --- a/ext/ed25519-amd64-asm/ge25519_unpackneg.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "fe25519.h" -#include "ge25519.h" - -/* d */ -static const fe25519 ecd = {{0x75EB4DCA135978A3, 0x00700A4D4141D8AB, 0x8CC740797779E898, 0x52036CEE2B6FFE73}}; -/* sqrt(-1) */ -static const fe25519 sqrtm1 = {{0xC4EE1B274A0EA0B0, 0x2F431806AD2FE478, 0x2B4D00993DFBD7A7, 0x2B8324804FC1DF0B}}; - -/* return 0 on success, -1 otherwise */ -int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32]) -{ - fe25519 t, chk, num, den, den2, den4, den6; - unsigned char par = p[31] >> 7; - - fe25519_setint(&r->z,1); - fe25519_unpack(&r->y, p); - fe25519_square(&num, &r->y); /* x = y^2 */ - fe25519_mul(&den, &num, &ecd); /* den = dy^2 */ - fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */ - fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */ - - /* Computation of sqrt(num/den) - 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) - */ - fe25519_square(&den2, &den); - fe25519_square(&den4, &den2); - fe25519_mul(&den6, &den4, &den2); - fe25519_mul(&t, &den6, &num); - fe25519_mul(&t, &t, &den); - - fe25519_pow2523(&t, &t); - /* 2. computation of r->x = t * num * den^3 - */ - fe25519_mul(&t, &t, &num); - fe25519_mul(&t, &t, &den); - fe25519_mul(&t, &t, &den); - fe25519_mul(&r->x, &t, &den); - - /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: - */ - fe25519_square(&chk, &r->x); - fe25519_mul(&chk, &chk, &den); - if (!fe25519_iseq_vartime(&chk, &num)) - fe25519_mul(&r->x, &r->x, &sqrtm1); - - /* 4. Now we have one of the two square roots, except if input was not a square - */ - fe25519_square(&chk, &r->x); - fe25519_mul(&chk, &chk, &den); - if (!fe25519_iseq_vartime(&chk, &num)) - return -1; - - /* 5. Choose the desired square root according to parity: - */ - if(fe25519_getparity(&r->x) != (1-par)) - fe25519_neg(&r->x, &r->x); - - fe25519_mul(&r->t, &r->x, &r->y); - return 0; -} diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced.s b/ext/ed25519-amd64-asm/heap_rootreplaced.s deleted file mode 100644 index 8fe385b4..00000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced.s +++ /dev/null @@ -1,476 +0,0 @@ - -# qhasm: int64 hp - -# qhasm: int64 hlen - -# qhasm: int64 sp - -# qhasm: int64 pp - -# qhasm: input hp - -# qhasm: input hlen - -# qhasm: input sp - -# qhasm: int64 prc - -# qhasm: int64 plc - -# qhasm: int64 pc - -# qhasm: int64 d - -# qhasm: int64 spp - -# qhasm: int64 sprc - -# qhasm: int64 spc - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 p0 - -# qhasm: int64 p1 - -# qhasm: int64 p2 - -# qhasm: int64 p3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced -.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced -_crypto_sign_ed25519_amd64_64_heap_rootreplaced: -crypto_sign_ed25519_amd64_64_heap_rootreplaced: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: pp = 0 -# asm 1: mov $0,>pp=int64#4 -# asm 2: mov $0,>pp=%rcx -mov $0,%rcx - -# qhasm: siftdownloop: -._siftdownloop: - -# qhasm: prc = pp -# asm 1: mov prc=int64#5 -# asm 2: mov prc=%r8 -mov %rcx,%r8 - -# qhasm: prc *= 2 -# asm 1: imulq $2,prc=int64#5 -# asm 2: imulq $2,prc=%r8 -imulq $2,%r8,%r8 - -# qhasm: pc = prc -# asm 1: mov pc=int64#6 -# asm 2: mov pc=%r9 -mov %r8,%r9 - -# qhasm: prc += 2 -# asm 1: add $2,? hlen - prc -# asm 1: cmp -jbe ._siftuploop - -# qhasm: sprc = *(uint64 *)(hp + prc * 8) -# asm 1: movq (sprc=int64#7 -# asm 2: movq (sprc=%rax -movq (%rdi,%r8,8),%rax - -# qhasm: sprc <<= 5 -# asm 1: shl $5,spc=int64#8 -# asm 2: movq (spc=%r10 -movq (%rdi,%r9,8),%r10 - -# qhasm: spc <<= 5 -# asm 1: shl $5,c0=int64#9 -# asm 2: movq 0(c0=%r11 -movq 0(%r10),%r11 - -# qhasm: c1 = *(uint64 *)(spc + 8) -# asm 1: movq 8(c1=int64#10 -# asm 2: movq 8(c1=%r12 -movq 8(%r10),%r12 - -# qhasm: c2 = *(uint64 *)(spc + 16) -# asm 1: movq 16(c2=int64#11 -# asm 2: movq 16(c2=%r13 -movq 16(%r10),%r13 - -# qhasm: c3 = *(uint64 *)(spc + 24) -# asm 1: movq 24(c3=int64#12 -# asm 2: movq 24(c3=%r14 -movq 24(%r10),%r14 - -# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: *(uint64 *)(hp + pp * 8) = spc -# asm 1: movq pp=int64#4 -# asm 2: mov pp=%rcx -mov %r9,%rcx -# comment:fp stack unchanged by jump - -# qhasm: goto siftdownloop -jmp ._siftdownloop - -# qhasm: siftuploop: -._siftuploop: - -# qhasm: pc = pp -# asm 1: mov pc=int64#2 -# asm 2: mov pc=%rsi -mov %rcx,%rsi - -# qhasm: pp -= 1 -# asm 1: sub $1,>= 1 -# asm 1: shr $1,? pc - 0 -# asm 1: cmp $0, -jbe ._end - -# qhasm: spp = *(uint64 *)(hp + pp * 8) -# asm 1: movq (spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: spc = *(uint64 *)(hp + pc * 8) -# asm 1: movq (spc=int64#6 -# asm 2: movq (spc=%r9 -movq (%rdi,%rsi,8),%r9 - -# qhasm: spp <<= 5 -# asm 1: shl $5,c0=int64#7 -# asm 2: movq 0(c0=%rax -movq 0(%r9),%rax - -# qhasm: c1 = *(uint64 *)(spc + 8) -# asm 1: movq 8(c1=int64#8 -# asm 2: movq 8(c1=%r10 -movq 8(%r9),%r10 - -# qhasm: c2 = *(uint64 *)(spc + 16) -# asm 1: movq 16(c2=int64#9 -# asm 2: movq 16(c2=%r11 -movq 16(%r9),%r11 - -# qhasm: c3 = *(uint64 *)(spc + 24) -# asm 1: movq 24(c3=int64#10 -# asm 2: movq 24(c3=%r12 -movq 24(%r9),%r12 - -# qhasm: carry? c0 -= *(uint64 *)(spp + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,>= 5 -# asm 1: shr $5,caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s b/ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s deleted file mode 100644 index 488e9c52..00000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced_1limb.s +++ /dev/null @@ -1,416 +0,0 @@ - -# qhasm: int64 hp - -# qhasm: int64 hlen - -# qhasm: int64 sp - -# qhasm: int64 pp - -# qhasm: input hp - -# qhasm: input hlen - -# qhasm: input sp - -# qhasm: int64 prc - -# qhasm: int64 plc - -# qhasm: int64 pc - -# qhasm: int64 d - -# qhasm: int64 spp - -# qhasm: int64 sprc - -# qhasm: int64 spc - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 p0 - -# qhasm: int64 p1 - -# qhasm: int64 p2 - -# qhasm: int64 p3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb -.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb -_crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb: -crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: pp = 0 -# asm 1: mov $0,>pp=int64#4 -# asm 2: mov $0,>pp=%rcx -mov $0,%rcx - -# qhasm: siftdownloop: -._siftdownloop: - -# qhasm: prc = pp -# asm 1: mov prc=int64#5 -# asm 2: mov prc=%r8 -mov %rcx,%r8 - -# qhasm: prc *= 2 -# asm 1: imulq $2,prc=int64#5 -# asm 2: imulq $2,prc=%r8 -imulq $2,%r8,%r8 - -# qhasm: pc = prc -# asm 1: mov pc=int64#6 -# asm 2: mov pc=%r9 -mov %r8,%r9 - -# qhasm: prc += 2 -# asm 1: add $2,? hlen - prc -# asm 1: cmp -jbe ._siftuploop - -# qhasm: sprc = *(uint64 *)(hp + prc * 8) -# asm 1: movq (sprc=int64#7 -# asm 2: movq (sprc=%rax -movq (%rdi,%r8,8),%rax - -# qhasm: sprc <<= 5 -# asm 1: shl $5,spc=int64#8 -# asm 2: movq (spc=%r10 -movq (%rdi,%r9,8),%r10 - -# qhasm: spc <<= 5 -# asm 1: shl $5,c0=int64#9 -# asm 2: movq 0(c0=%r11 -movq 0(%r10),%r11 - -# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: *(uint64 *)(hp + pp * 8) = spc -# asm 1: movq pp=int64#4 -# asm 2: mov pp=%rcx -mov %r9,%rcx -# comment:fp stack unchanged by jump - -# qhasm: goto siftdownloop -jmp ._siftdownloop - -# qhasm: siftuploop: -._siftuploop: - -# qhasm: pc = pp -# asm 1: mov pc=int64#2 -# asm 2: mov pc=%rsi -mov %rcx,%rsi - -# qhasm: pp -= 1 -# asm 1: sub $1,>= 1 -# asm 1: shr $1,? pc - 0 -# asm 1: cmp $0, -jbe ._end - -# qhasm: spp = *(uint64 *)(hp + pp * 8) -# asm 1: movq (spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: spc = *(uint64 *)(hp + pc * 8) -# asm 1: movq (spc=int64#6 -# asm 2: movq (spc=%r9 -movq (%rdi,%rsi,8),%r9 - -# qhasm: spp <<= 5 -# asm 1: shl $5,c0=int64#7 -# asm 2: movq 0(c0=%rax -movq 0(%r9),%rax - -# qhasm: carry? c0 -= *(uint64 *)(spp + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,>= 5 -# asm 1: shr $5,caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s b/ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s deleted file mode 100644 index f9259184..00000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced_2limbs.s +++ /dev/null @@ -1,436 +0,0 @@ - -# qhasm: int64 hp - -# qhasm: int64 hlen - -# qhasm: int64 sp - -# qhasm: int64 pp - -# qhasm: input hp - -# qhasm: input hlen - -# qhasm: input sp - -# qhasm: int64 prc - -# qhasm: int64 plc - -# qhasm: int64 pc - -# qhasm: int64 d - -# qhasm: int64 spp - -# qhasm: int64 sprc - -# qhasm: int64 spc - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 p0 - -# qhasm: int64 p1 - -# qhasm: int64 p2 - -# qhasm: int64 p3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs -.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs -_crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs: -crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: pp = 0 -# asm 1: mov $0,>pp=int64#4 -# asm 2: mov $0,>pp=%rcx -mov $0,%rcx - -# qhasm: siftdownloop: -._siftdownloop: - -# qhasm: prc = pp -# asm 1: mov prc=int64#5 -# asm 2: mov prc=%r8 -mov %rcx,%r8 - -# qhasm: prc *= 2 -# asm 1: imulq $2,prc=int64#5 -# asm 2: imulq $2,prc=%r8 -imulq $2,%r8,%r8 - -# qhasm: pc = prc -# asm 1: mov pc=int64#6 -# asm 2: mov pc=%r9 -mov %r8,%r9 - -# qhasm: prc += 2 -# asm 1: add $2,? hlen - prc -# asm 1: cmp -jbe ._siftuploop - -# qhasm: sprc = *(uint64 *)(hp + prc * 8) -# asm 1: movq (sprc=int64#7 -# asm 2: movq (sprc=%rax -movq (%rdi,%r8,8),%rax - -# qhasm: sprc <<= 5 -# asm 1: shl $5,spc=int64#8 -# asm 2: movq (spc=%r10 -movq (%rdi,%r9,8),%r10 - -# qhasm: spc <<= 5 -# asm 1: shl $5,c0=int64#9 -# asm 2: movq 0(c0=%r11 -movq 0(%r10),%r11 - -# qhasm: c1 = *(uint64 *)(spc + 8) -# asm 1: movq 8(c1=int64#10 -# asm 2: movq 8(c1=%r12 -movq 8(%r10),%r12 - -# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: *(uint64 *)(hp + pp * 8) = spc -# asm 1: movq pp=int64#4 -# asm 2: mov pp=%rcx -mov %r9,%rcx -# comment:fp stack unchanged by jump - -# qhasm: goto siftdownloop -jmp ._siftdownloop - -# qhasm: siftuploop: -._siftuploop: - -# qhasm: pc = pp -# asm 1: mov pc=int64#2 -# asm 2: mov pc=%rsi -mov %rcx,%rsi - -# qhasm: pp -= 1 -# asm 1: sub $1,>= 1 -# asm 1: shr $1,? pc - 0 -# asm 1: cmp $0, -jbe ._end - -# qhasm: spp = *(uint64 *)(hp + pp * 8) -# asm 1: movq (spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: spc = *(uint64 *)(hp + pc * 8) -# asm 1: movq (spc=int64#6 -# asm 2: movq (spc=%r9 -movq (%rdi,%rsi,8),%r9 - -# qhasm: spp <<= 5 -# asm 1: shl $5,c0=int64#7 -# asm 2: movq 0(c0=%rax -movq 0(%r9),%rax - -# qhasm: c1 = *(uint64 *)(spc + 8) -# asm 1: movq 8(c1=int64#8 -# asm 2: movq 8(c1=%r10 -movq 8(%r9),%r10 - -# qhasm: carry? c0 -= *(uint64 *)(spp + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,>= 5 -# asm 1: shr $5,caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s b/ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s deleted file mode 100644 index dcf890ea..00000000 --- a/ext/ed25519-amd64-asm/heap_rootreplaced_3limbs.s +++ /dev/null @@ -1,456 +0,0 @@ - -# qhasm: int64 hp - -# qhasm: int64 hlen - -# qhasm: int64 sp - -# qhasm: int64 pp - -# qhasm: input hp - -# qhasm: input hlen - -# qhasm: input sp - -# qhasm: int64 prc - -# qhasm: int64 plc - -# qhasm: int64 pc - -# qhasm: int64 d - -# qhasm: int64 spp - -# qhasm: int64 sprc - -# qhasm: int64 spc - -# qhasm: int64 c0 - -# qhasm: int64 c1 - -# qhasm: int64 c2 - -# qhasm: int64 c3 - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 p0 - -# qhasm: int64 p1 - -# qhasm: int64 p2 - -# qhasm: int64 p3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs -.globl crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs -_crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs: -crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: pp = 0 -# asm 1: mov $0,>pp=int64#4 -# asm 2: mov $0,>pp=%rcx -mov $0,%rcx - -# qhasm: siftdownloop: -._siftdownloop: - -# qhasm: prc = pp -# asm 1: mov prc=int64#5 -# asm 2: mov prc=%r8 -mov %rcx,%r8 - -# qhasm: prc *= 2 -# asm 1: imulq $2,prc=int64#5 -# asm 2: imulq $2,prc=%r8 -imulq $2,%r8,%r8 - -# qhasm: pc = prc -# asm 1: mov pc=int64#6 -# asm 2: mov pc=%r9 -mov %r8,%r9 - -# qhasm: prc += 2 -# asm 1: add $2,? hlen - prc -# asm 1: cmp -jbe ._siftuploop - -# qhasm: sprc = *(uint64 *)(hp + prc * 8) -# asm 1: movq (sprc=int64#7 -# asm 2: movq (sprc=%rax -movq (%rdi,%r8,8),%rax - -# qhasm: sprc <<= 5 -# asm 1: shl $5,spc=int64#8 -# asm 2: movq (spc=%r10 -movq (%rdi,%r9,8),%r10 - -# qhasm: spc <<= 5 -# asm 1: shl $5,c0=int64#9 -# asm 2: movq 0(c0=%r11 -movq 0(%r10),%r11 - -# qhasm: c1 = *(uint64 *)(spc + 8) -# asm 1: movq 8(c1=int64#10 -# asm 2: movq 8(c1=%r12 -movq 8(%r10),%r12 - -# qhasm: c2 = *(uint64 *)(spc + 16) -# asm 1: movq 16(c2=int64#11 -# asm 2: movq 16(c2=%r13 -movq 16(%r10),%r13 - -# qhasm: carry? c0 -= *(uint64 *)(sprc + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: *(uint64 *)(hp + pp * 8) = spc -# asm 1: movq pp=int64#4 -# asm 2: mov pp=%rcx -mov %r9,%rcx -# comment:fp stack unchanged by jump - -# qhasm: goto siftdownloop -jmp ._siftdownloop - -# qhasm: siftuploop: -._siftuploop: - -# qhasm: pc = pp -# asm 1: mov pc=int64#2 -# asm 2: mov pc=%rsi -mov %rcx,%rsi - -# qhasm: pp -= 1 -# asm 1: sub $1,>= 1 -# asm 1: shr $1,? pc - 0 -# asm 1: cmp $0, -jbe ._end - -# qhasm: spp = *(uint64 *)(hp + pp * 8) -# asm 1: movq (spp=int64#5 -# asm 2: movq (spp=%r8 -movq (%rdi,%rcx,8),%r8 - -# qhasm: spc = *(uint64 *)(hp + pc * 8) -# asm 1: movq (spc=int64#6 -# asm 2: movq (spc=%r9 -movq (%rdi,%rsi,8),%r9 - -# qhasm: spp <<= 5 -# asm 1: shl $5,c0=int64#7 -# asm 2: movq 0(c0=%rax -movq 0(%r9),%rax - -# qhasm: c1 = *(uint64 *)(spc + 8) -# asm 1: movq 8(c1=int64#8 -# asm 2: movq 8(c1=%r10 -movq 8(%r9),%r10 - -# qhasm: c2 = *(uint64 *)(spc + 16) -# asm 1: movq 16(c2=int64#9 -# asm 2: movq 16(c2=%r11 -movq 16(%r9),%r11 - -# qhasm: carry? c0 -= *(uint64 *)(spp + 0) -# asm 1: subq 0(>= 5 -# asm 1: shr $5,>= 5 -# asm 1: shr $5,caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/hram.c b/ext/ed25519-amd64-asm/hram.c deleted file mode 100644 index 6f99fc62..00000000 --- a/ext/ed25519-amd64-asm/hram.c +++ /dev/null @@ -1,16 +0,0 @@ -/*#include "crypto_hash_sha512.h"*/ -#include "hram.h" - -extern void ZT_sha512internal(void *digest,const void *data,unsigned int len); - -void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) -{ - unsigned long long i; - - for (i = 0;i < 32;++i) playground[i] = sm[i]; - for (i = 32;i < 64;++i) playground[i] = pk[i-32]; - for (i = 64;i < smlen;++i) playground[i] = sm[i]; - - /*crypto_hash_sha512(hram,playground,smlen);*/ - ZT_sha512internal(hram,playground,smlen); -} diff --git a/ext/ed25519-amd64-asm/hram.h b/ext/ed25519-amd64-asm/hram.h deleted file mode 100644 index 1740c78a..00000000 --- a/ext/ed25519-amd64-asm/hram.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef HRAM_H -#define HRAM_H - -#define get_hram crypto_sign_ed25519_amd64_64_get_hram - -extern void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen); - -#endif diff --git a/ext/ed25519-amd64-asm/implementors b/ext/ed25519-amd64-asm/implementors deleted file mode 100644 index 9b5399a3..00000000 --- a/ext/ed25519-amd64-asm/implementors +++ /dev/null @@ -1,5 +0,0 @@ -Daniel J. Bernstein -Niels Duif -Tanja Lange -lead: Peter Schwabe -Bo-Yin Yang diff --git a/ext/ed25519-amd64-asm/index_heap.c b/ext/ed25519-amd64-asm/index_heap.c deleted file mode 100644 index f29f7a28..00000000 --- a/ext/ed25519-amd64-asm/index_heap.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "sc25519.h" -#include "index_heap.h" - -/* caller's responsibility to ensure hlen>=3 */ -void heap_init(unsigned long long *h, unsigned long long hlen, sc25519 *scalars) -{ - h[0] = 0; - unsigned long long i=1; - while(i 0) - { - /* if(sc25519_lt_vartime(&scalars[h[ppos]], &scalars[h[pos]])) */ - if(sc25519_lt(&scalars[h[ppos]], &scalars[h[pos]])) - { - t = h[ppos]; - h[ppos] = h[pos]; - h[pos] = t; - pos = ppos; - ppos = (pos-1)/2; - } - else break; - } - (*hlen)++; -} - -/* Put the largest value in the heap in max1, the second largest in max2 */ -void heap_get2max(unsigned long long *h, unsigned long long *max1, unsigned long long *max2, sc25519 *scalars) -{ - *max1 = h[0]; - *max2 = h[1]; - if(sc25519_lt(&scalars[h[1]],&scalars[h[2]])) - *max2 = h[2]; -} - -/* After the root has been replaced, restore heap property */ -/* extern void heap_rootreplaced(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); -*/ -/* extern void heap_rootreplaced_shortscalars(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); -*/ diff --git a/ext/ed25519-amd64-asm/index_heap.h b/ext/ed25519-amd64-asm/index_heap.h deleted file mode 100644 index 7dee9161..00000000 --- a/ext/ed25519-amd64-asm/index_heap.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef INDEX_HEAP_H -#define INDEX_HEAP_H - -#include "sc25519.h" - -#define heap_init crypto_sign_ed25519_amd64_64_heap_init -#define heap_extend crypto_sign_ed25519_amd64_64_heap_extend -#define heap_pop crypto_sign_ed25519_amd64_64_heap_pop -#define heap_push crypto_sign_ed25519_amd64_64_heap_push -#define heap_get2max crypto_sign_ed25519_amd64_64_heap_get2max -#define heap_rootreplaced crypto_sign_ed25519_amd64_64_heap_rootreplaced -#define heap_rootreplaced_3limbs crypto_sign_ed25519_amd64_64_heap_rootreplaced_3limbs -#define heap_rootreplaced_2limbs crypto_sign_ed25519_amd64_64_heap_rootreplaced_2limbs -#define heap_rootreplaced_1limb crypto_sign_ed25519_amd64_64_heap_rootreplaced_1limb - -void heap_init(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); - -void heap_extend(unsigned long long *h, unsigned long long oldlen, unsigned long long newlen, sc25519 *scalars); - -unsigned long long heap_pop(unsigned long long *h, unsigned long long *hlen, sc25519 *scalars); - -void heap_push(unsigned long long *h, unsigned long long *hlen, unsigned long long elem, sc25519 *scalars); - -void heap_get2max(unsigned long long *h, unsigned long long *max1, unsigned long long *max2, sc25519 *scalars); - -void heap_rootreplaced(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); -void heap_rootreplaced_3limbs(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); -void heap_rootreplaced_2limbs(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); -void heap_rootreplaced_1limb(unsigned long long *h, unsigned long long hlen, sc25519 *scalars); - -#endif diff --git a/ext/ed25519-amd64-asm/keypair.c b/ext/ed25519-amd64-asm/keypair.c deleted file mode 100644 index 7e094710..00000000 --- a/ext/ed25519-amd64-asm/keypair.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include "crypto_sign.h" -#include "crypto_hash_sha512.h" -#include "randombytes.h" -#include "ge25519.h" - -int crypto_sign_keypair(unsigned char *pk,unsigned char *sk) -{ - unsigned char az[64]; - sc25519 scsk; - ge25519 gepk; - - randombytes(sk,32); - crypto_hash_sha512(az,sk,32); - az[0] &= 248; - az[31] &= 127; - az[31] |= 64; - - sc25519_from32bytes(&scsk,az); - - ge25519_scalarmult_base(&gepk, &scsk); - ge25519_pack(pk, &gepk); - memmove(sk + 32,pk,32); - return 0; -} diff --git a/ext/ed25519-amd64-asm/open.c b/ext/ed25519-amd64-asm/open.c deleted file mode 100644 index 104d48dc..00000000 --- a/ext/ed25519-amd64-asm/open.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include "crypto_sign.h" -#include "crypto_verify_32.h" -#include "crypto_hash_sha512.h" -#include "ge25519.h" - -int crypto_sign_open( - unsigned char *m,unsigned long long *mlen, - const unsigned char *sm,unsigned long long smlen, - const unsigned char *pk - ) -{ - unsigned char pkcopy[32]; - unsigned char rcopy[32]; - unsigned char hram[64]; - unsigned char rcheck[32]; - ge25519 get1, get2; - sc25519 schram, scs; - - if (smlen < 64) goto badsig; - if (sm[63] & 224) goto badsig; - if (ge25519_unpackneg_vartime(&get1,pk)) goto badsig; - - memmove(pkcopy,pk,32); - memmove(rcopy,sm,32); - - sc25519_from32bytes(&scs, sm+32); - - memmove(m,sm,smlen); - memmove(m + 32,pkcopy,32); - crypto_hash_sha512(hram,m,smlen); - - sc25519_from64bytes(&schram, hram); - - ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &scs); - ge25519_pack(rcheck, &get2); - - if (crypto_verify_32(rcopy,rcheck) == 0) { - memmove(m,m + 64,smlen - 64); - memset(m + smlen - 64,0,64); - *mlen = smlen - 64; - return 0; - } - -badsig: - *mlen = (unsigned long long) -1; - memset(m,0,smlen); - return -1; -} diff --git a/ext/ed25519-amd64-asm/sc25519.h b/ext/ed25519-amd64-asm/sc25519.h deleted file mode 100644 index 8ff1b1ca..00000000 --- a/ext/ed25519-amd64-asm/sc25519.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef SC25519_H -#define SC25519_H - -#define sc25519 crypto_sign_ed25519_amd64_64_sc25519 -#define shortsc25519 crypto_sign_ed25519_amd64_64_shortsc25519 -#define sc25519_from32bytes crypto_sign_ed25519_amd64_64_sc25519_from32bytes -#define shortsc25519_from16bytes crypto_sign_ed25519_amd64_64_shortsc25519_from16bytes -#define sc25519_from64bytes crypto_sign_ed25519_amd64_64_sc25519_from64bytes -#define sc25519_from_shortsc crypto_sign_ed25519_amd64_64_sc25519_from_shortsc -#define sc25519_to32bytes crypto_sign_ed25519_amd64_64_sc25519_to32bytes -#define sc25519_iszero_vartime crypto_sign_ed25519_amd64_64_sc25519_iszero_vartime -#define sc25519_isshort_vartime crypto_sign_ed25519_amd64_64_sc25519_isshort_vartime -#define sc25519_lt crypto_sign_ed25519_amd64_64_sc25519_lt -#define sc25519_add crypto_sign_ed25519_amd64_64_sc25519_add -#define sc25519_sub_nored crypto_sign_ed25519_amd64_64_sc25519_sub_nored -#define sc25519_mul crypto_sign_ed25519_amd64_64_sc25519_mul -#define sc25519_mul_shortsc crypto_sign_ed25519_amd64_64_sc25519_mul_shortsc -#define sc25519_window4 crypto_sign_ed25519_amd64_64_sc25519_window4 -#define sc25519_slide crypto_sign_ed25519_amd64_64_sc25519_slide -#define sc25519_2interleave2 crypto_sign_ed25519_amd64_64_sc25519_2interleave2 -#define sc25519_barrett crypto_sign_ed25519_amd64_64_sc25519_barrett - -typedef struct -{ - unsigned long long v[4]; -} -sc25519; - -typedef struct -{ - unsigned long long v[2]; -} -shortsc25519; - -void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]); - -void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]); - -void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x); - -void sc25519_to32bytes(unsigned char r[32], const sc25519 *x); - -int sc25519_iszero_vartime(const sc25519 *x); - -int sc25519_lt(const sc25519 *x, const sc25519 *y); - -void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y); - -void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y); - -void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y); - -void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y); - -/* Convert s into a representation of the form \sum_{i=0}^{63}r[i]2^(4*i) - * with r[i] in {-8,...,7} - */ -void sc25519_window4(signed char r[85], const sc25519 *s); - -void sc25519_slide(signed char r[256], const sc25519 *s, int swindowsize); - -void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2); - -void sc25519_barrett(sc25519 *r, unsigned long long x[8]); - -#endif diff --git a/ext/ed25519-amd64-asm/sc25519_add.s b/ext/ed25519-amd64-asm/sc25519_add.s deleted file mode 100644 index d5b941cd..00000000 --- a/ext/ed25519-amd64-asm/sc25519_add.s +++ /dev/null @@ -1,232 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: int64 yp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: input yp - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_add -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_sc25519_add -.globl crypto_sign_ed25519_amd64_64_sc25519_add -_crypto_sign_ed25519_amd64_64_sc25519_add: -crypto_sign_ed25519_amd64_64_sc25519_add: -mov %rsp,%r11 -and $31,%r11 -add $32,%r11 -sub %r11,%rsp - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#1 -# asm 2: movq caller4_stack=0(%rsp) -movq %r14,0(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#2 -# asm 2: movq caller5_stack=8(%rsp) -movq %r15,8(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#3 -# asm 2: movq caller6_stack=16(%rsp) -movq %rbx,16(%rsp) - -# qhasm: r0 = *(uint64 *)(xp + 0) -# asm 1: movq 0(r0=int64#4 -# asm 2: movq 0(r0=%rcx -movq 0(%rsi),%rcx - -# qhasm: r1 = *(uint64 *)(xp + 8) -# asm 1: movq 8(r1=int64#5 -# asm 2: movq 8(r1=%r8 -movq 8(%rsi),%r8 - -# qhasm: r2 = *(uint64 *)(xp + 16) -# asm 1: movq 16(r2=int64#6 -# asm 2: movq 16(r2=%r9 -movq 16(%rsi),%r9 - -# qhasm: r3 = *(uint64 *)(xp + 24) -# asm 1: movq 24(r3=int64#2 -# asm 2: movq 24(r3=%rsi -movq 24(%rsi),%rsi - -# qhasm: carry? r0 += *(uint64 *)(yp + 0) -# asm 1: addq 0(t0=int64#3 -# asm 2: mov t0=%rdx -mov %rcx,%rdx - -# qhasm: t1 = r1 -# asm 1: mov t1=int64#7 -# asm 2: mov t1=%rax -mov %r8,%rax - -# qhasm: t2 = r2 -# asm 1: mov t2=int64#8 -# asm 2: mov t2=%r10 -mov %r9,%r10 - -# qhasm: t3 = r3 -# asm 1: mov t3=int64#12 -# asm 2: mov t3=%r14 -mov %rsi,%r14 - -# qhasm: carry? t0 -= *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 -# asm 1: sub crypto_sign_ed25519_amd64_64_ORDER0,caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 0(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 8(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 16(%rsp),%rbx - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/sc25519_barrett.s b/ext/ed25519-amd64-asm/sc25519_barrett.s deleted file mode 100644 index 7eb56fad..00000000 --- a/ext/ed25519-amd64-asm/sc25519_barrett.s +++ /dev/null @@ -1,1188 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: int64 q23 - -# qhasm: int64 q24 - -# qhasm: int64 q30 - -# qhasm: int64 q31 - -# qhasm: int64 q32 - -# qhasm: int64 q33 - -# qhasm: int64 r20 - -# qhasm: int64 r21 - -# qhasm: int64 r22 - -# qhasm: int64 r23 - -# qhasm: int64 r24 - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 rax - -# qhasm: int64 rdx - -# qhasm: int64 c - -# qhasm: int64 zero - -# qhasm: int64 mask - -# qhasm: int64 nmask - -# qhasm: stack64 q30_stack - -# qhasm: stack64 q31_stack - -# qhasm: stack64 q32_stack - -# qhasm: stack64 q33_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_barrett -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_sc25519_barrett -.globl crypto_sign_ed25519_amd64_64_sc25519_barrett -_crypto_sign_ed25519_amd64_64_sc25519_barrett: -crypto_sign_ed25519_amd64_64_sc25519_barrett: -mov %rsp,%r11 -and $31,%r11 -add $96,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: zero ^= zero -# asm 1: xor rax=int64#7 -# asm 2: movq 24(rax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 -mulq crypto_sign_ed25519_amd64_64_MU3(%rip) - -# qhasm: q23 = rax -# asm 1: mov q23=int64#10 -# asm 2: mov q23=%r12 -mov %rax,%r12 - -# qhasm: c = rdx -# asm 1: mov c=int64#11 -# asm 2: mov c=%r13 -mov %rdx,%r13 - -# qhasm: rax = *(uint64 *)(xp + 24) -# asm 1: movq 24(rax=int64#7 -# asm 2: movq 24(rax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 -mulq crypto_sign_ed25519_amd64_64_MU4(%rip) - -# qhasm: q24 = rax -# asm 1: mov q24=int64#12 -# asm 2: mov q24=%r14 -mov %rax,%r14 - -# qhasm: carry? q24 += c -# asm 1: add rax=int64#7 -# asm 2: movq 32(rax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 -mulq crypto_sign_ed25519_amd64_64_MU2(%rip) - -# qhasm: carry? q23 += rax -# asm 1: add c=int64#11 -# asm 2: mov $0,>c=%r13 -mov $0,%r13 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 32(rax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 -mulq crypto_sign_ed25519_amd64_64_MU3(%rip) - -# qhasm: carry? q24 += rax -# asm 1: add c=int64#11 -# asm 2: mov $0,>c=%r13 -mov $0,%r13 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 32(rax=%rax -movq 32(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 -mulq crypto_sign_ed25519_amd64_64_MU4(%rip) - -# qhasm: carry? q30 += rax -# asm 1: add rax=int64#7 -# asm 2: movq 40(rax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU1 -mulq crypto_sign_ed25519_amd64_64_MU1(%rip) - -# qhasm: carry? q23 += rax -# asm 1: add c=int64#11 -# asm 2: mov $0,>c=%r13 -mov $0,%r13 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 40(rax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 -mulq crypto_sign_ed25519_amd64_64_MU2(%rip) - -# qhasm: carry? q24 += rax -# asm 1: add c=int64#11 -# asm 2: mov $0,>c=%r13 -mov $0,%r13 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 40(rax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 -mulq crypto_sign_ed25519_amd64_64_MU3(%rip) - -# qhasm: carry? q30 += rax -# asm 1: add c=int64#11 -# asm 2: mov $0,>c=%r13 -mov $0,%r13 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 40(rax=%rax -movq 40(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 -mulq crypto_sign_ed25519_amd64_64_MU4(%rip) - -# qhasm: carry? q31 += rax -# asm 1: add rax=int64#7 -# asm 2: movq 48(rax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU0 -mulq crypto_sign_ed25519_amd64_64_MU0(%rip) - -# qhasm: carry? q23 += rax -# asm 1: add c=int64#10 -# asm 2: mov $0,>c=%r12 -mov $0,%r12 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 48(rax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU1 -mulq crypto_sign_ed25519_amd64_64_MU1(%rip) - -# qhasm: carry? q24 += rax -# asm 1: add c=int64#10 -# asm 2: mov $0,>c=%r12 -mov $0,%r12 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 48(rax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 -mulq crypto_sign_ed25519_amd64_64_MU2(%rip) - -# qhasm: carry? q30 += rax -# asm 1: add c=int64#10 -# asm 2: mov $0,>c=%r12 -mov $0,%r12 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 48(rax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 -mulq crypto_sign_ed25519_amd64_64_MU3(%rip) - -# qhasm: carry? q31 += rax -# asm 1: add c=int64#10 -# asm 2: mov $0,>c=%r12 -mov $0,%r12 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 48(rax=%rax -movq 48(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 -mulq crypto_sign_ed25519_amd64_64_MU4(%rip) - -# qhasm: carry? q32 += rax -# asm 1: add rax=int64#7 -# asm 2: movq 56(rax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU0 -mulq crypto_sign_ed25519_amd64_64_MU0(%rip) - -# qhasm: carry? q24 += rax -# asm 1: add c=int64#10 -# asm 2: mov $0,>c=%r12 -mov $0,%r12 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 56(rax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU1 -mulq crypto_sign_ed25519_amd64_64_MU1(%rip) - -# qhasm: carry? q30 += rax -# asm 1: add c=int64#10 -# asm 2: mov $0,>c=%r12 -mov $0,%r12 - -# qhasm: c += rdx + carry -# asm 1: adc q30_stack=stack64#8 -# asm 2: movq q30_stack=56(%rsp) -movq %r8,56(%rsp) - -# qhasm: rax = *(uint64 *)(xp + 56) -# asm 1: movq 56(rax=int64#7 -# asm 2: movq 56(rax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU2 -mulq crypto_sign_ed25519_amd64_64_MU2(%rip) - -# qhasm: carry? q31 += rax -# asm 1: add c=int64#5 -# asm 2: mov $0,>c=%r8 -mov $0,%r8 - -# qhasm: c += rdx + carry -# asm 1: adc q31_stack=stack64#9 -# asm 2: movq q31_stack=64(%rsp) -movq %r9,64(%rsp) - -# qhasm: rax = *(uint64 *)(xp + 56) -# asm 1: movq 56(rax=int64#7 -# asm 2: movq 56(rax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU3 -mulq crypto_sign_ed25519_amd64_64_MU3(%rip) - -# qhasm: carry? q32 += rax -# asm 1: add c=int64#5 -# asm 2: mov $0,>c=%r8 -mov $0,%r8 - -# qhasm: c += rdx + carry -# asm 1: adc q32_stack=stack64#10 -# asm 2: movq q32_stack=72(%rsp) -movq %r10,72(%rsp) - -# qhasm: rax = *(uint64 *)(xp + 56) -# asm 1: movq 56(rax=int64#7 -# asm 2: movq 56(rax=%rax -movq 56(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_MU4 -mulq crypto_sign_ed25519_amd64_64_MU4(%rip) - -# qhasm: carry? q33 += rax -# asm 1: add q33_stack=stack64#11 -# asm 2: movq q33_stack=80(%rsp) -movq %r11,80(%rsp) - -# qhasm: rax = q30_stack -# asm 1: movq rax=int64#7 -# asm 2: movq rax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 -mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) - -# qhasm: r20 = rax -# asm 1: mov r20=int64#5 -# asm 2: mov r20=%r8 -mov %rax,%r8 - -# qhasm: c = rdx -# asm 1: mov c=int64#6 -# asm 2: mov c=%r9 -mov %rdx,%r9 - -# qhasm: rax = q30_stack -# asm 1: movq rax=int64#7 -# asm 2: movq rax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER1 -mulq crypto_sign_ed25519_amd64_64_ORDER1(%rip) - -# qhasm: r21 = rax -# asm 1: mov r21=int64#8 -# asm 2: mov r21=%r10 -mov %rax,%r10 - -# qhasm: carry? r21 += c -# asm 1: add c=int64#6 -# asm 2: mov $0,>c=%r9 -mov $0,%r9 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq rax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER2 -mulq crypto_sign_ed25519_amd64_64_ORDER2(%rip) - -# qhasm: r22 = rax -# asm 1: mov r22=int64#9 -# asm 2: mov r22=%r11 -mov %rax,%r11 - -# qhasm: carry? r22 += c -# asm 1: add c=int64#6 -# asm 2: mov $0,>c=%r9 -mov $0,%r9 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq rax=%rax -movq 56(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER3 -mulq crypto_sign_ed25519_amd64_64_ORDER3(%rip) - -# qhasm: free rdx - -# qhasm: r23 = rax -# asm 1: mov r23=int64#10 -# asm 2: mov r23=%r12 -mov %rax,%r12 - -# qhasm: r23 += c -# asm 1: add rax=int64#7 -# asm 2: movq rax=%rax -movq 64(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 -mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) - -# qhasm: carry? r21 += rax -# asm 1: add c=int64#6 -# asm 2: mov $0,>c=%r9 -mov $0,%r9 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq rax=%rax -movq 64(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER1 -mulq crypto_sign_ed25519_amd64_64_ORDER1(%rip) - -# qhasm: carry? r22 += rax -# asm 1: add c=int64#4 -# asm 2: mov $0,>c=%rcx -mov $0,%rcx - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq rax=%rax -movq 64(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER2 -mulq crypto_sign_ed25519_amd64_64_ORDER2(%rip) - -# qhasm: free rdx - -# qhasm: r23 += rax -# asm 1: add rax=int64#7 -# asm 2: movq rax=%rax -movq 72(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 -mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) - -# qhasm: carry? r22 += rax -# asm 1: add c=int64#4 -# asm 2: mov $0,>c=%rcx -mov $0,%rcx - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq rax=%rax -movq 72(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER1 -mulq crypto_sign_ed25519_amd64_64_ORDER1(%rip) - -# qhasm: free rdx - -# qhasm: r23 += rax -# asm 1: add rax=int64#7 -# asm 2: movq rax=%rax -movq 80(%rsp),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 -mulq crypto_sign_ed25519_amd64_64_ORDER0(%rip) - -# qhasm: free rdx - -# qhasm: r23 += rax -# asm 1: add r0=int64#3 -# asm 2: movq 0(r0=%rdx -movq 0(%rsi),%rdx - -# qhasm: carry? r0 -= r20 -# asm 1: sub t0=int64#4 -# asm 2: mov t0=%rcx -mov %rdx,%rcx - -# qhasm: r1 = *(uint64 *)(xp + 8) -# asm 1: movq 8(r1=int64#5 -# asm 2: movq 8(r1=%r8 -movq 8(%rsi),%r8 - -# qhasm: carry? r1 -= r21 - carry -# asm 1: sbb t1=int64#6 -# asm 2: mov t1=%r9 -mov %r8,%r9 - -# qhasm: r2 = *(uint64 *)(xp + 16) -# asm 1: movq 16(r2=int64#7 -# asm 2: movq 16(r2=%rax -movq 16(%rsi),%rax - -# qhasm: carry? r2 -= r22 - carry -# asm 1: sbb t2=int64#8 -# asm 2: mov t2=%r10 -mov %rax,%r10 - -# qhasm: r3 = *(uint64 *)(xp + 24) -# asm 1: movq 24(r3=int64#2 -# asm 2: movq 24(r3=%rsi -movq 24(%rsi),%rsi - -# qhasm: r3 -= r23 - carry -# asm 1: sbb t3=int64#9 -# asm 2: mov t3=%r11 -mov %rsi,%r11 - -# qhasm: carry? t0 -= *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 -# asm 1: sub crypto_sign_ed25519_amd64_64_ORDER0,t0=int64#4 -# asm 2: mov t0=%rcx -mov %rdx,%rcx - -# qhasm: r1 = t1 if !unsigned< -# asm 1: cmovae t1=int64#6 -# asm 2: mov t1=%r9 -mov %r8,%r9 - -# qhasm: r2 = t2 if !unsigned< -# asm 1: cmovae t2=int64#8 -# asm 2: mov t2=%r10 -mov %rax,%r10 - -# qhasm: r3 = t3 if !unsigned< -# asm 1: cmovae t3=int64#9 -# asm 2: mov t3=%r11 -mov %rsi,%r11 - -# qhasm: carry? t0 -= *(uint64 *) &crypto_sign_ed25519_amd64_64_ORDER0 -# asm 1: sub crypto_sign_ed25519_amd64_64_ORDER0,caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/ed25519-amd64-asm/sc25519_from32bytes.c b/ext/ed25519-amd64-asm/sc25519_from32bytes.c deleted file mode 100644 index 7f21e686..00000000 --- a/ext/ed25519-amd64-asm/sc25519_from32bytes.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "sc25519.h" - -/*Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 - * = 7237005577332262213973186563042994240857116359379907606001950938285454250989 - */ - -/* Contains order, 2*order, 4*order, 8*order, each represented in 4 consecutive unsigned long long */ -static const unsigned long long order[16] = {0x5812631A5CF5D3EDULL, 0x14DEF9DEA2F79CD6ULL, - 0x0000000000000000ULL, 0x1000000000000000ULL, - 0xB024C634B9EBA7DAULL, 0x29BDF3BD45EF39ACULL, - 0x0000000000000000ULL, 0x2000000000000000ULL, - 0x60498C6973D74FB4ULL, 0x537BE77A8BDE7359ULL, - 0x0000000000000000ULL, 0x4000000000000000ULL, - 0xC09318D2E7AE9F68ULL, 0xA6F7CEF517BCE6B2ULL, - 0x0000000000000000ULL, 0x8000000000000000ULL}; - -static unsigned long long smaller(unsigned long long a,unsigned long long b) -{ - unsigned long long atop = a >> 32; - unsigned long long abot = a & 4294967295; - unsigned long long btop = b >> 32; - unsigned long long bbot = b & 4294967295; - unsigned long long atopbelowbtop = (atop - btop) >> 63; - unsigned long long atopeqbtop = ((atop ^ btop) - 1) >> 63; - unsigned long long abotbelowbbot = (abot - bbot) >> 63; - return atopbelowbtop | (atopeqbtop & abotbelowbbot); -} - -void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]) -{ - unsigned long long t[4]; - unsigned long long b; - unsigned long long mask; - int i, j; - - /* assuming little-endian */ - r->v[0] = *(unsigned long long *)x; - r->v[1] = *(((unsigned long long *)x)+1); - r->v[2] = *(((unsigned long long *)x)+2); - r->v[3] = *(((unsigned long long *)x)+3); - - for(j=3;j>=0;j--) - { - b=0; - for(i=0;i<4;i++) - { - b += order[4*j+i]; /* no overflow for this particular order */ - t[i] = r->v[i] - b; - b = smaller(r->v[i],b); - } - mask = b - 1; - for(i=0;i<4;i++) - r->v[i] ^= mask & (r->v[i] ^ t[i]); - } -} diff --git a/ext/ed25519-amd64-asm/sc25519_from64bytes.c b/ext/ed25519-amd64-asm/sc25519_from64bytes.c deleted file mode 100644 index 8e76a1b3..00000000 --- a/ext/ed25519-amd64-asm/sc25519_from64bytes.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "sc25519.h" - -void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]) -{ - /* assuming little-endian representation of unsigned long long */ - sc25519_barrett(r, (unsigned long long *)x); -} diff --git a/ext/ed25519-amd64-asm/sc25519_from_shortsc.c b/ext/ed25519-amd64-asm/sc25519_from_shortsc.c deleted file mode 100644 index 3b8ff2fb..00000000 --- a/ext/ed25519-amd64-asm/sc25519_from_shortsc.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "sc25519.h" - -void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x) -{ - r->v[0] = x->v[0]; - r->v[1] = x->v[1]; - r->v[2] = 0; - r->v[3] = 0; -} diff --git a/ext/ed25519-amd64-asm/sc25519_iszero.c b/ext/ed25519-amd64-asm/sc25519_iszero.c deleted file mode 100644 index 21f593d7..00000000 --- a/ext/ed25519-amd64-asm/sc25519_iszero.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "sc25519.h" - -int sc25519_iszero_vartime(const sc25519 *x) -{ - if(x->v[0] != 0) return 0; - if(x->v[1] != 0) return 0; - if(x->v[2] != 0) return 0; - if(x->v[3] != 0) return 0; - return 1; -} diff --git a/ext/ed25519-amd64-asm/sc25519_lt.s b/ext/ed25519-amd64-asm/sc25519_lt.s deleted file mode 100644 index 3ba43178..00000000 --- a/ext/ed25519-amd64-asm/sc25519_lt.s +++ /dev/null @@ -1,131 +0,0 @@ - -# qhasm: int64 xp - -# qhasm: int64 yp - -# qhasm: int64 ret - -# qhasm: input xp - -# qhasm: input yp - -# qhasm: output ret - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 doof - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_lt -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_sc25519_lt -.globl crypto_sign_ed25519_amd64_64_sc25519_lt -_crypto_sign_ed25519_amd64_64_sc25519_lt: -crypto_sign_ed25519_amd64_64_sc25519_lt: -mov %rsp,%r11 -and $31,%r11 -add $0,%r11 -sub %r11,%rsp - -# qhasm: t0 = *(uint64 *)(xp + 0) -# asm 1: movq 0(t0=int64#3 -# asm 2: movq 0(t0=%rdx -movq 0(%rdi),%rdx - -# qhasm: t1 = *(uint64 *)(xp + 8) -# asm 1: movq 8(t1=int64#4 -# asm 2: movq 8(t1=%rcx -movq 8(%rdi),%rcx - -# qhasm: t2 = *(uint64 *)(xp + 16) -# asm 1: movq 16(t2=int64#5 -# asm 2: movq 16(t2=%r8 -movq 16(%rdi),%r8 - -# qhasm: t3 = *(uint64 *)(xp + 24) -# asm 1: movq 24(t3=int64#1 -# asm 2: movq 24(t3=%rdi -movq 24(%rdi),%rdi - -# qhasm: carry? t0 -= *(uint64 *)(yp + 0) -# asm 1: subq 0(ret=int64#1 -# asm 2: mov $0,>ret=%rdi -mov $0,%rdi - -# qhasm: doof = 1 -# asm 1: mov $1,>doof=int64#2 -# asm 2: mov $1,>doof=%rsi -mov $1,%rsi - -# qhasm: ret = doof if carry -# asm 1: cmovc v, y->v); - sc25519_barrett(r, t); -} diff --git a/ext/ed25519-amd64-asm/sc25519_mul_shortsc.c b/ext/ed25519-amd64-asm/sc25519_mul_shortsc.c deleted file mode 100644 index 0c67250d..00000000 --- a/ext/ed25519-amd64-asm/sc25519_mul_shortsc.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "sc25519.h" - -void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y) -{ - /* XXX: This wants to be faster */ - sc25519 t; - sc25519_from_shortsc(&t, y); - sc25519_mul(r, x, &t); -} diff --git a/ext/ed25519-amd64-asm/sc25519_slide.c b/ext/ed25519-amd64-asm/sc25519_slide.c deleted file mode 100644 index 4e52010d..00000000 --- a/ext/ed25519-amd64-asm/sc25519_slide.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "sc25519.h" - -void sc25519_slide(signed char r[256], const sc25519 *s, int swindowsize) -{ - int i,j,k,b,m=(1<<(swindowsize-1))-1, soplen=256; - unsigned long long sv0 = s->v[0]; - unsigned long long sv1 = s->v[1]; - unsigned long long sv2 = s->v[2]; - unsigned long long sv3 = s->v[3]; - - /* first put the binary expansion into r */ - for(i=0;i<64;i++) { - r[i] = sv0 & 1; - r[i+64] = sv1 & 1; - r[i+128] = sv2 & 1; - r[i+192] = sv3 & 1; - sv0 >>= 1; - sv1 >>= 1; - sv2 >>= 1; - sv3 >>= 1; - } - - /* Making it sliding window */ - for (j = 0;j < soplen;++j) - { - if (r[j]) { - for (b = 1;b < soplen - j && b <= 6;++b) { - if (r[j] + (r[j + b] << b) <= m) - { - r[j] += r[j + b] << b; r[j + b] = 0; - } - else if (r[j] - (r[j + b] << b) >= -m) - { - r[j] -= r[j + b] << b; - for (k = j + b;k < soplen;++k) - { - if (!r[k]) { - r[k] = 1; - break; - } - r[k] = 0; - } - } - else if (r[j + b]) - break; - } - } - } -} diff --git a/ext/ed25519-amd64-asm/sc25519_sub_nored.s b/ext/ed25519-amd64-asm/sc25519_sub_nored.s deleted file mode 100644 index a347e7d4..00000000 --- a/ext/ed25519-amd64-asm/sc25519_sub_nored.s +++ /dev/null @@ -1,142 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: int64 yp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: input yp - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 t0 - -# qhasm: int64 t1 - -# qhasm: int64 t2 - -# qhasm: int64 t3 - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_sc25519_sub_nored -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_sc25519_sub_nored -.globl crypto_sign_ed25519_amd64_64_sc25519_sub_nored -_crypto_sign_ed25519_amd64_64_sc25519_sub_nored: -crypto_sign_ed25519_amd64_64_sc25519_sub_nored: -mov %rsp,%r11 -and $31,%r11 -add $0,%r11 -sub %r11,%rsp - -# qhasm: r0 = *(uint64 *)(xp + 0) -# asm 1: movq 0(r0=int64#4 -# asm 2: movq 0(r0=%rcx -movq 0(%rsi),%rcx - -# qhasm: r1 = *(uint64 *)(xp + 8) -# asm 1: movq 8(r1=int64#5 -# asm 2: movq 8(r1=%r8 -movq 8(%rsi),%r8 - -# qhasm: r2 = *(uint64 *)(xp + 16) -# asm 1: movq 16(r2=int64#6 -# asm 2: movq 16(r2=%r9 -movq 16(%rsi),%r9 - -# qhasm: r3 = *(uint64 *)(xp + 24) -# asm 1: movq 24(r3=int64#2 -# asm 2: movq 24(r3=%rsi -movq 24(%rsi),%rsi - -# qhasm: carry? r0 -= *(uint64 *)(yp + 0) -# asm 1: subq 0(v]; -} diff --git a/ext/ed25519-amd64-asm/sc25519_window4.c b/ext/ed25519-amd64-asm/sc25519_window4.c deleted file mode 100644 index 683a1d4b..00000000 --- a/ext/ed25519-amd64-asm/sc25519_window4.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "sc25519.h" - -void sc25519_window4(signed char r[64], const sc25519 *s) -{ - char carry; - int i; - for(i=0;i<16;i++) - r[i] = (s->v[0] >> (4*i)) & 15; - for(i=0;i<16;i++) - r[i+16] = (s->v[1] >> (4*i)) & 15; - for(i=0;i<16;i++) - r[i+32] = (s->v[2] >> (4*i)) & 15; - for(i=0;i<16;i++) - r[i+48] = (s->v[3] >> (4*i)) & 15; - - /* Making it signed */ - carry = 0; - for(i=0;i<63;i++) - { - r[i] += carry; - r[i+1] += r[i] >> 4; - r[i] &= 15; - carry = r[i] >> 3; - r[i] -= carry << 4; - } - r[63] += carry; -} diff --git a/ext/ed25519-amd64-asm/sign.c b/ext/ed25519-amd64-asm/sign.c deleted file mode 100644 index 882ae76f..00000000 --- a/ext/ed25519-amd64-asm/sign.c +++ /dev/null @@ -1,162 +0,0 @@ -#include -#include -/*#include "crypto_sign.h" -#include "crypto_hash_sha512.h"*/ -#include "ge25519.h" - -/* Original */ -#if 0 -int crypto_sign( - unsigned char *sm,unsigned long long *smlen, - const unsigned char *m,unsigned long long mlen, - const unsigned char *sk - ) -{ - unsigned char pk[32]; - unsigned char az[64]; - unsigned char nonce[64]; - unsigned char hram[64]; - sc25519 sck, scs, scsk; - ge25519 ger; - - memmove(pk,sk + 32,32); - /* pk: 32-byte public key A */ - - crypto_hash_sha512(az,sk,32); - az[0] &= 248; - az[31] &= 127; - az[31] |= 64; - /* az: 32-byte scalar a, 32-byte randomizer z */ - - *smlen = mlen + 64; - memmove(sm + 64,m,mlen); - memmove(sm + 32,az + 32,32); - /* sm: 32-byte uninit, 32-byte z, mlen-byte m */ - - crypto_hash_sha512(nonce, sm+32, mlen+32); - /* nonce: 64-byte H(z,m) */ - - sc25519_from64bytes(&sck, nonce); - ge25519_scalarmult_base(&ger, &sck); - ge25519_pack(sm, &ger); - /* sm: 32-byte R, 32-byte z, mlen-byte m */ - - memmove(sm + 32,pk,32); - /* sm: 32-byte R, 32-byte A, mlen-byte m */ - - crypto_hash_sha512(hram,sm,mlen + 64); - /* hram: 64-byte H(R,A,m) */ - - sc25519_from64bytes(&scs, hram); - sc25519_from32bytes(&scsk, az); - sc25519_mul(&scs, &scs, &scsk); - sc25519_add(&scs, &scs, &sck); - /* scs: S = nonce + H(R,A,m)a */ - - sc25519_to32bytes(sm + 32,&scs); - /* sm: 32-byte R, 32-byte S, mlen-byte m */ - - return 0; -} -#endif - -#if 0 -void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPublic,const void *msg,unsigned int len,void *signature) -{ - sc25519 sck, scs, scsk; - ge25519 ger; - unsigned char r[32]; - unsigned char s[32]; - unsigned char extsk[64]; - unsigned char hmg[crypto_hash_sha512_BYTES]; - unsigned char hram[crypto_hash_sha512_BYTES]; - unsigned char *sig = (unsigned char *)signature; - unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) - - SHA512::hash(digest,msg,len); - - SHA512::hash(extsk,myPrivate.data + 32,32); - extsk[0] &= 248; - extsk[31] &= 127; - extsk[31] |= 64; - - for(unsigned int i=0;i<32;i++) - sig[32 + i] = extsk[32 + i]; - for(unsigned int i=0;i<32;i++) - sig[64 + i] = digest[i]; - - SHA512::hash(hmg,sig + 32,64); - - /* Computation of R */ - sc25519_from64bytes(&sck, hmg); - ge25519_scalarmult_base(&ger, &sck); - ge25519_pack(r, &ger); - - /* Computation of s */ - for(unsigned int i=0;i<32;i++) - sig[i] = r[i]; - - get_hram(hram,sig,myPublic.data + 32,sig,96); - - sc25519_from64bytes(&scs, hram); - sc25519_from32bytes(&scsk, extsk); - sc25519_mul(&scs, &scs, &scsk); - - sc25519_add(&scs, &scs, &sck); - - sc25519_to32bytes(s,&scs); /* cat s */ - for(unsigned int i=0;i<32;i++) - sig[32 + i] = s[i]; -} - -void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) -{ - unsigned long long i; - - for (i = 0;i < 32;++i) playground[i] = sm[i]; - for (i = 32;i < 64;++i) playground[i] = pk[i-32]; - for (i = 64;i < smlen;++i) playground[i] = sm[i]; - - //crypto_hash_sha512(hram,playground,smlen); - ZeroTier::SHA512::hash(hram,playground,(unsigned int)smlen); -} -#endif - -extern void ZT_sha512internal(void *digest,const void *data,unsigned int len); - -extern void ed25519_amd64_asm_sign(const unsigned char *sk,const unsigned char *pk,const unsigned char *digest,unsigned char *sig) -{ - unsigned char az[64]; - unsigned char nonce[64]; - unsigned char hram[64]; - sc25519 sck, scs, scsk; - ge25519 ger; - unsigned int i; - - ZT_sha512internal(az,sk,32); - az[0] &= 248; - az[31] &= 127; - az[31] |= 64; - - for(i=0;i<32;i++) - sig[32 + i] = az[32 + i]; - for(i=0;i<32;i++) - sig[64 + i] = digest[i]; - - ZT_sha512internal(nonce,sig + 32,64); - - sc25519_from64bytes(&sck, nonce); - ge25519_scalarmult_base(&ger, &sck); - ge25519_pack(sig, &ger); - - memmove(sig + 32,pk,32); - - ZT_sha512internal(hram,sig,96); - - sc25519_from64bytes(&scs, hram); - sc25519_from32bytes(&scsk, az); - sc25519_mul(&scs, &scs, &scsk); - sc25519_add(&scs, &scs, &sck); - - sc25519_to32bytes(sig + 32,&scs); -} diff --git a/ext/ed25519-amd64-asm/ull4_mul.s b/ext/ed25519-amd64-asm/ull4_mul.s deleted file mode 100644 index 9f7b4fa2..00000000 --- a/ext/ed25519-amd64-asm/ull4_mul.s +++ /dev/null @@ -1,716 +0,0 @@ - -# qhasm: int64 rp - -# qhasm: int64 xp - -# qhasm: int64 yp - -# qhasm: input rp - -# qhasm: input xp - -# qhasm: input yp - -# qhasm: int64 r0 - -# qhasm: int64 r1 - -# qhasm: int64 r2 - -# qhasm: int64 r3 - -# qhasm: int64 r4 - -# qhasm: int64 r5 - -# qhasm: int64 r6 - -# qhasm: int64 r7 - -# qhasm: int64 c - -# qhasm: int64 zero - -# qhasm: int64 rax - -# qhasm: int64 rdx - -# qhasm: int64 caller1 - -# qhasm: int64 caller2 - -# qhasm: int64 caller3 - -# qhasm: int64 caller4 - -# qhasm: int64 caller5 - -# qhasm: int64 caller6 - -# qhasm: int64 caller7 - -# qhasm: caller caller1 - -# qhasm: caller caller2 - -# qhasm: caller caller3 - -# qhasm: caller caller4 - -# qhasm: caller caller5 - -# qhasm: caller caller6 - -# qhasm: caller caller7 - -# qhasm: stack64 caller1_stack - -# qhasm: stack64 caller2_stack - -# qhasm: stack64 caller3_stack - -# qhasm: stack64 caller4_stack - -# qhasm: stack64 caller5_stack - -# qhasm: stack64 caller6_stack - -# qhasm: stack64 caller7_stack - -# qhasm: enter crypto_sign_ed25519_amd64_64_ull4_mul -.text -.p2align 5 -.globl _crypto_sign_ed25519_amd64_64_ull4_mul -.globl crypto_sign_ed25519_amd64_64_ull4_mul -_crypto_sign_ed25519_amd64_64_ull4_mul: -crypto_sign_ed25519_amd64_64_ull4_mul: -mov %rsp,%r11 -and $31,%r11 -add $64,%r11 -sub %r11,%rsp - -# qhasm: caller1_stack = caller1 -# asm 1: movq caller1_stack=stack64#1 -# asm 2: movq caller1_stack=0(%rsp) -movq %r11,0(%rsp) - -# qhasm: caller2_stack = caller2 -# asm 1: movq caller2_stack=stack64#2 -# asm 2: movq caller2_stack=8(%rsp) -movq %r12,8(%rsp) - -# qhasm: caller3_stack = caller3 -# asm 1: movq caller3_stack=stack64#3 -# asm 2: movq caller3_stack=16(%rsp) -movq %r13,16(%rsp) - -# qhasm: caller4_stack = caller4 -# asm 1: movq caller4_stack=stack64#4 -# asm 2: movq caller4_stack=24(%rsp) -movq %r14,24(%rsp) - -# qhasm: caller5_stack = caller5 -# asm 1: movq caller5_stack=stack64#5 -# asm 2: movq caller5_stack=32(%rsp) -movq %r15,32(%rsp) - -# qhasm: caller6_stack = caller6 -# asm 1: movq caller6_stack=stack64#6 -# asm 2: movq caller6_stack=40(%rsp) -movq %rbx,40(%rsp) - -# qhasm: caller7_stack = caller7 -# asm 1: movq caller7_stack=stack64#7 -# asm 2: movq caller7_stack=48(%rsp) -movq %rbp,48(%rsp) - -# qhasm: yp = yp -# asm 1: mov yp=int64#4 -# asm 2: mov yp=%rcx -mov %rdx,%rcx - -# qhasm: r4 = 0 -# asm 1: mov $0,>r4=int64#5 -# asm 2: mov $0,>r4=%r8 -mov $0,%r8 - -# qhasm: r5 = 0 -# asm 1: mov $0,>r5=int64#6 -# asm 2: mov $0,>r5=%r9 -mov $0,%r9 - -# qhasm: r6 = 0 -# asm 1: mov $0,>r6=int64#8 -# asm 2: mov $0,>r6=%r10 -mov $0,%r10 - -# qhasm: r7 = 0 -# asm 1: mov $0,>r7=int64#9 -# asm 2: mov $0,>r7=%r11 -mov $0,%r11 - -# qhasm: zero = 0 -# asm 1: mov $0,>zero=int64#10 -# asm 2: mov $0,>zero=%r12 -mov $0,%r12 - -# qhasm: rax = *(uint64 *)(xp + 0) -# asm 1: movq 0(rax=int64#7 -# asm 2: movq 0(rax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) -# asm 1: mulq 0(r0=int64#11 -# asm 2: mov r0=%r13 -mov %rax,%r13 - -# qhasm: c = rdx -# asm 1: mov c=int64#12 -# asm 2: mov c=%r14 -mov %rdx,%r14 - -# qhasm: rax = *(uint64 *)(xp + 0) -# asm 1: movq 0(rax=int64#7 -# asm 2: movq 0(rax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) -# asm 1: mulq 8(r1=int64#13 -# asm 2: mov r1=%r15 -mov %rax,%r15 - -# qhasm: carry? r1 += c -# asm 1: add c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 0(rax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) -# asm 1: mulq 16(r2=int64#14 -# asm 2: mov r2=%rbx -mov %rax,%rbx - -# qhasm: carry? r2 += c -# asm 1: add c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 0(rax=%rax -movq 0(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) -# asm 1: mulq 24(r3=int64#15 -# asm 2: mov r3=%rbp -mov %rax,%rbp - -# qhasm: carry? r3 += c -# asm 1: add rax=int64#7 -# asm 2: movq 8(rax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) -# asm 1: mulq 0(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 8(rax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) -# asm 1: mulq 8(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 8(rax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) -# asm 1: mulq 16(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 8(rax=%rax -movq 8(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) -# asm 1: mulq 24(rax=int64#7 -# asm 2: movq 16(rax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) -# asm 1: mulq 0(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 16(rax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) -# asm 1: mulq 8(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 16(rax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) -# asm 1: mulq 16(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 16(rax=%rax -movq 16(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) -# asm 1: mulq 24(rax=int64#7 -# asm 2: movq 24(rax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 0) -# asm 1: mulq 0(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 24(rax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 8) -# asm 1: mulq 8(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 24(rax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 16) -# asm 1: mulq 16(c=int64#12 -# asm 2: mov $0,>c=%r14 -mov $0,%r14 - -# qhasm: c += rdx + carry -# asm 1: adc rax=int64#7 -# asm 2: movq 24(rax=%rax -movq 24(%rsi),%rax - -# qhasm: (uint128) rdx rax = rax * *(uint64 *)(yp + 24) -# asm 1: mulq 24(caller1=int64#9 -# asm 2: movq caller1=%r11 -movq 0(%rsp),%r11 - -# qhasm: caller2 = caller2_stack -# asm 1: movq caller2=int64#10 -# asm 2: movq caller2=%r12 -movq 8(%rsp),%r12 - -# qhasm: caller3 = caller3_stack -# asm 1: movq caller3=int64#11 -# asm 2: movq caller3=%r13 -movq 16(%rsp),%r13 - -# qhasm: caller4 = caller4_stack -# asm 1: movq caller4=int64#12 -# asm 2: movq caller4=%r14 -movq 24(%rsp),%r14 - -# qhasm: caller5 = caller5_stack -# asm 1: movq caller5=int64#13 -# asm 2: movq caller5=%r15 -movq 32(%rsp),%r15 - -# qhasm: caller6 = caller6_stack -# asm 1: movq caller6=int64#14 -# asm 2: movq caller6=%rbx -movq 40(%rsp),%rbx - -# qhasm: caller7 = caller7_stack -# asm 1: movq caller7=int64#15 -# asm 2: movq caller7=%rbp -movq 48(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -mov %rdi,%rax -mov %rsi,%rdx -ret diff --git a/ext/http-parser/AUTHORS b/ext/http-parser/AUTHORS deleted file mode 100644 index 5323b685..00000000 --- a/ext/http-parser/AUTHORS +++ /dev/null @@ -1,68 +0,0 @@ -# Authors ordered by first contribution. -Ryan Dahl -Jeremy Hinegardner -Sergey Shepelev -Joe Damato -tomika -Phoenix Sol -Cliff Frey -Ewen Cheslack-Postava -Santiago Gala -Tim Becker -Jeff Terrace -Ben Noordhuis -Nathan Rajlich -Mark Nottingham -Aman Gupta -Tim Becker -Sean Cunningham -Peter Griess -Salman Haq -Cliff Frey -Jon Kolb -Fouad Mardini -Paul Querna -Felix Geisendörfer -koichik -Andre Caron -Ivo Raisr -James McLaughlin -David Gwynne -Thomas LE ROUX -Randy Rizun -Andre Louis Caron -Simon Zimmermann -Erik Dubbelboer -Martell Malone -Bertrand Paquet -BogDan Vatra -Peter Faiman -Corey Richardson -Tóth Tamás -Cam Swords -Chris Dickinson -Uli Köhler -Charlie Somerville -Patrik Stutz -Fedor Indutny -runner -Alexis Campailla -David Wragg -Vinnie Falco -Alex Butum -Rex Feng -Alex Kocharin -Mark Koopman -Helge Heß -Alexis La Goutte -George Miroshnykov -Maciej Małecki -Marc O'Morain -Jeff Pinner -Timothy J Fontaine -Akagi201 -Romain Giraud -Jay Satiro -Arne Steen -Kjell Schubert -Olivier Mengué diff --git a/ext/http-parser/LICENSE-MIT b/ext/http-parser/LICENSE-MIT deleted file mode 100644 index 58010b38..00000000 --- a/ext/http-parser/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright -Igor Sysoev. - -Additional changes are licensed under the same terms as NGINX and -copyright Joyent, Inc. and other Node contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/ext/http-parser/README.md b/ext/http-parser/README.md deleted file mode 100644 index 439b3099..00000000 --- a/ext/http-parser/README.md +++ /dev/null @@ -1,246 +0,0 @@ -HTTP Parser -=========== - -[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser) - -This is a parser for HTTP messages written in C. It parses both requests and -responses. The parser is designed to be used in performance HTTP -applications. It does not make any syscalls nor allocations, it does not -buffer data, it can be interrupted at anytime. Depending on your -architecture, it only requires about 40 bytes of data per message -stream (in a web server that is per connection). - -Features: - - * No dependencies - * Handles persistent streams (keep-alive). - * Decodes chunked encoding. - * Upgrade support - * Defends against buffer overflow attacks. - -The parser extracts the following information from HTTP messages: - - * Header fields and values - * Content-Length - * Request method - * Response status code - * Transfer-Encoding - * HTTP version - * Request URL - * Message body - - -Usage ------ - -One `http_parser` object is used per TCP connection. Initialize the struct -using `http_parser_init()` and set the callbacks. That might look something -like this for a request parser: -```c -http_parser_settings settings; -settings.on_url = my_url_callback; -settings.on_header_field = my_header_field_callback; -/* ... */ - -http_parser *parser = malloc(sizeof(http_parser)); -http_parser_init(parser, HTTP_REQUEST); -parser->data = my_socket; -``` - -When data is received on the socket execute the parser and check for errors. - -```c -size_t len = 80*1024, nparsed; -char buf[len]; -ssize_t recved; - -recved = recv(fd, buf, len, 0); - -if (recved < 0) { - /* Handle error. */ -} - -/* Start up / continue the parser. - * Note we pass recved==0 to signal that EOF has been received. - */ -nparsed = http_parser_execute(parser, &settings, buf, recved); - -if (parser->upgrade) { - /* handle new protocol */ -} else if (nparsed != recved) { - /* Handle error. Usually just close the connection. */ -} -``` - -HTTP needs to know where the end of the stream is. For example, sometimes -servers send responses without Content-Length and expect the client to -consume input (for the body) until EOF. To tell http_parser about EOF, give -`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors -can still be encountered during an EOF, so one must still be prepared -to receive them. - -Scalar valued message information such as `status_code`, `method`, and the -HTTP version are stored in the parser structure. This data is only -temporally stored in `http_parser` and gets reset on each new message. If -this information is needed later, copy it out of the structure during the -`headers_complete` callback. - -The parser decodes the transfer-encoding for both requests and responses -transparently. That is, a chunked encoding is decoded before being sent to -the on_body callback. - - -The Special Problem of Upgrade ------------------------------- - -HTTP supports upgrading the connection to a different protocol. An -increasingly common example of this is the WebSocket protocol which sends -a request like - - GET /demo HTTP/1.1 - Upgrade: WebSocket - Connection: Upgrade - Host: example.com - Origin: http://example.com - WebSocket-Protocol: sample - -followed by non-HTTP data. - -(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the -WebSocket protocol.) - -To support this, the parser will treat this as a normal HTTP message without a -body, issuing both on_headers_complete and on_message_complete callbacks. However -http_parser_execute() will stop parsing at the end of the headers and return. - -The user is expected to check if `parser->upgrade` has been set to 1 after -`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied -offset by the return value of `http_parser_execute()`. - - -Callbacks ---------- - -During the `http_parser_execute()` call, the callbacks set in -`http_parser_settings` will be executed. The parser maintains state and -never looks behind, so buffering the data is not necessary. If you need to -save certain data for later usage, you can do that from the callbacks. - -There are two types of callbacks: - -* notification `typedef int (*http_cb) (http_parser*);` - Callbacks: on_message_begin, on_headers_complete, on_message_complete. -* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);` - Callbacks: (requests only) on_url, - (common) on_header_field, on_header_value, on_body; - -Callbacks must return 0 on success. Returning a non-zero value indicates -error to the parser, making it exit immediately. - -For cases where it is necessary to pass local information to/from a callback, -the `http_parser` object's `data` field can be used. -An example of such a case is when using threads to handle a socket connection, -parse a request, and then give a response over that socket. By instantiation -of a thread-local struct containing relevant data (e.g. accepted socket, -allocated memory for callbacks to write into, etc), a parser's callbacks are -able to communicate data between the scope of the thread and the scope of the -callback in a threadsafe manner. This allows http-parser to be used in -multi-threaded contexts. - -Example: -```c - typedef struct { - socket_t sock; - void* buffer; - int buf_len; - } custom_data_t; - - -int my_url_callback(http_parser* parser, const char *at, size_t length) { - /* access to thread local custom_data_t struct. - Use this access save parsed data for later use into thread local - buffer, or communicate over socket - */ - parser->data; - ... - return 0; -} - -... - -void http_parser_thread(socket_t sock) { - int nparsed = 0; - /* allocate memory for user data */ - custom_data_t *my_data = malloc(sizeof(custom_data_t)); - - /* some information for use by callbacks. - * achieves thread -> callback information flow */ - my_data->sock = sock; - - /* instantiate a thread-local parser */ - http_parser *parser = malloc(sizeof(http_parser)); - http_parser_init(parser, HTTP_REQUEST); /* initialise parser */ - /* this custom data reference is accessible through the reference to the - parser supplied to callback functions */ - parser->data = my_data; - - http_parser_settings settings; /* set up callbacks */ - settings.on_url = my_url_callback; - - /* execute parser */ - nparsed = http_parser_execute(parser, &settings, buf, recved); - - ... - /* parsed information copied from callback. - can now perform action on data copied into thread-local memory from callbacks. - achieves callback -> thread information flow */ - my_data->buffer; - ... -} - -``` - -In case you parse HTTP message in chunks (i.e. `read()` request line -from socket, parse, read half headers, parse, etc) your data callbacks -may be called more than once. Http-parser guarantees that data pointer is only -valid for the lifetime of callback. You can also `read()` into a heap allocated -buffer to avoid copying memory around if this fits your application. - -Reading headers may be a tricky task if you read/parse headers partially. -Basically, you need to remember whether last header callback was field or value -and apply the following logic: - - (on_header_field and on_header_value shortened to on_h_*) - ------------------------ ------------ -------------------------------------------- - | State (prev. callback) | Callback | Description/action | - ------------------------ ------------ -------------------------------------------- - | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | - | | | into it | - ------------------------ ------------ -------------------------------------------- - | value | on_h_field | New header started. | - | | | Copy current name,value buffers to headers | - | | | list and allocate new buffer for new name | - ------------------------ ------------ -------------------------------------------- - | field | on_h_field | Previous name continues. Reallocate name | - | | | buffer and append callback data to it | - ------------------------ ------------ -------------------------------------------- - | field | on_h_value | Value for current header started. Allocate | - | | | new buffer and copy callback data to it | - ------------------------ ------------ -------------------------------------------- - | value | on_h_value | Value continues. Reallocate value buffer | - | | | and append callback data to it | - ------------------------ ------------ -------------------------------------------- - - -Parsing URLs ------------- - -A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`. -Users of this library may wish to use it to parse URLs constructed from -consecutive `on_url` callbacks. - -See examples of reading in headers: - -* [partial example](http://gist.github.com/155877) in C -* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C -* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript diff --git a/ext/http-parser/http_parser.c b/ext/http-parser/http_parser.c deleted file mode 100644 index 895bf0c7..00000000 --- a/ext/http-parser/http_parser.c +++ /dev/null @@ -1,2470 +0,0 @@ -/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev - * - * Additional changes are licensed under the same terms as NGINX and - * copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include "http_parser.h" -#include -#include -#include -#include -#include -#include - -#ifndef ULLONG_MAX -# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ -#endif - -#ifndef MIN -# define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -#endif - -#ifndef BIT_AT -# define BIT_AT(a, i) \ - (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ - (1 << ((unsigned int) (i) & 7)))) -#endif - -#ifndef ELEM_AT -# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) -#endif - -#define SET_ERRNO(e) \ -do { \ - parser->http_errno = (e); \ -} while(0) - -#define CURRENT_STATE() p_state -#define UPDATE_STATE(V) p_state = (enum state) (V); -#define RETURN(V) \ -do { \ - parser->state = CURRENT_STATE(); \ - return (V); \ -} while (0); -#define REEXECUTE() \ - goto reexecute; \ - - -#ifdef __GNUC__ -# define LIKELY(X) __builtin_expect(!!(X), 1) -# define UNLIKELY(X) __builtin_expect(!!(X), 0) -#else -# define LIKELY(X) (X) -# define UNLIKELY(X) (X) -#endif - - -/* Run the notify callback FOR, returning ER if it fails */ -#define CALLBACK_NOTIFY_(FOR, ER) \ -do { \ - assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ - \ - if (LIKELY(settings->on_##FOR)) { \ - parser->state = CURRENT_STATE(); \ - if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ - SET_ERRNO(HPE_CB_##FOR); \ - } \ - UPDATE_STATE(parser->state); \ - \ - /* We either errored above or got paused; get out */ \ - if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ - return (ER); \ - } \ - } \ -} while (0) - -/* Run the notify callback FOR and consume the current byte */ -#define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) - -/* Run the notify callback FOR and don't consume the current byte */ -#define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) - -/* Run data callback FOR with LEN bytes, returning ER if it fails */ -#define CALLBACK_DATA_(FOR, LEN, ER) \ -do { \ - assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ - \ - if (FOR##_mark) { \ - if (LIKELY(settings->on_##FOR)) { \ - parser->state = CURRENT_STATE(); \ - if (UNLIKELY(0 != \ - settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ - SET_ERRNO(HPE_CB_##FOR); \ - } \ - UPDATE_STATE(parser->state); \ - \ - /* We either errored above or got paused; get out */ \ - if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ - return (ER); \ - } \ - } \ - FOR##_mark = NULL; \ - } \ -} while (0) - -/* Run the data callback FOR and consume the current byte */ -#define CALLBACK_DATA(FOR) \ - CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) - -/* Run the data callback FOR and don't consume the current byte */ -#define CALLBACK_DATA_NOADVANCE(FOR) \ - CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) - -/* Set the mark FOR; non-destructive if mark is already set */ -#define MARK(FOR) \ -do { \ - if (!FOR##_mark) { \ - FOR##_mark = p; \ - } \ -} while (0) - -/* Don't allow the total size of the HTTP headers (including the status - * line) to exceed HTTP_MAX_HEADER_SIZE. This check is here to protect - * embedders against denial-of-service attacks where the attacker feeds - * us a never-ending header that the embedder keeps buffering. - * - * This check is arguably the responsibility of embedders but we're doing - * it on the embedder's behalf because most won't bother and this way we - * make the web a little safer. HTTP_MAX_HEADER_SIZE is still far bigger - * than any reasonable request or response so this should never affect - * day-to-day operation. - */ -#define COUNT_HEADER_SIZE(V) \ -do { \ - parser->nread += (V); \ - if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \ - SET_ERRNO(HPE_HEADER_OVERFLOW); \ - goto error; \ - } \ -} while (0) - - -#define PROXY_CONNECTION "proxy-connection" -#define CONNECTION "connection" -#define CONTENT_LENGTH "content-length" -#define TRANSFER_ENCODING "transfer-encoding" -#define UPGRADE "upgrade" -#define CHUNKED "chunked" -#define KEEP_ALIVE "keep-alive" -#define CLOSE "close" - - -static const char *method_strings[] = - { -#define XX(num, name, string) #string, - HTTP_METHOD_MAP(XX) -#undef XX - }; - - -/* Tokens as defined by rfc 2616. Also lowercases them. - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - */ -static const char tokens[256] = { -/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ - 0, '!', 0, '#', '$', '%', '&', '\'', -/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ - 0, 0, '*', '+', 0, '-', '.', 0, -/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ - '0', '1', '2', '3', '4', '5', '6', '7', -/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ - '8', '9', 0, 0, 0, 0, 0, 0, -/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ - 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', -/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', -/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ - 'x', 'y', 'z', 0, 0, 0, '^', '_', -/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', -/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', -/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ - 'x', 'y', 'z', 0, '|', 0, '~', 0 }; - - -static const int8_t unhex[256] = - {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 - ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - }; - - -#if HTTP_PARSER_STRICT -# define T(v) 0 -#else -# define T(v) v -#endif - - -static const uint8_t normal_url_char[32] = { -/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ - 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, -/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ - 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, -/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ - 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, -/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ - 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, -/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ - 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, -/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, -/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, -/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; - -#undef T - -enum state - { s_dead = 1 /* important that this is > 0 */ - - , s_start_req_or_res - , s_res_or_resp_H - , s_start_res - , s_res_H - , s_res_HT - , s_res_HTT - , s_res_HTTP - , s_res_first_http_major - , s_res_http_major - , s_res_first_http_minor - , s_res_http_minor - , s_res_first_status_code - , s_res_status_code - , s_res_status_start - , s_res_status - , s_res_line_almost_done - - , s_start_req - - , s_req_method - , s_req_spaces_before_url - , s_req_schema - , s_req_schema_slash - , s_req_schema_slash_slash - , s_req_server_start - , s_req_server - , s_req_server_with_at - , s_req_path - , s_req_query_string_start - , s_req_query_string - , s_req_fragment_start - , s_req_fragment - , s_req_http_start - , s_req_http_H - , s_req_http_HT - , s_req_http_HTT - , s_req_http_HTTP - , s_req_first_http_major - , s_req_http_major - , s_req_first_http_minor - , s_req_http_minor - , s_req_line_almost_done - - , s_header_field_start - , s_header_field - , s_header_value_discard_ws - , s_header_value_discard_ws_almost_done - , s_header_value_discard_lws - , s_header_value_start - , s_header_value - , s_header_value_lws - - , s_header_almost_done - - , s_chunk_size_start - , s_chunk_size - , s_chunk_parameters - , s_chunk_size_almost_done - - , s_headers_almost_done - , s_headers_done - - /* Important: 's_headers_done' must be the last 'header' state. All - * states beyond this must be 'body' states. It is used for overflow - * checking. See the PARSING_HEADER() macro. - */ - - , s_chunk_data - , s_chunk_data_almost_done - , s_chunk_data_done - - , s_body_identity - , s_body_identity_eof - - , s_message_done - }; - - -#define PARSING_HEADER(state) (state <= s_headers_done) - - -enum header_states - { h_general = 0 - , h_C - , h_CO - , h_CON - - , h_matching_connection - , h_matching_proxy_connection - , h_matching_content_length - , h_matching_transfer_encoding - , h_matching_upgrade - - , h_connection - , h_content_length - , h_transfer_encoding - , h_upgrade - - , h_matching_transfer_encoding_chunked - , h_matching_connection_token_start - , h_matching_connection_keep_alive - , h_matching_connection_close - , h_matching_connection_upgrade - , h_matching_connection_token - - , h_transfer_encoding_chunked - , h_connection_keep_alive - , h_connection_close - , h_connection_upgrade - }; - -enum http_host_state - { - s_http_host_dead = 1 - , s_http_userinfo_start - , s_http_userinfo - , s_http_host_start - , s_http_host_v6_start - , s_http_host - , s_http_host_v6 - , s_http_host_v6_end - , s_http_host_v6_zone_start - , s_http_host_v6_zone - , s_http_host_port_start - , s_http_host_port -}; - -/* Macros for character classes; depends on strict-mode */ -#define CR '\r' -#define LF '\n' -#define LOWER(c) (unsigned char)(c | 0x20) -#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') -#define IS_NUM(c) ((c) >= '0' && (c) <= '9') -#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) -#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) -#define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ - (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ - (c) == ')') -#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ - (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ - (c) == '$' || (c) == ',') - -#define STRICT_TOKEN(c) (tokens[(unsigned char)c]) - -#if HTTP_PARSER_STRICT -#define TOKEN(c) (tokens[(unsigned char)c]) -#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) -#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') -#else -#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) -#define IS_URL_CHAR(c) \ - (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) -#define IS_HOST_CHAR(c) \ - (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') -#endif - -/** - * Verify that a char is a valid visible (printable) US-ASCII - * character or %x80-FF - **/ -#define IS_HEADER_CHAR(ch) \ - (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127)) - -#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) - - -#if HTTP_PARSER_STRICT -# define STRICT_CHECK(cond) \ -do { \ - if (cond) { \ - SET_ERRNO(HPE_STRICT); \ - goto error; \ - } \ -} while (0) -# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) -#else -# define STRICT_CHECK(cond) -# define NEW_MESSAGE() start_state -#endif - - -/* Map errno values to strings for human-readable output */ -#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, -static struct { - const char *name; - const char *description; -} http_strerror_tab[] = { - HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) -}; -#undef HTTP_STRERROR_GEN - -int http_message_needs_eof(const http_parser *parser); - -/* Our URL parser. - * - * This is designed to be shared by http_parser_execute() for URL validation, - * hence it has a state transition + byte-for-byte interface. In addition, it - * is meant to be embedded in http_parser_parse_url(), which does the dirty - * work of turning state transitions URL components for its API. - * - * This function should only be invoked with non-space characters. It is - * assumed that the caller cares about (and can detect) the transition between - * URL and non-URL states by looking for these. - */ -static enum state -parse_url_char(enum state s, const char ch) -{ - if (ch == ' ' || ch == '\r' || ch == '\n') { - return s_dead; - } - -#if HTTP_PARSER_STRICT - if (ch == '\t' || ch == '\f') { - return s_dead; - } -#endif - - switch (s) { - case s_req_spaces_before_url: - /* Proxied requests are followed by scheme of an absolute URI (alpha). - * All methods except CONNECT are followed by '/' or '*'. - */ - - if (ch == '/' || ch == '*') { - return s_req_path; - } - - if (IS_ALPHA(ch)) { - return s_req_schema; - } - - break; - - case s_req_schema: - if (IS_ALPHA(ch)) { - return s; - } - - if (ch == ':') { - return s_req_schema_slash; - } - - break; - - case s_req_schema_slash: - if (ch == '/') { - return s_req_schema_slash_slash; - } - - break; - - case s_req_schema_slash_slash: - if (ch == '/') { - return s_req_server_start; - } - - break; - - case s_req_server_with_at: - if (ch == '@') { - return s_dead; - } - - /* FALLTHROUGH */ - case s_req_server_start: - case s_req_server: - if (ch == '/') { - return s_req_path; - } - - if (ch == '?') { - return s_req_query_string_start; - } - - if (ch == '@') { - return s_req_server_with_at; - } - - if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { - return s_req_server; - } - - break; - - case s_req_path: - if (IS_URL_CHAR(ch)) { - return s; - } - - switch (ch) { - case '?': - return s_req_query_string_start; - - case '#': - return s_req_fragment_start; - } - - break; - - case s_req_query_string_start: - case s_req_query_string: - if (IS_URL_CHAR(ch)) { - return s_req_query_string; - } - - switch (ch) { - case '?': - /* allow extra '?' in query string */ - return s_req_query_string; - - case '#': - return s_req_fragment_start; - } - - break; - - case s_req_fragment_start: - if (IS_URL_CHAR(ch)) { - return s_req_fragment; - } - - switch (ch) { - case '?': - return s_req_fragment; - - case '#': - return s; - } - - break; - - case s_req_fragment: - if (IS_URL_CHAR(ch)) { - return s; - } - - switch (ch) { - case '?': - case '#': - return s; - } - - break; - - default: - break; - } - - /* We should never fall out of the switch above unless there's an error */ - return s_dead; -} - -size_t http_parser_execute (http_parser *parser, - const http_parser_settings *settings, - const char *data, - size_t len) -{ - char c, ch; - int8_t unhex_val; - const char *p = data; - const char *header_field_mark = 0; - const char *header_value_mark = 0; - const char *url_mark = 0; - const char *body_mark = 0; - const char *status_mark = 0; - enum state p_state = (enum state) parser->state; - const unsigned int lenient = parser->lenient_http_headers; - - /* We're in an error state. Don't bother doing anything. */ - if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { - return 0; - } - - if (len == 0) { - switch (CURRENT_STATE()) { - case s_body_identity_eof: - /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if - * we got paused. - */ - CALLBACK_NOTIFY_NOADVANCE(message_complete); - return 0; - - case s_dead: - case s_start_req_or_res: - case s_start_res: - case s_start_req: - return 0; - - default: - SET_ERRNO(HPE_INVALID_EOF_STATE); - return 1; - } - } - - - if (CURRENT_STATE() == s_header_field) - header_field_mark = data; - if (CURRENT_STATE() == s_header_value) - header_value_mark = data; - switch (CURRENT_STATE()) { - case s_req_path: - case s_req_schema: - case s_req_schema_slash: - case s_req_schema_slash_slash: - case s_req_server_start: - case s_req_server: - case s_req_server_with_at: - case s_req_query_string_start: - case s_req_query_string: - case s_req_fragment_start: - case s_req_fragment: - url_mark = data; - break; - case s_res_status: - status_mark = data; - break; - default: - break; - } - - for (p=data; p != data + len; p++) { - ch = *p; - - if (PARSING_HEADER(CURRENT_STATE())) - COUNT_HEADER_SIZE(1); - -reexecute: - switch (CURRENT_STATE()) { - - case s_dead: - /* this state is used after a 'Connection: close' message - * the parser will error out if it reads another message - */ - if (LIKELY(ch == CR || ch == LF)) - break; - - SET_ERRNO(HPE_CLOSED_CONNECTION); - goto error; - - case s_start_req_or_res: - { - if (ch == CR || ch == LF) - break; - parser->flags = 0; - parser->content_length = ULLONG_MAX; - - if (ch == 'H') { - UPDATE_STATE(s_res_or_resp_H); - - CALLBACK_NOTIFY(message_begin); - } else { - parser->type = HTTP_REQUEST; - UPDATE_STATE(s_start_req); - REEXECUTE(); - } - - break; - } - - case s_res_or_resp_H: - if (ch == 'T') { - parser->type = HTTP_RESPONSE; - UPDATE_STATE(s_res_HT); - } else { - if (UNLIKELY(ch != 'E')) { - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - - parser->type = HTTP_REQUEST; - parser->method = HTTP_HEAD; - parser->index = 2; - UPDATE_STATE(s_req_method); - } - break; - - case s_start_res: - { - parser->flags = 0; - parser->content_length = ULLONG_MAX; - - switch (ch) { - case 'H': - UPDATE_STATE(s_res_H); - break; - - case CR: - case LF: - break; - - default: - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - - CALLBACK_NOTIFY(message_begin); - break; - } - - case s_res_H: - STRICT_CHECK(ch != 'T'); - UPDATE_STATE(s_res_HT); - break; - - case s_res_HT: - STRICT_CHECK(ch != 'T'); - UPDATE_STATE(s_res_HTT); - break; - - case s_res_HTT: - STRICT_CHECK(ch != 'P'); - UPDATE_STATE(s_res_HTTP); - break; - - case s_res_HTTP: - STRICT_CHECK(ch != '/'); - UPDATE_STATE(s_res_first_http_major); - break; - - case s_res_first_http_major: - if (UNLIKELY(ch < '0' || ch > '9')) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major = ch - '0'; - UPDATE_STATE(s_res_http_major); - break; - - /* major HTTP version or dot */ - case s_res_http_major: - { - if (ch == '.') { - UPDATE_STATE(s_res_first_http_minor); - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (UNLIKELY(parser->http_major > 999)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* first digit of minor HTTP version */ - case s_res_first_http_minor: - if (UNLIKELY(!IS_NUM(ch))) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor = ch - '0'; - UPDATE_STATE(s_res_http_minor); - break; - - /* minor HTTP version or end of request line */ - case s_res_http_minor: - { - if (ch == ' ') { - UPDATE_STATE(s_res_first_status_code); - break; - } - - if (UNLIKELY(!IS_NUM(ch))) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (UNLIKELY(parser->http_minor > 999)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - case s_res_first_status_code: - { - if (!IS_NUM(ch)) { - if (ch == ' ') { - break; - } - - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - parser->status_code = ch - '0'; - UPDATE_STATE(s_res_status_code); - break; - } - - case s_res_status_code: - { - if (!IS_NUM(ch)) { - switch (ch) { - case ' ': - UPDATE_STATE(s_res_status_start); - break; - case CR: - UPDATE_STATE(s_res_line_almost_done); - break; - case LF: - UPDATE_STATE(s_header_field_start); - break; - default: - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - break; - } - - parser->status_code *= 10; - parser->status_code += ch - '0'; - - if (UNLIKELY(parser->status_code > 999)) { - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - - break; - } - - case s_res_status_start: - { - if (ch == CR) { - UPDATE_STATE(s_res_line_almost_done); - break; - } - - if (ch == LF) { - UPDATE_STATE(s_header_field_start); - break; - } - - MARK(status); - UPDATE_STATE(s_res_status); - parser->index = 0; - break; - } - - case s_res_status: - if (ch == CR) { - UPDATE_STATE(s_res_line_almost_done); - CALLBACK_DATA(status); - break; - } - - if (ch == LF) { - UPDATE_STATE(s_header_field_start); - CALLBACK_DATA(status); - break; - } - - break; - - case s_res_line_almost_done: - STRICT_CHECK(ch != LF); - UPDATE_STATE(s_header_field_start); - break; - - case s_start_req: - { - if (ch == CR || ch == LF) - break; - parser->flags = 0; - parser->content_length = ULLONG_MAX; - - if (UNLIKELY(!IS_ALPHA(ch))) { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - parser->method = (enum http_method) 0; - parser->index = 1; - switch (ch) { - case 'A': parser->method = HTTP_ACL; break; - case 'B': parser->method = HTTP_BIND; break; - case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; - case 'D': parser->method = HTTP_DELETE; break; - case 'G': parser->method = HTTP_GET; break; - case 'H': parser->method = HTTP_HEAD; break; - case 'L': parser->method = HTTP_LOCK; /* or LINK */ break; - case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; - case 'N': parser->method = HTTP_NOTIFY; break; - case 'O': parser->method = HTTP_OPTIONS; break; - case 'P': parser->method = HTTP_POST; - /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ - break; - case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break; - case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; - case 'T': parser->method = HTTP_TRACE; break; - case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break; - default: - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - UPDATE_STATE(s_req_method); - - CALLBACK_NOTIFY(message_begin); - - break; - } - - case s_req_method: - { - const char *matcher; - if (UNLIKELY(ch == '\0')) { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - matcher = method_strings[parser->method]; - if (ch == ' ' && matcher[parser->index] == '\0') { - UPDATE_STATE(s_req_spaces_before_url); - } else if (ch == matcher[parser->index]) { - ; /* nada */ - } else if (IS_ALPHA(ch)) { - - switch (parser->method << 16 | parser->index << 8 | ch) { -#define XX(meth, pos, ch, new_meth) \ - case (HTTP_##meth << 16 | pos << 8 | ch): \ - parser->method = HTTP_##new_meth; break; - - XX(POST, 1, 'U', PUT) - XX(POST, 1, 'A', PATCH) - XX(CONNECT, 1, 'H', CHECKOUT) - XX(CONNECT, 2, 'P', COPY) - XX(MKCOL, 1, 'O', MOVE) - XX(MKCOL, 1, 'E', MERGE) - XX(MKCOL, 2, 'A', MKACTIVITY) - XX(MKCOL, 3, 'A', MKCALENDAR) - XX(SUBSCRIBE, 1, 'E', SEARCH) - XX(REPORT, 2, 'B', REBIND) - XX(POST, 1, 'R', PROPFIND) - XX(PROPFIND, 4, 'P', PROPPATCH) - XX(PUT, 2, 'R', PURGE) - XX(LOCK, 1, 'I', LINK) - XX(UNLOCK, 2, 'S', UNSUBSCRIBE) - XX(UNLOCK, 2, 'B', UNBIND) - XX(UNLOCK, 3, 'I', UNLINK) -#undef XX - - default: - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - } else if (ch == '-' && - parser->index == 1 && - parser->method == HTTP_MKCOL) { - parser->method = HTTP_MSEARCH; - } else { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - ++parser->index; - break; - } - - case s_req_spaces_before_url: - { - if (ch == ' ') break; - - MARK(url); - if (parser->method == HTTP_CONNECT) { - UPDATE_STATE(s_req_server_start); - } - - UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); - if (UNLIKELY(CURRENT_STATE() == s_dead)) { - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - - break; - } - - case s_req_schema: - case s_req_schema_slash: - case s_req_schema_slash_slash: - case s_req_server_start: - { - switch (ch) { - /* No whitespace allowed here */ - case ' ': - case CR: - case LF: - SET_ERRNO(HPE_INVALID_URL); - goto error; - default: - UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); - if (UNLIKELY(CURRENT_STATE() == s_dead)) { - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - } - - break; - } - - case s_req_server: - case s_req_server_with_at: - case s_req_path: - case s_req_query_string_start: - case s_req_query_string: - case s_req_fragment_start: - case s_req_fragment: - { - switch (ch) { - case ' ': - UPDATE_STATE(s_req_http_start); - CALLBACK_DATA(url); - break; - case CR: - case LF: - parser->http_major = 0; - parser->http_minor = 9; - UPDATE_STATE((ch == CR) ? - s_req_line_almost_done : - s_header_field_start); - CALLBACK_DATA(url); - break; - default: - UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); - if (UNLIKELY(CURRENT_STATE() == s_dead)) { - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - } - break; - } - - case s_req_http_start: - switch (ch) { - case 'H': - UPDATE_STATE(s_req_http_H); - break; - case ' ': - break; - default: - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - break; - - case s_req_http_H: - STRICT_CHECK(ch != 'T'); - UPDATE_STATE(s_req_http_HT); - break; - - case s_req_http_HT: - STRICT_CHECK(ch != 'T'); - UPDATE_STATE(s_req_http_HTT); - break; - - case s_req_http_HTT: - STRICT_CHECK(ch != 'P'); - UPDATE_STATE(s_req_http_HTTP); - break; - - case s_req_http_HTTP: - STRICT_CHECK(ch != '/'); - UPDATE_STATE(s_req_first_http_major); - break; - - /* first digit of major HTTP version */ - case s_req_first_http_major: - if (UNLIKELY(ch < '1' || ch > '9')) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major = ch - '0'; - UPDATE_STATE(s_req_http_major); - break; - - /* major HTTP version or dot */ - case s_req_http_major: - { - if (ch == '.') { - UPDATE_STATE(s_req_first_http_minor); - break; - } - - if (UNLIKELY(!IS_NUM(ch))) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (UNLIKELY(parser->http_major > 999)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* first digit of minor HTTP version */ - case s_req_first_http_minor: - if (UNLIKELY(!IS_NUM(ch))) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor = ch - '0'; - UPDATE_STATE(s_req_http_minor); - break; - - /* minor HTTP version or end of request line */ - case s_req_http_minor: - { - if (ch == CR) { - UPDATE_STATE(s_req_line_almost_done); - break; - } - - if (ch == LF) { - UPDATE_STATE(s_header_field_start); - break; - } - - /* XXX allow spaces after digit? */ - - if (UNLIKELY(!IS_NUM(ch))) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (UNLIKELY(parser->http_minor > 999)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* end of request line */ - case s_req_line_almost_done: - { - if (UNLIKELY(ch != LF)) { - SET_ERRNO(HPE_LF_EXPECTED); - goto error; - } - - UPDATE_STATE(s_header_field_start); - break; - } - - case s_header_field_start: - { - if (ch == CR) { - UPDATE_STATE(s_headers_almost_done); - break; - } - - if (ch == LF) { - /* they might be just sending \n instead of \r\n so this would be - * the second \n to denote the end of headers*/ - UPDATE_STATE(s_headers_almost_done); - REEXECUTE(); - } - - c = TOKEN(ch); - - if (UNLIKELY(!c)) { - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - - MARK(header_field); - - parser->index = 0; - UPDATE_STATE(s_header_field); - - switch (c) { - case 'c': - parser->header_state = h_C; - break; - - case 'p': - parser->header_state = h_matching_proxy_connection; - break; - - case 't': - parser->header_state = h_matching_transfer_encoding; - break; - - case 'u': - parser->header_state = h_matching_upgrade; - break; - - default: - parser->header_state = h_general; - break; - } - break; - } - - case s_header_field: - { - const char* start = p; - for (; p != data + len; p++) { - ch = *p; - c = TOKEN(ch); - - if (!c) - break; - - switch (parser->header_state) { - case h_general: - break; - - case h_C: - parser->index++; - parser->header_state = (c == 'o' ? h_CO : h_general); - break; - - case h_CO: - parser->index++; - parser->header_state = (c == 'n' ? h_CON : h_general); - break; - - case h_CON: - parser->index++; - switch (c) { - case 'n': - parser->header_state = h_matching_connection; - break; - case 't': - parser->header_state = h_matching_content_length; - break; - default: - parser->header_state = h_general; - break; - } - break; - - /* connection */ - - case h_matching_connection: - parser->index++; - if (parser->index > sizeof(CONNECTION)-1 - || c != CONNECTION[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CONNECTION)-2) { - parser->header_state = h_connection; - } - break; - - /* proxy-connection */ - - case h_matching_proxy_connection: - parser->index++; - if (parser->index > sizeof(PROXY_CONNECTION)-1 - || c != PROXY_CONNECTION[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { - parser->header_state = h_connection; - } - break; - - /* content-length */ - - case h_matching_content_length: - parser->index++; - if (parser->index > sizeof(CONTENT_LENGTH)-1 - || c != CONTENT_LENGTH[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { - parser->header_state = h_content_length; - } - break; - - /* transfer-encoding */ - - case h_matching_transfer_encoding: - parser->index++; - if (parser->index > sizeof(TRANSFER_ENCODING)-1 - || c != TRANSFER_ENCODING[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { - parser->header_state = h_transfer_encoding; - } - break; - - /* upgrade */ - - case h_matching_upgrade: - parser->index++; - if (parser->index > sizeof(UPGRADE)-1 - || c != UPGRADE[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(UPGRADE)-2) { - parser->header_state = h_upgrade; - } - break; - - case h_connection: - case h_content_length: - case h_transfer_encoding: - case h_upgrade: - if (ch != ' ') parser->header_state = h_general; - break; - - default: - assert(0 && "Unknown header_state"); - break; - } - } - - COUNT_HEADER_SIZE(p - start); - - if (p == data + len) { - --p; - break; - } - - if (ch == ':') { - UPDATE_STATE(s_header_value_discard_ws); - CALLBACK_DATA(header_field); - break; - } - - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - - case s_header_value_discard_ws: - if (ch == ' ' || ch == '\t') break; - - if (ch == CR) { - UPDATE_STATE(s_header_value_discard_ws_almost_done); - break; - } - - if (ch == LF) { - UPDATE_STATE(s_header_value_discard_lws); - break; - } - - /* FALLTHROUGH */ - - case s_header_value_start: - { - MARK(header_value); - - UPDATE_STATE(s_header_value); - parser->index = 0; - - c = LOWER(ch); - - switch (parser->header_state) { - case h_upgrade: - parser->flags |= F_UPGRADE; - parser->header_state = h_general; - break; - - case h_transfer_encoding: - /* looking for 'Transfer-Encoding: chunked' */ - if ('c' == c) { - parser->header_state = h_matching_transfer_encoding_chunked; - } else { - parser->header_state = h_general; - } - break; - - case h_content_length: - if (UNLIKELY(!IS_NUM(ch))) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - if (parser->flags & F_CONTENTLENGTH) { - SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); - goto error; - } - - parser->flags |= F_CONTENTLENGTH; - parser->content_length = ch - '0'; - break; - - case h_connection: - /* looking for 'Connection: keep-alive' */ - if (c == 'k') { - parser->header_state = h_matching_connection_keep_alive; - /* looking for 'Connection: close' */ - } else if (c == 'c') { - parser->header_state = h_matching_connection_close; - } else if (c == 'u') { - parser->header_state = h_matching_connection_upgrade; - } else { - parser->header_state = h_matching_connection_token; - } - break; - - /* Multi-value `Connection` header */ - case h_matching_connection_token_start: - break; - - default: - parser->header_state = h_general; - break; - } - break; - } - - case s_header_value: - { - const char* start = p; - enum header_states h_state = (enum header_states) parser->header_state; - for (; p != data + len; p++) { - ch = *p; - if (ch == CR) { - UPDATE_STATE(s_header_almost_done); - parser->header_state = h_state; - CALLBACK_DATA(header_value); - break; - } - - if (ch == LF) { - UPDATE_STATE(s_header_almost_done); - COUNT_HEADER_SIZE(p - start); - parser->header_state = h_state; - CALLBACK_DATA_NOADVANCE(header_value); - REEXECUTE(); - } - - if (!lenient && !IS_HEADER_CHAR(ch)) { - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - - c = LOWER(ch); - - switch (h_state) { - case h_general: - { - const char* p_cr; - const char* p_lf; - size_t limit = data + len - p; - - limit = MIN(limit, HTTP_MAX_HEADER_SIZE); - - p_cr = (const char*) memchr(p, CR, limit); - p_lf = (const char*) memchr(p, LF, limit); - if (p_cr != NULL) { - if (p_lf != NULL && p_cr >= p_lf) - p = p_lf; - else - p = p_cr; - } else if (UNLIKELY(p_lf != NULL)) { - p = p_lf; - } else { - p = data + len; - } - --p; - - break; - } - - case h_connection: - case h_transfer_encoding: - assert(0 && "Shouldn't get here."); - break; - - case h_content_length: - { - uint64_t t; - - if (ch == ' ') break; - - if (UNLIKELY(!IS_NUM(ch))) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - parser->header_state = h_state; - goto error; - } - - t = parser->content_length; - t *= 10; - t += ch - '0'; - - /* Overflow? Test against a conservative limit for simplicity. */ - if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - parser->header_state = h_state; - goto error; - } - - parser->content_length = t; - break; - } - - /* Transfer-Encoding: chunked */ - case h_matching_transfer_encoding_chunked: - parser->index++; - if (parser->index > sizeof(CHUNKED)-1 - || c != CHUNKED[parser->index]) { - h_state = h_general; - } else if (parser->index == sizeof(CHUNKED)-2) { - h_state = h_transfer_encoding_chunked; - } - break; - - case h_matching_connection_token_start: - /* looking for 'Connection: keep-alive' */ - if (c == 'k') { - h_state = h_matching_connection_keep_alive; - /* looking for 'Connection: close' */ - } else if (c == 'c') { - h_state = h_matching_connection_close; - } else if (c == 'u') { - h_state = h_matching_connection_upgrade; - } else if (STRICT_TOKEN(c)) { - h_state = h_matching_connection_token; - } else if (c == ' ' || c == '\t') { - /* Skip lws */ - } else { - h_state = h_general; - } - break; - - /* looking for 'Connection: keep-alive' */ - case h_matching_connection_keep_alive: - parser->index++; - if (parser->index > sizeof(KEEP_ALIVE)-1 - || c != KEEP_ALIVE[parser->index]) { - h_state = h_matching_connection_token; - } else if (parser->index == sizeof(KEEP_ALIVE)-2) { - h_state = h_connection_keep_alive; - } - break; - - /* looking for 'Connection: close' */ - case h_matching_connection_close: - parser->index++; - if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { - h_state = h_matching_connection_token; - } else if (parser->index == sizeof(CLOSE)-2) { - h_state = h_connection_close; - } - break; - - /* looking for 'Connection: upgrade' */ - case h_matching_connection_upgrade: - parser->index++; - if (parser->index > sizeof(UPGRADE) - 1 || - c != UPGRADE[parser->index]) { - h_state = h_matching_connection_token; - } else if (parser->index == sizeof(UPGRADE)-2) { - h_state = h_connection_upgrade; - } - break; - - case h_matching_connection_token: - if (ch == ',') { - h_state = h_matching_connection_token_start; - parser->index = 0; - } - break; - - case h_transfer_encoding_chunked: - if (ch != ' ') h_state = h_general; - break; - - case h_connection_keep_alive: - case h_connection_close: - case h_connection_upgrade: - if (ch == ',') { - if (h_state == h_connection_keep_alive) { - parser->flags |= F_CONNECTION_KEEP_ALIVE; - } else if (h_state == h_connection_close) { - parser->flags |= F_CONNECTION_CLOSE; - } else if (h_state == h_connection_upgrade) { - parser->flags |= F_CONNECTION_UPGRADE; - } - h_state = h_matching_connection_token_start; - parser->index = 0; - } else if (ch != ' ') { - h_state = h_matching_connection_token; - } - break; - - default: - UPDATE_STATE(s_header_value); - h_state = h_general; - break; - } - } - parser->header_state = h_state; - - COUNT_HEADER_SIZE(p - start); - - if (p == data + len) - --p; - break; - } - - case s_header_almost_done: - { - if (UNLIKELY(ch != LF)) { - SET_ERRNO(HPE_LF_EXPECTED); - goto error; - } - - UPDATE_STATE(s_header_value_lws); - break; - } - - case s_header_value_lws: - { - if (ch == ' ' || ch == '\t') { - UPDATE_STATE(s_header_value_start); - REEXECUTE(); - } - - /* finished the header */ - switch (parser->header_state) { - case h_connection_keep_alive: - parser->flags |= F_CONNECTION_KEEP_ALIVE; - break; - case h_connection_close: - parser->flags |= F_CONNECTION_CLOSE; - break; - case h_transfer_encoding_chunked: - parser->flags |= F_CHUNKED; - break; - case h_connection_upgrade: - parser->flags |= F_CONNECTION_UPGRADE; - break; - default: - break; - } - - UPDATE_STATE(s_header_field_start); - REEXECUTE(); - } - - case s_header_value_discard_ws_almost_done: - { - STRICT_CHECK(ch != LF); - UPDATE_STATE(s_header_value_discard_lws); - break; - } - - case s_header_value_discard_lws: - { - if (ch == ' ' || ch == '\t') { - UPDATE_STATE(s_header_value_discard_ws); - break; - } else { - switch (parser->header_state) { - case h_connection_keep_alive: - parser->flags |= F_CONNECTION_KEEP_ALIVE; - break; - case h_connection_close: - parser->flags |= F_CONNECTION_CLOSE; - break; - case h_connection_upgrade: - parser->flags |= F_CONNECTION_UPGRADE; - break; - case h_transfer_encoding_chunked: - parser->flags |= F_CHUNKED; - break; - default: - break; - } - - /* header value was empty */ - MARK(header_value); - UPDATE_STATE(s_header_field_start); - CALLBACK_DATA_NOADVANCE(header_value); - REEXECUTE(); - } - } - - case s_headers_almost_done: - { - STRICT_CHECK(ch != LF); - - if (parser->flags & F_TRAILING) { - /* End of a chunked request */ - UPDATE_STATE(s_message_done); - CALLBACK_NOTIFY_NOADVANCE(chunk_complete); - REEXECUTE(); - } - - /* Cannot use chunked encoding and a content-length header together - per the HTTP specification. */ - if ((parser->flags & F_CHUNKED) && - (parser->flags & F_CONTENTLENGTH)) { - SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); - goto error; - } - - UPDATE_STATE(s_headers_done); - - /* Set this here so that on_headers_complete() callbacks can see it */ - parser->upgrade = - ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) == - (F_UPGRADE | F_CONNECTION_UPGRADE) || - parser->method == HTTP_CONNECT); - - /* Here we call the headers_complete callback. This is somewhat - * different than other callbacks because if the user returns 1, we - * will interpret that as saying that this message has no body. This - * is needed for the annoying case of recieving a response to a HEAD - * request. - * - * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so - * we have to simulate it by handling a change in errno below. - */ - if (settings->on_headers_complete) { - switch (settings->on_headers_complete(parser)) { - case 0: - break; - - case 2: - parser->upgrade = 1; - - case 1: - parser->flags |= F_SKIPBODY; - break; - - default: - SET_ERRNO(HPE_CB_headers_complete); - RETURN(p - data); /* Error */ - } - } - - if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { - RETURN(p - data); - } - - REEXECUTE(); - } - - case s_headers_done: - { - int hasBody; - STRICT_CHECK(ch != LF); - - parser->nread = 0; - - hasBody = parser->flags & F_CHUNKED || - (parser->content_length > 0 && parser->content_length != ULLONG_MAX); - if (parser->upgrade && (parser->method == HTTP_CONNECT || - (parser->flags & F_SKIPBODY) || !hasBody)) { - /* Exit, the rest of the message is in a different protocol. */ - UPDATE_STATE(NEW_MESSAGE()); - CALLBACK_NOTIFY(message_complete); - RETURN((p - data) + 1); - } - - if (parser->flags & F_SKIPBODY) { - UPDATE_STATE(NEW_MESSAGE()); - CALLBACK_NOTIFY(message_complete); - } else if (parser->flags & F_CHUNKED) { - /* chunked encoding - ignore Content-Length header */ - UPDATE_STATE(s_chunk_size_start); - } else { - if (parser->content_length == 0) { - /* Content-Length header given but zero: Content-Length: 0\r\n */ - UPDATE_STATE(NEW_MESSAGE()); - CALLBACK_NOTIFY(message_complete); - } else if (parser->content_length != ULLONG_MAX) { - /* Content-Length header given and non-zero */ - UPDATE_STATE(s_body_identity); - } else { - if (!http_message_needs_eof(parser)) { - /* Assume content-length 0 - read the next */ - UPDATE_STATE(NEW_MESSAGE()); - CALLBACK_NOTIFY(message_complete); - } else { - /* Read body until EOF */ - UPDATE_STATE(s_body_identity_eof); - } - } - } - - break; - } - - case s_body_identity: - { - uint64_t to_read = MIN(parser->content_length, - (uint64_t) ((data + len) - p)); - - assert(parser->content_length != 0 - && parser->content_length != ULLONG_MAX); - - /* The difference between advancing content_length and p is because - * the latter will automaticaly advance on the next loop iteration. - * Further, if content_length ends up at 0, we want to see the last - * byte again for our message complete callback. - */ - MARK(body); - parser->content_length -= to_read; - p += to_read - 1; - - if (parser->content_length == 0) { - UPDATE_STATE(s_message_done); - - /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. - * - * The alternative to doing this is to wait for the next byte to - * trigger the data callback, just as in every other case. The - * problem with this is that this makes it difficult for the test - * harness to distinguish between complete-on-EOF and - * complete-on-length. It's not clear that this distinction is - * important for applications, but let's keep it for now. - */ - CALLBACK_DATA_(body, p - body_mark + 1, p - data); - REEXECUTE(); - } - - break; - } - - /* read until EOF */ - case s_body_identity_eof: - MARK(body); - p = data + len - 1; - - break; - - case s_message_done: - UPDATE_STATE(NEW_MESSAGE()); - CALLBACK_NOTIFY(message_complete); - if (parser->upgrade) { - /* Exit, the rest of the message is in a different protocol. */ - RETURN((p - data) + 1); - } - break; - - case s_chunk_size_start: - { - assert(parser->nread == 1); - assert(parser->flags & F_CHUNKED); - - unhex_val = unhex[(unsigned char)ch]; - if (UNLIKELY(unhex_val == -1)) { - SET_ERRNO(HPE_INVALID_CHUNK_SIZE); - goto error; - } - - parser->content_length = unhex_val; - UPDATE_STATE(s_chunk_size); - break; - } - - case s_chunk_size: - { - uint64_t t; - - assert(parser->flags & F_CHUNKED); - - if (ch == CR) { - UPDATE_STATE(s_chunk_size_almost_done); - break; - } - - unhex_val = unhex[(unsigned char)ch]; - - if (unhex_val == -1) { - if (ch == ';' || ch == ' ') { - UPDATE_STATE(s_chunk_parameters); - break; - } - - SET_ERRNO(HPE_INVALID_CHUNK_SIZE); - goto error; - } - - t = parser->content_length; - t *= 16; - t += unhex_val; - - /* Overflow? Test against a conservative limit for simplicity. */ - if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - parser->content_length = t; - break; - } - - case s_chunk_parameters: - { - assert(parser->flags & F_CHUNKED); - /* just ignore this shit. TODO check for overflow */ - if (ch == CR) { - UPDATE_STATE(s_chunk_size_almost_done); - break; - } - break; - } - - case s_chunk_size_almost_done: - { - assert(parser->flags & F_CHUNKED); - STRICT_CHECK(ch != LF); - - parser->nread = 0; - - if (parser->content_length == 0) { - parser->flags |= F_TRAILING; - UPDATE_STATE(s_header_field_start); - } else { - UPDATE_STATE(s_chunk_data); - } - CALLBACK_NOTIFY(chunk_header); - break; - } - - case s_chunk_data: - { - uint64_t to_read = MIN(parser->content_length, - (uint64_t) ((data + len) - p)); - - assert(parser->flags & F_CHUNKED); - assert(parser->content_length != 0 - && parser->content_length != ULLONG_MAX); - - /* See the explanation in s_body_identity for why the content - * length and data pointers are managed this way. - */ - MARK(body); - parser->content_length -= to_read; - p += to_read - 1; - - if (parser->content_length == 0) { - UPDATE_STATE(s_chunk_data_almost_done); - } - - break; - } - - case s_chunk_data_almost_done: - assert(parser->flags & F_CHUNKED); - assert(parser->content_length == 0); - STRICT_CHECK(ch != CR); - UPDATE_STATE(s_chunk_data_done); - CALLBACK_DATA(body); - break; - - case s_chunk_data_done: - assert(parser->flags & F_CHUNKED); - STRICT_CHECK(ch != LF); - parser->nread = 0; - UPDATE_STATE(s_chunk_size_start); - CALLBACK_NOTIFY(chunk_complete); - break; - - default: - assert(0 && "unhandled state"); - SET_ERRNO(HPE_INVALID_INTERNAL_STATE); - goto error; - } - } - - /* Run callbacks for any marks that we have leftover after we ran our of - * bytes. There should be at most one of these set, so it's OK to invoke - * them in series (unset marks will not result in callbacks). - * - * We use the NOADVANCE() variety of callbacks here because 'p' has already - * overflowed 'data' and this allows us to correct for the off-by-one that - * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' - * value that's in-bounds). - */ - - assert(((header_field_mark ? 1 : 0) + - (header_value_mark ? 1 : 0) + - (url_mark ? 1 : 0) + - (body_mark ? 1 : 0) + - (status_mark ? 1 : 0)) <= 1); - - CALLBACK_DATA_NOADVANCE(header_field); - CALLBACK_DATA_NOADVANCE(header_value); - CALLBACK_DATA_NOADVANCE(url); - CALLBACK_DATA_NOADVANCE(body); - CALLBACK_DATA_NOADVANCE(status); - - RETURN(len); - -error: - if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { - SET_ERRNO(HPE_UNKNOWN); - } - - RETURN(p - data); -} - - -/* Does the parser need to see an EOF to find the end of the message? */ -int -http_message_needs_eof (const http_parser *parser) -{ - if (parser->type == HTTP_REQUEST) { - return 0; - } - - /* See RFC 2616 section 4.4 */ - if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ - parser->status_code == 204 || /* No Content */ - parser->status_code == 304 || /* Not Modified */ - parser->flags & F_SKIPBODY) { /* response to a HEAD request */ - return 0; - } - - if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { - return 0; - } - - return 1; -} - - -int -http_should_keep_alive (const http_parser *parser) -{ - if (parser->http_major > 0 && parser->http_minor > 0) { - /* HTTP/1.1 */ - if (parser->flags & F_CONNECTION_CLOSE) { - return 0; - } - } else { - /* HTTP/1.0 or earlier */ - if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { - return 0; - } - } - - return !http_message_needs_eof(parser); -} - - -const char * -http_method_str (enum http_method m) -{ - return ELEM_AT(method_strings, m, ""); -} - - -void -http_parser_init (http_parser *parser, enum http_parser_type t) -{ - void *data = parser->data; /* preserve application data */ - memset(parser, 0, sizeof(*parser)); - parser->data = data; - parser->type = t; - parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); - parser->http_errno = HPE_OK; -} - -void -http_parser_settings_init(http_parser_settings *settings) -{ - memset(settings, 0, sizeof(*settings)); -} - -const char * -http_errno_name(enum http_errno err) { - assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); - return http_strerror_tab[err].name; -} - -const char * -http_errno_description(enum http_errno err) { - assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); - return http_strerror_tab[err].description; -} - -static enum http_host_state -http_parse_host_char(enum http_host_state s, const char ch) { - switch(s) { - case s_http_userinfo: - case s_http_userinfo_start: - if (ch == '@') { - return s_http_host_start; - } - - if (IS_USERINFO_CHAR(ch)) { - return s_http_userinfo; - } - break; - - case s_http_host_start: - if (ch == '[') { - return s_http_host_v6_start; - } - - if (IS_HOST_CHAR(ch)) { - return s_http_host; - } - - break; - - case s_http_host: - if (IS_HOST_CHAR(ch)) { - return s_http_host; - } - - /* FALLTHROUGH */ - case s_http_host_v6_end: - if (ch == ':') { - return s_http_host_port_start; - } - - break; - - case s_http_host_v6: - if (ch == ']') { - return s_http_host_v6_end; - } - - /* FALLTHROUGH */ - case s_http_host_v6_start: - if (IS_HEX(ch) || ch == ':' || ch == '.') { - return s_http_host_v6; - } - - if (s == s_http_host_v6 && ch == '%') { - return s_http_host_v6_zone_start; - } - break; - - case s_http_host_v6_zone: - if (ch == ']') { - return s_http_host_v6_end; - } - - /* FALLTHROUGH */ - case s_http_host_v6_zone_start: - /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */ - if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' || - ch == '~') { - return s_http_host_v6_zone; - } - break; - - case s_http_host_port: - case s_http_host_port_start: - if (IS_NUM(ch)) { - return s_http_host_port; - } - - break; - - default: - break; - } - return s_http_host_dead; -} - -static int -http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { - enum http_host_state s; - - const char *p; - size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; - - assert(u->field_set & (1 << UF_HOST)); - - u->field_data[UF_HOST].len = 0; - - s = found_at ? s_http_userinfo_start : s_http_host_start; - - for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { - enum http_host_state new_s = http_parse_host_char(s, *p); - - if (new_s == s_http_host_dead) { - return 1; - } - - switch(new_s) { - case s_http_host: - if (s != s_http_host) { - u->field_data[UF_HOST].off = p - buf; - } - u->field_data[UF_HOST].len++; - break; - - case s_http_host_v6: - if (s != s_http_host_v6) { - u->field_data[UF_HOST].off = p - buf; - } - u->field_data[UF_HOST].len++; - break; - - case s_http_host_v6_zone_start: - case s_http_host_v6_zone: - u->field_data[UF_HOST].len++; - break; - - case s_http_host_port: - if (s != s_http_host_port) { - u->field_data[UF_PORT].off = p - buf; - u->field_data[UF_PORT].len = 0; - u->field_set |= (1 << UF_PORT); - } - u->field_data[UF_PORT].len++; - break; - - case s_http_userinfo: - if (s != s_http_userinfo) { - u->field_data[UF_USERINFO].off = p - buf ; - u->field_data[UF_USERINFO].len = 0; - u->field_set |= (1 << UF_USERINFO); - } - u->field_data[UF_USERINFO].len++; - break; - - default: - break; - } - s = new_s; - } - - /* Make sure we don't end somewhere unexpected */ - switch (s) { - case s_http_host_start: - case s_http_host_v6_start: - case s_http_host_v6: - case s_http_host_v6_zone_start: - case s_http_host_v6_zone: - case s_http_host_port_start: - case s_http_userinfo: - case s_http_userinfo_start: - return 1; - default: - break; - } - - return 0; -} - -void -http_parser_url_init(struct http_parser_url *u) { - memset(u, 0, sizeof(*u)); -} - -int -http_parser_parse_url(const char *buf, size_t buflen, int is_connect, - struct http_parser_url *u) -{ - enum state s; - const char *p; - enum http_parser_url_fields uf, old_uf; - int found_at = 0; - - u->port = u->field_set = 0; - s = is_connect ? s_req_server_start : s_req_spaces_before_url; - old_uf = UF_MAX; - - for (p = buf; p < buf + buflen; p++) { - s = parse_url_char(s, *p); - - /* Figure out the next field that we're operating on */ - switch (s) { - case s_dead: - return 1; - - /* Skip delimeters */ - case s_req_schema_slash: - case s_req_schema_slash_slash: - case s_req_server_start: - case s_req_query_string_start: - case s_req_fragment_start: - continue; - - case s_req_schema: - uf = UF_SCHEMA; - break; - - case s_req_server_with_at: - found_at = 1; - - /* FALLTROUGH */ - case s_req_server: - uf = UF_HOST; - break; - - case s_req_path: - uf = UF_PATH; - break; - - case s_req_query_string: - uf = UF_QUERY; - break; - - case s_req_fragment: - uf = UF_FRAGMENT; - break; - - default: - assert(!"Unexpected state"); - return 1; - } - - /* Nothing's changed; soldier on */ - if (uf == old_uf) { - u->field_data[uf].len++; - continue; - } - - u->field_data[uf].off = p - buf; - u->field_data[uf].len = 1; - - u->field_set |= (1 << uf); - old_uf = uf; - } - - /* host must be present if there is a schema */ - /* parsing http:///toto will fail */ - if ((u->field_set & (1 << UF_SCHEMA)) && - (u->field_set & (1 << UF_HOST)) == 0) { - return 1; - } - - if (u->field_set & (1 << UF_HOST)) { - if (http_parse_host(buf, u, found_at) != 0) { - return 1; - } - } - - /* CONNECT requests can only contain "hostname:port" */ - if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { - return 1; - } - - if (u->field_set & (1 << UF_PORT)) { - /* Don't bother with endp; we've already validated the string */ - unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); - - /* Ports have a max value of 2^16 */ - if (v > 0xffff) { - return 1; - } - - u->port = (uint16_t) v; - } - - return 0; -} - -void -http_parser_pause(http_parser *parser, int paused) { - /* Users should only be pausing/unpausing a parser that is not in an error - * state. In non-debug builds, there's not much that we can do about this - * other than ignore it. - */ - if (HTTP_PARSER_ERRNO(parser) == HPE_OK || - HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { - SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); - } else { - assert(0 && "Attempting to pause parser in error state"); - } -} - -int -http_body_is_final(const struct http_parser *parser) { - return parser->state == s_message_done; -} - -unsigned long -http_parser_version(void) { - return HTTP_PARSER_VERSION_MAJOR * 0x10000 | - HTTP_PARSER_VERSION_MINOR * 0x00100 | - HTTP_PARSER_VERSION_PATCH * 0x00001; -} diff --git a/ext/http-parser/http_parser.h b/ext/http-parser/http_parser.h deleted file mode 100644 index 45c72a07..00000000 --- a/ext/http-parser/http_parser.h +++ /dev/null @@ -1,432 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#ifndef http_parser_h -#define http_parser_h -#ifdef __cplusplus -extern "C" { -#endif - -/* Also update SONAME in the Makefile whenever you change these. */ -#define HTTP_PARSER_VERSION_MAJOR 2 -#define HTTP_PARSER_VERSION_MINOR 7 -#define HTTP_PARSER_VERSION_PATCH 1 - -#include -#if defined(_WIN32) && !defined(__MINGW32__) && \ - (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) -#include -#include -typedef __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -#include -#endif - -/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run - * faster - */ -#ifndef HTTP_PARSER_STRICT -# define HTTP_PARSER_STRICT 1 -#endif - -/* Maximium header size allowed. If the macro is not defined - * before including this header then the default is used. To - * change the maximum header size, define the macro in the build - * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove - * the effective limit on the size of the header, define the macro - * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) - */ -#ifndef HTTP_MAX_HEADER_SIZE -# define HTTP_MAX_HEADER_SIZE (80*1024) -#endif - -typedef struct http_parser http_parser; -typedef struct http_parser_settings http_parser_settings; - - -/* Callbacks should return non-zero to indicate an error. The parser will - * then halt execution. - * - * The one exception is on_headers_complete. In a HTTP_RESPONSE parser - * returning '1' from on_headers_complete will tell the parser that it - * should not expect a body. This is used when receiving a response to a - * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: - * chunked' headers that indicate the presence of a body. - * - * Returning `2` from on_headers_complete will tell parser that it should not - * expect neither a body nor any futher responses on this connection. This is - * useful for handling responses to a CONNECT request which may not contain - * `Upgrade` or `Connection: upgrade` headers. - * - * http_data_cb does not return data chunks. It will be called arbitrarily - * many times for each string. E.G. you might get 10 callbacks for "on_url" - * each providing just a few characters more data. - */ -typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); -typedef int (*http_cb) (http_parser*); - - -/* Status Codes */ -#define HTTP_STATUS_MAP(XX) \ - XX(100, CONTINUE, Continue) \ - XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \ - XX(102, PROCESSING, Processing) \ - XX(200, OK, OK) \ - XX(201, CREATED, Created) \ - XX(202, ACCEPTED, Accepted) \ - XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \ - XX(204, NO_CONTENT, No Content) \ - XX(205, RESET_CONTENT, Reset Content) \ - XX(206, PARTIAL_CONTENT, Partial Content) \ - XX(207, MULTI_STATUS, Multi-Status) \ - XX(208, ALREADY_REPORTED, Already Reported) \ - XX(226, IM_USED, IM Used) \ - XX(300, MULTIPLE_CHOICES, Multiple Choices) \ - XX(301, MOVED_PERMANENTLY, Moved Permanently) \ - XX(302, FOUND, Found) \ - XX(303, SEE_OTHER, See Other) \ - XX(304, NOT_MODIFIED, Not Modified) \ - XX(305, USE_PROXY, Use Proxy) \ - XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \ - XX(308, PERMANENT_REDIRECT, Permanent Redirect) \ - XX(400, BAD_REQUEST, Bad Request) \ - XX(401, UNAUTHORIZED, Unauthorized) \ - XX(402, PAYMENT_REQUIRED, Payment Required) \ - XX(403, FORBIDDEN, Forbidden) \ - XX(404, NOT_FOUND, Not Found) \ - XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \ - XX(406, NOT_ACCEPTABLE, Not Acceptable) \ - XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \ - XX(408, REQUEST_TIMEOUT, Request Timeout) \ - XX(409, CONFLICT, Conflict) \ - XX(410, GONE, Gone) \ - XX(411, LENGTH_REQUIRED, Length Required) \ - XX(412, PRECONDITION_FAILED, Precondition Failed) \ - XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \ - XX(414, URI_TOO_LONG, URI Too Long) \ - XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \ - XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \ - XX(417, EXPECTATION_FAILED, Expectation Failed) \ - XX(421, MISDIRECTED_REQUEST, Misdirected Request) \ - XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \ - XX(423, LOCKED, Locked) \ - XX(424, FAILED_DEPENDENCY, Failed Dependency) \ - XX(426, UPGRADE_REQUIRED, Upgrade Required) \ - XX(428, PRECONDITION_REQUIRED, Precondition Required) \ - XX(429, TOO_MANY_REQUESTS, Too Many Requests) \ - XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \ - XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \ - XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \ - XX(501, NOT_IMPLEMENTED, Not Implemented) \ - XX(502, BAD_GATEWAY, Bad Gateway) \ - XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \ - XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \ - XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \ - XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \ - XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ - XX(508, LOOP_DETECTED, Loop Detected) \ - XX(510, NOT_EXTENDED, Not Extended) \ - XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \ - -enum http_status - { -#define XX(num, name, string) HTTP_STATUS_##name = num, - HTTP_STATUS_MAP(XX) -#undef XX - }; - - -/* Request Methods */ -#define HTTP_METHOD_MAP(XX) \ - XX(0, DELETE, DELETE) \ - XX(1, GET, GET) \ - XX(2, HEAD, HEAD) \ - XX(3, POST, POST) \ - XX(4, PUT, PUT) \ - /* pathological */ \ - XX(5, CONNECT, CONNECT) \ - XX(6, OPTIONS, OPTIONS) \ - XX(7, TRACE, TRACE) \ - /* WebDAV */ \ - XX(8, COPY, COPY) \ - XX(9, LOCK, LOCK) \ - XX(10, MKCOL, MKCOL) \ - XX(11, MOVE, MOVE) \ - XX(12, PROPFIND, PROPFIND) \ - XX(13, PROPPATCH, PROPPATCH) \ - XX(14, SEARCH, SEARCH) \ - XX(15, UNLOCK, UNLOCK) \ - XX(16, BIND, BIND) \ - XX(17, REBIND, REBIND) \ - XX(18, UNBIND, UNBIND) \ - XX(19, ACL, ACL) \ - /* subversion */ \ - XX(20, REPORT, REPORT) \ - XX(21, MKACTIVITY, MKACTIVITY) \ - XX(22, CHECKOUT, CHECKOUT) \ - XX(23, MERGE, MERGE) \ - /* upnp */ \ - XX(24, MSEARCH, M-SEARCH) \ - XX(25, NOTIFY, NOTIFY) \ - XX(26, SUBSCRIBE, SUBSCRIBE) \ - XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ - /* RFC-5789 */ \ - XX(28, PATCH, PATCH) \ - XX(29, PURGE, PURGE) \ - /* CalDAV */ \ - XX(30, MKCALENDAR, MKCALENDAR) \ - /* RFC-2068, section 19.6.1.2 */ \ - XX(31, LINK, LINK) \ - XX(32, UNLINK, UNLINK) \ - -enum http_method - { -#define XX(num, name, string) HTTP_##name = num, - HTTP_METHOD_MAP(XX) -#undef XX - }; - - -enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; - - -/* Flag values for http_parser.flags field */ -enum flags - { F_CHUNKED = 1 << 0 - , F_CONNECTION_KEEP_ALIVE = 1 << 1 - , F_CONNECTION_CLOSE = 1 << 2 - , F_CONNECTION_UPGRADE = 1 << 3 - , F_TRAILING = 1 << 4 - , F_UPGRADE = 1 << 5 - , F_SKIPBODY = 1 << 6 - , F_CONTENTLENGTH = 1 << 7 - }; - - -/* Map for errno-related constants - * - * The provided argument should be a macro that takes 2 arguments. - */ -#define HTTP_ERRNO_MAP(XX) \ - /* No error */ \ - XX(OK, "success") \ - \ - /* Callback-related errors */ \ - XX(CB_message_begin, "the on_message_begin callback failed") \ - XX(CB_url, "the on_url callback failed") \ - XX(CB_header_field, "the on_header_field callback failed") \ - XX(CB_header_value, "the on_header_value callback failed") \ - XX(CB_headers_complete, "the on_headers_complete callback failed") \ - XX(CB_body, "the on_body callback failed") \ - XX(CB_message_complete, "the on_message_complete callback failed") \ - XX(CB_status, "the on_status callback failed") \ - XX(CB_chunk_header, "the on_chunk_header callback failed") \ - XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ - \ - /* Parsing-related errors */ \ - XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ - XX(HEADER_OVERFLOW, \ - "too many header bytes seen; overflow detected") \ - XX(CLOSED_CONNECTION, \ - "data received after completed connection: close message") \ - XX(INVALID_VERSION, "invalid HTTP version") \ - XX(INVALID_STATUS, "invalid HTTP status code") \ - XX(INVALID_METHOD, "invalid HTTP method") \ - XX(INVALID_URL, "invalid URL") \ - XX(INVALID_HOST, "invalid host") \ - XX(INVALID_PORT, "invalid port") \ - XX(INVALID_PATH, "invalid path") \ - XX(INVALID_QUERY_STRING, "invalid query string") \ - XX(INVALID_FRAGMENT, "invalid fragment") \ - XX(LF_EXPECTED, "LF character expected") \ - XX(INVALID_HEADER_TOKEN, "invalid character in header") \ - XX(INVALID_CONTENT_LENGTH, \ - "invalid character in content-length header") \ - XX(UNEXPECTED_CONTENT_LENGTH, \ - "unexpected content-length header") \ - XX(INVALID_CHUNK_SIZE, \ - "invalid character in chunk size header") \ - XX(INVALID_CONSTANT, "invalid constant string") \ - XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ - XX(STRICT, "strict mode assertion failed") \ - XX(PAUSED, "parser is paused") \ - XX(UNKNOWN, "an unknown error occurred") - - -/* Define HPE_* values for each errno value above */ -#define HTTP_ERRNO_GEN(n, s) HPE_##n, -enum http_errno { - HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) -}; -#undef HTTP_ERRNO_GEN - - -/* Get an http_errno value from an http_parser */ -#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) - - -struct http_parser { - /** PRIVATE **/ - unsigned int type : 2; /* enum http_parser_type */ - unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */ - unsigned int state : 7; /* enum state from http_parser.c */ - unsigned int header_state : 7; /* enum header_state from http_parser.c */ - unsigned int index : 7; /* index into current matcher */ - unsigned int lenient_http_headers : 1; - - uint32_t nread; /* # bytes read in various scenarios */ - uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ - - /** READ-ONLY **/ - unsigned short http_major; - unsigned short http_minor; - unsigned int status_code : 16; /* responses only */ - unsigned int method : 8; /* requests only */ - unsigned int http_errno : 7; - - /* 1 = Upgrade header was present and the parser has exited because of that. - * 0 = No upgrade header present. - * Should be checked when http_parser_execute() returns in addition to - * error checking. - */ - unsigned int upgrade : 1; - - /** PUBLIC **/ - void *data; /* A pointer to get hook to the "connection" or "socket" object */ -}; - - -struct http_parser_settings { - http_cb on_message_begin; - http_data_cb on_url; - http_data_cb on_status; - http_data_cb on_header_field; - http_data_cb on_header_value; - http_cb on_headers_complete; - http_data_cb on_body; - http_cb on_message_complete; - /* When on_chunk_header is called, the current chunk length is stored - * in parser->content_length. - */ - http_cb on_chunk_header; - http_cb on_chunk_complete; -}; - - -enum http_parser_url_fields - { UF_SCHEMA = 0 - , UF_HOST = 1 - , UF_PORT = 2 - , UF_PATH = 3 - , UF_QUERY = 4 - , UF_FRAGMENT = 5 - , UF_USERINFO = 6 - , UF_MAX = 7 - }; - - -/* Result structure for http_parser_parse_url(). - * - * Callers should index into field_data[] with UF_* values iff field_set - * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and - * because we probably have padding left over), we convert any port to - * a uint16_t. - */ -struct http_parser_url { - uint16_t field_set; /* Bitmask of (1 << UF_*) values */ - uint16_t port; /* Converted UF_PORT string */ - - struct { - uint16_t off; /* Offset into buffer in which field starts */ - uint16_t len; /* Length of run in buffer */ - } field_data[UF_MAX]; -}; - - -/* Returns the library version. Bits 16-23 contain the major version number, - * bits 8-15 the minor version number and bits 0-7 the patch level. - * Usage example: - * - * unsigned long version = http_parser_version(); - * unsigned major = (version >> 16) & 255; - * unsigned minor = (version >> 8) & 255; - * unsigned patch = version & 255; - * printf("http_parser v%u.%u.%u\n", major, minor, patch); - */ -unsigned long http_parser_version(void); - -void http_parser_init(http_parser *parser, enum http_parser_type type); - - -/* Initialize http_parser_settings members to 0 - */ -void http_parser_settings_init(http_parser_settings *settings); - - -/* Executes the parser. Returns number of parsed bytes. Sets - * `parser->http_errno` on error. */ -size_t http_parser_execute(http_parser *parser, - const http_parser_settings *settings, - const char *data, - size_t len); - - -/* If http_should_keep_alive() in the on_headers_complete or - * on_message_complete callback returns 0, then this should be - * the last message on the connection. - * If you are the server, respond with the "Connection: close" header. - * If you are the client, close the connection. - */ -int http_should_keep_alive(const http_parser *parser); - -/* Returns a string version of the HTTP method. */ -const char *http_method_str(enum http_method m); - -/* Return a string name of the given error */ -const char *http_errno_name(enum http_errno err); - -/* Return a string description of the given error */ -const char *http_errno_description(enum http_errno err); - -/* Initialize all http_parser_url members to 0 */ -void http_parser_url_init(struct http_parser_url *u); - -/* Parse a URL; return nonzero on failure */ -int http_parser_parse_url(const char *buf, size_t buflen, - int is_connect, - struct http_parser_url *u); - -/* Pause or un-pause the parser; a nonzero value pauses */ -void http_parser_pause(http_parser *parser, int paused); - -/* Checks if this is the final chunk of the body. */ -int http_body_is_final(const http_parser *parser); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ext/libnatpmp/Changelog.txt b/ext/libnatpmp/Changelog.txt deleted file mode 100644 index be75a0b6..00000000 --- a/ext/libnatpmp/Changelog.txt +++ /dev/null @@ -1,98 +0,0 @@ -$Id: Changelog.txt,v 1.33 2013/11/26 08:47:36 nanard Exp $ - -2013/11/26: - enforce strict aliasing rules. - -2013/09/10: - small patch for MSVC >= 16 - rename win32 implementation of gettimeofday() to natpmp_gettimeofday() - -2012/08/21: - Little change in Makefile - removed warnings in testgetgateway.c - Fixed bugs in command line argumentparsing in natpmpc.c - -2011/08/07: - Patch to build on debian/kFreeBSD. - -2011/07/15: - Put 3 clauses BSD licence at the top of source files. - -2011/06/18: - --no-undefined => -Wl,--no-undefined - adding a natpmpc.1 man page - -2011/05/19: - Small fix in libnatpmpmodule.c thanks to Manuel Mausz - -2011/01/03: - Added an argument to initnatpmp() in order to force the gateway to be used - -2011/01/01: - fix in make install - -2010/05/21: - make install now working under MacOSX (and BSD) - -2010/04/12: - cplusplus stuff in natpmp.h - -2010/02/02: - Fixed compilation under Mac OS X - -2009/12/19: - improve and fix building under Windows. - Project files for MS Visual Studio 2008 - More simple (and working) code for Win32. - More checks in the /proc/net/route parsing. Add some comments. - -2009/08/04: - improving getgateway.c for windows - -2009/07/13: - Adding Haiku code in getgateway.c - -2009/06/04: - Adding Python module thanks to David Wu - -2009/03/10: - Trying to have windows get gateway working if not using DHCP - -2009/02/27: - dont include declspec.h if not under WIN32. - -2009/01/23: - Prefixed the libraries name with lib - -2008/10/06: - Fixed a memory leak in getdefaultgateway() (USE_SYSCTL_NET_ROUTE) - -2008/07/03: - Adding WIN32 code from Robbie Hanson - -2008/06/30: - added a Solaris implementation for getgateway(). - added a LICENCE file to the distribution - -2008/05/29: - Anonymous unions are forbidden in ANSI C. That was causing problems with - non-GCC compilers. - -2008/04/28: - introduced strnatpmperr() - improved natpmpc.c sample - make install now install the binary - -2007/12/13: - Fixed getgateway.c for working under OS X ;) - Fixed values for NATPMP_PROTOCOL_TCP and NATPMP_PROTOCOL_UDP - -2007/12/11: - Fixed getgateway.c for compilation under Mac OS X - -2007/12/01: - added some comments in .h - -2007/11/30: - implemented almost everything - diff --git a/ext/libnatpmp/JavaTest.java b/ext/libnatpmp/JavaTest.java deleted file mode 100644 index 0379c182..00000000 --- a/ext/libnatpmp/JavaTest.java +++ /dev/null @@ -1,42 +0,0 @@ -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; - -import fr.free.miniupnp.libnatpmp.NatPmp; -import fr.free.miniupnp.libnatpmp.NatPmpResponse; - -class JavaTest { - public static void main(String[] args) { - NatPmp natpmp = new NatPmp(); - - natpmp.sendPublicAddressRequest(); - NatPmpResponse response = new NatPmpResponse(); - - int result = -1; - do{ - result = natpmp.readNatPmpResponseOrRetry(response); - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - //fallthrough - } - } while (result != 0); - - byte[] bytes = intToByteArray(response.addr); - - try { - InetAddress inetAddress = InetAddress.getByAddress(bytes); - System.out.println("Public address is " + inetAddress); - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } - } - - public static final byte[] intToByteArray(int value) { - return new byte[] { - (byte)value, - (byte)(value >>> 8), - (byte)(value >>> 16), - (byte)(value >>> 24)}; - } -} diff --git a/ext/libnatpmp/LICENSE b/ext/libnatpmp/LICENSE deleted file mode 100644 index 7fff2c26..00000000 --- a/ext/libnatpmp/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2007-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/ext/libnatpmp/Makefile b/ext/libnatpmp/Makefile deleted file mode 100644 index b67b3e85..00000000 --- a/ext/libnatpmp/Makefile +++ /dev/null @@ -1,177 +0,0 @@ -# $Id: Makefile,v 1.23 2013/11/26 16:38:15 nanard Exp $ -# This Makefile is designed for use with GNU make -# libnatpmp -# (c) 2007-2013 Thomas Bernard -# http://miniupnp.free.fr/libnatpmp.html - -OS = $(shell uname -s) -CC = gcc -INSTALL = install -p -ARCH = $(shell uname -m | sed -e s/i.86/i686/) -VERSION = $(shell cat VERSION) - -ifeq ($(OS), Darwin) -JARSUFFIX=mac -endif -ifeq ($(OS), Linux) -JARSUFFIX=linux -endif -ifneq (,$(findstring WIN,$(OS))) -JARSUFFIX=win32 -endif - -# APIVERSION is used in soname -APIVERSION = 1 -#LDFLAGS = -Wl,--no-undefined -CFLAGS ?= -Os -#CFLAGS = -g -O0 -CFLAGS += -fPIC -CFLAGS += -Wall -#CFLAGS += -Wextra -CFLAGS += -DENABLE_STRNATPMPERR -#CFLAGS += -Wstrict-aliasing - -LIBOBJS = natpmp.o getgateway.o - -OBJS = $(LIBOBJS) testgetgateway.o natpmpc.o natpmp-jni.o - -STATICLIB = libnatpmp.a -ifeq ($(OS), Darwin) - SHAREDLIB = libnatpmp.dylib - JNISHAREDLIB = libjninatpmp.dylib - SONAME = $(basename $(SHAREDLIB)).$(APIVERSION).dylib - CFLAGS := -DMACOSX -D_DARWIN_C_SOURCE $(CFLAGS) - SONAMEFLAGS=-Wl,-install_name,$(JNISHAREDLIB) -dynamiclib -framework JavaVM -else -ifneq (,$(findstring WIN,$(OS))) - SHAREDLIB = natpmp.dll - JNISHAREDLIB = jninatpmp.dll - CC = i686-w64-mingw32-gcc - EXTRA_LD = -lws2_32 -lIphlpapi -Wl,--no-undefined -Wl,--enable-runtime-pseudo-reloc --Wl,kill-at -else - SHAREDLIB = libnatpmp.so - JNISHAREDLIB = libjninatpmp.so - SONAME = $(SHAREDLIB).$(APIVERSION) - SONAMEFLAGS=-Wl,-soname,$(JNISHAREDLIB) -endif -endif - -HEADERS = natpmp.h - -EXECUTABLES = testgetgateway natpmpc-shared natpmpc-static - -INSTALLPREFIX ?= $(PREFIX)/usr -INSTALLDIRINC = $(INSTALLPREFIX)/include -INSTALLDIRLIB = $(INSTALLPREFIX)/lib -INSTALLDIRBIN = $(INSTALLPREFIX)/bin - -JAVA ?= java -JAVAC ?= javac -JAVAH ?= javah -JAVAPACKAGE = fr/free/miniupnp/libnatpmp -JAVACLASSES = $(JAVAPACKAGE)/NatPmp.class $(JAVAPACKAGE)/NatPmpResponse.class $(JAVAPACKAGE)/LibraryExtractor.class $(JAVAPACKAGE)/URLUtils.class -JNIHEADERS = fr_free_miniupnp_libnatpmp_NatPmp.h - -.PHONY: all clean depend install cleaninstall installpythonmodule - -all: $(STATICLIB) $(SHAREDLIB) $(EXECUTABLES) - -pythonmodule: $(STATICLIB) libnatpmpmodule.c setup.py - python setup.py build - touch $@ - -installpythonmodule: pythonmodule - python setup.py install - -clean: - $(RM) $(OBJS) $(EXECUTABLES) $(STATICLIB) $(SHAREDLIB) $(JAVACLASSES) $(JNISHAREDLIB) - $(RM) pythonmodule - $(RM) -r build/ dist/ libraries/ - -depend: - makedepend -f$(MAKEFILE_LIST) -Y $(OBJS:.o=.c) 2>/dev/null - -install: $(HEADERS) $(STATICLIB) $(SHAREDLIB) natpmpc-shared - $(INSTALL) -d $(INSTALLDIRINC) - $(INSTALL) -m 644 $(HEADERS) $(INSTALLDIRINC) - $(INSTALL) -d $(INSTALLDIRLIB) - $(INSTALL) -m 644 $(STATICLIB) $(INSTALLDIRLIB) - $(INSTALL) -m 644 $(SHAREDLIB) $(INSTALLDIRLIB)/$(SONAME) - $(INSTALL) -d $(INSTALLDIRBIN) - $(INSTALL) -m 755 natpmpc-shared $(INSTALLDIRBIN)/natpmpc - ln -s -f $(SONAME) $(INSTALLDIRLIB)/$(SHAREDLIB) - -$(JNIHEADERS): fr/free/miniupnp/libnatpmp/NatPmp.class - $(JAVAH) -jni fr.free.miniupnp.libnatpmp.NatPmp - -%.class: %.java - $(JAVAC) -cp . $< - -$(JNISHAREDLIB): $(SHAREDLIB) $(JNIHEADERS) $(JAVACLASSES) -ifeq (,$(JAVA_HOME)) - @echo "Check your JAVA_HOME environement variable" && false -endif -ifneq (,$(findstring WIN,$(OS))) - $(CC) -m32 -D_JNI_Implementation_ -Wl,--kill-at \ - -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" \ - natpmp-jni.c -shared \ - -o $(JNISHAREDLIB) -L. -lnatpmp -lws2_32 -lIphlpapi -else - $(CC) $(CFLAGS) -c -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/win32" natpmp-jni.c - $(CC) $(CFLAGS) -o $(JNISHAREDLIB) -shared $(SONAMEFLAGS) natpmp-jni.o -lc -L. -lnatpmp -endif - -jar: $(JNISHAREDLIB) - find fr -name '*.class' -print > classes.list - $(eval JNISHAREDLIBPATH := $(shell java fr.free.miniupnp.libnatpmp.LibraryExtractor)) - mkdir -p libraries/$(JNISHAREDLIBPATH) - mv $(JNISHAREDLIB) libraries/$(JNISHAREDLIBPATH)/$(JNISHAREDLIB) - jar cf natpmp_$(JARSUFFIX).jar @classes.list libraries/$(JNISHAREDLIBPATH)/$(JNISHAREDLIB) - $(RM) classes.list - -jnitest: $(JNISHAREDLIB) JavaTest.class - $(RM) libjninatpmp.so - $(JAVA) -Djna.nosys=true -cp . JavaTest - -mvn_install: - mvn install:install-file -Dfile=java/natpmp_$(JARSUFFIX).jar \ - -DgroupId=com.github \ - -DartifactId=natpmp \ - -Dversion=$(VERSION) \ - -Dpackaging=jar \ - -Dclassifier=$(JARSUFFIX) \ - -DgeneratePom=true \ - -DcreateChecksum=true - -cleaninstall: - $(RM) $(addprefix $(INSTALLDIRINC), $(HEADERS)) - $(RM) $(INSTALLDIRLIB)/$(SONAME) - $(RM) $(INSTALLDIRLIB)/$(SHAREDLIB) - $(RM) $(INSTALLDIRLIB)/$(STATICLIB) - -testgetgateway: testgetgateway.o getgateway.o - $(CC) $(LDFLAGS) -o $@ $^ $(EXTRA_LD) - -natpmpc-static: natpmpc.o $(STATICLIB) - $(CC) $(LDFLAGS) -o $@ $^ $(EXTRA_LD) - -natpmpc-shared: natpmpc.o $(SHAREDLIB) - $(CC) $(LDFLAGS) -o $@ $^ $(EXTRA_LD) - -$(STATICLIB): $(LIBOBJS) - $(AR) crs $@ $? - -$(SHAREDLIB): $(LIBOBJS) -ifeq ($(OS), Darwin) - $(CC) -dynamiclib -Wl,-install_name,$(SONAME) -o $@ $^ -else - $(CC) -shared -Wl,-soname,$(SONAME) -o $@ $^ $(EXTRA_LD) -endif - - -# DO NOT DELETE - -natpmp.o: natpmp.h getgateway.h declspec.h -getgateway.o: getgateway.h declspec.h -testgetgateway.o: getgateway.h declspec.h -natpmpc.o: natpmp.h diff --git a/ext/libnatpmp/README b/ext/libnatpmp/README deleted file mode 100644 index 269392d2..00000000 --- a/ext/libnatpmp/README +++ /dev/null @@ -1,7 +0,0 @@ -libnatpmp (c) 2007-2009 Thomas Bernard -contact : miniupnp@free.fr - -see http://miniupnp.free.fr/libnatpmp.html -or http://miniupnp.tuxfamily.org/libnatpmp.html -for some documentation and code samples. - diff --git a/ext/libnatpmp/build.bat b/ext/libnatpmp/build.bat deleted file mode 100644 index 2d2f27cd..00000000 --- a/ext/libnatpmp/build.bat +++ /dev/null @@ -1,30 +0,0 @@ -@echo Compiling with MinGW -@SET LIBS=-lws2_32 -liphlpapi - -@echo Compile getgateway -gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c -gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR testgetgateway.c -gcc -o testgetgateway getgateway.o testgetgateway.o %LIBS% -del testgetgateway.o - -@echo Compile natpmp-static: -gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR getgateway.c -gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmp.c -gcc -c -Wall -Os -DWIN32 wingettimeofday.c -ar cr natpmp.a getgateway.o natpmp.o wingettimeofday.o -del getgateway.o natpmp.o -gcc -c -Wall -Os -DWIN32 -DSTATICLIB -DENABLE_STRNATPMPERR natpmpc.c -gcc -o natpmpc-static natpmpc.o natpmp.a %LIBS% -upx --best natpmpc-static.exe -del natpmpc.o - -@echo Create natpmp.dll: -gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS getgateway.c -gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmp.c -dllwrap -k --driver-name gcc --def natpmp.def --output-def natpmp.dll.def --implib natpmp.lib -o natpmp.dll getgateway.o natpmp.o wingettimeofday.o %LIBS% - -@echo Compile natpmp-shared: -gcc -c -Wall -Os -DWIN32 -DENABLE_STRNATPMPERR -DNATPMP_EXPORTS natpmpc.c -gcc -o natpmpc-shared natpmpc.o natpmp.lib -lws2_32 -upx --best natpmpc-shared.exe -del *.o diff --git a/ext/libnatpmp/declspec.h b/ext/libnatpmp/declspec.h deleted file mode 100644 index a76be021..00000000 --- a/ext/libnatpmp/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 NATPMP_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/ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java deleted file mode 100644 index 5491d940..00000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/LibraryExtractor.java +++ /dev/null @@ -1,238 +0,0 @@ -package fr.free.miniupnp.libnatpmp; - -/** I (Leah X Schmidt) copied this code from jnaerator, because -JNAerator's extractor requires you to buy into the whole JNA -concept. - -JNAErator is -Copyright (c) 2009 Olivier Chafik, All Rights Reserved - -JNAerator is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -JNAerator is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with JNAerator. If not, see . - -*/ - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -public class LibraryExtractor { - - private static boolean libPathSet = false; - - public static String getLibraryPath(String libraryName, boolean extractAllLibraries, Class cl) { - try { - String customPath = System.getProperty("library." + libraryName); - if (customPath == null) - customPath = System.getenv(libraryName.toUpperCase() + "_LIBRARY"); - if (customPath != null) { - File f = new File(customPath); - if (!f.exists()) - System.err.println("Library file '" + customPath + "' does not exist !"); - else - return f.getAbsolutePath(); - } - //ClassLoader cl = LibraryExtractor.class.getClassLoader(); - String prefix = "(?i)" + (isWindows() ? "" : "lib") + libraryName + "[^A-Za-z_].*"; - String libsuffix = "(?i).*\\.(so|dll|dylib|jnilib)"; - //String othersuffix = "(?i).*\\.(pdb)"; - - URL sourceURL = null; - List otherURLs = new ArrayList(); - - - String arch = getCurrentOSAndArchString(); - //System.out.println("libURL = " + libURL); - List list = URLUtils.listFiles(URLUtils.getResource(cl, "libraries/" + arch)), - noArchList = URLUtils.listFiles(URLUtils.getResource(cl, "libraries/noarch")); - - Set names = new HashSet(); - for (URL url : list) { - String name = getFileName(url); - names.add(name); - } - for (URL url : noArchList) { - String name = getFileName(url); - if (names.add(name)) - list.add(url); - } - - for (File f : new File(".").listFiles()) - if (f.isFile()) - list.add(f.toURI().toURL()); - - for (URL url : list) { - String name = getFileName(url); - boolean pref = name.matches(prefix), suff = name.matches(libsuffix); - if (pref && suff) - sourceURL = url; - else //if (suff || fileName.matches(othersuffix)) - otherURLs.add(url); - } - List files = new ArrayList(); - if (extractAllLibraries) { - for (URL url : otherURLs) - files.add(extract(url)); - } - - if (System.getProperty("javawebstart.version") != null) { - if (isWindows()) { - //File f = new File("c:\\Windows\\" + (Platform.is64Bit() ? "SysWOW64\\" : "System32\\") + libraryName + ".dll"); - File f = new File("c:\\Windows\\" + "System32\\" + libraryName + ".dll"); - if (f.exists()) - return f.toString(); - } else if (isMac()) { - File f = new File("/System/Library/Frameworks/" + libraryName + ".framework/" + libraryName); - if (f.exists()) - return f.toString(); - } - } - - if (sourceURL == null) - return libraryName; - else { - File file = extract(sourceURL); - files.add(file); - - int lastSize; - do { - lastSize = files.size(); - for (Iterator it = files.iterator(); it.hasNext();) { - File f = it.next(); - if (!f.getName().matches(libsuffix)) - continue; - - try { - System.load(f.toString()); - it.remove(); - } catch (Throwable ex) { - System.err.println("Loading " + f.getName() + " failed (" + ex + ")"); - } - } - } while (files.size() < lastSize); - - return file.getCanonicalPath(); - } - } catch (Throwable ex) { - System.err.println("ERROR: Failed to extract library " + libraryName); - ex.printStackTrace(); - return libraryName; - } - } - - public static final boolean isWindows() { - String osName = System.getProperty("os.name"); - return osName.startsWith("Windows"); - } - - public static final boolean isMac() { - String osName = System.getProperty("os.name"); - return osName.startsWith("Mac") || osName.startsWith("Darwin"); - } - - //this code is from JNA, but JNA has a fallback to some native - //stuff in case this doesn't work. Since sun.arch.data.model is - //defined for Sun and IBM, this should work nearly everywhere. - public static final boolean is64Bit() { - String model = System.getProperty("sun.arch.data.model", - System.getProperty("com.ibm.vm.bitmode")); - if (model != null) { - return "64".equals(model); - } - String arch = System.getProperty("os.arch").toLowerCase(); - if ("x86_64".equals(arch) - || "ia64".equals(arch) - || "ppc64".equals(arch) - || "sparcv9".equals(arch) - || "amd64".equals(arch)) { - return true; - } - - return false; - } - - public static String getCurrentOSAndArchString() { - String os = System.getProperty("os.name"), arch = System.getProperty("os.arch"); - if (os.equals("Mac OS X")) { - os = "darwin"; - arch = "fat"; - } else if (os.startsWith("Windows")) { - return "win" + (is64Bit() ? "64" : "32"); - } else if (os.matches("SunOS|Solaris")) - os = "solaris"; - return os + "-" + arch; - } - - private static File extract(URL url) throws IOException { - File localFile; - if ("file".equals(url.getProtocol())) - localFile = new File(URLDecoder.decode(url.getFile(), "UTF-8")); - else { - File f = new File(System.getProperty("user.home")); - f = new File(f, ".jnaerator"); - f = new File(f, "extractedLibraries"); - if (!f.exists()) - f.mkdirs(); - - if (!libPathSet) { - String path = System.getProperty("java.library.path"); - if (path == null) { - System.setProperty("java.library.path", f.toString()); - } else { - System.setProperty("java.library.path", path + ":" + f); - } - - libPathSet = true; - } - localFile = new File(f, new File(url.getFile()).getName()); - URLConnection c = url.openConnection(); - if (localFile.exists() && localFile.lastModified() > c.getLastModified()) { - c.getInputStream().close(); - } else { - System.out.println("Extracting " + url); - InputStream in = c.getInputStream(); - OutputStream out = new FileOutputStream(localFile); - int len; - byte[] b = new byte[1024]; - while ((len = in.read(b)) > 0) - out.write(b, 0, len); - out.close(); - in.close(); - } - } - return localFile; - } - - private static String getFileName(URL url) { - return new File(url.getFile()).getName(); - } - - public static void main(String[] args) { - System.out.println(getCurrentOSAndArchString()); - } -} \ No newline at end of file diff --git a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java deleted file mode 100644 index 2f1ddd3d..00000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmp.java +++ /dev/null @@ -1,50 +0,0 @@ -package fr.free.miniupnp.libnatpmp; - -import java.nio.ByteBuffer; - - -public class NatPmp { - private static final String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("jninatpmp", true, NatPmp.class); - - static { - String s = JNA_LIBRARY_NAME; - startup(); - } - - public ByteBuffer natpmp; - - public NatPmp() { - init(0, 0); - } - - public NatPmp(int forcedgw) { - init(1, forcedgw); - } - - /** Cleans up the native resources used by this object. - Attempting to use the object after this has been called - will lead to crashes.*/ - public void dispose() { - free(); - } - - - protected void finalize() { - if (natpmp != null) - free(); - } - - private native void init(int forcegw, int forcedgw); - private native void free(); - - private static native void startup(); - - public native int sendPublicAddressRequest(); - public native int sendNewPortMappingRequest(int protocol, int privateport, int publicport, int lifetime); - - //returns a number of milliseconds, in accordance with Java convention - public native long getNatPmpRequestTimeout(); - - public native int readNatPmpResponseOrRetry(NatPmpResponse response); - -} diff --git a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java deleted file mode 100644 index 35c87eab..00000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/NatPmpResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -package fr.free.miniupnp.libnatpmp; - -public class NatPmpResponse { - - public static final int TYPE_PUBLICADDRESS=0; - public static final int TYPE_UDPPORTMAPPING=1; - public static final int TYPE_TCPPORTMAPPING=2; - - /** see TYPE_* constants */ - public short type; - /** NAT-PMP response code */ - public short resultcode; - /** milliseconds since start of epoch */ - public long epoch; - - /** only defined if type == 0*/ - public int addr; - - /** only defined if type != 0 */ - public int privateport; - - /** only defined if type != 0 */ - public int mappedpublicport; - - /** only defined if type != 0 */ - public long lifetime; //milliseconds - -} \ No newline at end of file diff --git a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java b/ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java deleted file mode 100644 index 5b419ab3..00000000 --- a/ext/libnatpmp/fr/free/miniupnp/libnatpmp/URLUtils.java +++ /dev/null @@ -1,81 +0,0 @@ -package fr.free.miniupnp.libnatpmp; - -/** I (Leah X Schmidt) copied this code from jnaerator, because -JNAerator's extractor requires you to buy into the whole JNA -concept. - -JNAErator is -Copyright (c) 2009 Olivier Chafik, All Rights Reserved - -JNAerator is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -JNAerator is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with JNAerator. If not, see . - -*/ - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; - -public class URLUtils { - - public static URL getResource(Class cl, String path) throws IOException { - String clp = cl.getName().replace('.', '/') + ".class"; - URL clu = cl.getClassLoader().getResource(clp); - String s = clu.toString(); - if (s.endsWith(clp)) - return new URL(s.substring(0, s.length() - clp.length()) + path); - - if (s.startsWith("jar:")) { - String[] ss = s.split("!"); - return new URL(ss[1] + "!/" + path); - } - return null; - } - - public static List listFiles(URL directory) throws IOException { - List ret = new ArrayList(); - String s = directory.toString(); - if (s.startsWith("jar:")) { - String[] ss = s.substring("jar:".length()).split("!"); - String path = ss[1]; - URL target = new URL(ss[0]); - InputStream tin = target.openStream(); - try { - JarInputStream jin = new JarInputStream(tin); - JarEntry je; - while ((je = jin.getNextJarEntry()) != null) { - String p = "/" + je.getName(); - if (p.startsWith(path) && p.indexOf('/', path.length() + 1) < 0) - - ret.add(new URL("jar:" + target + "!" + p)); - } - } finally { - tin.close(); - } - } else if (s.startsWith("file:")) { - File f = new File(directory.getFile()); - File[] ffs = f.listFiles(); - if (ffs != null) - for (File ff : ffs) - ret.add(ff.toURI().toURL()); - } else - throw new IOException("Cannot list contents of " + directory); - - return ret; - } -} \ No newline at end of file diff --git a/ext/libnatpmp/getgateway.c b/ext/libnatpmp/getgateway.c deleted file mode 100644 index f743a089..00000000 --- a/ext/libnatpmp/getgateway.c +++ /dev/null @@ -1,573 +0,0 @@ -/* $Id: getgateway.c,v 1.25 2014/04/22 10:28:57 nanard Exp $ */ -/* libnatpmp - -Copyright (c) 2007-2014, 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. -*/ -#include -#include -#ifndef WIN32 -#include -#endif -#if !defined(_MSC_VER) -#include -#endif -/* There is no portable method to get the default route gateway. - * So below are four (or five ?) differents functions implementing this. - * Parsing /proc/net/route is for linux. - * sysctl is the way to access such informations on BSD systems. - * Many systems should provide route information through raw PF_ROUTE - * sockets. - * In MS Windows, default gateway is found by looking into the registry - * or by using GetBestRoute(). */ -#ifdef __linux__ -#define USE_PROC_NET_ROUTE -#undef USE_SOCKET_ROUTE -#undef USE_SYSCTL_NET_ROUTE -#endif - -#if defined(BSD) || defined(__FreeBSD_kernel__) -#undef USE_PROC_NET_ROUTE -#define USE_SOCKET_ROUTE -#undef USE_SYSCTL_NET_ROUTE -#include -#endif - -#ifdef __APPLE__ -#undef USE_PROC_NET_ROUTE -#undef USE_SOCKET_ROUTE -#define USE_SYSCTL_NET_ROUTE -#endif - -#if (defined(sun) && defined(__SVR4)) -#undef USE_PROC_NET_ROUTE -#define USE_SOCKET_ROUTE -#undef USE_SYSCTL_NET_ROUTE -#endif - -#ifdef WIN32 -#undef USE_PROC_NET_ROUTE -#undef USE_SOCKET_ROUTE -#undef USE_SYSCTL_NET_ROUTE -//#define USE_WIN32_CODE -#define USE_WIN32_CODE_2 -#endif - -#ifdef __CYGWIN__ -#undef USE_PROC_NET_ROUTE -#undef USE_SOCKET_ROUTE -#undef USE_SYSCTL_NET_ROUTE -#define USE_WIN32_CODE -#include -#include -#include -#include -#endif - -#ifdef __HAIKU__ -#include -#include -#include -#include -#define USE_HAIKU_CODE -#endif - -#ifdef USE_SYSCTL_NET_ROUTE -#include -#include -#include -#endif -#ifdef USE_SOCKET_ROUTE -#include -#include -#include -#include -#include -#endif - -#ifdef USE_WIN32_CODE -#include -#include -#define MAX_KEY_LENGTH 255 -#define MAX_VALUE_LENGTH 16383 -#endif - -#ifdef USE_WIN32_CODE_2 -#include -#include -#endif - -#include "getgateway.h" - -#ifndef WIN32 -#define SUCCESS (0) -#define FAILED (-1) -#endif - -#ifdef USE_PROC_NET_ROUTE -/* - parse /proc/net/route which is as follow : - -Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT -wlan0 0001A8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0 -eth0 0000FEA9 00000000 0001 0 0 0 0000FFFF 0 0 0 -wlan0 00000000 0101A8C0 0003 0 0 0 00000000 0 0 0 -eth0 00000000 00000000 0001 0 0 1000 00000000 0 0 0 - - One header line, and then one line by route by route table entry. -*/ -int getdefaultgateway(in_addr_t * addr) -{ - unsigned long d, g; - char buf[256]; - int line = 0; - FILE * f; - char * p; - f = fopen("/proc/net/route", "r"); - if(!f) - return FAILED; - while(fgets(buf, sizeof(buf), f)) { - if(line > 0) { /* skip the first line */ - p = buf; - /* skip the interface name */ - while(*p && !isspace(*p)) - p++; - while(*p && isspace(*p)) - p++; - if(sscanf(p, "%lx%lx", &d, &g)==2) { - if(d == 0 && g != 0) { /* default */ - *addr = g; - fclose(f); - return SUCCESS; - } - } - } - line++; - } - /* default route not found ! */ - if(f) - fclose(f); - return FAILED; -} -#endif /* #ifdef USE_PROC_NET_ROUTE */ - - -#ifdef USE_SYSCTL_NET_ROUTE - -#define ROUNDUP(a) \ - ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) - -int getdefaultgateway(in_addr_t * addr) -{ -#if 0 - /* net.route.0.inet.dump.0.0 ? */ - int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, - NET_RT_DUMP, 0, 0/*tableid*/}; -#endif - /* net.route.0.inet.flags.gateway */ - int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, - NET_RT_FLAGS, RTF_GATEWAY}; - size_t l; - char * buf, * p; - struct rt_msghdr * rt; - struct sockaddr * sa; - struct sockaddr * sa_tab[RTAX_MAX]; - int i; - int r = FAILED; - if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) { - return FAILED; - } - if(l>0) { - buf = malloc(l); - if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) { - free(buf); - return FAILED; - } - for(p=buf; prtm_msglen) { - rt = (struct rt_msghdr *)p; - sa = (struct sockaddr *)(rt + 1); - for(i=0; irtm_addrs & (1 << i)) { - sa_tab[i] = sa; - sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); - } else { - sa_tab[i] = NULL; - } - } - if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) - && sa_tab[RTAX_DST]->sa_family == AF_INET - && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) { - if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) { - *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr; - r = SUCCESS; - } - } - } - free(buf); - } - return r; -} -#endif /* #ifdef USE_SYSCTL_NET_ROUTE */ - - -#ifdef USE_SOCKET_ROUTE -/* Thanks to Darren Kenny for this code */ -#define NEXTADDR(w, u) \ - if (rtm_addrs & (w)) {\ - l = sizeof(struct sockaddr); memmove(cp, &(u), l); cp += l;\ - } - -#define rtm m_rtmsg.m_rtm - -struct { - struct rt_msghdr m_rtm; - char m_space[512]; -} m_rtmsg; - -int getdefaultgateway(in_addr_t *addr) -{ - int s, seq, l, rtm_addrs, i; - pid_t pid; - struct sockaddr so_dst, so_mask; - char *cp = m_rtmsg.m_space; - struct sockaddr *gate = NULL, *sa; - struct rt_msghdr *msg_hdr; - - pid = getpid(); - seq = 0; - rtm_addrs = RTA_DST | RTA_NETMASK; - - memset(&so_dst, 0, sizeof(so_dst)); - memset(&so_mask, 0, sizeof(so_mask)); - memset(&rtm, 0, sizeof(struct rt_msghdr)); - - rtm.rtm_type = RTM_GET; - rtm.rtm_flags = RTF_UP | RTF_GATEWAY; - rtm.rtm_version = RTM_VERSION; - rtm.rtm_seq = ++seq; - rtm.rtm_addrs = rtm_addrs; - - so_dst.sa_family = AF_INET; - so_mask.sa_family = AF_INET; - - NEXTADDR(RTA_DST, so_dst); - NEXTADDR(RTA_NETMASK, so_mask); - - rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; - - s = socket(PF_ROUTE, SOCK_RAW, 0); - - if (write(s, (char *)&m_rtmsg, l) < 0) { - close(s); - return FAILED; - } - - do { - l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); - } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); - - close(s); - - msg_hdr = &rtm; - - cp = ((char *)(msg_hdr + 1)); - if (msg_hdr->rtm_addrs) { - for (i = 1; i; i <<= 1) - if (i & msg_hdr->rtm_addrs) { - sa = (struct sockaddr *)cp; - if (i == RTA_GATEWAY ) - gate = sa; - - cp += sizeof(struct sockaddr); - } - } else { - return FAILED; - } - - - if (gate != NULL ) { - *addr = ((struct sockaddr_in *)gate)->sin_addr.s_addr; - return SUCCESS; - } else { - return FAILED; - } -} -#endif /* #ifdef USE_SOCKET_ROUTE */ - -#ifdef USE_WIN32_CODE -LIBSPEC int getdefaultgateway(in_addr_t * addr) -{ - HKEY networkCardsKey; - HKEY networkCardKey; - HKEY interfacesKey; - HKEY interfaceKey; - DWORD i = 0; - DWORD numSubKeys = 0; - TCHAR keyName[MAX_KEY_LENGTH]; - DWORD keyNameLength = MAX_KEY_LENGTH; - TCHAR keyValue[MAX_VALUE_LENGTH]; - DWORD keyValueLength = MAX_VALUE_LENGTH; - DWORD keyValueType = REG_SZ; - TCHAR gatewayValue[MAX_VALUE_LENGTH]; - DWORD gatewayValueLength = MAX_VALUE_LENGTH; - DWORD gatewayValueType = REG_MULTI_SZ; - int done = 0; - - //const char * networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; - //const char * interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; -#ifdef UNICODE - LPCTSTR networkCardsPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; - LPCTSTR interfacesPath = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; -#define STR_SERVICENAME L"ServiceName" -#define STR_DHCPDEFAULTGATEWAY L"DhcpDefaultGateway" -#define STR_DEFAULTGATEWAY L"DefaultGateway" -#else - LPCTSTR networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"; - LPCTSTR interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"; -#define STR_SERVICENAME "ServiceName" -#define STR_DHCPDEFAULTGATEWAY "DhcpDefaultGateway" -#define STR_DEFAULTGATEWAY "DefaultGateway" -#endif - // The windows registry lists its primary network devices in the following location: - // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards - // - // Each network device has its own subfolder, named with an index, with various properties: - // -NetworkCards - // -5 - // -Description = Broadcom 802.11n Network Adapter - // -ServiceName = {E35A72F8-5065-4097-8DFE-C7790774EE4D} - // -8 - // -Description = Marvell Yukon 88E8058 PCI-E Gigabit Ethernet Controller - // -ServiceName = {86226414-5545-4335-A9D1-5BD7120119AD} - // - // The above service name is the name of a subfolder within: - // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces - // - // There may be more subfolders in this interfaces path than listed in the network cards path above: - // -Interfaces - // -{3a539854-6a70-11db-887c-806e6f6e6963} - // -DhcpIPAddress = 0.0.0.0 - // -[more] - // -{E35A72F8-5065-4097-8DFE-C7790774EE4D} - // -DhcpIPAddress = 10.0.1.4 - // -DhcpDefaultGateway = 10.0.1.1 - // -[more] - // -{86226414-5545-4335-A9D1-5BD7120119AD} - // -DhcpIpAddress = 10.0.1.5 - // -DhcpDefaultGateay = 10.0.1.1 - // -[more] - // - // In order to extract this information, we enumerate each network card, and extract the ServiceName value. - // This is then used to open the interface subfolder, and attempt to extract a DhcpDefaultGateway value. - // Once one is found, we're done. - // - // It may be possible to simply enumerate the interface folders until we find one with a DhcpDefaultGateway value. - // However, the technique used is the technique most cited on the web, and we assume it to be more correct. - - if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predifined key - networkCardsPath, // Name of registry subkey to open - 0, // Reserved - must be zero - KEY_READ, // Mask - desired access rights - &networkCardsKey)) // Pointer to output key - { - // Unable to open network cards keys - return -1; - } - - if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predefined key - interfacesPath, // Name of registry subkey to open - 0, // Reserved - must be zero - KEY_READ, // Mask - desired access rights - &interfacesKey)) // Pointer to output key - { - // Unable to open interfaces key - RegCloseKey(networkCardsKey); - return -1; - } - - // Figure out how many subfolders are within the NetworkCards folder - RegQueryInfoKey(networkCardsKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - - //printf( "Number of subkeys: %u\n", (unsigned int)numSubKeys); - - // Enumrate through each subfolder within the NetworkCards folder - for(i = 0; i < numSubKeys && !done; i++) - { - keyNameLength = MAX_KEY_LENGTH; - if(ERROR_SUCCESS == RegEnumKeyEx(networkCardsKey, // Open registry key - i, // Index of subkey to retrieve - keyName, // Buffer that receives the name of the subkey - &keyNameLength, // Variable that receives the size of the above buffer - NULL, // Reserved - must be NULL - NULL, // Buffer that receives the class string - NULL, // Variable that receives the size of the above buffer - NULL)) // Variable that receives the last write time of subkey - { - if(RegOpenKeyEx(networkCardsKey, keyName, 0, KEY_READ, &networkCardKey) == ERROR_SUCCESS) - { - keyValueLength = MAX_VALUE_LENGTH; - if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey, // Open registry key - STR_SERVICENAME, // Name of key to query - NULL, // Reserved - must be NULL - &keyValueType, // Receives value type - (LPBYTE)keyValue, // Receives value - &keyValueLength)) // Receives value length in bytes - { -// printf("keyValue: %s\n", keyValue); - if(RegOpenKeyEx(interfacesKey, keyValue, 0, KEY_READ, &interfaceKey) == ERROR_SUCCESS) - { - gatewayValueLength = MAX_VALUE_LENGTH; - if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key - STR_DHCPDEFAULTGATEWAY, // Name of key to query - NULL, // Reserved - must be NULL - &gatewayValueType, // Receives value type - (LPBYTE)gatewayValue, // Receives value - &gatewayValueLength)) // Receives value length in bytes - { - // Check to make sure it's a string - if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1)) - { - //printf("gatewayValue: %s\n", gatewayValue); - done = 1; - } - } - else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey, // Open registry key - STR_DEFAULTGATEWAY, // Name of key to query - NULL, // Reserved - must be NULL - &gatewayValueType, // Receives value type - (LPBYTE)gatewayValue,// Receives value - &gatewayValueLength)) // Receives value length in bytes - { - // Check to make sure it's a string - if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1)) - { - //printf("gatewayValue: %s\n", gatewayValue); - done = 1; - } - } - RegCloseKey(interfaceKey); - } - } - RegCloseKey(networkCardKey); - } - } - } - - RegCloseKey(interfacesKey); - RegCloseKey(networkCardsKey); - - if(done) - { -#if UNICODE - char tmp[32]; - for(i = 0; i < 32; i++) { - tmp[i] = (char)gatewayValue[i]; - if(!tmp[i]) - break; - } - tmp[31] = '\0'; - *addr = inet_addr(tmp); -#else - *addr = inet_addr(gatewayValue); -#endif - return 0; - } - - return -1; -} -#endif /* #ifdef USE_WIN32_CODE */ - -#ifdef USE_WIN32_CODE_2 -int getdefaultgateway(in_addr_t *addr) -{ - MIB_IPFORWARDROW ip_forward; - memset(&ip_forward, 0, sizeof(ip_forward)); - if(GetBestRoute(inet_addr("0.0.0.0"), 0, &ip_forward) != NO_ERROR) - return -1; - *addr = ip_forward.dwForwardNextHop; - return 0; -} -#endif /* #ifdef USE_WIN32_CODE_2 */ - -#ifdef USE_HAIKU_CODE -int getdefaultgateway(in_addr_t *addr) -{ - int fd, ret = -1; - struct ifconf config; - void *buffer = NULL; - struct ifreq *interface; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - return -1; - } - if (ioctl(fd, SIOCGRTSIZE, &config, sizeof(config)) != 0) { - goto fail; - } - if (config.ifc_value < 1) { - goto fail; /* No routes */ - } - if ((buffer = malloc(config.ifc_value)) == NULL) { - goto fail; - } - config.ifc_len = config.ifc_value; - config.ifc_buf = buffer; - if (ioctl(fd, SIOCGRTTABLE, &config, sizeof(config)) != 0) { - goto fail; - } - for (interface = buffer; - (uint8_t *)interface < (uint8_t *)buffer + config.ifc_len; ) { - struct route_entry route = interface->ifr_route; - int intfSize; - if (route.flags & (RTF_GATEWAY | RTF_DEFAULT)) { - *addr = ((struct sockaddr_in *)route.gateway)->sin_addr.s_addr; - ret = 0; - break; - } - intfSize = sizeof(route) + IF_NAMESIZE; - if (route.destination != NULL) { - intfSize += route.destination->sa_len; - } - if (route.mask != NULL) { - intfSize += route.mask->sa_len; - } - if (route.gateway != NULL) { - intfSize += route.gateway->sa_len; - } - interface = (struct ifreq *)((uint8_t *)interface + intfSize); - } -fail: - free(buffer); - close(fd); - return ret; -} -#endif /* #ifdef USE_HAIKU_CODE */ - -#if !defined(USE_PROC_NET_ROUTE) && !defined(USE_SOCKET_ROUTE) && !defined(USE_SYSCTL_NET_ROUTE) && !defined(USE_WIN32_CODE) && !defined(USE_WIN32_CODE_2) && !defined(USE_HAIKU_CODE) -int getdefaultgateway(in_addr_t * addr) -{ - return -1; -} -#endif diff --git a/ext/libnatpmp/getgateway.h b/ext/libnatpmp/getgateway.h deleted file mode 100644 index 5d3df731..00000000 --- a/ext/libnatpmp/getgateway.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $Id: getgateway.h,v 1.8 2014/04/22 09:15:40 nanard Exp $ */ -/* libnatpmp -Copyright (c) 2007-2014, 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. -*/ -#ifndef __GETGATEWAY_H__ -#define __GETGATEWAY_H__ - -#ifdef WIN32 -#if !defined(_MSC_VER) || _MSC_VER >= 1600 -#include -#else -typedef unsigned long uint32_t; -typedef unsigned short uint16_t; -#endif -#define in_addr_t uint32_t -#endif -/* #include "declspec.h" */ - -/* getdefaultgateway() : - * return value : - * 0 : success - * -1 : failure */ -/* LIBSPEC */int getdefaultgateway(in_addr_t * addr); - -#endif diff --git a/ext/libnatpmp/libnatpmpmodule.c b/ext/libnatpmp/libnatpmpmodule.c deleted file mode 100644 index 0fd9914b..00000000 --- a/ext/libnatpmp/libnatpmpmodule.c +++ /dev/null @@ -1,281 +0,0 @@ -/* $Id: libnatpmpmodule.c,v 1.7 2012/03/05 19:38:37 nanard Exp $ */ -/* libnatpmp - * http://miniupnp.free.fr/libnatpmp.html -Copyright (c) 2007-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. -*/ -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif - -#define STATICLIB -#include "structmember.h" -#include "natpmp.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 - -typedef struct { - PyObject_HEAD - - /* Type-specific fields go here. */ - unsigned int discoverdelay; - - natpmp_t natpmp; -} NATPMPObject; - -static PyMemberDef NATPMP_members[] = { - {"discoverdelay", T_UINT, offsetof(NATPMPObject, discoverdelay), - 0/*READWRITE*/, "value in ms used to wait for NATPMP responses" - }, - {NULL} -}; - -static PyObject * -NATPMPObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - NATPMPObject *self; - - self = (NATPMPObject *)type->tp_alloc(type, 0); - if (self) { - initnatpmp(&self->natpmp, 0, 0); - } - - return (PyObject *)self; -} - -static void -NATPMPObject_dealloc(NATPMPObject *self) -{ - closenatpmp(&self->natpmp); - self->ob_type->tp_free((PyObject*)self); -} - -static PyObject * -NATPMP_externalipaddress(NATPMPObject *self) -{ - int r; - struct timeval timeout; - fd_set fds; - natpmpresp_t response; - - r = sendpublicaddressrequest(&self->natpmp); - - if (r < 0) { -#ifdef ENABLE_STRNATPMPERR - PyErr_SetString(PyExc_Exception, strnatpmperr(r)); -#endif - return NULL; - } - - do { - FD_ZERO(&fds); - FD_SET(self->natpmp.s, &fds); - getnatpmprequesttimeout(&self->natpmp, &timeout); - select(FD_SETSIZE, &fds, NULL, NULL, &timeout); - r = readnatpmpresponseorretry(&self->natpmp, &response); - if (r < 0 && r != NATPMP_TRYAGAIN) { -#ifdef ENABLE_STRNATPMPERR - PyErr_SetString(PyExc_Exception, strnatpmperr(r)); -#endif - return NULL; - } - } while (r == NATPMP_TRYAGAIN); - - return Py_BuildValue("s", inet_ntoa(response.pnu.publicaddress.addr)); -} - -static PyObject * -NATPMP_domapping(natpmp_t *n, unsigned short eport, unsigned short iport, - const char *protocol, unsigned int lifetime) -{ - int proto; - struct timeval timeout; - fd_set fds; - natpmpresp_t response; - int r; - - if (!strncasecmp("tcp", protocol, 3)) { - proto = NATPMP_PROTOCOL_TCP; - } else if (!strncasecmp("udp", protocol, 3)) { - proto = NATPMP_PROTOCOL_UDP; - } else { - PyErr_SetString(PyExc_Exception, "Unknown protocol"); - return NULL; - } - - r = sendnewportmappingrequest(n, proto, iport, eport, - lifetime); - - if (r < 0) { -#ifdef ENABLE_STRNATPMPERR - PyErr_SetString(PyExc_Exception, strnatpmperr(r)); -#endif - return NULL; - } - - do { - FD_ZERO(&fds); - FD_SET(n->s, &fds); - getnatpmprequesttimeout(n, &timeout); - select(FD_SETSIZE, &fds, NULL, NULL, &timeout); - r = readnatpmpresponseorretry(n, &response); - if (r < 0 && r != NATPMP_TRYAGAIN) { -#ifdef ENABLE_STRNATPMPERR - PyErr_SetString(PyExc_Exception, strnatpmperr(r)); -#endif - return NULL; - } - } while (r == NATPMP_TRYAGAIN); - - return Py_BuildValue("H", response.pnu.newportmapping.mappedpublicport); -} - - -/* AddPortMapping(externalPort, protocol, internalPort, lifetime) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -NATPMP_addportmapping(NATPMPObject *self, PyObject *args) -{ - unsigned short eport; - unsigned short iport; - unsigned int lifetime; - const char *protocol; - - if (!PyArg_ParseTuple(args, "HsHI", &eport, &protocol, &iport, &lifetime)) - return NULL; - - return NATPMP_domapping(&self->natpmp, eport, iport, protocol, lifetime); -} - -/* DeletePortMapping(externalPort, protocol, internalPort) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -NATPMP_deleteportmapping(NATPMPObject *self, PyObject *args) -{ - unsigned short eport; - unsigned short iport; - const char *protocol; - - if (!PyArg_ParseTuple(args, "HsH", &eport, &protocol, &iport)) - return NULL; - - return NATPMP_domapping(&self->natpmp, eport, iport, protocol, 0); -} - -/* natpmp.NATPMP object Method Table */ -static PyMethodDef NATPMP_methods[] = { - {"externalipaddress", (PyCFunction)NATPMP_externalipaddress, METH_NOARGS, - "return external IP address" - }, - {"addportmapping", (PyCFunction)NATPMP_addportmapping, METH_VARARGS, - "add a port mapping" - }, - {"deleteportmapping", (PyCFunction)NATPMP_deleteportmapping, METH_VARARGS, - "delete a port mapping" - }, - {NULL} /* Sentinel */ -}; - -static PyTypeObject NATPMPType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "libnatpmp.NATPMP", /*tp_name*/ - sizeof(NATPMPObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)NATPMPObject_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*/ - "NATPMP objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - NATPMP_methods, /* tp_methods */ - NATPMP_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - NATPMPObject_new, /* tp_new */ -}; - -/* module methods */ -static PyMethodDef libnatpmp_methods[] = { - {NULL} /* Sentinel */ -}; - -#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ -#define PyMODINIT_FUNC void -#endif -PyMODINIT_FUNC -initlibnatpmp(void) -{ - PyObject* m; - - if (PyType_Ready(&NATPMPType) < 0) - return; - - m = Py_InitModule3("libnatpmp", libnatpmp_methods, - "libnatpmp module."); - - Py_INCREF(&NATPMPType); - PyModule_AddObject(m, "NATPMP", (PyObject *)&NATPMPType); -} - diff --git a/ext/libnatpmp/msvc/libnatpmp.sln b/ext/libnatpmp/msvc/libnatpmp.sln deleted file mode 100644 index ac746d41..00000000 --- a/ext/libnatpmp/msvc/libnatpmp.sln +++ /dev/null @@ -1,29 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnatpmp", "libnatpmp.vcproj", "{D59B6527-F3DE-4D26-A08D-52F1EE989301}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "natpmpc-static", "natpmpc-static.vcproj", "{A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}" - ProjectSection(ProjectDependencies) = postProject - {D59B6527-F3DE-4D26-A08D-52F1EE989301} = {D59B6527-F3DE-4D26-A08D-52F1EE989301} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.ActiveCfg = Debug|Win32 - {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Debug|Win32.Build.0 = Debug|Win32 - {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.ActiveCfg = Release|Win32 - {D59B6527-F3DE-4D26-A08D-52F1EE989301}.Release|Win32.Build.0 = Release|Win32 - {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.ActiveCfg = Debug|Win32 - {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Debug|Win32.Build.0 = Debug|Win32 - {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.ActiveCfg = Release|Win32 - {A0B49FA9-98AB-4A74-8B4C-8AB7FA36089B}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/ext/libnatpmp/msvc/libnatpmp.vcproj b/ext/libnatpmp/msvc/libnatpmp.vcproj deleted file mode 100644 index 9bae5c18..00000000 --- a/ext/libnatpmp/msvc/libnatpmp.vcproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ext/libnatpmp/msvc/natpmpc-static.vcproj b/ext/libnatpmp/msvc/natpmpc-static.vcproj deleted file mode 100644 index c2052d98..00000000 --- a/ext/libnatpmp/msvc/natpmpc-static.vcproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ext/libnatpmp/natpmp-jni.c b/ext/libnatpmp/natpmp-jni.c deleted file mode 100644 index feec1cea..00000000 --- a/ext/libnatpmp/natpmp-jni.c +++ /dev/null @@ -1,157 +0,0 @@ -#ifdef __CYGWIN__ -#include -#define __int64 uint64_t -#endif - -#ifdef WIN32 -#include -#include -#include -#endif - -#include -#include "natpmp.h" - -#include "fr_free_miniupnp_libnatpmp_NatPmp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_init (JNIEnv *env, jobject obj, jint forcegw, jint forcedgw) { - natpmp_t *p = malloc (sizeof(natpmp_t)); - if (p == NULL) return; - - initnatpmp(p, forcegw, (in_addr_t) forcedgw); - - jobject wrapped = (*env)->NewDirectByteBuffer(env, p, sizeof(natpmp_t)); - if (wrapped == NULL) return; - - jclass thisClass = (*env)->GetObjectClass(env,obj); - if (thisClass == NULL) return; - - jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); - if (fid == NULL) return; - (*env)->SetObjectField(env, obj, fid, wrapped); -} - -JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_free (JNIEnv *env, jobject obj) { - - jclass thisClass = (*env)->GetObjectClass(env,obj); - if (thisClass == NULL) return; - - jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); - - if (fid == NULL) return; - jobject wrapped = (*env)->GetObjectField(env, obj, fid); - if (wrapped == NULL) return; - - natpmp_t* natpmp = (natpmp_t*) (*env)->GetDirectBufferAddress(env, wrapped); - - closenatpmp(natpmp); - - if (natpmp == NULL) return; - free(natpmp); - - (*env)->SetObjectField(env, obj, fid, NULL); -} - -static natpmp_t* getNatPmp(JNIEnv* env, jobject obj) { - jclass thisClass = (*env)->GetObjectClass(env,obj); - if (thisClass == NULL) return NULL; - - jfieldID fid = (*env)->GetFieldID(env, thisClass, "natpmp", "Ljava/nio/ByteBuffer;"); - - if (fid == NULL) return NULL; - jobject wrapped = (*env)->GetObjectField(env, obj, fid); - if (wrapped == NULL) return NULL; - - natpmp_t* natpmp = (natpmp_t*) (*env)->GetDirectBufferAddress(env, wrapped); - - return natpmp; -} - -JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_sendPublicAddressRequest(JNIEnv* env, jobject obj) { - natpmp_t* natpmp = getNatPmp(env, obj); - if (natpmp == NULL) return -1; - - return sendpublicaddressrequest(natpmp); -} - - -JNIEXPORT void JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_startup(JNIEnv* env, jclass cls) { - (void)env; - (void)cls; -#ifdef WIN32 - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(2, 2); - WSAStartup(wVersionRequested, &wsaData); -#endif -} - - -JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_sendNewPortMappingRequest(JNIEnv* env, jobject obj, jint protocol, jint privateport, jint publicport, jint lifetime) { - natpmp_t* natpmp = getNatPmp(env, obj); - if (natpmp == NULL) return -1; - - return sendnewportmappingrequest(natpmp, protocol, privateport, publicport, lifetime); -} - -JNIEXPORT jlong JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_getNatPmpRequestTimeout(JNIEnv* env, jobject obj) { - natpmp_t* natpmp = getNatPmp(env, obj); - - struct timeval timeout; - - getnatpmprequesttimeout(natpmp, &timeout); - - return ((jlong) timeout.tv_sec) * 1000 + (timeout.tv_usec / 1000); - -} - -#define SET_FIELD(prefix, name, type, longtype) { \ - jfieldID fid = (*env)->GetFieldID(env, thisClass, #name, type); \ - if (fid == NULL) return -1; \ - (*env)->Set ## longtype ## Field(env, response, fid, resp. prefix name); \ -} - -JNIEXPORT jint JNICALL Java_fr_free_miniupnp_libnatpmp_NatPmp_readNatPmpResponseOrRetry(JNIEnv* env, jobject obj, jobject response) { - - natpmp_t* natpmp = getNatPmp(env, obj); - natpmpresp_t resp; - int result = readnatpmpresponseorretry(natpmp, &resp); - - if (result != 0) { - return result; - } - - jclass thisClass = (*env)->GetObjectClass(env, response); - if (thisClass == NULL) return -1; - - SET_FIELD(,type, "S", Short); - SET_FIELD(,resultcode, "S", Short); - - jfieldID fid = (*env)->GetFieldID(env, thisClass, "epoch", "J"); - if (fid == NULL) return -1; - (*env)->SetLongField(env, response, fid, ((jlong)resp.epoch) * 1000); - - if (resp.type == 0) { - jfieldID fid = (*env)->GetFieldID(env, thisClass, "addr", "I"); - if (fid == NULL) return -1; - (*env)->SetIntField(env, response, fid, resp.pnu.publicaddress.addr.s_addr); - - - } else { - SET_FIELD(pnu.newportmapping., privateport, "I", Int); - SET_FIELD(pnu.newportmapping., mappedpublicport, "I", Int); - - jfieldID fid = (*env)->GetFieldID(env, thisClass, "lifetime", "J"); - if (fid == NULL) return -1; - (*env)->SetLongField(env, response, fid, ((jlong) resp.pnu.newportmapping.lifetime) * 1000 * 1000); - } - return result; -} - - -#ifdef __cplusplus -} -#endif diff --git a/ext/libnatpmp/natpmp.c b/ext/libnatpmp/natpmp.c deleted file mode 100644 index 9843c41e..00000000 --- a/ext/libnatpmp/natpmp.c +++ /dev/null @@ -1,383 +0,0 @@ -/* $Id: natpmp.c,v 1.20 2015/05/27 12:43:15 nanard Exp $ */ -/* libnatpmp -Copyright (c) 2007-2015, 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. -*/ -#ifdef __linux__ -#define _BSD_SOURCE 1 -#endif -#include -#include -#if !defined(_MSC_VER) -#include -#endif -#ifdef WIN32 -#include -#include -#include -#include -#ifndef EWOULDBLOCK -#define EWOULDBLOCK WSAEWOULDBLOCK -#endif -#ifndef ECONNREFUSED -#define ECONNREFUSED WSAECONNREFUSED -#endif -#include "wingettimeofday.h" -#define gettimeofday natpmp_gettimeofday -#else -#include -#include -#include -#include -#include -#define closesocket close -#endif -#include "natpmp.h" -#include "getgateway.h" -#include - -LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw) -{ -#ifdef WIN32 - u_long ioctlArg = 1; -#else - int flags; -#endif - struct sockaddr_in addr; - if(!p) - return NATPMP_ERR_INVALIDARGS; - memset(p, 0, sizeof(natpmp_t)); - p->s = socket(PF_INET, SOCK_DGRAM, 0); - if(p->s < 0) - return NATPMP_ERR_SOCKETERROR; -#ifdef WIN32 - if(ioctlsocket(p->s, FIONBIO, &ioctlArg) == SOCKET_ERROR) - return NATPMP_ERR_FCNTLERROR; -#else - if((flags = fcntl(p->s, F_GETFL, 0)) < 0) - return NATPMP_ERR_FCNTLERROR; - if(fcntl(p->s, F_SETFL, flags | O_NONBLOCK) < 0) - return NATPMP_ERR_FCNTLERROR; -#endif - - if(forcegw) { - p->gateway = forcedgw; - } else { - if(getdefaultgateway(&(p->gateway)) < 0) - return NATPMP_ERR_CANNOTGETGATEWAY; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(NATPMP_PORT); - addr.sin_addr.s_addr = p->gateway; - if(connect(p->s, (struct sockaddr *)&addr, sizeof(addr)) < 0) - return NATPMP_ERR_CONNECTERR; - return 0; -} - -LIBSPEC int closenatpmp(natpmp_t * p) -{ - if(!p) - return NATPMP_ERR_INVALIDARGS; - if(closesocket(p->s) < 0) - return NATPMP_ERR_CLOSEERR; - return 0; -} - -int sendpendingrequest(natpmp_t * p) -{ - int r; -/* struct sockaddr_in addr;*/ - if(!p) - return NATPMP_ERR_INVALIDARGS; -/* memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(NATPMP_PORT); - addr.sin_addr.s_addr = p->gateway; - r = (int)sendto(p->s, p->pending_request, p->pending_request_len, 0, - (struct sockaddr *)&addr, sizeof(addr));*/ - r = (int)send(p->s, (const char *)p->pending_request, p->pending_request_len, 0); - return (r<0) ? NATPMP_ERR_SENDERR : r; -} - -int sendnatpmprequest(natpmp_t * p) -{ - int n; - if(!p) - return NATPMP_ERR_INVALIDARGS; - /* TODO : check if no request is already pending */ - p->has_pending_request = 1; - p->try_number = 1; - n = sendpendingrequest(p); - gettimeofday(&p->retry_time, NULL); // check errors ! - p->retry_time.tv_usec += 250000; /* add 250ms */ - if(p->retry_time.tv_usec >= 1000000) { - p->retry_time.tv_usec -= 1000000; - p->retry_time.tv_sec++; - } - return n; -} - -LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout) -{ - struct timeval now; - if(!p || !timeout) - return NATPMP_ERR_INVALIDARGS; - if(!p->has_pending_request) - return NATPMP_ERR_NOPENDINGREQ; - if(gettimeofday(&now, NULL) < 0) - return NATPMP_ERR_GETTIMEOFDAYERR; - timeout->tv_sec = p->retry_time.tv_sec - now.tv_sec; - timeout->tv_usec = p->retry_time.tv_usec - now.tv_usec; - if(timeout->tv_usec < 0) { - timeout->tv_usec += 1000000; - timeout->tv_sec--; - } - return 0; -} - -LIBSPEC int sendpublicaddressrequest(natpmp_t * p) -{ - if(!p) - return NATPMP_ERR_INVALIDARGS; - //static const unsigned char request[] = { 0, 0 }; - p->pending_request[0] = 0; - p->pending_request[1] = 0; - p->pending_request_len = 2; - // TODO: return 0 instead of sizeof(request) ?? - return sendnatpmprequest(p); -} - -LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, - uint16_t privateport, uint16_t publicport, - uint32_t lifetime) -{ - if(!p || (protocol!=NATPMP_PROTOCOL_TCP && protocol!=NATPMP_PROTOCOL_UDP)) - return NATPMP_ERR_INVALIDARGS; - p->pending_request[0] = 0; - p->pending_request[1] = protocol; - p->pending_request[2] = 0; - p->pending_request[3] = 0; - /* break strict-aliasing rules : - *((uint16_t *)(p->pending_request + 4)) = htons(privateport); */ - p->pending_request[4] = (privateport >> 8) & 0xff; - p->pending_request[5] = privateport & 0xff; - /* break stric-aliasing rules : - *((uint16_t *)(p->pending_request + 6)) = htons(publicport); */ - p->pending_request[6] = (publicport >> 8) & 0xff; - p->pending_request[7] = publicport & 0xff; - /* break stric-aliasing rules : - *((uint32_t *)(p->pending_request + 8)) = htonl(lifetime); */ - p->pending_request[8] = (lifetime >> 24) & 0xff; - p->pending_request[9] = (lifetime >> 16) & 0xff; - p->pending_request[10] = (lifetime >> 8) & 0xff; - p->pending_request[11] = lifetime & 0xff; - p->pending_request_len = 12; - return sendnatpmprequest(p); -} - -LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response) -{ - unsigned char buf[16]; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); - int n; - if(!p) - return NATPMP_ERR_INVALIDARGS; - n = recvfrom(p->s, (char *)buf, sizeof(buf), 0, - (struct sockaddr *)&addr, &addrlen); - if(n<0) -#ifdef WIN32 - switch(WSAGetLastError()) { -#else - switch(errno) { -#endif - /*case EAGAIN:*/ - case EWOULDBLOCK: - n = NATPMP_TRYAGAIN; - break; - case ECONNREFUSED: - n = NATPMP_ERR_NOGATEWAYSUPPORT; - break; - default: - n = NATPMP_ERR_RECVFROM; - } - /* check that addr is correct (= gateway) */ - else if(addr.sin_addr.s_addr != p->gateway) - n = NATPMP_ERR_WRONGPACKETSOURCE; - else { - response->resultcode = ntohs(*((uint16_t *)(buf + 2))); - response->epoch = ntohl(*((uint32_t *)(buf + 4))); - if(buf[0] != 0) - n = NATPMP_ERR_UNSUPPORTEDVERSION; - else if(buf[1] < 128 || buf[1] > 130) - n = NATPMP_ERR_UNSUPPORTEDOPCODE; - else if(response->resultcode != 0) { - switch(response->resultcode) { - case 1: - n = NATPMP_ERR_UNSUPPORTEDVERSION; - break; - case 2: - n = NATPMP_ERR_NOTAUTHORIZED; - break; - case 3: - n = NATPMP_ERR_NETWORKFAILURE; - break; - case 4: - n = NATPMP_ERR_OUTOFRESOURCES; - break; - case 5: - n = NATPMP_ERR_UNSUPPORTEDOPCODE; - break; - default: - n = NATPMP_ERR_UNDEFINEDERROR; - } - } else { - response->type = buf[1] & 0x7f; - if(buf[1] == 128) - //response->publicaddress.addr = *((uint32_t *)(buf + 8)); - response->pnu.publicaddress.addr.s_addr = *((uint32_t *)(buf + 8)); - else { - response->pnu.newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8))); - response->pnu.newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10))); - response->pnu.newportmapping.lifetime = ntohl(*((uint32_t *)(buf + 12))); - } - n = 0; - } - } - return n; -} - -int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response) -{ - int n; - if(!p || !response) - return NATPMP_ERR_INVALIDARGS; - if(!p->has_pending_request) - return NATPMP_ERR_NOPENDINGREQ; - n = readnatpmpresponse(p, response); - if(n<0) { - if(n==NATPMP_TRYAGAIN) { - struct timeval now; - gettimeofday(&now, NULL); // check errors ! - if(timercmp(&now, &p->retry_time, >=)) { - int delay, r; - if(p->try_number >= 9) { - return NATPMP_ERR_NOGATEWAYSUPPORT; - } - /*printf("retry! %d\n", p->try_number);*/ - delay = 250 * (1<try_number); // ms - /*for(i=0; itry_number; i++) - delay += delay;*/ - p->retry_time.tv_sec += (delay / 1000); - p->retry_time.tv_usec += (delay % 1000) * 1000; - if(p->retry_time.tv_usec >= 1000000) { - p->retry_time.tv_usec -= 1000000; - p->retry_time.tv_sec++; - } - p->try_number++; - r = sendpendingrequest(p); - if(r<0) - return r; - } - } - } else { - p->has_pending_request = 0; - } - return n; -} - -#ifdef ENABLE_STRNATPMPERR -LIBSPEC const char * strnatpmperr(int r) -{ - const char * s; - switch(r) { - case NATPMP_ERR_INVALIDARGS: - s = "invalid arguments"; - break; - case NATPMP_ERR_SOCKETERROR: - s = "socket() failed"; - break; - case NATPMP_ERR_CANNOTGETGATEWAY: - s = "cannot get default gateway ip address"; - break; - case NATPMP_ERR_CLOSEERR: -#ifdef WIN32 - s = "closesocket() failed"; -#else - s = "close() failed"; -#endif - break; - case NATPMP_ERR_RECVFROM: - s = "recvfrom() failed"; - break; - case NATPMP_ERR_NOPENDINGREQ: - s = "no pending request"; - break; - case NATPMP_ERR_NOGATEWAYSUPPORT: - s = "the gateway does not support nat-pmp"; - break; - case NATPMP_ERR_CONNECTERR: - s = "connect() failed"; - break; - case NATPMP_ERR_WRONGPACKETSOURCE: - s = "packet not received from the default gateway"; - break; - case NATPMP_ERR_SENDERR: - s = "send() failed"; - break; - case NATPMP_ERR_FCNTLERROR: - s = "fcntl() failed"; - break; - case NATPMP_ERR_GETTIMEOFDAYERR: - s = "gettimeofday() failed"; - break; - case NATPMP_ERR_UNSUPPORTEDVERSION: - s = "unsupported nat-pmp version error from server"; - break; - case NATPMP_ERR_UNSUPPORTEDOPCODE: - s = "unsupported nat-pmp opcode error from server"; - break; - case NATPMP_ERR_UNDEFINEDERROR: - s = "undefined nat-pmp server error"; - break; - case NATPMP_ERR_NOTAUTHORIZED: - s = "not authorized"; - break; - case NATPMP_ERR_NETWORKFAILURE: - s = "network failure"; - break; - case NATPMP_ERR_OUTOFRESOURCES: - s = "nat-pmp server out of resources"; - break; - default: - s = "Unknown libnatpmp error"; - } - return s; -} -#endif - diff --git a/ext/libnatpmp/natpmp.def b/ext/libnatpmp/natpmp.def deleted file mode 100644 index cd110033..00000000 --- a/ext/libnatpmp/natpmp.def +++ /dev/null @@ -1,11 +0,0 @@ -LIBRARY -; libnatpmp library - -EXPORTS - initnatpmp - closenatpmp - sendpublicaddressrequest - sendnewportmappingrequest - getnatpmprequesttimeout - readnatpmpresponseorretry - strnatpmperr diff --git a/ext/libnatpmp/natpmp.h b/ext/libnatpmp/natpmp.h deleted file mode 100644 index 7889d206..00000000 --- a/ext/libnatpmp/natpmp.h +++ /dev/null @@ -1,219 +0,0 @@ -/* $Id: natpmp.h,v 1.20 2014/04/22 09:15:40 nanard Exp $ */ -/* libnatpmp -Copyright (c) 2007-2014, 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. -*/ -#ifndef __NATPMP_H__ -#define __NATPMP_H__ - -/* NAT-PMP Port as defined by the NAT-PMP draft */ -#define NATPMP_PORT (5351) - -#include -#if !defined(_MSC_VER) -#include -#endif /* !defined(_MSC_VER) */ - -#ifdef WIN32 -#include -#if !defined(_MSC_VER) || _MSC_VER >= 1600 -#include -#else /* !defined(_MSC_VER) || _MSC_VER >= 1600 */ -typedef unsigned long uint32_t; -typedef unsigned short uint16_t; -#endif /* !defined(_MSC_VER) || _MSC_VER >= 1600 */ -#define in_addr_t uint32_t -#include "declspec.h" -#else /* WIN32 */ -#define LIBSPEC -#include -#endif /* WIN32 */ - -/* causes problem when installing. Maybe should it be inlined ? */ -/* #include "declspec.h" */ - -typedef struct { - int s; /* socket */ - in_addr_t gateway; /* default gateway (IPv4) */ - int has_pending_request; - unsigned char pending_request[12]; - int pending_request_len; - int try_number; - struct timeval retry_time; -} natpmp_t; - -typedef struct { - uint16_t type; /* NATPMP_RESPTYPE_* */ - uint16_t resultcode; /* NAT-PMP response code */ - uint32_t epoch; /* Seconds since start of epoch */ - union { - struct { - //in_addr_t addr; - struct in_addr addr; - } publicaddress; - struct { - uint16_t privateport; - uint16_t mappedpublicport; - uint32_t lifetime; - } newportmapping; - } pnu; -} natpmpresp_t; - -/* possible values for type field of natpmpresp_t */ -#define NATPMP_RESPTYPE_PUBLICADDRESS (0) -#define NATPMP_RESPTYPE_UDPPORTMAPPING (1) -#define NATPMP_RESPTYPE_TCPPORTMAPPING (2) - -/* Values to pass to sendnewportmappingrequest() */ -#define NATPMP_PROTOCOL_UDP (1) -#define NATPMP_PROTOCOL_TCP (2) - -/* return values */ -/* NATPMP_ERR_INVALIDARGS : invalid arguments passed to the function */ -#define NATPMP_ERR_INVALIDARGS (-1) -/* NATPMP_ERR_SOCKETERROR : socket() failed. check errno for details */ -#define NATPMP_ERR_SOCKETERROR (-2) -/* NATPMP_ERR_CANNOTGETGATEWAY : can't get default gateway IP */ -#define NATPMP_ERR_CANNOTGETGATEWAY (-3) -/* NATPMP_ERR_CLOSEERR : close() failed. check errno for details */ -#define NATPMP_ERR_CLOSEERR (-4) -/* NATPMP_ERR_RECVFROM : recvfrom() failed. check errno for details */ -#define NATPMP_ERR_RECVFROM (-5) -/* NATPMP_ERR_NOPENDINGREQ : readnatpmpresponseorretry() called while - * no NAT-PMP request was pending */ -#define NATPMP_ERR_NOPENDINGREQ (-6) -/* NATPMP_ERR_NOGATEWAYSUPPORT : the gateway does not support NAT-PMP */ -#define NATPMP_ERR_NOGATEWAYSUPPORT (-7) -/* NATPMP_ERR_CONNECTERR : connect() failed. check errno for details */ -#define NATPMP_ERR_CONNECTERR (-8) -/* NATPMP_ERR_WRONGPACKETSOURCE : packet not received from the network gateway */ -#define NATPMP_ERR_WRONGPACKETSOURCE (-9) -/* NATPMP_ERR_SENDERR : send() failed. check errno for details */ -#define NATPMP_ERR_SENDERR (-10) -/* NATPMP_ERR_FCNTLERROR : fcntl() failed. check errno for details */ -#define NATPMP_ERR_FCNTLERROR (-11) -/* NATPMP_ERR_GETTIMEOFDAYERR : gettimeofday() failed. check errno for details */ -#define NATPMP_ERR_GETTIMEOFDAYERR (-12) - -/* */ -#define NATPMP_ERR_UNSUPPORTEDVERSION (-14) -#define NATPMP_ERR_UNSUPPORTEDOPCODE (-15) - -/* Errors from the server : */ -#define NATPMP_ERR_UNDEFINEDERROR (-49) -#define NATPMP_ERR_NOTAUTHORIZED (-51) -#define NATPMP_ERR_NETWORKFAILURE (-52) -#define NATPMP_ERR_OUTOFRESOURCES (-53) - -/* NATPMP_TRYAGAIN : no data available for the moment. try again later */ -#define NATPMP_TRYAGAIN (-100) - -#ifdef __cplusplus -extern "C" { -#endif - -/* initnatpmp() - * initialize a natpmp_t object - * With forcegw=1 the gateway is not detected automaticaly. - * Return values : - * 0 = OK - * NATPMP_ERR_INVALIDARGS - * NATPMP_ERR_SOCKETERROR - * NATPMP_ERR_FCNTLERROR - * NATPMP_ERR_CANNOTGETGATEWAY - * NATPMP_ERR_CONNECTERR */ -LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw); - -/* closenatpmp() - * close resources associated with a natpmp_t object - * Return values : - * 0 = OK - * NATPMP_ERR_INVALIDARGS - * NATPMP_ERR_CLOSEERR */ -LIBSPEC int closenatpmp(natpmp_t * p); - -/* sendpublicaddressrequest() - * send a public address NAT-PMP request to the network gateway - * Return values : - * 2 = OK (size of the request) - * NATPMP_ERR_INVALIDARGS - * NATPMP_ERR_SENDERR */ -LIBSPEC int sendpublicaddressrequest(natpmp_t * p); - -/* sendnewportmappingrequest() - * send a new port mapping NAT-PMP request to the network gateway - * Arguments : - * protocol is either NATPMP_PROTOCOL_TCP or NATPMP_PROTOCOL_UDP, - * lifetime is in seconds. - * To remove a port mapping, set lifetime to zero. - * To remove all port mappings to the host, set lifetime and both ports - * to zero. - * Return values : - * 12 = OK (size of the request) - * NATPMP_ERR_INVALIDARGS - * NATPMP_ERR_SENDERR */ -LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol, - uint16_t privateport, uint16_t publicport, - uint32_t lifetime); - -/* getnatpmprequesttimeout() - * fills the timeval structure with the timeout duration of the - * currently pending NAT-PMP request. - * Return values : - * 0 = OK - * NATPMP_ERR_INVALIDARGS - * NATPMP_ERR_GETTIMEOFDAYERR - * NATPMP_ERR_NOPENDINGREQ */ -LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout); - -/* readnatpmpresponseorretry() - * fills the natpmpresp_t structure if possible - * Return values : - * 0 = OK - * NATPMP_TRYAGAIN - * NATPMP_ERR_INVALIDARGS - * NATPMP_ERR_NOPENDINGREQ - * NATPMP_ERR_NOGATEWAYSUPPORT - * NATPMP_ERR_RECVFROM - * NATPMP_ERR_WRONGPACKETSOURCE - * NATPMP_ERR_UNSUPPORTEDVERSION - * NATPMP_ERR_UNSUPPORTEDOPCODE - * NATPMP_ERR_NOTAUTHORIZED - * NATPMP_ERR_NETWORKFAILURE - * NATPMP_ERR_OUTOFRESOURCES - * NATPMP_ERR_UNSUPPORTEDOPCODE - * NATPMP_ERR_UNDEFINEDERROR */ -LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response); - -#ifdef ENABLE_STRNATPMPERR -LIBSPEC const char * strnatpmperr(int t); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ext/libnatpmp/natpmpc.1 b/ext/libnatpmp/natpmpc.1 deleted file mode 100644 index 5f0003da..00000000 --- a/ext/libnatpmp/natpmpc.1 +++ /dev/null @@ -1,19 +0,0 @@ -.TH natpmpc 1 - -.SH NAME -natpmpc \- NAT\-PMP library test client and mapping setter. - -.SH "SYNOPSIS" -Display the public IP address: -.br -\fBnatpmpc\fP - -Add a port mapping: -.br -\fBnatpmpc\fP \-a [lifetime] - -.SH DESCRIPTION - -In order to remove a mapping, set it with a lifetime of 0 seconds. -To remove all mappings for your machine, use 0 as private port and -lifetime. diff --git a/ext/libnatpmp/natpmpc.c b/ext/libnatpmp/natpmpc.c deleted file mode 100644 index 611bd2d1..00000000 --- a/ext/libnatpmp/natpmpc.c +++ /dev/null @@ -1,244 +0,0 @@ -/* $Id: natpmpc.c,v 1.13 2012/08/21 17:23:38 nanard Exp $ */ -/* libnatpmp -Copyright (c) 2007-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. -*/ -#include -#include -#include -#if defined(_MSC_VER) -#if _MSC_VER >= 1400 -#define strcasecmp _stricmp -#else -#define strcasecmp stricmp -#endif -#else -#include -#endif -#ifdef WIN32 -#include -#else -#include -#include -#endif -#include "natpmp.h" - -void usage(FILE * out, const char * argv0) -{ - fprintf(out, "Usage :\n"); - fprintf(out, " %s [options]\n", argv0); - fprintf(out, "\tdisplay the public IP address.\n"); - fprintf(out, " %s -h\n", argv0); - fprintf(out, "\tdisplay this help screen.\n"); - fprintf(out, " %s [options] -a [lifetime]\n", argv0); - fprintf(out, "\tadd a port mapping.\n"); - fprintf(out, "\nOption available :\n"); - fprintf(out, " -g ipv4address\n"); - fprintf(out, "\tforce the gateway to be used as destination for NAT-PMP commands.\n"); - fprintf(out, "\n In order to remove a mapping, set it with a lifetime of 0 seconds.\n"); - fprintf(out, " To remove all mappings for your machine, use 0 as private port and lifetime.\n"); -} - -/* sample code for using libnatpmp */ -int main(int argc, char * * argv) -{ - natpmp_t natpmp; - natpmpresp_t response; - int r; - int sav_errno; - struct timeval timeout; - fd_set fds; - int i; - int protocol = 0; - uint16_t privateport = 0; - uint16_t publicport = 0; - uint32_t lifetime = 3600; - int command = 0; - int forcegw = 0; - in_addr_t gateway = 0; - struct in_addr gateway_in_use; - -#ifdef WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - - /* argument parsing */ - for(i=1; i i + 1) { - if(1 != sscanf(argv[i+1], "%u", &lifetime)) { - fprintf(stderr, "%s is not a correct 32bits unsigned integer\n", argv[i]); - } else { - i++; - } - } - break; - default: - fprintf(stderr, "Unknown option %s\n", argv[i]); - usage(stderr, argv[0]); - return 1; - } - } else { - fprintf(stderr, "Unknown option %s\n", argv[i]); - usage(stderr, argv[0]); - return 1; - } - } - - /* initnatpmp() */ - r = initnatpmp(&natpmp, forcegw, gateway); - printf("initnatpmp() returned %d (%s)\n", r, r?"FAILED":"SUCCESS"); - if(r<0) - return 1; - - gateway_in_use.s_addr = natpmp.gateway; - printf("using gateway : %s\n", inet_ntoa(gateway_in_use)); - - /* sendpublicaddressrequest() */ - r = sendpublicaddressrequest(&natpmp); - printf("sendpublicaddressrequest returned %d (%s)\n", - r, r==2?"SUCCESS":"FAILED"); - if(r<0) - return 1; - - do { - FD_ZERO(&fds); - FD_SET(natpmp.s, &fds); - getnatpmprequesttimeout(&natpmp, &timeout); - r = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); - if(r<0) { - fprintf(stderr, "select()"); - return 1; - } - r = readnatpmpresponseorretry(&natpmp, &response); - sav_errno = errno; - printf("readnatpmpresponseorretry returned %d (%s)\n", - r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED")); - if(r<0 && r!=NATPMP_TRYAGAIN) { -#ifdef ENABLE_STRNATPMPERR - fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n", - strnatpmperr(r)); -#endif - fprintf(stderr, " errno=%d '%s'\n", - sav_errno, strerror(sav_errno)); - } - } while(r==NATPMP_TRYAGAIN); - if(r<0) - return 1; - - /* TODO : check that response.type == 0 */ - printf("Public IP address : %s\n", inet_ntoa(response.pnu.publicaddress.addr)); - printf("epoch = %u\n", response.epoch); - - if(command == 'a') { - /* sendnewportmappingrequest() */ - r = sendnewportmappingrequest(&natpmp, protocol, - privateport, publicport, - lifetime); - printf("sendnewportmappingrequest returned %d (%s)\n", - r, r==12?"SUCCESS":"FAILED"); - if(r < 0) - return 1; - - do { - FD_ZERO(&fds); - FD_SET(natpmp.s, &fds); - getnatpmprequesttimeout(&natpmp, &timeout); - select(FD_SETSIZE, &fds, NULL, NULL, &timeout); - r = readnatpmpresponseorretry(&natpmp, &response); - printf("readnatpmpresponseorretry returned %d (%s)\n", - r, r==0?"OK":(r==NATPMP_TRYAGAIN?"TRY AGAIN":"FAILED")); - } while(r==NATPMP_TRYAGAIN); - if(r<0) { -#ifdef ENABLE_STRNATPMPERR - fprintf(stderr, "readnatpmpresponseorretry() failed : %s\n", - strnatpmperr(r)); -#endif - return 1; - } - - printf("Mapped public port %hu protocol %s to local port %hu " - "liftime %u\n", - response.pnu.newportmapping.mappedpublicport, - response.type == NATPMP_RESPTYPE_UDPPORTMAPPING ? "UDP" : - (response.type == NATPMP_RESPTYPE_TCPPORTMAPPING ? "TCP" : - "UNKNOWN"), - response.pnu.newportmapping.privateport, - response.pnu.newportmapping.lifetime); - printf("epoch = %u\n", response.epoch); - } - - r = closenatpmp(&natpmp); - printf("closenatpmp() returned %d (%s)\n", r, r==0?"SUCCESS":"FAILED"); - if(r<0) - return 1; - - return 0; -} - diff --git a/ext/libnatpmp/setup.py b/ext/libnatpmp/setup.py deleted file mode 100644 index aa774ee7..00000000 --- a/ext/libnatpmp/setup.py +++ /dev/null @@ -1,18 +0,0 @@ -#! /usr/bin/python -# $Id: setup.py,v 1.3 2012/03/05 04:54:01 nanard Exp $ -# -# python script to build the libnatpmp module under unix -# -# replace libnatpmp.a by libnatpmp.so for shared library usage -from distutils.core import setup, Extension -from distutils import sysconfig -sysconfig.get_config_vars()["OPT"] = '' -sysconfig.get_config_vars()["CFLAGS"] = '' -setup(name="libnatpmp", version="1.0", - ext_modules=[ - Extension(name="libnatpmp", sources=["libnatpmpmodule.c"], - extra_objects=["libnatpmp.a"], - define_macros=[('ENABLE_STRNATPMPERR', None)] - )] - ) - diff --git a/ext/libnatpmp/setupmingw32.py b/ext/libnatpmp/setupmingw32.py deleted file mode 100644 index d02fdfca..00000000 --- a/ext/libnatpmp/setupmingw32.py +++ /dev/null @@ -1,17 +0,0 @@ -#! /usr/bin/python -# $Id: setupmingw32.py,v 1.3 2012/03/05 04:54:01 nanard Exp $ -# python script to build the miniupnpc module under windows -# -from distutils.core import setup, Extension -from distutils import sysconfig -sysconfig.get_config_vars()["OPT"] = '' -sysconfig.get_config_vars()["CFLAGS"] = '' -setup(name="libnatpmp", version="1.0", - ext_modules=[ - Extension(name="libnatpmp", sources=["libnatpmpmodule.c"], - libraries=["ws2_32"], - extra_objects=["libnatpmp.a"], - define_macros=[('ENABLE_STRNATPMPERR', None)] - )] - ) - diff --git a/ext/libnatpmp/testgetgateway.c b/ext/libnatpmp/testgetgateway.c deleted file mode 100644 index 24cbe7d0..00000000 --- a/ext/libnatpmp/testgetgateway.c +++ /dev/null @@ -1,57 +0,0 @@ -/* $Id: testgetgateway.c,v 1.7 2012/08/21 17:13:31 nanard Exp $ */ -/* libnatpmp -Copyright (c) 2007-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. -*/ -#include -#ifdef WIN32 -#include -#else -#include -#include -#endif -#include "getgateway.h" - -int main(int argc, char * * argv) -{ - (void)argc; - (void)argv; - struct in_addr gatewayaddr; - int r; -#ifdef WIN32 - uint32_t temp = 0; - r = getdefaultgateway(&temp); - gatewayaddr.S_un.S_addr = temp; -#else - r = getdefaultgateway(&(gatewayaddr.s_addr)); -#endif - if(r>=0) - printf("default gateway : %s\n", inet_ntoa(gatewayaddr)); - else - fprintf(stderr, "getdefaultgateway() failed\n"); - return 0; -} - diff --git a/ext/libnatpmp/wingettimeofday.c b/ext/libnatpmp/wingettimeofday.c deleted file mode 100644 index cb730e17..00000000 --- a/ext/libnatpmp/wingettimeofday.c +++ /dev/null @@ -1,60 +0,0 @@ -/* $Id: wingettimeofday.c,v 1.6 2013/09/10 20:13:26 nanard Exp $ */ -/* libnatpmp -Copyright (c) 2007-2013, 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. -*/ -#ifdef WIN32 -#if defined(_MSC_VER) -struct timeval { - long tv_sec; - long tv_usec; -}; -#else -#include -#endif - -typedef struct _FILETIME { - unsigned long dwLowDateTime; - unsigned long dwHighDateTime; -} FILETIME; - -void __stdcall GetSystemTimeAsFileTime(FILETIME*); - -int natpmp_gettimeofday(struct timeval* p, void* tz /* IGNORED */) { - union { - long long ns100; /*time since 1 Jan 1601 in 100ns units */ - FILETIME ft; - } _now; - - if(!p) - return -1; - GetSystemTimeAsFileTime( &(_now.ft) ); - p->tv_usec =(long)((_now.ns100 / 10LL) % 1000000LL ); - p->tv_sec = (long)((_now.ns100-(116444736000000000LL))/10000000LL); - return 0; -} -#endif - diff --git a/ext/libnatpmp/wingettimeofday.h b/ext/libnatpmp/wingettimeofday.h deleted file mode 100644 index 1d18d9fa..00000000 --- a/ext/libnatpmp/wingettimeofday.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $Id: wingettimeofday.h,v 1.5 2013/09/11 07:22:25 nanard Exp $ */ -/* libnatpmp -Copyright (c) 2007-2013, 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. -*/ -#ifndef __WINGETTIMEOFDAY_H__ -#define __WINGETTIMEOFDAY_H__ -#ifdef WIN32 -#if defined(_MSC_VER) -#include -#else -#include -#endif -int natpmp_gettimeofday(struct timeval* p, void* tz /* IGNORED */); -#endif -#endif diff --git a/ext/librabbitmq/.clang-format b/ext/librabbitmq/.clang-format new file mode 100644 index 00000000..8aa6b1a8 --- /dev/null +++ b/ext/librabbitmq/.clang-format @@ -0,0 +1,47 @@ +--- +# BasedOnStyle: Google +AccessModifierOffset: -1 +ConstructorInitializerIndentWidth: 4 +AlignEscapedNewlinesLeft: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakTemplateDeclarations: true +AlwaysBreakBeforeMultilineStrings: true +BreakBeforeBinaryOperators: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BinPackParameters: true +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +DerivePointerBinding: true +ExperimentalAutoDetectBinPacking: false +IndentCaseLabels: true +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 60 +PenaltyBreakString: 1000 +PenaltyBreakFirstLessLess: 120 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerBindsToType: true +SpacesBeforeTrailingComments: 2 +Cpp11BracedListStyle: true +Standard: Auto +IndentWidth: 2 +TabWidth: 8 +UseTab: Never +BreakBeforeBraces: Attach +IndentFunctionDeclarationAfterType: true +SpacesInParentheses: false +SpacesInAngles: false +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpaceAfterControlStatementKeyword: true +SpaceBeforeAssignmentOperators: true +ContinuationIndentWidth: 4 +... + diff --git a/ext/librabbitmq/.gitattributes b/ext/librabbitmq/.gitattributes new file mode 100644 index 00000000..a465161d --- /dev/null +++ b/ext/librabbitmq/.gitattributes @@ -0,0 +1,18 @@ +# Default for those who don't have core.autocrlf set +* text=auto + +# Things that should be treated like text (lines converted on checkout): +*.c text +*.h text +*.py text +*.cmake text +*.md text +# This is for the output of table_test +*.expected text +*.xml + +# Exceptions to the rule: +*.ac text eol=lf +*.am text eol=lf +*.m4 text eol=lf + diff --git a/ext/librabbitmq/.gitignore b/ext/librabbitmq/.gitignore new file mode 100644 index 00000000..1791e280 --- /dev/null +++ b/ext/librabbitmq/.gitignore @@ -0,0 +1,73 @@ +*.la +*.lo +*.o +.deps +.dirstamp +.libs +/aclocal.m4 +/autom4te.cache +/bin* +/build +/compile +/config.guess +/config.h +/config.h.in +/config.h.in~ +/config.log +/config.status +/config.sub +/configure +/cscope.* +/depcomp +/install-sh +/libtool +/ltmain.sh +/missing +/stamp-h1 +/test-suite.log +INSTALL +Makefile +Makefile.in +examples/amqp_bind +examples/amqp_connect_timeout +examples/amqp_consumer +examples/amqp_exchange_declare +examples/amqp_listen +examples/amqp_listenq +examples/amqp_producer +examples/amqp_rpc_sendstring_client +examples/amqp_sendstring +examples/amqp_unbind +examples/amqps_bind +examples/amqps_connect_timeout +examples/amqps_consumer +examples/amqps_exchange_declare +examples/amqps_listen +examples/amqps_listenq +examples/amqps_producer +examples/amqps_sendstring +examples/amqps_unbind +librabbitmq.pc +test-driver +tests/*.log +tests/*.trs +tests/test_hostcheck +tests/test_parse_url +tests/test_status_enum +tests/test_tables +tools/amqp-consume +tools/amqp-declare-queue +tools/amqp-delete-queue +tools/amqp-get +tools/amqp-publish +tools/doc/*.1 +tools/doc/*.7 +tools/doc/man-date.ent +.ycm_extra_conf.py? +.DS_Store + +# Ignore editor swap files +*~ +*.sw? +.#* +\#*# diff --git a/ext/librabbitmq/.gitmodules b/ext/librabbitmq/.gitmodules new file mode 100644 index 00000000..b7f37f73 --- /dev/null +++ b/ext/librabbitmq/.gitmodules @@ -0,0 +1,6 @@ +[submodule "codegen"] + path = codegen + url = https://github.com/rabbitmq/rabbitmq-codegen.git +[submodule "travis/run-clang-format"] + path = travis/run-clang-format + url = https://github.com/Sarcasm/run-clang-format.git diff --git a/ext/librabbitmq/.travis.yml b/ext/librabbitmq/.travis.yml new file mode 100644 index 00000000..5d26e0f2 --- /dev/null +++ b/ext/librabbitmq/.travis.yml @@ -0,0 +1,92 @@ +# Travis-CI Build for rabbitmq-c +# see travis-ci.org for details + +language: c + +dist: trusty +# Currently libpopt-dev is not on the list of whitelisted apt-packages. +sudo: true + +env: + global: + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "gDwqo3jHj+HHGzFKnxL/nwZhbVeh2pItw0TbeaHcLtWubUZaf85ViEQRaXPyfnbG7l0OEQq+PjyhKAfvViVq2NP0lGeeu4VM5uMZJhsCLN594BJr39Y4XzOapg0O8mEMhQ0DU2u1Zo4LMgEcRz67aosVQOj6QV30tOzp9fnxn9U=" + +services: + - rabbitmq + +matrix: + include: + # Note that the first compiler in the matrix must be gcc, so that the + # coverity_scan branch hack below works correctly. + - compiler: gcc + os: linux + env: CONFIG=cmake + - compiler: gcc + os: linux + env: CONFIG=format + - compiler: gcc + os: linux + env: CONFIG=coverage + - compiler: clang + os: linux + env: CONFIG=cmake + - compiler: clang + os: linux + env: CONFIG=asan + - compiler: clang + os: linux + env: CONFIG=tsan + - compiler: clang + os: linux + env: CONFIG=scan-build + - compiler: clang + os: osx + env: CONFIG=cmake + - compiler: gcc + os: linux + env: NAME="openssl-1.1.0" CONFIG=cmake + addons: + apt: + sources: + - sourceline: 'ppa:ondrej/nginx-mainline' + packages: + - libssl1.1 + - openssl + - libssl-dev + + allow_failures: + - compiler: clang + os: linux + env: CONFIG=tsan + +before_install: + - | + if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then + wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo apt-add-repository "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.9 main" + sudo apt-get -q update; + sudo apt-get install -y clang-3.9 clang-format-3.9 libpopt-dev; + fi + # ugly hack; if running a coverity scan abort all except the 1st build + # see note re gcc compiler above needing to be 1st + # also note that branch_pattern & the TRAVIS_BRANCH check must match + # unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the + # build process + - if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi + + +script: + # Don't bother building if this is being done in the coverity_scan branch. + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./travis.sh $CONFIG ; fi + +addons: + coverity_scan: + project: + name: "alanxz/rabbitmq-c" + description: "C AMQP client for RabbitMQ" + notification_email: alan.antonuk@gmail.com + build_command_prepend: mkdir build && pushd build && cmake .. && popd + build_command: cmake --build ./build + branch_pattern: coverity_scan diff --git a/ext/librabbitmq/.ycm_extra_conf.py b/ext/librabbitmq/.ycm_extra_conf.py new file mode 100644 index 00000000..d9ef11c6 --- /dev/null +++ b/ext/librabbitmq/.ycm_extra_conf.py @@ -0,0 +1,157 @@ +# This file is NOT licensed under the GPLv3, which is the license for the rest +# of YouCompleteMe. +# +# Here's the license text for this file: +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# For more information, please refer to + +import os +import ycm_core + +# These are the compilation flags that will be used in case there's no +# compilation database set (by default, one is not set). +# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. +flags = [ +'-Wall', +'-Wextra', +# THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which +# language to use when compiling headers. So it will guess. Badly. So C++ +# headers will be compiled as C headers. You don't want that so ALWAYS specify +# a "-std=". +# For a C project, you would set this to something like 'c99' instead of +# 'c++11'. +'-std=gnu90', +# ...and the same thing goes for the magic -x option which specifies the +# language that the files to be compiled are written in. This is mostly +# relevant for c++ headers. +# For a C project, you would set this to 'c' instead of 'c++'. +'-x', +'c', +'-I', './librabbitmq', +'-I', './librabbitmq/unix', +'-D', 'HAVE_POLL', +] + + +# Set this to the absolute path to the folder (NOT the file!) containing the +# compile_commands.json file to use that instead of 'flags'. See here for +# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html +# +# You can get CMake to generate this file for you by adding: +# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 ) +# to your CMakeLists.txt file. +# +# Most projects will NOT need to set this to anything; you can just change the +# 'flags' list of compilation flags. Notice that YCM itself uses that approach. +compilation_database_folder = '' + +if os.path.exists( compilation_database_folder ): + database = ycm_core.CompilationDatabase( compilation_database_folder ) +else: + database = None + +SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] + +def DirectoryOfThisScript(): + return os.path.dirname( os.path.abspath( __file__ ) ) + + +def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): + if not working_directory: + return list( flags ) + new_flags = [] + make_next_absolute = False + path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] + for flag in flags: + new_flag = flag + + if make_next_absolute: + make_next_absolute = False + if not flag.startswith( '/' ): + new_flag = os.path.join( working_directory, flag ) + + for path_flag in path_flags: + if flag == path_flag: + make_next_absolute = True + break + + if flag.startswith( path_flag ): + path = flag[ len( path_flag ): ] + new_flag = path_flag + os.path.join( working_directory, path ) + break + + if new_flag: + new_flags.append( new_flag ) + return new_flags + + +def IsHeaderFile( filename ): + extension = os.path.splitext( filename )[ 1 ] + return extension in [ '.h', '.hxx', '.hpp', '.hh' ] + + +def GetCompilationInfoForFile( filename ): + # The compilation_commands.json file generated by CMake does not have entries + # for header files. So we do our best by asking the db for flags for a + # corresponding source file, if any. If one exists, the flags for that file + # should be good enough. + if IsHeaderFile( filename ): + basename = os.path.splitext( filename )[ 0 ] + for extension in SOURCE_EXTENSIONS: + replacement_file = basename + extension + if os.path.exists( replacement_file ): + compilation_info = database.GetCompilationInfoForFile( + replacement_file ) + if compilation_info.compiler_flags_: + return compilation_info + return None + return database.GetCompilationInfoForFile( filename ) + + +def FlagsForFile( filename, **kwargs ): + if database: + # Bear in mind that compilation_info.compiler_flags_ does NOT return a + # python list, but a "list-like" StringVec object + compilation_info = GetCompilationInfoForFile( filename ) + if not compilation_info: + relative_to = DirectoryOfThisScript() + return { + 'flags': MakeRelativePathsInFlagsAbsolute( flags, relative_to ), + 'do_cache': True + } + + final_flags = MakeRelativePathsInFlagsAbsolute( + compilation_info.compiler_flags_, + compilation_info.compiler_working_dir_ ) + + else: + relative_to = DirectoryOfThisScript() + final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) + + return { + 'flags': final_flags, + 'do_cache': True + } diff --git a/ext/librabbitmq/AUTHORS b/ext/librabbitmq/AUTHORS new file mode 100644 index 00000000..bd0070cf --- /dev/null +++ b/ext/librabbitmq/AUTHORS @@ -0,0 +1,2 @@ +Tony Garnock-Jones +The RabbitMQ team diff --git a/ext/librabbitmq/CMakeLists.txt b/ext/librabbitmq/CMakeLists.txt new file mode 100644 index 00000000..b5a93114 --- /dev/null +++ b/ext/librabbitmq/CMakeLists.txt @@ -0,0 +1,343 @@ +cmake_minimum_required(VERSION 2.8.12) +project(rabbitmq-c "C") + +# Enable MACOSX_RPATH by default. See: cmake --help-policy CMP0042 +if (POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) +endif() + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +# Follow all steps below in order to calculate new ABI version when updating the library +# NOTE: THIS IS UNRELATED to the actual project version +# +# 1. If the library source code has changed at all since the last update, then increment revision +# 2. If any interfaces have been added, removed, or changed since the last update, increment current and set revision to 0. +# 3. If any interfaces have been added since the last public release, then increment age. +# 4. If any interfaces have been removed since the last public release, then set age to 0. + +set(RMQ_SOVERSION_CURRENT 7) +set(RMQ_SOVERSION_REVISION 0) +set(RMQ_SOVERSION_AGE 3) + +math(EXPR RMQ_SOVERSION_MAJOR "${RMQ_SOVERSION_CURRENT} - ${RMQ_SOVERSION_AGE}") +math(EXPR RMQ_SOVERSION_MINOR "${RMQ_SOVERSION_AGE}") +math(EXPR RMQ_SOVERSION_PATCH "${RMQ_SOVERSION_REVISION}") + +set(RMQ_VERSION ${RMQ_SOVERSION_MAJOR}.${RMQ_SOVERSION_MINOR}.${RMQ_SOVERSION_PATCH}) +set(RMQ_SOVERSION ${RMQ_SOVERSION_MAJOR}) + +file(STRINGS librabbitmq/amqp.h _API_VERSION_MAJOR REGEX "^#define AMQP_VERSION_MAJOR [0-9]+$") +file(STRINGS librabbitmq/amqp.h _API_VERSION_MINOR REGEX "^#define AMQP_VERSION_MINOR [0-9]+$") +file(STRINGS librabbitmq/amqp.h _API_VERSION_PATCH REGEX "^#define AMQP_VERSION_PATCH [0-9]+$") + +string(REGEX MATCH "[0-9]+" _API_VERSION_MAJOR ${_API_VERSION_MAJOR}) +string(REGEX MATCH "[0-9]+" _API_VERSION_MINOR ${_API_VERSION_MINOR}) +string(REGEX MATCH "[0-9]+" _API_VERSION_PATCH ${_API_VERSION_PATCH}) + +# VERSION to match what is in autotools +set(VERSION ${_API_VERSION_MAJOR}.${_API_VERSION_MINOR}.${_API_VERSION_PATCH}) + +if (CMAKE_GENERATOR MATCHES ".*(Make|Ninja).*" + AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) + message(STATUS "CMAKE_BUILD_TYPE not specified. Creating ${CMAKE_BUILD_TYPE} build") +endif() + +include(TestCInline) +include(CheckSymbolExists) +include(CheckLibraryExists) +include(CMakePushCheckState) +include(GNUInstallDirs) +include(CheckCCompilerFlag) + +# Detect if we need to link against a socket library: +cmake_push_check_state() +if (WIN32) + # Always use WinSock2 on Windows + set(SOCKET_LIBRARIES ws2_32) +else () + # Is it in the default link? + check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO) + if (NOT (HAVE_GETADDRINFO EQUAL 1)) + SET(CMAKE_REQUIRED_LIBRARIES "socket") + check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO2) + if (HAVE_GETADDRINFO2 EQUAL 1) + set(SOCKET_LIBRARIES socket) + else () + SET(CMAKE_REQUIRED_LIBRARIES "socket;nsl") + check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO3) + if (HAVE_GETADDRINFO3 EQUAL 1) + set(SOCKET_LIBRARIES socket nsl) + else () + message(FATAL_ERROR "Cannot find name resolution library (containing symbol getaddrinfo)") + endif () + endif () + endif () + + set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES}) + check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET) + if (NOT HAVE_SOCKET EQUAL 1) + set(CMAKE_REQUIRED_LIBRARIES socket ${SOCKET_LIBRARIES}) + check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET2) + if (HAVE_SOCKET2 EQUAL 1) + set(SOCKET_LIBRARIES socket ${SOCKET_LIBRARIES}) + else () + set(CMAKE_REQUIRED_LIBRARIES socket nsl ${SOCKET_LIBRARIES}) + check_symbol_exists(socket "sys/types.h;sys/socket.h" HAVE_SOCKET3) + if (HAVE_SOCKET3 EQUAL 1) + set(SOCKET_LIBRARIES socket nsl ${SOCKET_LIBRARIES}) + else () + message(FATAL_ERROR "Cannot find socket library (containing symbol socket)") + endif () + endif () + endif () +endif () +cmake_pop_check_state() + +cmake_push_check_state() +set(CMAKE_REQUIRED_LIBRARIES ${SOCKET_LIBRARIES}) +check_symbol_exists(poll poll.h HAVE_POLL) +if (NOT HAVE_POLL) + if (WIN32) + set(HAVE_SELECT 1) + else() + check_symbol_exists(select sys/select.h HAVE_SELECT) + endif() + if (NOT HAVE_SELECT) + message(FATAL_ERROR "rabbitmq-c requires poll() or select() to be available") + endif() +endif() +cmake_pop_check_state() + +check_library_exists(rt clock_gettime "time.h" CLOCK_GETTIME_NEEDS_LIBRT) +check_library_exists(rt posix_spawnp "spawn.h" POSIX_SPAWNP_NEEDS_LIBRT) +if (CLOCK_GETTIME_NEEDS_LIBRT OR POSIX_SPAWNP_NEEDS_LIBRT) + set(LIBRT rt) +endif() + +option(ENABLE_SSL_SUPPORT "Enable SSL support" ON) + +if (ENABLE_SSL_SUPPORT) + find_package(OpenSSL 0.9.8 REQUIRED) + + cmake_push_check_state() + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads REQUIRED) + cmake_pop_check_state() +endif() + +if (MSVC) + set(CMAKE_C_FLAGS "/W4 /nologo ${CMAKE_C_FLAGS}") +elseif (CMAKE_C_COMPILER_ID MATCHES ".*Clang") + set(CMAKE_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common -fvisibility=hidden ${CMAKE_C_FLAGS}") +elseif (CMAKE_COMPILER_IS_GNUCC) + set(RMQ_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wno-unused-function -fno-common") + execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + if (GCC_VERSION VERSION_GREATER 4.0 OR GCC_VERSION VERSION_EQUAL 4.0) + set(RMQ_C_FLAGS "${RMQ_C_FLAGS} -fvisibility=hidden") + endif() + set(CMAKE_C_FLAGS "${RMQ_C_FLAGS} ${CMAKE_C_FLAGS}") +endif () + +CHECK_C_COMPILER_FLAG("-std=gnu90" HAVE_GNU90) +if (HAVE_GNU90) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu90") +else() + CHECK_C_COMPILER_FLAG("-std=c90" HAVE_C90) + if (HAVE_C90) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c90") + endif() +endif() + +option(REGENERATE_AMQP_FRAMING "Regenerate amqp_framing.h/amqp_framing.c sources (for developer use)" OFF) +mark_as_advanced(REGENERATE_AMQP_FRAMING) + +if (REGENERATE_AMQP_FRAMING) + find_package(PythonInterp) + if (NOT PYTHONINTERP_FOUND) + message(FATAL_ERROR "REGENERATE_AMQP_FRAMING requires Python to be available") + endif () + + #Determine Python Version: + if(PYTHON_EXECUTABLE) + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c + "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))" + OUTPUT_VARIABLE _VERSION + RESULT_VARIABLE _PYTHON_VERSION_RESULT + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}") + list(GET _VERSION 0 PYTHON_VERSION_MAJOR) + list(GET _VERSION 1 PYTHON_VERSION_MINOR) + list(GET _VERSION 2 PYTHON_VERSION_PATCH) + if(PYTHON_VERSION_PATCH EQUAL 0) + # it's called "Python 2.7", not "2.7.0" + string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}") + endif() + else() + # sys.version predates sys.version_info, so use that + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.version)" + OUTPUT_VARIABLE _VERSION + RESULT_VARIABLE _PYTHON_VERSION_RESULT + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}") + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}") + if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}") + else() + set(PYTHON_VERSION_PATCH "0") + endif() + else() + # sys.version was first documented for Python 1.5, so assume + # this is older. + set(PYTHON_VERSION_STRING "1.4") + set(PYTHON_VERSION_MAJOR "1") + set(PYTHON_VERSION_MAJOR "4") + set(PYTHON_VERSION_MAJOR "0") + endif() + endif() + unset(_PYTHON_VERSION_RESULT) + unset(_VERSION) + endif(PYTHON_EXECUTABLE) + + # If we're running v3.x look for a 2to3 utility + if (PYTHON_VERSION_MAJOR GREATER 2) + get_filename_component(PYTHON_EXE_DIR ${PYTHON_EXECUTABLE} PATH) + find_program(PYTHON_2TO3_EXECUTABLE + NAMES 2to3 + HINTS ${PYTHON_EXE_DIR} + ) + + if ("PYTHON_2TO3_EXECUTABLE-NOTFOUND" STREQUAL PYTHON_2TO3_EXECUTABLE) + message(FATAL_ERROR "Unable to find 2to3 python utility, specify python 2.7 or specify 2to3 utility") + endif () + endif (PYTHON_VERSION_MAJOR GREATER 2) + + + #check for json or simplejson + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import json" + RESULT_VARIABLE CHECK_PYTHON_JSON_FAILED + ) + + if (CHECK_PYTHON_JSON_FAILED) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import simplejson" + RESULT_VARIABLE CHECK_PYTHON_SIMPLEJSON_FAILED + ) + + if (CHECK_PYTHON_SIMPLEJSON_FAILED) + message(FATAL_ERROR "REGENERATE_AMQP_FRAMING requires a python with json or simplejson modules") + endif (CHECK_PYTHON_SIMPLEJSON_FAILED) + endif (CHECK_PYTHON_JSON_FAILED) + + + find_path(AMQP_CODEGEN_DIR + amqp_codegen.py + PATHS ${CMAKE_CURRENT_SOURCE_DIR}/codegen + ${CMAKE_CURRENT_SOURCE_DIR}/rabbitmq-codegen + ${CMAKE_CURRENT_SOURCE_DIR}/../rabbitmq-codegen + DOC "Path to directory containing amqp_codegen.py (rabbitmq-codegen)" + NO_DEFAULT_PATH + ) + + if (AMQP_CODEGEN_DIR STREQUAL "AMQP_CODEGEN_DIR-NOTFOUND") + message(SEND_ERROR "REGENERATE_AMQP_FRAMING requires the amqp_codegen.py script. If this is a git clone you can:\n\ngit submodule init\ngit submodule update\n\n Or set AMQP_CODEGEN_DIR to directory containing amqp_codegen.py") + else () + message(STATUS "Found amqp_codegen.py in ${AMQP_CODEGEN_DIR}") + endif() +endif (REGENERATE_AMQP_FRAMING) + +find_package(POPT) +find_package(XmlTo) +find_package(Doxygen) + +if (POPT_FOUND AND XmlTo_FOUND) + set(DO_DOCS ON) +endif() + + +option(BUILD_SHARED_LIBS "Build rabbitmq-c as a shared library" ON) +option(BUILD_STATIC_LIBS "Build rabbitmq-c as a static library" ON) + +option(BUILD_EXAMPLES "Build Examples" ON) +option(BUILD_TOOLS "Build Tools (requires POPT Library)" ${POPT_FOUND}) +option(BUILD_TOOLS_DOCS "Build man pages for Tools (requires xmlto)" ${DO_DOCS}) +option(BUILD_TESTS "Build tests (run tests with make test)" ON) +option(BUILD_API_DOCS "Build Doxygen API docs" ${DOXYGEN_FOUND}) + +if (NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS) + message(FATAL_ERROR "One or both of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON to build") +endif() + +add_subdirectory(librabbitmq) + +if (BUILD_EXAMPLES) + add_subdirectory(examples) +endif () + +if (BUILD_TOOLS) + if (POPT_FOUND) + add_subdirectory(tools) + else () + message(WARNING "POpt library was not found. Tools will not be built") + endif () +endif () + +if (BUILD_TESTS) + if (NOT BUILD_STATIC_LIBS) + message(FATAL_ERROR + "Tests can only be built against static libraries " + "(set BUILD_STATIC_LIBS=ON)") + endif () + enable_testing() + add_subdirectory(tests) +endif (BUILD_TESTS) + +if (BUILD_API_DOCS) + if (NOT DOXYGEN_FOUND) + message(FATAL_ERROR "Doxygen is required to build the API documentation") + endif () + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile @ONLY) + + add_custom_target(docs + COMMAND ${DOXYGEN_EXECUTABLE} + VERBATIM + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs + DEPENDS rabbitmq + COMMENT "Generating API documentation" + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in + ) +endif () + +set(libs_private ${SOCKET_LIBRARIES} ${LIBRT}) +if (ENABLE_SSL_SUPPORT) + set(requires_private "openssl") + set(libs_private ${libs_private} ${CMAKE_THREAD_LIBS_INIT}) +endif() + +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix "\${prefix}") +set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") +set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") + +configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq/config.h) +configure_file(librabbitmq.pc.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc @ONLY) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) + +if (BUILD_SHARED_LIBS) + message(STATUS "Building rabbitmq as a shared library - yes") +else () + message(STATUS "Building rabbitmq as a shared library - no") +endif () + +if (BUILD_STATIC_LIBS) + message(STATUS "Building rabbitmq as a static library - yes") +else () + message(STATUS "Building rabbitmq as a static library - no") +endif () diff --git a/ext/librabbitmq/CONTRIBUTING.md b/ext/librabbitmq/CONTRIBUTING.md new file mode 100644 index 00000000..20c2e4d7 --- /dev/null +++ b/ext/librabbitmq/CONTRIBUTING.md @@ -0,0 +1,26 @@ +Contributing to rabbitmq-c +========================== + +Thanks for contributing to rabbitmq-c. I firmly believe that participation helps +make open source software great. With that there are a few things that can be +done to make our interaction a bit smoother. + +Please use the following guidelines when creating an issue or submitting a +pull request + +Creating an issue +----------------- +When submitting an issue its helpful to know the following + - What version of rabbitmq-c are you using? + - What operating system and version are you running on? + - What compiler and version are you running? + - + - If its a build system issue: which build system are you using ( + + +Submitting a pull-request +------------------------- +I love to get code contributions, a few things that can help out: + - Make sure your commits are rebased on the current master branch + - Please collapse your commits down to a couple logical commits + diff --git a/ext/librabbitmq/ChangeLog.md b/ext/librabbitmq/ChangeLog.md new file mode 100644 index 00000000..f9d7e400 --- /dev/null +++ b/ext/librabbitmq/ChangeLog.md @@ -0,0 +1,221 @@ +# Change Log +## v0.9.0 - 2018-05-08 +### Added: +- amqp-publish: added support for specifying headers via the -H flag +- Add support for specifying timeout for amqp_login calls via + amqp_set_handshake_timeout +- Add support for specifying timeouts in RPC-style AMQP methods via + amqp_set_rpc_timeout +- Add define for `AMQP_DEFAULT_VHOST` +- Support for SSL SNI +- Support for OpenSSL v1.1.0 + +### Changed: +- rabbitmq-c now requires Windows Vista or better +- rabbitmq-c enables TCP keep-alive by default on platforms that support it +- dropped support for compiling rabbitmq-c without threading support +- OpenSSL is no longer un-intialized automatically by default. OpenSSL can be + explicitly initialized by calling amqp_initialize_ssl_library and + uninitialized by calling amqp_uninitialize_ssl_library. + +### Fixed: +- Correct bugs in processing of --url flag in tools (#364). +- Improve documentation on AMQP_SASL_METHOD_EXTERNAL (#349) +- Improve support for compiling under mingw-w64 +- Better support for handing SIGPIPE on Linux over SSL (#401) +- Improve publish performance on Linux by not specifying MSG_MORE on last part + of message. +- Fix connection logic where multiple hostnames won't be tried if connection to + doesn't fail immediately (#430) + +### Removed: +- autotools build system has been removed +- many duplicate amqps_* examples, they did not add a lot of value + + +## v0.8.0 - 2016-04-09 +### Added: +- SSL: peer certificate and hostname validation can now be controlled separately + using `amqp_ssl_socket_set_verify_peer` and + `amqp_ssl_socket_set_verify_hostname`. +- SSL: the desire SSL version range can now be specified using the + `amqp_ssl_socket_set_ssl_versions` function. +- Add flags to SSL examples on controlling hostname verification. + +### Changed: +- SSL: SSLv2, and SSLv3 have been disabled by default. +- SSL: OpenSSL hostname validation has been improved. +- Win32 debug information is built with /Z7 on MSVC to embed debug info instead + of using a .pdb + +### Fixed: +- Connection failure results in hang on Win32 (#297, #346) +- Rabbitmq-c may block when attempting to close an SSL socket (#313) +- amqp_parse_url does not correctly initialize default parameters (#319) +- x509 objects are leaked in verify_hostname (#323) +- TCP_NOPUSH doesn't work under cygwin (#335) + +### Deprecated +- SSL: `amqp_ssl_socket_set_verify` is being replaced by + `amqp_ssl_socket_set_verify_peer` and `amqp_ssl_socket_set_verify_hostname`. + +### Removed: +- OpenVMS build system and related files. +- Unmaintained PolarSSL, CyaSSL, and gnuTLS SSL backends + +## Changes since v0.7.0 (a.k.a., v0.7.1) +- `41fa9df` Autoconf: add missing files in build system +- `ef73c06` Win32: Use WSAEWOULDBLOCK instead of EWOULDBLOCK on Win32 +- `ceca348` CI: use travis-ci container based builds +- `393e2df` Lib: if channel_max is 0 use server's channel_max +- `ff47574` Lib: fix build on OpenBSD +- `8429496...0ac6430` CI: enable CI on Mac OS X in travis-ci + +## Changes since v0.6.0 (a.k.a., v0.7.0) +- `3379812` Tools: Add support for heartbeats +- `d7029db` CI: Add continuous integration on Win32 using Appveyor +- `a5f7ffb` Tests: only link against static libraries +- `a16ad45...9cf7a3b` Lib: add support for EXTERNAL SASL method +- `038a9ed` Lib: fix incorrect parameters to WSAPoll on Win32 +- `a240c69...14ae307` Lib: use non-blocking sockets internally +- `8d1d5cc`, `5498dc6` Lib: simplify timer/timeout logic +- `61fc4e1` Lib: add support for heartbeat checks in blocking send calls +- `f462c0f...3546a70` Lib: Fix warnings on Win32 +- `ba9d8ba...112a54d` Lib: Add support for RabbitMQ auth failure extension +- `fb8e318` Lib: allow calling functions to override client-properties +- `3ef3f5f` examples: replace usleep() with nanosleep() +- `9027a94` Lib: add AMQP_VERSION code +- `9ee1718` Lib: fix res maybe returned uninitialized in amqp_merge_capbilities +- `22a36db` Lib: Fix SSL_connection status check +- `abbefd4` Lib: Fix issues with c89 compatiblity +- `2bc1f9b...816cbfc` Lib: perf improvements when sending small messages by + hinting to the OS message boundaries. +- `be2e6dd...784a0e9` Lib: add select()-based timeout implementation +- `91db548...8d77b4c` CI: add ubsan, asan, and tsan CI builds + +## Changes since v0.5.2 (a.k.a., v0.6.0) +- `e1746f9` Tools: Enable support for SSL in tools. +- `9626dd5` Lib: ABI CHANGE: enable support for auto_delete, internal flags to + amqp_exchange_declare +- `ee54e27`, `656f833` Lib: check for double-close in SSL/TCP socket impl +- `cf2760d` Lib: allocate struct when method has no field. +- `513ad4a` Lib: add support for SANs in OpenSSL socket impl. +- `5348c69` Lib: add functions to get negotiated frame_max and heartbeat parms. + +## Changes since v0.5.1 (a.k.a., v0.5.2) +- `fcdf0f8` Autoconf: check for htonll as declaration in a header file +- `5790ec7` SSL: correctly report hostname verification errors. +- `d60c28c` Build: disable OpenSSL deprecation warnings on OSX +- `072191a` Lib: include platform, version and copyright in AMQP handshake +- `8b448c6` Examples: print message body in amqp[s]_listen[q] examples +- `7188e5d` Tools: Add flag to set prefetch for amqp-consume tool + +## Changes since v0.5.0 (a.k.a., v0.5.1) +### Enhancements: +- `a566929` SSL: Add support for wildcards in hostname verification (Mike + Steinert) +- `a78aa8a` Lib: Use poll(2) instead of select(2) for timeouts on sockets. +- `357bdb3` Lib: support for specifying frame and decoding pool sizes. (Mike + Stitt) +- `8956003` Lib: improve invalid frame detection code. + +### Bug fixes: +- `b852f84` Lib: Add missing amqp_get_server_properties() function. +- `7001e82` Lib: Add missing ssize_t on Win32 (emazv72) +- `c2ce2cb` Lib: Correctly specify WINVER on Win32 when unspecified. +- `fe844e4` CMake: specify -DHAVE_CONFIG_H in examples. +- `932de5f` Lib: correct time computation on Win32 (jestor) +- `3e83192` HPUX: use gethrtime on HP-UX for timers. +- `cb1b44e` HPUX: correct include location of sys/uio.h +- `8ce585d` Lib: incorrect OOM condition when 0-lenth exchange name is received. +- `c7716b8` CMake: correct htonll detection code on platforms defined with a + macro. +- `4dc4eda` Lib: remove unused assignment. +- `45302cf` Lib: remove range-check of channel-ids. + + +## Changes since v0.4.1 (a.k.a., v0.5.0): +### Major changes: +- Add amqp_get_broker_properties() function 5c7c40adc1 +- Remove distro-specific packaging a5749657ee +- Add -x flag to amqp-consume utilty 1d9c5291ff +- Add amqp_basic_nack() public API 9b168776fb +- Add delivery mode constants to amqp.h 5f291ea772 +- Add support for connection.blocked/connection.unblocked methods ccbc24d270 + +### Bug fixes: +- `f8c6cee749` Examples: Destroy amqp_envelope_t in consumer example +- `ac88db56d3` CMake: fix generation of librabbitmq.pc +- `d5b35afa40` CMake: fix missing POPT_INCLUDE_DIRS variable in tools/ +- `5ea6a0945a` build: provide independent locations for x64 libs +- `fac34656c0` Doc: documentation fixes +- `715901d675` Lib: Correct OpenSSL initialization under threaded conditions +- `ce64e57df8` Examples: Handle unexpected frames in amqp_consumer.c +- `bcda3e933d` CMake: Use GnuInstallDirs to generate install dirs +- `27245a4e15` Lib: correctly handle amqp_get_monotonic_timestamp on win32 +- `693662ef5b` Tools: honor --persistent flag in publish utility +- `01d9c3ca60` Doc: improve documentation in amqp_ssl_socket functions +- `02d5c58ae4` autoconf: correct librabbitmq.pc generation +- `1f4e0cc48b` Doc: improve documentation in amqp_tcp_socket functions + +## Changes since v0.4.0: +### Major changes: +- Removed distro-specific packaging d285d01 + +### Bug fixes: +- `a642602` FIX: destroy amqp_envelop_t object in consumer example +- `860dd71` FIX: correct generation of librabbitmq.pc under CMake +- `bdda7ab` FIX: amqp_socket_close() should not be exported from shlib +- `24f4131` FIX: Use correct buf/len vars when re-starting send() + +## Changes since v0.3.0: +### New Features/Enhancements: +- `amqp_login_with_properties()` function to connect to a broker sending a + properties table to the broker 21b124e #101 +- SSL support (Mike Steinert) 473c865 #17 +- `amqp_simple_wait_frame_noblock()` function variant to wait for a frame + with a timeout f8cfc72 #119 +- Allow memory to be released on a per-channel basis with + `amqp_maybe_release_buffers_on_channel()` 4a2d899 #5 +- Support for AMQP heartbeats while blocking in `amqp_simple_wait_frame*()` + and `amqp_basic_publish()` daa0e66 aca5dc1 +- `amqp_socket_open_noblock()` for a non-blocking socket connection + (Bogdan Padalko) 6ad770d +- `amqp_table_clone()` to do a deep-copy of an amqp_table_t 08af83a +- Add option to listen to multiple keys in `amqp_consume` tool (Brian Hammond) e6c256d +- Add contributed OpenVMS build system 448ab68 +- Higher level APIs for consuming messages 33ebeed #8 +- Doxygen-based API documentation. +- Many improvements to error-handling and reporting + +### Bug Fixes: +- `24ffaf8` FIX: autotools was broken when dependency-tracking was disabled +- `38e741b` FIX: CMake XmlTo not found warning +- `906f04f` FIX: htonll redeclared on Win32 v8 +- `8e41603` FIX: SIGPIPE not disabled on OS X/BSD #102 +- `872ea49` FIX: Header issues with amqp.h on Mingw on Win32 (yoniyoni) +- `0f1f75b` FIX: potential memory leak in amqp_new_connection +- `c9f6312` FIX: missing va_end in `amqp_login()`/`amqp_login_with_properties()` +- `7bb64e4` FIX: include amqp_tcp_socket.h in dpkg (Tim Stewart) +- `ba9d1f5` FIX: Report out of buffer space in `amqp_table_encode()` +- `9496e10` FIX: Remove `abort()` on invalid parameter in `amqp_send_frame()` +- `f209420` FIX: Remote `abort()` in `amqp_simple_wait_method()` +- `f027518` FIX: Return error on socket lib init error +- `0ae534a` FIX: Correctly handle 0 return val from `SSL_read()`/`SSL_write()` +- `22e41b8` FIX: Improve error handling in socket functions +- `33c2353` FIX: Set state->socket to NULL after `amqp_socket_close()` +- `c83e728` FIX: Incorrect error code returned +- `1a19879` FIX: redecl of int i in `amqp_tcp_socket_writev()` +- `7477449` FIX: incorrect bit-shift in `amqp_error_string2()` +- `2e37bb3` FIX: correctly handle `amqp_get_sockfd()` in `amqp_simple_wait_frame()` +- `52a459b` FIX: Don't delete state in `amqp_tune_connection()` on error +- `01e38dd` FIX: Correctly handle `mach_timebase_info()` failure +- `34bffb7` FIX: Correctly disable `SIGPIPE` on platforms with `SO_NOSIGPIPE` +- `3866433` FIX: Use correct number of bits in timer precision on MacOSX +- `b6a1dfe` FIX: Squash OpenSSL deprecated warnings on MacOSX (Bogdan Padalko) +- `7a217d5` FIX: Incorrect `assert()` in `wait_frame_inner()` +- `7942af3` FIX: Correctly handle 0-length table in `amqp_table_clone()` +- `157788e` FIX: Correctly handle 0-length strings in `amqp_basic_properties_clone()` +- `4eaf771` FIX: Correctly handle 0-length message body in `amqp_read_message()` +- `59f943b` FIX: Double-free SSL on connection failure +- `7a451a4` FIX: `amqp_open_socket()` not defined diff --git a/ext/librabbitmq/LICENSE-MIT b/ext/librabbitmq/LICENSE-MIT new file mode 100644 index 00000000..5c7630d8 --- /dev/null +++ b/ext/librabbitmq/LICENSE-MIT @@ -0,0 +1,28 @@ +Portions created by Alan Antonuk are Copyright (c) 2012-2013 +Alan Antonuk. All Rights Reserved. + +Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. +All Rights Reserved. + +Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 +VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/ext/librabbitmq/README.md b/ext/librabbitmq/README.md new file mode 100644 index 00000000..52553158 --- /dev/null +++ b/ext/librabbitmq/README.md @@ -0,0 +1,128 @@ +# RabbitMQ C AMQP client library + +[![Build Status](https://secure.travis-ci.org/alanxz/rabbitmq-c.png?branch=master)](http://travis-ci.org/alanxz/rabbitmq-c) + +[![Coverage Status](https://coveralls.io/repos/github/alanxz/rabbitmq-c/badge.svg?branch=master)](https://coveralls.io/github/alanxz/rabbitmq-c?branch=master) + +## Introduction + +This is a C-language AMQP client library for use with v2.0+ of the +[RabbitMQ](http://www.rabbitmq.com/) broker. + + - + +Announcements regarding the library are periodically made on the +rabbitmq-c-users and cross-posted to rabbitmq-users. + + - + - + +## Latest Stable Version + +The latest stable release of rabbitmq-c can be found at: + + - + +## Documentation + +API documentation for v0.8.0+ can viewed from: + + + +## Getting started + +### Building and installing + +#### Prereqs: +- [CMake v2.6 or better](http://www.cmake.org/) +- A C compiler (GCC 4.4+, clang, and MSVC are test. Other compilers may also + work) +- *Optionally* [OpenSSL](http://www.openssl.org/) v0.9.8+ to enable support for + connecting to RabbitMQ over SSL/TLS +- *Optionally* [POpt](http://freecode.com/projects/popt) to build some handy + command-line tools. +- *Optionally* [XmlTo](https://fedorahosted.org/xmlto/) to build man pages for + the handy command-line tools +- *Optionally* [Doxygen](http://www.stack.nl/~dimitri/doxygen/) to build + developer API documentation. + +After downloading and extracting the source from a tarball to a directory +([see above](#latest-stable-version)), the commands to build rabbitmq-c on most +systems are: + + mkdir build && cd build + cmake .. + cmake --build [--config Release] . + +The --config Release flag should be used in multi-configuration generators e.g., +Visual Studio or XCode. + +It is also possible to point the CMake GUI tool at the CMakeLists.txt in the root of +the source tree and generate build projects or IDE workspace + +Installing the library and optionally specifying a prefix can be done with: + + cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. + cmake --build . [--config Release] --target install + +More information on CMake can be found on its FAQ (http://www.cmake.org/Wiki/CMake_FAQ) + +Other interesting flags that can be passed to CMake: + +* `BUILD_EXAMPLES=ON/OFF` toggles building the examples. ON by default. +* `BUILD_SHARED_LIBS=ON/OFF` toggles building rabbitmq-c as a shared library. + ON by default. +* `BUILD_STATIC_LIBS=ON/OFF` toggles building rabbitmq-c as a static library. + OFF by default. +* `BUILD_TESTS=ON/OFF` toggles building test code. ON by default. +* `BUILD_TOOLS=ON/OFF` toggles building the command line tools. By default + this is ON if the build system can find the POpt header and library. +* `BUILD_TOOLS_DOCS=ON/OFF` toggles building the man pages for the command line + tools. By default this is ON if BUILD_TOOLS is ON and the build system can + find the XmlTo utility. +* `ENABLE_SSL_SUPPORT=ON/OFF` toggles building rabbitmq-c with SSL support. By + default this is ON if the OpenSSL headers and library can be found. +* `BUILD_API_DOCS=ON/OFF` - toggles building the Doxygen API documentation, by + default this is OFF + +## Running the examples + +Arrange for a RabbitMQ or other AMQP server to be running on +`localhost` at TCP port number 5672. + +In one terminal, run + + ./examples/amqp_listen localhost 5672 amq.direct test + +In another terminal, + + ./examples/amqp_sendstring localhost 5672 amq.direct test "hello world" + +You should see output similar to the following in the listener's +terminal window: + + Delivery 1, exchange amq.direct routingkey test + Content-type: text/plain + ---- + 00000000: 68 65 6C 6C 6F 20 77 6F : 72 6C 64 hello world + 0000000B: + +## Writing applications using `librabbitmq` + +Please see the `examples` directory for short examples of the use of +the `librabbitmq` library. + +### Threading + +You cannot share a socket, an `amqp_connection_state_t`, or a channel +between threads using `librabbitmq`. The `librabbitmq` library is +built with event-driven, single-threaded applications in mind, and +does not yet cater to any of the requirements of `pthread`ed +applications. + +Your applications instead should open an AMQP connection (and an +associated socket, of course) per thread. If your program needs to +access an AMQP connection or any of its channels from more than one +thread, it is entirely responsible for designing and implementing an +appropriate locking scheme. It will generally be much simpler to have +a connection exclusive to each thread that needs AMQP service. diff --git a/ext/librabbitmq/THANKS b/ext/librabbitmq/THANKS new file mode 100644 index 00000000..1f378ead --- /dev/null +++ b/ext/librabbitmq/THANKS @@ -0,0 +1,8 @@ +Thank-you to the following people for their contributions to the +codebase: + + - Scott Brooks / Epic Advertising + + - Frank Gönninger + + - Daniel Schauenberg diff --git a/ext/librabbitmq/TODO b/ext/librabbitmq/TODO new file mode 100644 index 00000000..179d297a --- /dev/null +++ b/ext/librabbitmq/TODO @@ -0,0 +1,9 @@ +Deal with version-mismatch-header received from the server + +Cope with unknown frame types better. Currently it gets horribly +confused about frame lengths. + +Make client brutal by default, killing the program on any amqp +error. Only if the user disables this behaviour will the user get to +deal with error conditions themselves. Make use of amqp_rpc_reply +consistent (i.e. universal), and rename it something like amqp_errno. diff --git a/ext/librabbitmq/appveyor.yml b/ext/librabbitmq/appveyor.yml new file mode 100644 index 00000000..0ef27f90 --- /dev/null +++ b/ext/librabbitmq/appveyor.yml @@ -0,0 +1,34 @@ +# appveyor configuration +version: '{build}' + +# Limit history cloned. This matches what travis-CI currently does. +clone_depth: 50 + +environment: + matrix: + - GENERATOR: Visual Studio 12 Win64 + BITS: 64 + - GENERATOR: Visual Studio 12 + BITS: 32 + +cache: + - c:\deps -> appveyor.yml + +# borrowed from https://github.com/FreeTDS/freetds +install: + # xidel (xpath command line tool) + - appveyor DownloadFile "https://downloads.sourceforge.net/project/videlibri/Xidel/Xidel 0.9.6/xidel-0.9.6.win32.zip" + - 7z x xidel-0.9.6.win32.zip xidel.exe + # detect version of Windows OpenSSL binaries published by the Shining Light Productions crew + - xidel https://slproweb.com/products/Win32OpenSSL.html --extract "(//td/a[starts-with(@href, '/download') and starts-with(text(), 'Win32 OpenSSL') and ends-with(text(), 'Light')])[1]/translate(substring-before(substring-after(text(), 'Win32 OpenSSL v'), ' Light'), '.', '_')" > openssl_ver.txt + - set /P OPENSSL_VER=< openssl_ver.txt + # OpenSSL + - appveyor DownloadFile https://slproweb.com/download/Win%BITS%OpenSSL-%OPENSSL_VER%.exe + - "Win%BITS%OpenSSL-%OPENSSL_VER%.exe /SP- /SILENT /SUPPRESSMSGBOXES /NORESTART" + +before_build: + - cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DBUILD_TESTS=ON -DENABLE_SSL_SUPPORT=True -G"%GENERATOR%" . + +build: + project: ALL_BUILD.vcxproj + verbosity: normal diff --git a/ext/librabbitmq/centos_x64/lib/librabbitmq.a b/ext/librabbitmq/centos_x64/lib/librabbitmq.a deleted file mode 100644 index d5c3e8b4..00000000 Binary files a/ext/librabbitmq/centos_x64/lib/librabbitmq.a and /dev/null differ diff --git a/ext/librabbitmq/cmake/CMakePushCheckState.cmake b/ext/librabbitmq/cmake/CMakePushCheckState.cmake new file mode 100644 index 00000000..038319b4 --- /dev/null +++ b/ext/librabbitmq/cmake/CMakePushCheckState.cmake @@ -0,0 +1,103 @@ +# This module defines two macros: +# CMAKE_PUSH_CHECK_STATE() +# and +# CMAKE_POP_CHECK_STATE() +# These two macros can be used to save and restore the state of the variables +# CMAKE_REQUIRED_FLAGS, CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_LIBRARIES +# and CMAKE_REQUIRED_INCLUDES used by the various Check-files coming with CMake, +# like e.g. check_function_exists() etc. +# The variable contents are pushed on a stack, pushing multiple times is supported. +# This is useful e.g. when executing such tests in a Find-module, where they have to be set, +# but after the Find-module has been executed they should have the same value +# as they had before. +# +# Usage: +# cmake_push_check_state() +# set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DSOME_MORE_DEF) +# check_function_exists(...) +# cmake_pop_check_state() + +#============================================================================= +# Copyright 2006-2011 Alexander Neundorf, +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ------------------------------------------------------------------------------ +# +# The above copyright and license notice applies to distributions of +# CMake in source and binary form. Some source files contain additional +# notices of original copyright by their contributors; see each source +# for details. Third-party software packages supplied with CMake under +# compatible licenses provide their own copyright notices documented in +# corresponding subdirectories. +# +# ------------------------------------------------------------------------------ +# +# CMake was initially developed by Kitware with the following sponsorship: +# +# * National Library of Medicine at the National Institutes of Health +# as part of the Insight Segmentation and Registration Toolkit (ITK). +# +# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel +# Visualization Initiative. +# +# * National Alliance for Medical Image Computing (NAMIC) is funded by the +# National Institutes of Health through the NIH Roadmap for Medical Research, +# Grant U54 EB005149. +# +# * Kitware, Inc. + +macro(CMAKE_PUSH_CHECK_STATE) + + if(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER) + set(_CMAKE_PUSH_CHECK_STATE_COUNTER 0) + endif() + + math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1") + + set(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES}) + set(_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_DEFINITIONS}) + set(_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_LIBRARIES}) + set(_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_FLAGS}) +endmacro() + +macro(CMAKE_POP_CHECK_STATE) + +# don't pop more than we pushed + if("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0") + + set(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_DEFINITIONS ${_CMAKE_REQUIRED_DEFINITIONS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + set(CMAKE_REQUIRED_FLAGS ${_CMAKE_REQUIRED_FLAGS_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}}) + + math(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1") + endif() + +endmacro() diff --git a/ext/librabbitmq/cmake/COPYING-CMAKE-SCRIPTS b/ext/librabbitmq/cmake/COPYING-CMAKE-SCRIPTS new file mode 100644 index 00000000..53b6b71e --- /dev/null +++ b/ext/librabbitmq/cmake/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,22 @@ +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 copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. 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 AUTHOR ``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 AUTHOR 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/ext/librabbitmq/cmake/FindPOPT.cmake b/ext/librabbitmq/cmake/FindPOPT.cmake new file mode 100644 index 00000000..79caa018 --- /dev/null +++ b/ext/librabbitmq/cmake/FindPOPT.cmake @@ -0,0 +1,39 @@ +# - Try to find the popt options processing library +# The module will set the following variables +# +# POPT_FOUND - System has popt +# POPT_INCLUDE_DIR - The popt include directory +# POPT_LIBRARY - The libraries needed to use popt + +# use pkg-config to get the directories and then use these values +# in the FIND_PATH() and FIND_LIBRARY() calls + +find_package(PkgConfig QUIET) +if (PKG_CONFIG_FOUND) + pkg_search_module(PC_POPT QUIET popt) +endif () + +# Find the include directories +FIND_PATH(POPT_INCLUDE_DIR + NAMES popt.h + HINTS + ${PC_POPT_INCLUDEDIR} + ${PC_POPT_INCLUDE_DIRS} + DOC "Path containing the popt.h include file" + ) + +FIND_LIBRARY(POPT_LIBRARY + NAMES popt + HINTS + ${PC_POPT_LIBRARYDIR} + ${PC_POPT_LIBRARY_DIRS} + DOC "popt library path" + ) + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(POPT + REQUIRED_VARS POPT_INCLUDE_DIR POPT_LIBRARY + VERSION_VAR PC_POPT_VERSION) + +MARK_AS_ADVANCED(POPT_INCLUDE_DIR POPT_LIBRARY) diff --git a/ext/librabbitmq/cmake/FindXmlTo.cmake b/ext/librabbitmq/cmake/FindXmlTo.cmake new file mode 100644 index 00000000..d2d4d632 --- /dev/null +++ b/ext/librabbitmq/cmake/FindXmlTo.cmake @@ -0,0 +1,98 @@ +# - Convert XML docBook files to various formats +# This will convert XML docBook files to various formats like: +# man html txt dvi ps pdf +# macro XMLTO(outfiles infiles... MODES modes...) + +find_program ( XMLTO_EXECUTABLE + NAMES xmlto + DOC "path to the xmlto docbook xslt frontend" +) + + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XMLTO + REQUIRED_VARS XMLTO_EXECUTABLE) + +mark_as_advanced( XMLTO_EXECUTABLE ) + +macro ( _XMLTO_FILE outfiles mode) + #special settings + set ( XMLTO_FILEEXT_man 1 ) + set ( XMLTO_MODE_html xhtml-nochunks ) + + if ( NOT XMLTO_MODE_${mode}) + set ( XMLTO_MODE_${mode} ${mode} ) + endif ( NOT XMLTO_MODE_${mode} ) + if ( NOT XMLTO_FILEEXT_${mode} ) + set ( XMLTO_FILEEXT_${mode} ${mode} ) + endif ( NOT XMLTO_FILEEXT_${mode} ) + + foreach ( dbFile ${ARGN} ) + #TODO: set XMLTO_FILEEXT_man to value from + if ( "${mode}" STREQUAL "man" ) + file ( READ "${dbFile}" _DB_FILE_CONTENTS ) + string ( REGEX MATCH "[^<]*" XMLTO_FILEEXT_${mode} "${_DB_FILE_CONTENTS}" ) + string ( REGEX REPLACE "^" "" XMLTO_FILEEXT_${mode} "${XMLTO_FILEEXT_${mode}}" ) + string ( REGEX REPLACE "[[:space:]]" "" XMLTO_FILEEXT_${mode} "${XMLTO_FILEEXT_${mode}}" ) + endif ( "${mode}" STREQUAL "man" ) + + get_filename_component ( dbFilePath ${CMAKE_CURRENT_BINARY_DIR}/${dbFile} PATH ) + get_filename_component ( dbFileWE ${dbFile} NAME_WE ) + get_filename_component ( dbFileAbsWE ${dbFilePath}/${dbFileWE} ABSOLUTE ) + + add_custom_command ( + OUTPUT ${dbFileAbsWE}.${XMLTO_FILEEXT_${mode}} + COMMAND ${XMLTO_EXECUTABLE} ${XMLTO_COMMAND_ARGS} -o ${dbFilePath} + ${XMLTO_MODE_${mode}} "${CMAKE_CURRENT_SOURCE_DIR}/${dbFile}" + MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${dbFile} + DEPENDS ${XMLTO_DEPENDS} + VERBATIM + ) + + set ( ${outfiles} + ${${outfiles}} + ${dbFileAbsWE}.${XMLTO_FILEEXT_${mode}} + ) + endforeach ( dbFile ) +endmacro ( _XMLTO_FILE outfiles ) + +macro ( XMLTO ) + set ( XMLTO_MODES ) + set ( XMLTO_FILES ) + set ( XMLTO_HAS_MODES false ) + set ( XMLTO_ADD_DEFAULT false ) + foreach ( arg ${ARGN} ) + if ( ${arg} STREQUAL "MODES" ) + set ( XMLTO_HAS_MODES true ) + elseif ( ${arg} STREQUAL "ALL" ) + set ( XMLTO_ADD_DEFAULT true ) + else ( ${arg} STREQUAL "MODES" ) + if ( XMLTO_HAS_MODES ) + set ( XMLTO_MODES ${XMLTO_MODES} ${arg} ) + else ( XMLTO_HAS_MODES ) + set ( XMLTO_FILES ${XMLTO_FILES} ${arg} ) + endif ( XMLTO_HAS_MODES ) + endif ( ${arg} STREQUAL "MODES" ) + endforeach ( arg ${ARGN} ) + if ( NOT XMLTO_MODES ) + set ( XMLTO_MODES html ) + endif ( NOT XMLTO_MODES ) + + foreach ( mode ${XMLTO_MODES} ) + _xmlto_file ( XMLTO_FILES_${mode} ${mode} ${XMLTO_FILES} ) + if ( XMLTO_ADD_DEFAULT ) + add_custom_target ( ${mode} ALL + DEPENDS ${XMLTO_FILES_${mode}} + VERBATIM + ) + else ( XMLTO_ADD_DEFAULT ) + add_custom_target ( ${mode} + DEPENDS ${XMLTO_FILES_${mode}} + VERBATIM + ) + endif ( XMLTO_ADD_DEFAULT ) + endforeach ( mode ) + + set ( XMLTO_MODES ) + set ( XMLTO_FILES ) +endmacro ( XMLTO ) diff --git a/ext/librabbitmq/cmake/GNUInstallDirs.cmake b/ext/librabbitmq/cmake/GNUInstallDirs.cmake new file mode 100644 index 00000000..c8d77c6a --- /dev/null +++ b/ext/librabbitmq/cmake/GNUInstallDirs.cmake @@ -0,0 +1,205 @@ +#.rst: +# GNUInstallDirs +# -------------- +# +# Define GNU standard installation directories +# +# Provides install directory variables as defined for GNU software: +# +# :: +# +# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html +# +# Inclusion of this module defines the following variables: +# +# :: +# +# CMAKE_INSTALL_ - destination for files of a given type +# CMAKE_INSTALL_FULL_ - corresponding absolute path +# +# where is one of: +# +# :: +# +# BINDIR - user executables (bin) +# SBINDIR - system admin executables (sbin) +# LIBEXECDIR - program executables (libexec) +# SYSCONFDIR - read-only single-machine data (etc) +# SHAREDSTATEDIR - modifiable architecture-independent data (com) +# LOCALSTATEDIR - modifiable single-machine data (var) +# LIBDIR - object code libraries (lib or lib64 or lib/ on Debian) +# INCLUDEDIR - C header files (include) +# OLDINCLUDEDIR - C header files for non-gcc (/usr/include) +# DATAROOTDIR - read-only architecture-independent data root (share) +# DATADIR - read-only architecture-independent data (DATAROOTDIR) +# INFODIR - info documentation (DATAROOTDIR/info) +# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale) +# MANDIR - man documentation (DATAROOTDIR/man) +# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME) +# +# Each CMAKE_INSTALL_ value may be passed to the DESTINATION +# options of install() commands for the corresponding file type. If the +# includer does not define a value the above-shown default will be used +# and the value will appear in the cache for editing by the user. Each +# CMAKE_INSTALL_FULL_ value contains an absolute path constructed +# from the corresponding destination by prepending (if necessary) the +# value of CMAKE_INSTALL_PREFIX. + +#============================================================================= +# Copyright 2011 Nikita Krupen'ko +# Copyright 2011 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Installation directories +# +if(NOT DEFINED CMAKE_INSTALL_BINDIR) + set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_SBINDIR) + set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR) + set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR) + set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR) + set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR) + set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_LIBDIR) + set(_LIBDIR_DEFAULT "lib") + # Override this default 'lib' with 'lib64' iff: + # - we are on Linux system but NOT cross-compiling + # - we are NOT on debian + # - we are on a 64 bits system + # reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf + # For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if + # CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu" + # See http://wiki.debian.org/Multiarch + if(CMAKE_SYSTEM_NAME MATCHES "Linux" + AND NOT CMAKE_CROSSCOMPILING) + if (EXISTS "/etc/debian_version") # is this a debian system ? + if(CMAKE_LIBRARY_ARCHITECTURE) + set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") + endif() + else() # not debian, rely on CMAKE_SIZEOF_VOID_P: + if(NOT DEFINED CMAKE_SIZEOF_VOID_P) + message(AUTHOR_WARNING + "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. " + "Please enable at least one language before including GNUInstallDirs.") + else() + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + set(_LIBDIR_DEFAULT "lib64") + endif() + endif() + endif() + endif() + set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})") +endif() + +if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR) + set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR) + set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)") +endif() + +if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR) + set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)") +endif() + +#----------------------------------------------------------------------------- +# Values whose defaults are relative to DATAROOTDIR. Store empty values in +# the cache and store the defaults in local variables if the cache values are +# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes. + +if(NOT CMAKE_INSTALL_DATADIR) + set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)") + set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}") +endif() + +if(NOT CMAKE_INSTALL_INFODIR) + set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)") + set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info") +endif() + +if(NOT CMAKE_INSTALL_LOCALEDIR) + set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)") + set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale") +endif() + +if(NOT CMAKE_INSTALL_MANDIR) + set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)") + set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man") +endif() + +if(NOT CMAKE_INSTALL_DOCDIR) + set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)") + set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}") +endif() + +#----------------------------------------------------------------------------- + +mark_as_advanced( + CMAKE_INSTALL_BINDIR + CMAKE_INSTALL_SBINDIR + CMAKE_INSTALL_LIBEXECDIR + CMAKE_INSTALL_SYSCONFDIR + CMAKE_INSTALL_SHAREDSTATEDIR + CMAKE_INSTALL_LOCALSTATEDIR + CMAKE_INSTALL_LIBDIR + CMAKE_INSTALL_INCLUDEDIR + CMAKE_INSTALL_OLDINCLUDEDIR + CMAKE_INSTALL_DATAROOTDIR + CMAKE_INSTALL_DATADIR + CMAKE_INSTALL_INFODIR + CMAKE_INSTALL_LOCALEDIR + CMAKE_INSTALL_MANDIR + CMAKE_INSTALL_DOCDIR + ) + +# Result directories +# +foreach(dir + BINDIR + SBINDIR + LIBEXECDIR + SYSCONFDIR + SHAREDSTATEDIR + LOCALSTATEDIR + LIBDIR + INCLUDEDIR + OLDINCLUDEDIR + DATAROOTDIR + DATADIR + INFODIR + LOCALEDIR + MANDIR + DOCDIR + ) + if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}}) + set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}") + else() + set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}") + endif() +endforeach() diff --git a/ext/librabbitmq/cmake/TestCInline.cmake b/ext/librabbitmq/cmake/TestCInline.cmake new file mode 100644 index 00000000..63436468 --- /dev/null +++ b/ext/librabbitmq/cmake/TestCInline.cmake @@ -0,0 +1,28 @@ +#Inspired from http://www.cmake.org/Wiki/CMakeTestInline + +IF(NOT DEFINED C_INLINE_KEYWORD) + + SET(INLINE_TEST_SRC "/* Inspired by autoconf's c.m4 */ +static inline int static_foo() {return 0\;} +int main(int argc, char *argv[]){return 0\;} +") + + FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CMakeTestCInline.c ${INLINE_TEST_SRC}) + + FOREACH(KEYWORD "inline" "__inline__" "__inline") + IF(NOT DEFINED C_INLINE) + TRY_COMPILE(C_HAS_${KEYWORD} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/CMakeTestCInline.c + COMPILE_DEFINITIONS "-Dinline=${KEYWORD}" + ) + IF(C_HAS_${KEYWORD}) + SET(C_INLINE ${KEYWORD}) + ENDIF(C_HAS_${KEYWORD}) + ENDIF(NOT DEFINED C_INLINE) + ENDFOREACH(KEYWORD) + + SET(C_INLINE_KEYWORD ${C_INLINE} CACHE INTERNAL "The keyword needed by the C compiler to inline a function" FORCE) + message(STATUS "Found C inline keyword: ${C_INLINE_KEYWORD}") + +ENDIF(NOT DEFINED C_INLINE_KEYWORD) diff --git a/ext/librabbitmq/cmake/config.h.in b/ext/librabbitmq/cmake/config.h.in new file mode 100644 index 00000000..297cf40b --- /dev/null +++ b/ext/librabbitmq/cmake/config.h.in @@ -0,0 +1,14 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#ifndef __cplusplus +# define inline ${C_INLINE_KEYWORD} +#endif + +#cmakedefine HAVE_SELECT + +#cmakedefine HAVE_POLL + +#define AMQ_PLATFORM "@CMAKE_SYSTEM@" + +#endif /* CONFIG_H */ diff --git a/ext/librabbitmq/coverity/model.c b/ext/librabbitmq/coverity/model.c new file mode 100644 index 00000000..dc1ad986 --- /dev/null +++ b/ext/librabbitmq/coverity/model.c @@ -0,0 +1,17 @@ +/* Functions to help coverity do static analysis on rabbitmq-c */ + +typedef struct { +} amqp_rpc_reply_t; + +/* librabbitmq/amqp_private.h */ +void amqp_abort(const char* fmt, ...) { __coverity_panic__(); } + +/* tools/common.h */ +void die(const char* fmt, ...) { __coverity_panic__(); } +void die_errno(int err, const char* fmt, ...) { __coverity_panic__(); } +void die_amqp_error(int err, const char* fmt, ...) { __coverity_panic__(); } +void die_rpc(amqp_rpc_reply_t r, const char* fmt, ...) { __coverity_panic__(); } + +/* examples/utils.h */ +void die_on_amqp_error(amqp_rpc_reply_t* r) { __coverity_panic__(); } +void die_on_error(int r) { __coverity_panic__(); } diff --git a/ext/librabbitmq/docs/Doxyfile.in b/ext/librabbitmq/docs/Doxyfile.in new file mode 100644 index 00000000..8b5da702 --- /dev/null +++ b/ext/librabbitmq/docs/Doxyfile.in @@ -0,0 +1,317 @@ +# Doxyfile 1.8.4 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = rabbitmq-c +PROJECT_NUMBER = @VERSION@ +PROJECT_BRIEF = "C AMQP Client library for RabbitMQ" +PROJECT_LOGO = +OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 2 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = YES +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/README.md \ + @CMAKE_CURRENT_SOURCE_DIR@/ChangeLog.md \ + @CMAKE_CURRENT_SOURCE_DIR@/librabbitmq \ + @CMAKE_CURRENT_SOURCE_DIR@/docs +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.h \ + *.md +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = amqp_private.h \ + config.h +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = @CMAKE_CURRENT_SOURCE_DIR@ \ + @CMAKE_CURRENT_SOURCE_DIR@/examples +EXAMPLE_PATTERNS = *.c \ + *.md +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = README.md +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = amqp_ +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://www.mathjax.org/mathjax +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/librabbitmq \ + @CMAKE_CURRENT_BINARY_DIR@/librabbitmq +INCLUDE_FILE_PATTERNS = +PREDEFINED = AMQP_BEGIN_DECLS= \ + AMQP_END_DECLS= \ + AMQP_PUBLIC_FUNCTION= \ + AMQP_PUBLIC_VARIABLE= \ + AMQP_CALL= \ + AMQP_DEPRECATED(x)=x +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/ext/librabbitmq/examples/CMakeLists.txt b/ext/librabbitmq/examples/CMakeLists.txt new file mode 100644 index 00000000..4ea8e93e --- /dev/null +++ b/ext/librabbitmq/examples/CMakeLists.txt @@ -0,0 +1,52 @@ +if (NOT BUILD_SHARED_LIBS) + add_definitions(-DAMQP_STATIC) +endif() + +include_directories(${LIBRABBITMQ_INCLUDE_DIRS}) + +if (WIN32) + set(PLATFORM_DIR win32) +else (WIN32) + set(PLATFORM_DIR unix) +endif (WIN32) + +set(COMMON_SRCS + utils.h + utils.c + ${PLATFORM_DIR}/platform_utils.c + ) + +add_executable(amqp_sendstring amqp_sendstring.c ${COMMON_SRCS}) +target_link_libraries(amqp_sendstring ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_rpc_sendstring_client amqp_rpc_sendstring_client.c ${COMMON_SRCS}) +target_link_libraries(amqp_rpc_sendstring_client ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_exchange_declare amqp_exchange_declare.c ${COMMON_SRCS}) +target_link_libraries(amqp_exchange_declare ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_listen amqp_listen.c ${COMMON_SRCS}) +target_link_libraries(amqp_listen ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_producer amqp_producer.c ${COMMON_SRCS}) +target_link_libraries(amqp_producer ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_connect_timeout amqp_connect_timeout.c ${COMMON_SRCS}) +target_link_libraries(amqp_connect_timeout ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_consumer amqp_consumer.c ${COMMON_SRCS}) +target_link_libraries(amqp_consumer ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_unbind amqp_unbind.c ${COMMON_SRCS}) +target_link_libraries(amqp_unbind ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_bind amqp_bind.c ${COMMON_SRCS}) +target_link_libraries(amqp_bind ${RMQ_LIBRARY_TARGET}) + +add_executable(amqp_listenq amqp_listenq.c ${COMMON_SRCS}) +target_link_libraries(amqp_listenq ${RMQ_LIBRARY_TARGET}) + +if (ENABLE_SSL_SUPPORT) +add_executable(amqp_ssl_connect amqp_ssl_connect.c ${COMMON_SRCS}) +target_link_libraries(amqp_ssl_connect ${RMQ_LIBRARY_TARGET}) +endif (ENABLE_SSL_SUPPORT) diff --git a/ext/librabbitmq/examples/amqp_bind.c b/ext/librabbitmq/examples/amqp_bind.c new file mode 100644 index 00000000..46371a41 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_bind.c @@ -0,0 +1,95 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + char const *exchange; + char const *bindingkey; + char const *queue; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + if (argc < 6) { + fprintf(stderr, "Usage: amqp_bind host port exchange bindingkey queue\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + exchange = argv[3]; + bindingkey = argv[4]; + queue = argv[5]; + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + amqp_queue_bind(conn, 1, amqp_cstring_bytes(queue), + amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey), + amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Unbinding"); + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_connect_timeout.c b/ext/librabbitmq/examples/amqp_connect_timeout.c new file mode 100644 index 00000000..21bd02e2 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_connect_timeout.c @@ -0,0 +1,114 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by Bogdan Padalko are Copyright (c) 2013. + * Bogdan Padalko. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#endif + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port; + amqp_socket_t *socket; + amqp_connection_state_t conn; + struct timeval tval; + struct timeval *tv; + + if (argc < 3) { + fprintf(stderr, + "Usage: amqp_connect_timeout host port [timeout_sec " + "[timeout_usec=0]]\n"); + return 1; + } + + if (argc > 3) { + tv = &tval; + + tv->tv_sec = atoi(argv[3]); + + if (argc > 4) { + tv->tv_usec = atoi(argv[4]); + } else { + tv->tv_usec = 0; + } + + } else { + tv = NULL; + } + + hostname = argv[1]; + port = atoi(argv[2]); + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + + if (!socket) { + die("creating TCP socket"); + } + + die_on_error(amqp_socket_open_noblock(socket, hostname, port, tv), + "opening TCP socket"); + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + + printf("Done\n"); + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_consumer.c b/ext/librabbitmq/examples/amqp_consumer.c new file mode 100644 index 00000000..93c7a21b --- /dev/null +++ b/ext/librabbitmq/examples/amqp_consumer.c @@ -0,0 +1,215 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include "utils.h" + +#define SUMMARY_EVERY_US 1000000 + +static void run(amqp_connection_state_t conn) { + uint64_t start_time = now_microseconds(); + int received = 0; + int previous_received = 0; + uint64_t previous_report_time = start_time; + uint64_t next_summary_time = start_time + SUMMARY_EVERY_US; + + amqp_frame_t frame; + + uint64_t now; + + for (;;) { + amqp_rpc_reply_t ret; + amqp_envelope_t envelope; + + now = now_microseconds(); + if (now > next_summary_time) { + int countOverInterval = received - previous_received; + double intervalRate = + countOverInterval / ((now - previous_report_time) / 1000000.0); + printf("%d ms: Received %d - %d since last report (%d Hz)\n", + (int)(now - start_time) / 1000, received, countOverInterval, + (int)intervalRate); + + previous_received = received; + previous_report_time = now; + next_summary_time += SUMMARY_EVERY_US; + } + + amqp_maybe_release_buffers(conn); + ret = amqp_consume_message(conn, &envelope, NULL, 0); + + if (AMQP_RESPONSE_NORMAL != ret.reply_type) { + if (AMQP_RESPONSE_LIBRARY_EXCEPTION == ret.reply_type && + AMQP_STATUS_UNEXPECTED_STATE == ret.library_error) { + if (AMQP_STATUS_OK != amqp_simple_wait_frame(conn, &frame)) { + return; + } + + if (AMQP_FRAME_METHOD == frame.frame_type) { + switch (frame.payload.method.id) { + case AMQP_BASIC_ACK_METHOD: + /* if we've turned publisher confirms on, and we've published a + * message here is a message being confirmed. + */ + break; + case AMQP_BASIC_RETURN_METHOD: + /* if a published message couldn't be routed and the mandatory + * flag was set this is what would be returned. The message then + * needs to be read. + */ + { + amqp_message_t message; + ret = amqp_read_message(conn, frame.channel, &message, 0); + if (AMQP_RESPONSE_NORMAL != ret.reply_type) { + return; + } + + amqp_destroy_message(&message); + } + + break; + + case AMQP_CHANNEL_CLOSE_METHOD: + /* a channel.close method happens when a channel exception occurs, + * this can happen by publishing to an exchange that doesn't exist + * for example. + * + * In this case you would need to open another channel redeclare + * any queues that were declared auto-delete, and restart any + * consumers that were attached to the previous channel. + */ + return; + + case AMQP_CONNECTION_CLOSE_METHOD: + /* a connection.close method happens when a connection exception + * occurs, this can happen by trying to use a channel that isn't + * open for example. + * + * In this case the whole connection must be restarted. + */ + return; + + default: + fprintf(stderr, "An unexpected method was received %u\n", + frame.payload.method.id); + return; + } + } + } + + } else { + amqp_destroy_envelope(&envelope); + } + + received++; + } +} + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + char const *exchange; + char const *bindingkey; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + amqp_bytes_t queuename; + + if (argc < 3) { + fprintf(stderr, "Usage: amqp_consumer host port\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + exchange = "amq.direct"; /* argv[3]; */ + bindingkey = "test queue"; /* argv[4]; */ + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + { + amqp_queue_declare_ok_t *r = amqp_queue_declare( + conn, 1, amqp_empty_bytes, 0, 0, 0, 1, amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); + queuename = amqp_bytes_malloc_dup(r->queue); + if (queuename.bytes == NULL) { + fprintf(stderr, "Out of memory while copying queue name"); + return 1; + } + } + + amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), + amqp_cstring_bytes(bindingkey), amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue"); + + amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, + amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); + + run(conn); + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_exchange_declare.c b/ext/librabbitmq/examples/amqp_exchange_declare.c new file mode 100644 index 00000000..2199a0b3 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_exchange_declare.c @@ -0,0 +1,94 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + char const *exchange; + char const *exchangetype; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + if (argc < 5) { + fprintf(stderr, + "Usage: amqp_exchange_declare host port exchange exchangetype\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + exchange = argv[3]; + exchangetype = argv[4]; + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange), + amqp_cstring_bytes(exchangetype), 0, 0, 0, 0, + amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring exchange"); + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_listen.c b/ext/librabbitmq/examples/amqp_listen.c new file mode 100644 index 00000000..90262266 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_listen.c @@ -0,0 +1,143 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + char const *exchange; + char const *bindingkey; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + amqp_bytes_t queuename; + + if (argc < 5) { + fprintf(stderr, "Usage: amqp_listen host port exchange bindingkey\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + exchange = argv[3]; + bindingkey = argv[4]; + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + { + amqp_queue_declare_ok_t *r = amqp_queue_declare( + conn, 1, amqp_empty_bytes, 0, 0, 0, 1, amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); + queuename = amqp_bytes_malloc_dup(r->queue); + if (queuename.bytes == NULL) { + fprintf(stderr, "Out of memory while copying queue name"); + return 1; + } + } + + amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), + amqp_cstring_bytes(bindingkey), amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue"); + + amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, + amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); + + { + for (;;) { + amqp_rpc_reply_t res; + amqp_envelope_t envelope; + + amqp_maybe_release_buffers(conn); + + res = amqp_consume_message(conn, &envelope, NULL, 0); + + if (AMQP_RESPONSE_NORMAL != res.reply_type) { + break; + } + + printf("Delivery %u, exchange %.*s routingkey %.*s\n", + (unsigned)envelope.delivery_tag, (int)envelope.exchange.len, + (char *)envelope.exchange.bytes, (int)envelope.routing_key.len, + (char *)envelope.routing_key.bytes); + + if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { + printf("Content-type: %.*s\n", + (int)envelope.message.properties.content_type.len, + (char *)envelope.message.properties.content_type.bytes); + } + printf("----\n"); + + amqp_dump(envelope.message.body.bytes, envelope.message.body.len); + + amqp_destroy_envelope(&envelope); + } + } + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_listenq.c b/ext/librabbitmq/examples/amqp_listenq.c new file mode 100644 index 00000000..624dc5cc --- /dev/null +++ b/ext/librabbitmq/examples/amqp_listenq.c @@ -0,0 +1,122 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + char const *queuename; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + if (argc < 4) { + fprintf(stderr, "Usage: amqp_listenq host port queuename\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + queuename = argv[3]; + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), amqp_empty_bytes, + 0, 0, 0, amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); + + for (;;) { + amqp_rpc_reply_t res; + amqp_envelope_t envelope; + + amqp_maybe_release_buffers(conn); + + res = amqp_consume_message(conn, &envelope, NULL, 0); + + if (AMQP_RESPONSE_NORMAL != res.reply_type) { + break; + } + + printf("Delivery %u, exchange %.*s routingkey %.*s\n", + (unsigned)envelope.delivery_tag, (int)envelope.exchange.len, + (char *)envelope.exchange.bytes, (int)envelope.routing_key.len, + (char *)envelope.routing_key.bytes); + + if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { + printf("Content-type: %.*s\n", + (int)envelope.message.properties.content_type.len, + (char *)envelope.message.properties.content_type.bytes); + } + printf("----\n"); + + amqp_dump(envelope.message.body.bytes, envelope.message.body.len); + + amqp_destroy_envelope(&envelope); + } + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_producer.c b/ext/librabbitmq/examples/amqp_producer.c new file mode 100644 index 00000000..6e78fcb6 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_producer.c @@ -0,0 +1,150 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include "utils.h" + +#define SUMMARY_EVERY_US 1000000 + +static void send_batch(amqp_connection_state_t conn, char const *queue_name, + int rate_limit, int message_count) { + uint64_t start_time = now_microseconds(); + int i; + int sent = 0; + int previous_sent = 0; + uint64_t previous_report_time = start_time; + uint64_t next_summary_time = start_time + SUMMARY_EVERY_US; + + char message[256]; + amqp_bytes_t message_bytes; + + for (i = 0; i < (int)sizeof(message); i++) { + message[i] = i & 0xff; + } + + message_bytes.len = sizeof(message); + message_bytes.bytes = message; + + for (i = 0; i < message_count; i++) { + uint64_t now = now_microseconds(); + + die_on_error(amqp_basic_publish(conn, 1, amqp_cstring_bytes("amq.direct"), + amqp_cstring_bytes(queue_name), 0, 0, NULL, + message_bytes), + "Publishing"); + sent++; + if (now > next_summary_time) { + int countOverInterval = sent - previous_sent; + double intervalRate = + countOverInterval / ((now - previous_report_time) / 1000000.0); + printf("%d ms: Sent %d - %d since last report (%d Hz)\n", + (int)(now - start_time) / 1000, sent, countOverInterval, + (int)intervalRate); + + previous_sent = sent; + previous_report_time = now; + next_summary_time += SUMMARY_EVERY_US; + } + + while (((i * 1000000.0) / (now - start_time)) > rate_limit) { + microsleep(2000); + now = now_microseconds(); + } + } + + { + uint64_t stop_time = now_microseconds(); + int total_delta = (int)(stop_time - start_time); + + printf("PRODUCER - Message count: %d\n", message_count); + printf("Total time, milliseconds: %d\n", total_delta / 1000); + printf("Overall messages-per-second: %g\n", + (message_count / (total_delta / 1000000.0))); + } +} + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + int rate_limit; + int message_count; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + if (argc < 5) { + fprintf(stderr, + "Usage: amqp_producer host port rate_limit message_count\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + rate_limit = atoi(argv[3]); + message_count = atoi(argv[4]); + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + send_batch(conn, "test queue", rate_limit, message_count); + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_rpc_sendstring_client.c b/ext/librabbitmq/examples/amqp_rpc_sendstring_client.c new file mode 100644 index 00000000..59918e53 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_rpc_sendstring_client.c @@ -0,0 +1,243 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include "utils.h" + +int main(int argc, char *argv[]) { + char const *hostname; + int port, status; + char const *exchange; + char const *routingkey; + char const *messagebody; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + amqp_bytes_t reply_to_queue; + + if (argc < 6) { /* minimum number of mandatory arguments */ + fprintf(stderr, + "usage:\namqp_rpc_sendstring_client host port exchange routingkey " + "messagebody\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + exchange = argv[3]; + routingkey = argv[4]; + messagebody = argv[5]; + + /* + establish a channel that is used to connect RabbitMQ server + */ + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + /* + create private reply_to queue + */ + + { + amqp_queue_declare_ok_t *r = amqp_queue_declare( + conn, 1, amqp_empty_bytes, 0, 0, 0, 1, amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue"); + reply_to_queue = amqp_bytes_malloc_dup(r->queue); + if (reply_to_queue.bytes == NULL) { + fprintf(stderr, "Out of memory while copying queue name"); + return 1; + } + } + + /* + send the message + */ + + { + /* + set properties + */ + amqp_basic_properties_t props; + props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | + AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_REPLY_TO_FLAG | + AMQP_BASIC_CORRELATION_ID_FLAG; + props.content_type = amqp_cstring_bytes("text/plain"); + props.delivery_mode = 2; /* persistent delivery mode */ + props.reply_to = amqp_bytes_malloc_dup(reply_to_queue); + if (props.reply_to.bytes == NULL) { + fprintf(stderr, "Out of memory while copying queue name"); + return 1; + } + props.correlation_id = amqp_cstring_bytes("1"); + + /* + publish + */ + die_on_error(amqp_basic_publish(conn, 1, amqp_cstring_bytes(exchange), + amqp_cstring_bytes(routingkey), 0, 0, + &props, amqp_cstring_bytes(messagebody)), + "Publishing"); + + amqp_bytes_free(props.reply_to); + } + + /* + wait an answer + */ + + { + amqp_basic_consume(conn, 1, reply_to_queue, amqp_empty_bytes, 0, 1, 0, + amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming"); + amqp_bytes_free(reply_to_queue); + + { + amqp_frame_t frame; + int result; + + amqp_basic_deliver_t *d; + amqp_basic_properties_t *p; + size_t body_target; + size_t body_received; + + for (;;) { + amqp_maybe_release_buffers(conn); + result = amqp_simple_wait_frame(conn, &frame); + printf("Result: %d\n", result); + if (result < 0) { + break; + } + + printf("Frame type: %u channel: %u\n", frame.frame_type, frame.channel); + if (frame.frame_type != AMQP_FRAME_METHOD) { + continue; + } + + printf("Method: %s\n", amqp_method_name(frame.payload.method.id)); + if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { + continue; + } + + d = (amqp_basic_deliver_t *)frame.payload.method.decoded; + printf("Delivery: %u exchange: %.*s routingkey: %.*s\n", + (unsigned)d->delivery_tag, (int)d->exchange.len, + (char *)d->exchange.bytes, (int)d->routing_key.len, + (char *)d->routing_key.bytes); + + result = amqp_simple_wait_frame(conn, &frame); + if (result < 0) { + break; + } + + if (frame.frame_type != AMQP_FRAME_HEADER) { + fprintf(stderr, "Expected header!"); + abort(); + } + p = (amqp_basic_properties_t *)frame.payload.properties.decoded; + if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { + printf("Content-type: %.*s\n", (int)p->content_type.len, + (char *)p->content_type.bytes); + } + printf("----\n"); + + body_target = (size_t)frame.payload.properties.body_size; + body_received = 0; + + while (body_received < body_target) { + result = amqp_simple_wait_frame(conn, &frame); + if (result < 0) { + break; + } + + if (frame.frame_type != AMQP_FRAME_BODY) { + fprintf(stderr, "Expected body!"); + abort(); + } + + body_received += frame.payload.body_fragment.len; + assert(body_received <= body_target); + + amqp_dump(frame.payload.body_fragment.bytes, + frame.payload.body_fragment.len); + } + + if (body_received != body_target) { + /* Can only happen when amqp_simple_wait_frame returns <= 0 */ + /* We break here to close the connection */ + break; + } + + /* everything was fine, we can quit now because we received the reply */ + break; + } + } + } + + /* + closing + */ + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_sendstring.c b/ext/librabbitmq/examples/amqp_sendstring.c new file mode 100644 index 00000000..75492aa3 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_sendstring.c @@ -0,0 +1,103 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + char const *exchange; + char const *routingkey; + char const *messagebody; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + if (argc < 6) { + fprintf( + stderr, + "Usage: amqp_sendstring host port exchange routingkey messagebody\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + exchange = argv[3]; + routingkey = argv[4]; + messagebody = argv[5]; + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + { + amqp_basic_properties_t props; + props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG; + props.content_type = amqp_cstring_bytes("text/plain"); + props.delivery_mode = 2; /* persistent delivery mode */ + die_on_error(amqp_basic_publish(conn, 1, amqp_cstring_bytes(exchange), + amqp_cstring_bytes(routingkey), 0, 0, + &props, amqp_cstring_bytes(messagebody)), + "Publishing"); + } + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_ssl_connect.c b/ext/librabbitmq/examples/amqp_ssl_connect.c new file mode 100644 index 00000000..3674c333 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_ssl_connect.c @@ -0,0 +1,135 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by Mike Steinert are Copyright (c) 2012-2013 + * Mike Steinert. All Rights Reserved. + * + * Portions created by Bogdan Padalko are Copyright (c) 2013. + * Bogdan Padalko. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#endif + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port; + int timeout; + amqp_socket_t *socket; + amqp_connection_state_t conn; + struct timeval tval; + struct timeval *tv; + + if (argc < 3) { + fprintf(stderr, + "Usage: amqps_connect_timeout host port timeout_sec " + "[cacert.pem [verifypeer] [verifyhostname] [key.pem cert.pem]]\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + + timeout = atoi(argv[3]); + if (timeout > 0) { + tv = &tval; + + tv->tv_sec = timeout; + tv->tv_usec = 0; + } else { + tv = NULL; + } + + conn = amqp_new_connection(); + + socket = amqp_ssl_socket_new(conn); + if (!socket) { + die("creating SSL/TLS socket"); + } + + amqp_ssl_socket_set_verify_peer(socket, 0); + amqp_ssl_socket_set_verify_hostname(socket, 0); + + if (argc > 5) { + int nextarg = 5; + die_on_error(amqp_ssl_socket_set_cacert(socket, argv[4]), + "setting CA certificate"); + if (argc > nextarg && !strcmp("verifypeer", argv[nextarg])) { + amqp_ssl_socket_set_verify_peer(socket, 1); + nextarg++; + } + if (argc > nextarg && !strcmp("verifyhostname", argv[nextarg])) { + amqp_ssl_socket_set_verify_hostname(socket, 1); + nextarg++; + } + if (argc > nextarg + 1) { + die_on_error( + amqp_ssl_socket_set_key(socket, argv[nextarg + 1], argv[nextarg]), + "setting client key"); + } + } + + die_on_error(amqp_socket_open_noblock(socket, hostname, port, tv), + "opening SSL/TLS connection"); + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + die_on_error(amqp_uninitialize_ssl_library(), "Uninitializing SSL library"); + + printf("Done\n"); + return 0; +} diff --git a/ext/librabbitmq/examples/amqp_unbind.c b/ext/librabbitmq/examples/amqp_unbind.c new file mode 100644 index 00000000..aea07381 --- /dev/null +++ b/ext/librabbitmq/examples/amqp_unbind.c @@ -0,0 +1,95 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include +#include + +#include "utils.h" + +int main(int argc, char const *const *argv) { + char const *hostname; + int port, status; + char const *exchange; + char const *bindingkey; + char const *queue; + amqp_socket_t *socket = NULL; + amqp_connection_state_t conn; + + if (argc < 6) { + fprintf(stderr, "Usage: amqp_unbind host port exchange bindingkey queue\n"); + return 1; + } + + hostname = argv[1]; + port = atoi(argv[2]); + exchange = argv[3]; + bindingkey = argv[4]; + queue = argv[5]; + + conn = amqp_new_connection(); + + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket"); + } + + status = amqp_socket_open(socket, hostname, port); + if (status) { + die("opening TCP socket"); + } + + die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, + "guest", "guest"), + "Logging in"); + amqp_channel_open(conn, 1); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel"); + + amqp_queue_unbind(conn, 1, amqp_cstring_bytes(queue), + amqp_cstring_bytes(exchange), + amqp_cstring_bytes(bindingkey), amqp_empty_table); + die_on_amqp_error(amqp_get_rpc_reply(conn), "Unbinding"); + + die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), + "Closing channel"); + die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "Closing connection"); + die_on_error(amqp_destroy_connection(conn), "Ending connection"); + return 0; +} diff --git a/ext/librabbitmq/examples/unix/platform_utils.c b/ext/librabbitmq/examples/unix/platform_utils.c new file mode 100644 index 00000000..e420b823 --- /dev/null +++ b/ext/librabbitmq/examples/unix/platform_utils.c @@ -0,0 +1,52 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +uint64_t now_microseconds(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec; +} + +void microsleep(int usec) { + struct timespec req; + req.tv_sec = 0; + req.tv_nsec = 1000 * usec; + nanosleep(&req, NULL); +} diff --git a/ext/librabbitmq/examples/utils.c b/ext/librabbitmq/examples/utils.c new file mode 100644 index 00000000..8d1b4c63 --- /dev/null +++ b/ext/librabbitmq/examples/utils.c @@ -0,0 +1,188 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "utils.h" + +void die(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(1); +} + +void die_on_error(int x, char const *context) { + if (x < 0) { + fprintf(stderr, "%s: %s\n", context, amqp_error_string2(x)); + exit(1); + } +} + +void die_on_amqp_error(amqp_rpc_reply_t x, char const *context) { + switch (x.reply_type) { + case AMQP_RESPONSE_NORMAL: + return; + + case AMQP_RESPONSE_NONE: + fprintf(stderr, "%s: missing RPC reply type!\n", context); + break; + + case AMQP_RESPONSE_LIBRARY_EXCEPTION: + fprintf(stderr, "%s: %s\n", context, amqp_error_string2(x.library_error)); + break; + + case AMQP_RESPONSE_SERVER_EXCEPTION: + switch (x.reply.id) { + case AMQP_CONNECTION_CLOSE_METHOD: { + amqp_connection_close_t *m = + (amqp_connection_close_t *)x.reply.decoded; + fprintf(stderr, "%s: server connection error %uh, message: %.*s\n", + context, m->reply_code, (int)m->reply_text.len, + (char *)m->reply_text.bytes); + break; + } + case AMQP_CHANNEL_CLOSE_METHOD: { + amqp_channel_close_t *m = (amqp_channel_close_t *)x.reply.decoded; + fprintf(stderr, "%s: server channel error %uh, message: %.*s\n", + context, m->reply_code, (int)m->reply_text.len, + (char *)m->reply_text.bytes); + break; + } + default: + fprintf(stderr, "%s: unknown server error, method id 0x%08X\n", + context, x.reply.id); + break; + } + break; + } + + exit(1); +} + +static void dump_row(long count, int numinrow, int *chs) { + int i; + + printf("%08lX:", count - numinrow); + + if (numinrow > 0) { + for (i = 0; i < numinrow; i++) { + if (i == 8) { + printf(" :"); + } + printf(" %02X", chs[i]); + } + for (i = numinrow; i < 16; i++) { + if (i == 8) { + printf(" :"); + } + printf(" "); + } + printf(" "); + for (i = 0; i < numinrow; i++) { + if (isprint(chs[i])) { + printf("%c", chs[i]); + } else { + printf("."); + } + } + } + printf("\n"); +} + +static int rows_eq(int *a, int *b) { + int i; + + for (i = 0; i < 16; i++) + if (a[i] != b[i]) { + return 0; + } + + return 1; +} + +void amqp_dump(void const *buffer, size_t len) { + unsigned char *buf = (unsigned char *)buffer; + long count = 0; + int numinrow = 0; + int chs[16]; + int oldchs[16] = {0}; + int showed_dots = 0; + size_t i; + + for (i = 0; i < len; i++) { + int ch = buf[i]; + + if (numinrow == 16) { + int j; + + if (rows_eq(oldchs, chs)) { + if (!showed_dots) { + showed_dots = 1; + printf( + " .. .. .. .. .. .. .. .. : .. .. .. .. .. .. .. ..\n"); + } + } else { + showed_dots = 0; + dump_row(count, numinrow, chs); + } + + for (j = 0; j < 16; j++) { + oldchs[j] = chs[j]; + } + + numinrow = 0; + } + + count++; + chs[numinrow++] = ch; + } + + dump_row(count, numinrow, chs); + + if (numinrow != 0) { + printf("%08lX:\n", count); + } +} diff --git a/ext/librabbitmq/examples/utils.h b/ext/librabbitmq/examples/utils.h new file mode 100644 index 00000000..0fa7392a --- /dev/null +++ b/ext/librabbitmq/examples/utils.h @@ -0,0 +1,48 @@ +#ifndef librabbitmq_examples_utils_h +#define librabbitmq_examples_utils_h + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +void die(const char *fmt, ...); +extern void die_on_error(int x, char const *context); +extern void die_on_amqp_error(amqp_rpc_reply_t x, char const *context); + +extern void amqp_dump(void const *buffer, size_t len); + +extern uint64_t now_microseconds(void); +extern void microsleep(int usec); + +#endif diff --git a/ext/librabbitmq/examples/win32/platform_utils.c b/ext/librabbitmq/examples/win32/platform_utils.c new file mode 100644 index 00000000..49fd377e --- /dev/null +++ b/ext/librabbitmq/examples/win32/platform_utils.c @@ -0,0 +1,47 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include + +#include + +uint64_t now_microseconds(void) { + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + return (((uint64_t)ft.dwHighDateTime << 32) | (uint64_t)ft.dwLowDateTime) / + 10; +} + +void microsleep(int usec) { Sleep(usec / 1000); } diff --git a/ext/librabbitmq/librabbitmq.pc.in b/ext/librabbitmq/librabbitmq.pc.in new file mode 100644 index 00000000..17c1e083 --- /dev/null +++ b/ext/librabbitmq/librabbitmq.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: rabbitmq-c +Description: An AMQP 0-9-1 client library +Version: @VERSION@ +URL: https://github.com/alanxz/rabbitmq-c +Requires.private: @requires_private@ +Libs: -L${libdir} -lrabbitmq +Libs.private: @libs_private@ +CFlags: -I${includedir} diff --git a/ext/librabbitmq/librabbitmq/CMakeLists.txt b/ext/librabbitmq/librabbitmq/CMakeLists.txt new file mode 100644 index 00000000..bd5369a8 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/CMakeLists.txt @@ -0,0 +1,186 @@ +project(librabbitmq "C") + +if (REGENERATE_AMQP_FRAMING) + set(AMQP_CODEGEN_PY "${CMAKE_CURRENT_BINARY_DIR}/amqp_codegen.py") + set(CODEGEN_PY "${CMAKE_CURRENT_BINARY_DIR}/codegen.py") + set(AMQP_SPEC_JSON_PATH "${AMQP_CODEGEN_DIR}/amqp-rabbitmq-0.9.1.json") + set(AMQP_FRAMING_H_PATH ${CMAKE_CURRENT_BINARY_DIR}/amqp_framing.h) + set(AMQP_FRAMING_C_PATH ${CMAKE_CURRENT_BINARY_DIR}/amqp_framing.c) + + if (PYTHON_VERSION_MAJOR GREATER 2) + set(CONVERT_CODEGEN ${PYTHON_2TO3_EXECUTABLE} -w ${CODEGEN_PY} > codegen_2to3.out) + set(CONVERT_AMQP_CODEGEN ${PYTHON_2TO3_EXECUTABLE} -w ${AMQP_CODEGEN_PY} > amqp_codegen_2to3.out) + else () + set(CONVERT_CODEGEN "") + set(CONVERT_AMQP_CODEGEN "") + endif () + + add_custom_command( + OUTPUT ${CODEGEN_PY} + COMMAND ${CMAKE_COMMAND} ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/codegen.py ${CODEGEN_PY} + COMMAND ${CONVERT_CODEGEN} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/codegen.py + VERBATIM) + + add_custom_command( + OUTPUT ${AMQP_CODEGEN_PY} + COMMAND ${CMAKE_COMMAND} ARGS -E copy ${AMQP_CODEGEN_DIR}/amqp_codegen.py ${AMQP_CODEGEN_PY} + COMMAND ${CONVERT_AMQP_CODEGEN} + DEPENDS ${AMQP_CODEGEN_DIR}/amqp_codegen.py ${AMQP_CODEGEN_TARGET} + VERBATIM) + + add_custom_command( + OUTPUT ${AMQP_FRAMING_H_PATH} + COMMAND ${PYTHON_EXECUTABLE} ARGS ${CODEGEN_PY} header ${AMQP_SPEC_JSON_PATH} ${AMQP_FRAMING_H_PATH} + DEPENDS ${AMQP_SPEC_JSON_PATH} ${CODEGEN_PY} ${AMQP_CODEGEN_PY} + VERBATIM) + + add_custom_command( + OUTPUT ${AMQP_FRAMING_C_PATH} + COMMAND ${PYTHON_EXECUTABLE} ARGS ${CODEGEN_PY} body ${AMQP_SPEC_JSON_PATH} ${AMQP_FRAMING_C_PATH} + DEPENDS ${AMQP_SPEC_JSON_PATH} ${CODEGEN_PY} ${AMQP_CODEGEN_PY} + VERBATIM) +else (REGENERATE_AMQP_FRAMING) + set(AMQP_FRAMING_H_PATH ${CMAKE_CURRENT_SOURCE_DIR}/amqp_framing.h) + set(AMQP_FRAMING_C_PATH ${CMAKE_CURRENT_SOURCE_DIR}/amqp_framing.c) +endif (REGENERATE_AMQP_FRAMING) + +if(WIN32) + set(SOCKET_IMPL "win32") +else(WIN32) + set(SOCKET_IMPL "unix") +endif(WIN32) + +if(MSVC) + if(MSVC_VERSION LESS 1600) + set(MSINTTYPES_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/win32/msinttypes") + set(STDINT_H_INSTALL_FILE "${CMAKE_CURRENT_SOURCE_DIR}/win32/msinttypes/stdint.h") + endif(MSVC_VERSION LESS 1600) +endif(MSVC) + +# NOTE: order is important here: if we generate amqp_framing.h/.c it'll be in the +# binary directory, and should shadow whats in the source directory +set(LIBRABBITMQ_INCLUDE_DIRS + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${SOCKET_IMPL} + ${MSINTTYPES_INCLUDE} + ) + +include_directories(${LIBRABBITMQ_INCLUDE_DIRS}) + +set(LIBRABBITMQ_INCLUDE_DIRS + ${LIBRABBITMQ_INCLUDE_DIRS} + PARENT_SCOPE) + +add_definitions(-DHAVE_CONFIG_H) + +if (ENABLE_SSL_SUPPORT) + add_definitions(-DWITH_SSL=1) + set(AMQP_SSL_SOCKET_H_PATH amqp_ssl_socket.h) + + set(AMQP_SSL_SRCS ${AMQP_SSL_SOCKET_H_PATH} + amqp_openssl.c + amqp_openssl_hostname_validation.c + amqp_openssl_hostname_validation.h + amqp_hostcheck.c + amqp_hostcheck.h + amqp_openssl_bio.c + amqp_openssl_bio.h + ) + include_directories(${OPENSSL_INCLUDE_DIR}) + set(AMQP_SSL_LIBS ${OPENSSL_LIBRARIES}) + if (APPLE) + # Apple has deprecated OpenSSL in 10.7+. This disables that warning. + set_source_files_properties(${AMQP_SSL_SRCS} + PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations) + endif() + + if (WIN32) + set(AMQP_SSL_SRCS ${AMQP_SSL_SRCS} win32/threads.h win32/threads.c) + else() + set(AMQP_SSL_SRCS ${AMQP_SSL_SRCS} unix/threads.h) + endif() +endif() + +set(RABBITMQ_SOURCES + ${AMQP_FRAMING_H_PATH} + ${AMQP_FRAMING_C_PATH} + amqp_api.c amqp.h amqp_connection.c amqp_mem.c amqp_private.h amqp_socket.c + amqp_table.c amqp_url.c amqp_socket.h amqp_tcp_socket.c amqp_tcp_socket.h + amqp_time.c amqp_time.h + amqp_consumer.c + ${AMQP_SSL_SRCS} +) + +add_definitions(-DAMQP_BUILD) + +set(RMQ_LIBRARIES ${AMQP_SSL_LIBS} ${SOCKET_LIBRARIES} ${LIBRT} ${CMAKE_THREAD_LIBS_INIT}) + +if (BUILD_SHARED_LIBS) + add_library(rabbitmq SHARED ${RABBITMQ_SOURCES}) + if (THREADS_HAVE_PTHREAD_ARG) + target_compile_options(rabbitmq PUBLIC "-pthread") + endif() + + target_link_libraries(rabbitmq ${RMQ_LIBRARIES}) + + if (WIN32) + set_target_properties(rabbitmq PROPERTIES VERSION ${RMQ_VERSION} OUTPUT_NAME rabbitmq.${RMQ_SOVERSION}) + else (WIN32) + set_target_properties(rabbitmq PROPERTIES VERSION ${RMQ_VERSION} SOVERSION ${RMQ_SOVERSION}) + endif (WIN32) + + install(TARGETS rabbitmq + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + + set(RMQ_LIBRARY_TARGET rabbitmq) +endif (BUILD_SHARED_LIBS) + +if (BUILD_STATIC_LIBS) + add_library(rabbitmq-static STATIC ${RABBITMQ_SOURCES}) + if (THREADS_HAVE_PTHREAD_ARG) + target_compile_options(rabbitmq-static PUBLIC "-pthread") + endif() + + target_link_libraries(rabbitmq-static ${RMQ_LIBRARIES}) + + set_target_properties(rabbitmq-static PROPERTIES COMPILE_DEFINITIONS AMQP_STATIC) + if (WIN32) + set_target_properties(rabbitmq-static PROPERTIES + VERSION ${RMQ_VERSION} + OUTPUT_NAME librabbitmq.${RMQ_SOVERSION}) + + if(MSVC) + set_target_properties(rabbitmq-static PROPERTIES + # Embed debugging info in the library itself instead of generating + # a .pdb file. + COMPILE_OPTIONS "/Z7") + endif(MSVC) + + else (WIN32) + set_target_properties(rabbitmq-static PROPERTIES VERSION ${RMQ_VERSION} SOVERSION ${RMQ_SOVERSION} OUTPUT_NAME rabbitmq) + endif (WIN32) + + install(TARGETS rabbitmq-static + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) + + if (NOT DEFINED RMQ_LIBRARY_TARGET) + set(RMQ_LIBRARY_TARGET rabbitmq-static) + endif () +endif (BUILD_STATIC_LIBS) + +install(FILES + amqp.h + ${AMQP_FRAMING_H_PATH} + amqp_tcp_socket.h + ${AMQP_SSL_SOCKET_H_PATH} + ${STDINT_H_INSTALL_FILE} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + +set(RMQ_LIBRARY_TARGET ${RMQ_LIBRARY_TARGET} PARENT_SCOPE) diff --git a/ext/librabbitmq/centos_x64/include/amqp.h b/ext/librabbitmq/librabbitmq/amqp.h similarity index 99% rename from ext/librabbitmq/centos_x64/include/amqp.h rename to ext/librabbitmq/librabbitmq/amqp.h index 2983b166..734abb8d 100644 --- a/ext/librabbitmq/centos_x64/include/amqp.h +++ b/ext/librabbitmq/librabbitmq/amqp.h @@ -219,9 +219,9 @@ AMQP_BEGIN_DECLS */ #define AMQP_VERSION_MAJOR 0 -#define AMQP_VERSION_MINOR 10 +#define AMQP_VERSION_MINOR 9 #define AMQP_VERSION_PATCH 0 -#define AMQP_VERSION_IS_RELEASE 0 +#define AMQP_VERSION_IS_RELEASE 1 /** * \def AMQP_VERSION_CODE @@ -328,16 +328,13 @@ char const *AMQP_CALL amqp_version(void); /** * \def AMQP_DEFAULT_MAX_CHANNELS * - * Default maximum number of channels (2047, RabbitMQ default limit of 2048, - * minus 1 for channel 0). RabbitMQ set a default limit of 2048 channels per - * connection in v3.7.5 to prevent broken clients from leaking too many - * channels. + * Default maximum number of channels (0, no limit) * * \sa amqp_login(), amqp_login_with_properties() * * \since v0.4.0 */ -#define AMQP_DEFAULT_MAX_CHANNELS 2047 +#define AMQP_DEFAULT_MAX_CHANNELS 0 /** * \def AMQP_DEFAULT_HEARTBEAT diff --git a/ext/librabbitmq/librabbitmq/amqp_api.c b/ext/librabbitmq/librabbitmq/amqp_api.c new file mode 100644 index 00000000..28b23847 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_api.c @@ -0,0 +1,394 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _MSC_VER +/* MSVC complains about sprintf being deprecated in favor of sprintf_s */ +#define _CRT_SECURE_NO_WARNINGS +/* MSVC complains about strdup being deprecated in favor of _strdup */ +#define _CRT_NONSTDC_NO_DEPRECATE +#endif + +#include "amqp_private.h" +#include "amqp_time.h" +#include +#include +#include +#include +#include + +#define ERROR_MASK (0x00FF) +#define ERROR_CATEGORY_MASK (0xFF00) + +enum error_category_enum_ { EC_base = 0, EC_tcp = 1, EC_ssl = 2 }; + +static const char *base_error_strings[] = { + /* AMQP_STATUS_OK 0x0 */ + "operation completed successfully", + /* AMQP_STATUS_NO_MEMORY -0x0001 */ + "could not allocate memory", + /* AMQP_STATUS_BAD_AQMP_DATA -0x0002 */ + "invalid AMQP data", + /* AMQP_STATUS_UNKNOWN_CLASS -0x0003 */ + "unknown AMQP class id", + /* AMQP_STATUS_UNKNOWN_METHOD -0x0004 */ + "unknown AMQP method id", + /* AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED -0x0005 */ + "hostname lookup failed", + /* AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION -0x0006 */ + "incompatible AMQP version", + /* AMQP_STATUS_CONNECTION_CLOSED -0x0007 */ + "connection closed unexpectedly", + /* AMQP_STATUS_BAD_AMQP_URL -0x0008 */ + "could not parse AMQP URL", + /* AMQP_STATUS_SOCKET_ERROR -0x0009 */ + "a socket error occurred", + /* AMQP_STATUS_INVALID_PARAMETER -0x000A */ + "invalid parameter", + /* AMQP_STATUS_TABLE_TOO_BIG -0x000B */ + "table too large for buffer", + /* AMQP_STATUS_WRONG_METHOD -0x000C */ + "unexpected method received", + /* AMQP_STATUS_TIMEOUT -0x000D */ + "request timed out", + /* AMQP_STATUS_TIMER_FAILED -0x000E */ + "system timer has failed", + /* AMQP_STATUS_HEARTBEAT_TIMEOUT -0x000F */ + "heartbeat timeout, connection closed", + /* AMQP_STATUS_UNEXPECTED STATE -0x0010 */ + "unexpected protocol state", + /* AMQP_STATUS_SOCKET_CLOSED -0x0011 */ + "socket is closed", + /* AMQP_STATUS_SOCKET_INUSE -0x0012 */ + "socket already open", + /* AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD -0x00013 */ + "unsupported sasl method requested", + /* AMQP_STATUS_UNSUPPORTED -0x0014 */ + "parameter value is unsupported"}; + +static const char *tcp_error_strings[] = { + /* AMQP_STATUS_TCP_ERROR -0x0100 */ + "a socket error occurred", + /* AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR -0x0101 */ + "socket library initialization failed"}; + +static const char *ssl_error_strings[] = { + /* AMQP_STATUS_SSL_ERRO R -0x0200 */ + "a SSL error occurred", + /* AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED -0x0201 */ + "SSL hostname verification failed", + /* AMQP_STATUS_SSL_PEER_VERIFY_FAILED -0x0202 */ + "SSL peer cert verification failed", + /* AMQP_STATUS_SSL_CONNECTION_FAILED -0x0203 */ + "SSL handshake failed"}; + +static const char *unknown_error_string = "(unknown error)"; + +const char *amqp_error_string2(int code) { + const char *error_string; + size_t category = (((-code) & ERROR_CATEGORY_MASK) >> 8); + size_t error = (-code) & ERROR_MASK; + + switch (category) { + case EC_base: + if (error < (sizeof(base_error_strings) / sizeof(char *))) { + error_string = base_error_strings[error]; + } else { + error_string = unknown_error_string; + } + break; + + case EC_tcp: + if (error < (sizeof(tcp_error_strings) / sizeof(char *))) { + error_string = tcp_error_strings[error]; + } else { + error_string = unknown_error_string; + } + break; + + case EC_ssl: + if (error < (sizeof(ssl_error_strings) / sizeof(char *))) { + error_string = ssl_error_strings[error]; + } else { + error_string = unknown_error_string; + } + + break; + + default: + error_string = unknown_error_string; + break; + } + + return error_string; +} + +char *amqp_error_string(int code) { + /* Previously sometimes clients had to flip the sign on a return value from a + * function to get the correct error code. Now, all error codes are negative. + * To keep people's legacy code running correctly, we map all error codes to + * negative values. + * + * This is only done with this deprecated function. + */ + if (code > 0) { + code = -code; + } + return strdup(amqp_error_string2(code)); +} + +void amqp_abort(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); + abort(); +} + +const amqp_bytes_t amqp_empty_bytes = {0, NULL}; +const amqp_table_t amqp_empty_table = {0, NULL}; +const amqp_array_t amqp_empty_array = {0, NULL}; + +int amqp_basic_publish(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_bytes_t routing_key, + amqp_boolean_t mandatory, amqp_boolean_t immediate, + amqp_basic_properties_t const *properties, + amqp_bytes_t body) { + amqp_frame_t f; + size_t body_offset; + size_t usable_body_payload_size = + state->frame_max - (HEADER_SIZE + FOOTER_SIZE); + int res; + int flagz; + + amqp_basic_publish_t m; + amqp_basic_properties_t default_properties; + + m.exchange = exchange; + m.routing_key = routing_key; + m.mandatory = mandatory; + m.immediate = immediate; + m.ticket = 0; + + /* TODO(alanxz): this heartbeat check is happening in the wrong place, it + * should really be done in amqp_try_send/writev */ + res = amqp_time_has_past(state->next_recv_heartbeat); + if (AMQP_STATUS_TIMER_FAILURE == res) { + return res; + } else if (AMQP_STATUS_TIMEOUT == res) { + res = amqp_try_recv(state); + if (AMQP_STATUS_TIMEOUT == res) { + return AMQP_STATUS_HEARTBEAT_TIMEOUT; + } else if (AMQP_STATUS_OK != res) { + return res; + } + } + + res = amqp_send_method_inner(state, channel, AMQP_BASIC_PUBLISH_METHOD, &m, + AMQP_SF_MORE, amqp_time_infinite()); + if (res < 0) { + return res; + } + + if (properties == NULL) { + memset(&default_properties, 0, sizeof(default_properties)); + properties = &default_properties; + } + + f.frame_type = AMQP_FRAME_HEADER; + f.channel = channel; + f.payload.properties.class_id = AMQP_BASIC_CLASS; + f.payload.properties.body_size = body.len; + f.payload.properties.decoded = (void *)properties; + + if (body.len > 0) { + flagz = AMQP_SF_MORE; + } else { + flagz = AMQP_SF_NONE; + } + res = amqp_send_frame_inner(state, &f, flagz, amqp_time_infinite()); + if (res < 0) { + return res; + } + + body_offset = 0; + while (body_offset < body.len) { + size_t remaining = body.len - body_offset; + + if (remaining == 0) { + break; + } + + f.frame_type = AMQP_FRAME_BODY; + f.channel = channel; + f.payload.body_fragment.bytes = amqp_offset(body.bytes, body_offset); + if (remaining >= usable_body_payload_size) { + f.payload.body_fragment.len = usable_body_payload_size; + flagz = AMQP_SF_MORE; + } else { + f.payload.body_fragment.len = remaining; + flagz = AMQP_SF_NONE; + } + + body_offset += f.payload.body_fragment.len; + res = amqp_send_frame_inner(state, &f, flagz, amqp_time_infinite()); + if (res < 0) { + return res; + } + } + + return AMQP_STATUS_OK; +} + +amqp_rpc_reply_t amqp_channel_close(amqp_connection_state_t state, + amqp_channel_t channel, int code) { + char codestr[13]; + amqp_method_number_t replies[2] = {AMQP_CHANNEL_CLOSE_OK_METHOD, 0}; + amqp_channel_close_t req; + + if (code < 0 || code > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + + req.reply_code = (uint16_t)code; + req.reply_text.bytes = codestr; + req.reply_text.len = sprintf(codestr, "%d", code); + req.class_id = 0; + req.method_id = 0; + + return amqp_simple_rpc(state, channel, AMQP_CHANNEL_CLOSE_METHOD, replies, + &req); +} + +amqp_rpc_reply_t amqp_connection_close(amqp_connection_state_t state, + int code) { + char codestr[13]; + amqp_method_number_t replies[2] = {AMQP_CONNECTION_CLOSE_OK_METHOD, 0}; + amqp_channel_close_t req; + + if (code < 0 || code > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + + req.reply_code = (uint16_t)code; + req.reply_text.bytes = codestr; + req.reply_text.len = sprintf(codestr, "%d", code); + req.class_id = 0; + req.method_id = 0; + + return amqp_simple_rpc(state, 0, AMQP_CONNECTION_CLOSE_METHOD, replies, &req); +} + +int amqp_basic_ack(amqp_connection_state_t state, amqp_channel_t channel, + uint64_t delivery_tag, amqp_boolean_t multiple) { + amqp_basic_ack_t m; + m.delivery_tag = delivery_tag; + m.multiple = multiple; + return amqp_send_method(state, channel, AMQP_BASIC_ACK_METHOD, &m); +} + +amqp_rpc_reply_t amqp_basic_get(amqp_connection_state_t state, + amqp_channel_t channel, amqp_bytes_t queue, + amqp_boolean_t no_ack) { + amqp_method_number_t replies[] = {AMQP_BASIC_GET_OK_METHOD, + AMQP_BASIC_GET_EMPTY_METHOD, 0}; + amqp_basic_get_t req; + req.ticket = 0; + req.queue = queue; + req.no_ack = no_ack; + + state->most_recent_api_result = + amqp_simple_rpc(state, channel, AMQP_BASIC_GET_METHOD, replies, &req); + return state->most_recent_api_result; +} + +int amqp_basic_reject(amqp_connection_state_t state, amqp_channel_t channel, + uint64_t delivery_tag, amqp_boolean_t requeue) { + amqp_basic_reject_t req; + req.delivery_tag = delivery_tag; + req.requeue = requeue; + return amqp_send_method(state, channel, AMQP_BASIC_REJECT_METHOD, &req); +} + +int amqp_basic_nack(amqp_connection_state_t state, amqp_channel_t channel, + uint64_t delivery_tag, amqp_boolean_t multiple, + amqp_boolean_t requeue) { + amqp_basic_nack_t req; + req.delivery_tag = delivery_tag; + req.multiple = multiple; + req.requeue = requeue; + return amqp_send_method(state, channel, AMQP_BASIC_NACK_METHOD, &req); +} + +struct timeval *amqp_get_handshake_timeout(amqp_connection_state_t state) { + return state->handshake_timeout; +} + +int amqp_set_handshake_timeout(amqp_connection_state_t state, + struct timeval *timeout) { + if (timeout) { + if (timeout->tv_sec < 0 || timeout->tv_usec < 0) { + return AMQP_STATUS_INVALID_PARAMETER; + } + state->internal_handshake_timeout = *timeout; + state->handshake_timeout = &state->internal_handshake_timeout; + } else { + state->handshake_timeout = NULL; + } + + return AMQP_STATUS_OK; +} + +struct timeval *amqp_get_rpc_timeout(amqp_connection_state_t state) { + return state->rpc_timeout; +} + +int amqp_set_rpc_timeout(amqp_connection_state_t state, + struct timeval *timeout) { + if (timeout) { + if (timeout->tv_sec < 0 || timeout->tv_usec < 0) { + return AMQP_STATUS_INVALID_PARAMETER; + } + state->rpc_timeout = &state->internal_rpc_timeout; + *state->rpc_timeout = *timeout; + } else { + state->rpc_timeout = NULL; + } + return AMQP_STATUS_OK; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_connection.c b/ext/librabbitmq/librabbitmq/amqp_connection.c new file mode 100644 index 00000000..034b2e96 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_connection.c @@ -0,0 +1,595 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2014 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "amqp_private.h" +#include "amqp_tcp_socket.h" +#include "amqp_time.h" +#include +#include +#include +#include +#include + +#ifndef AMQP_INITIAL_FRAME_POOL_PAGE_SIZE +#define AMQP_INITIAL_FRAME_POOL_PAGE_SIZE 65536 +#endif + +#ifndef AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE +#define AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE 131072 +#endif + +#ifndef AMQP_DEFAULT_LOGIN_TIMEOUT_SEC +#define AMQP_DEFAULT_LOGIN_TIMEOUT_SEC 12 +#endif + +#define ENFORCE_STATE(statevec, statenum) \ + { \ + amqp_connection_state_t _check_state = (statevec); \ + amqp_connection_state_enum _wanted_state = (statenum); \ + if (_check_state->state != _wanted_state) \ + amqp_abort( \ + "Programming error: invalid AMQP connection state: expected %d, " \ + "got %d", \ + _wanted_state, _check_state->state); \ + } + +amqp_connection_state_t amqp_new_connection(void) { + int res; + amqp_connection_state_t state = (amqp_connection_state_t)calloc( + 1, sizeof(struct amqp_connection_state_t_)); + + if (state == NULL) { + return NULL; + } + + res = amqp_tune_connection(state, 0, AMQP_INITIAL_FRAME_POOL_PAGE_SIZE, 0); + if (0 != res) { + goto out_nomem; + } + + state->inbound_buffer.bytes = state->header_buffer; + state->inbound_buffer.len = sizeof(state->header_buffer); + + state->state = CONNECTION_STATE_INITIAL; + /* the server protocol version response is 8 bytes, which conveniently + is also the minimum frame size */ + state->target_size = 8; + + state->sock_inbound_buffer.len = AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE; + state->sock_inbound_buffer.bytes = + malloc(AMQP_INITIAL_INBOUND_SOCK_BUFFER_SIZE); + if (state->sock_inbound_buffer.bytes == NULL) { + goto out_nomem; + } + + init_amqp_pool(&state->properties_pool, 512); + + /* Use address of the internal_handshake_timeout object by default. */ + state->internal_handshake_timeout.tv_sec = AMQP_DEFAULT_LOGIN_TIMEOUT_SEC; + state->internal_handshake_timeout.tv_usec = 0; + state->handshake_timeout = &state->internal_handshake_timeout; + + return state; + +out_nomem: + free(state->sock_inbound_buffer.bytes); + free(state); + return NULL; +} + +int amqp_get_sockfd(amqp_connection_state_t state) { + return state->socket ? amqp_socket_get_sockfd(state->socket) : -1; +} + +void amqp_set_sockfd(amqp_connection_state_t state, int sockfd) { + amqp_socket_t *socket = amqp_tcp_socket_new(state); + if (!socket) { + amqp_abort("%s", strerror(errno)); + } + amqp_tcp_socket_set_sockfd(socket, sockfd); +} + +void amqp_set_socket(amqp_connection_state_t state, amqp_socket_t *socket) { + amqp_socket_delete(state->socket); + state->socket = socket; +} + +amqp_socket_t *amqp_get_socket(amqp_connection_state_t state) { + return state->socket; +} + +int amqp_tune_connection(amqp_connection_state_t state, int channel_max, + int frame_max, int heartbeat) { + void *newbuf; + int res; + + ENFORCE_STATE(state, CONNECTION_STATE_IDLE); + + state->channel_max = channel_max; + state->frame_max = frame_max; + + state->heartbeat = heartbeat; + if (0 > state->heartbeat) { + state->heartbeat = 0; + } + + res = amqp_time_s_from_now(&state->next_send_heartbeat, + amqp_heartbeat_send(state)); + if (AMQP_STATUS_OK != res) { + return res; + } + res = amqp_time_s_from_now(&state->next_recv_heartbeat, + amqp_heartbeat_recv(state)); + if (AMQP_STATUS_OK != res) { + return res; + } + + state->outbound_buffer.len = frame_max; + newbuf = realloc(state->outbound_buffer.bytes, frame_max); + if (newbuf == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + state->outbound_buffer.bytes = newbuf; + + return AMQP_STATUS_OK; +} + +int amqp_get_channel_max(amqp_connection_state_t state) { + return state->channel_max; +} + +int amqp_get_frame_max(amqp_connection_state_t state) { + return state->frame_max; +} + +int amqp_get_heartbeat(amqp_connection_state_t state) { + return state->heartbeat; +} + +int amqp_destroy_connection(amqp_connection_state_t state) { + int status = AMQP_STATUS_OK; + if (state) { + int i; + for (i = 0; i < POOL_TABLE_SIZE; ++i) { + amqp_pool_table_entry_t *entry = state->pool_table[i]; + while (NULL != entry) { + amqp_pool_table_entry_t *todelete = entry; + empty_amqp_pool(&entry->pool); + entry = entry->next; + free(todelete); + } + } + + free(state->outbound_buffer.bytes); + free(state->sock_inbound_buffer.bytes); + amqp_socket_delete(state->socket); + empty_amqp_pool(&state->properties_pool); + free(state); + } + return status; +} + +static void return_to_idle(amqp_connection_state_t state) { + state->inbound_buffer.len = sizeof(state->header_buffer); + state->inbound_buffer.bytes = state->header_buffer; + state->inbound_offset = 0; + state->target_size = HEADER_SIZE; + state->state = CONNECTION_STATE_IDLE; +} + +static size_t consume_data(amqp_connection_state_t state, + amqp_bytes_t *received_data) { + /* how much data is available and will fit? */ + size_t bytes_consumed = state->target_size - state->inbound_offset; + if (received_data->len < bytes_consumed) { + bytes_consumed = received_data->len; + } + + memcpy(amqp_offset(state->inbound_buffer.bytes, state->inbound_offset), + received_data->bytes, bytes_consumed); + state->inbound_offset += bytes_consumed; + received_data->bytes = amqp_offset(received_data->bytes, bytes_consumed); + received_data->len -= bytes_consumed; + + return bytes_consumed; +} + +int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data, + amqp_frame_t *decoded_frame) { + size_t bytes_consumed; + void *raw_frame; + + /* Returning frame_type of zero indicates either insufficient input, + or a complete, ignored frame was read. */ + decoded_frame->frame_type = 0; + + if (received_data.len == 0) { + return AMQP_STATUS_OK; + } + + if (state->state == CONNECTION_STATE_IDLE) { + state->state = CONNECTION_STATE_HEADER; + } + + bytes_consumed = consume_data(state, &received_data); + + /* do we have target_size data yet? if not, return with the + expectation that more will arrive */ + if (state->inbound_offset < state->target_size) { + return (int)bytes_consumed; + } + + raw_frame = state->inbound_buffer.bytes; + + switch (state->state) { + case CONNECTION_STATE_INITIAL: + /* check for a protocol header from the server */ + if (memcmp(raw_frame, "AMQP", 4) == 0) { + decoded_frame->frame_type = AMQP_PSEUDOFRAME_PROTOCOL_HEADER; + decoded_frame->channel = 0; + + decoded_frame->payload.protocol_header.transport_high = + amqp_d8(amqp_offset(raw_frame, 4)); + decoded_frame->payload.protocol_header.transport_low = + amqp_d8(amqp_offset(raw_frame, 5)); + decoded_frame->payload.protocol_header.protocol_version_major = + amqp_d8(amqp_offset(raw_frame, 6)); + decoded_frame->payload.protocol_header.protocol_version_minor = + amqp_d8(amqp_offset(raw_frame, 7)); + + return_to_idle(state); + return (int)bytes_consumed; + } + + /* it's not a protocol header; fall through to process it as a + regular frame header */ + + case CONNECTION_STATE_HEADER: { + amqp_channel_t channel; + amqp_pool_t *channel_pool; + /* frame length is 3 bytes in */ + channel = amqp_d16(amqp_offset(raw_frame, 1)); + + state->target_size = + amqp_d32(amqp_offset(raw_frame, 3)) + HEADER_SIZE + FOOTER_SIZE; + + if ((size_t)state->frame_max < state->target_size) { + return AMQP_STATUS_BAD_AMQP_DATA; + } + + channel_pool = amqp_get_or_create_channel_pool(state, channel); + if (NULL == channel_pool) { + return AMQP_STATUS_NO_MEMORY; + } + + amqp_pool_alloc_bytes(channel_pool, state->target_size, + &state->inbound_buffer); + if (NULL == state->inbound_buffer.bytes) { + return AMQP_STATUS_NO_MEMORY; + } + memcpy(state->inbound_buffer.bytes, state->header_buffer, HEADER_SIZE); + raw_frame = state->inbound_buffer.bytes; + + state->state = CONNECTION_STATE_BODY; + + bytes_consumed += consume_data(state, &received_data); + + /* do we have target_size data yet? if not, return with the + expectation that more will arrive */ + if (state->inbound_offset < state->target_size) { + return (int)bytes_consumed; + } + } + /* fall through to process body */ + + case CONNECTION_STATE_BODY: { + amqp_bytes_t encoded; + int res; + amqp_pool_t *channel_pool; + + /* Check frame end marker (footer) */ + if (amqp_d8(amqp_offset(raw_frame, state->target_size - 1)) != + AMQP_FRAME_END) { + return AMQP_STATUS_BAD_AMQP_DATA; + } + + decoded_frame->frame_type = amqp_d8(amqp_offset(raw_frame, 0)); + decoded_frame->channel = amqp_d16(amqp_offset(raw_frame, 1)); + + channel_pool = + amqp_get_or_create_channel_pool(state, decoded_frame->channel); + if (NULL == channel_pool) { + return AMQP_STATUS_NO_MEMORY; + } + + switch (decoded_frame->frame_type) { + case AMQP_FRAME_METHOD: + decoded_frame->payload.method.id = + amqp_d32(amqp_offset(raw_frame, HEADER_SIZE)); + encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 4); + encoded.len = state->target_size - HEADER_SIZE - 4 - FOOTER_SIZE; + + res = amqp_decode_method(decoded_frame->payload.method.id, + channel_pool, encoded, + &decoded_frame->payload.method.decoded); + if (res < 0) { + return res; + } + + break; + + case AMQP_FRAME_HEADER: + decoded_frame->payload.properties.class_id = + amqp_d16(amqp_offset(raw_frame, HEADER_SIZE)); + /* unused 2-byte weight field goes here */ + decoded_frame->payload.properties.body_size = + amqp_d64(amqp_offset(raw_frame, HEADER_SIZE + 4)); + encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 12); + encoded.len = state->target_size - HEADER_SIZE - 12 - FOOTER_SIZE; + decoded_frame->payload.properties.raw = encoded; + + res = amqp_decode_properties( + decoded_frame->payload.properties.class_id, channel_pool, encoded, + &decoded_frame->payload.properties.decoded); + if (res < 0) { + return res; + } + + break; + + case AMQP_FRAME_BODY: + decoded_frame->payload.body_fragment.len = + state->target_size - HEADER_SIZE - FOOTER_SIZE; + decoded_frame->payload.body_fragment.bytes = + amqp_offset(raw_frame, HEADER_SIZE); + break; + + case AMQP_FRAME_HEARTBEAT: + break; + + default: + /* Ignore the frame */ + decoded_frame->frame_type = 0; + break; + } + + return_to_idle(state); + return (int)bytes_consumed; + } + + default: + amqp_abort("Internal error: invalid amqp_connection_state_t->state %d", + state->state); + } +} + +amqp_boolean_t amqp_release_buffers_ok(amqp_connection_state_t state) { + return (state->state == CONNECTION_STATE_IDLE); +} + +void amqp_release_buffers(amqp_connection_state_t state) { + int i; + ENFORCE_STATE(state, CONNECTION_STATE_IDLE); + + for (i = 0; i < POOL_TABLE_SIZE; ++i) { + amqp_pool_table_entry_t *entry = state->pool_table[i]; + + for (; NULL != entry; entry = entry->next) { + amqp_maybe_release_buffers_on_channel(state, entry->channel); + } + } +} + +void amqp_maybe_release_buffers(amqp_connection_state_t state) { + if (amqp_release_buffers_ok(state)) { + amqp_release_buffers(state); + } +} + +void amqp_maybe_release_buffers_on_channel(amqp_connection_state_t state, + amqp_channel_t channel) { + amqp_link_t *queued_link; + amqp_pool_t *pool; + if (CONNECTION_STATE_IDLE != state->state) { + return; + } + + queued_link = state->first_queued_frame; + + while (NULL != queued_link) { + amqp_frame_t *frame = queued_link->data; + if (channel == frame->channel) { + return; + } + + queued_link = queued_link->next; + } + + pool = amqp_get_channel_pool(state, channel); + + if (pool != NULL) { + recycle_amqp_pool(pool); + } +} + +static int amqp_frame_to_bytes(const amqp_frame_t *frame, amqp_bytes_t buffer, + amqp_bytes_t *encoded) { + void *out_frame = buffer.bytes; + size_t out_frame_len; + int res; + + amqp_e8(frame->frame_type, amqp_offset(out_frame, 0)); + amqp_e16(frame->channel, amqp_offset(out_frame, 1)); + + switch (frame->frame_type) { + case AMQP_FRAME_BODY: { + const amqp_bytes_t *body = &frame->payload.body_fragment; + + memcpy(amqp_offset(out_frame, HEADER_SIZE), body->bytes, body->len); + + out_frame_len = body->len; + break; + } + case AMQP_FRAME_METHOD: { + amqp_bytes_t method_encoded; + + amqp_e32(frame->payload.method.id, amqp_offset(out_frame, HEADER_SIZE)); + + method_encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 4); + method_encoded.len = buffer.len - HEADER_SIZE - 4 - FOOTER_SIZE; + + res = amqp_encode_method(frame->payload.method.id, + frame->payload.method.decoded, method_encoded); + if (res < 0) { + return res; + } + + out_frame_len = res + 4; + break; + } + + case AMQP_FRAME_HEADER: { + amqp_bytes_t properties_encoded; + + amqp_e16(frame->payload.properties.class_id, + amqp_offset(out_frame, HEADER_SIZE)); + amqp_e16(0, amqp_offset(out_frame, HEADER_SIZE + 2)); /* "weight" */ + amqp_e64(frame->payload.properties.body_size, + amqp_offset(out_frame, HEADER_SIZE + 4)); + + properties_encoded.bytes = amqp_offset(out_frame, HEADER_SIZE + 12); + properties_encoded.len = buffer.len - HEADER_SIZE - 12 - FOOTER_SIZE; + + res = amqp_encode_properties(frame->payload.properties.class_id, + frame->payload.properties.decoded, + properties_encoded); + if (res < 0) { + return res; + } + + out_frame_len = res + 12; + break; + } + + case AMQP_FRAME_HEARTBEAT: + out_frame_len = 0; + break; + + default: + return AMQP_STATUS_INVALID_PARAMETER; + } + + amqp_e32((uint32_t)out_frame_len, amqp_offset(out_frame, 3)); + amqp_e8(AMQP_FRAME_END, amqp_offset(out_frame, HEADER_SIZE + out_frame_len)); + + encoded->bytes = out_frame; + encoded->len = out_frame_len + HEADER_SIZE + FOOTER_SIZE; + + return AMQP_STATUS_OK; +} + +int amqp_send_frame(amqp_connection_state_t state, const amqp_frame_t *frame) { + return amqp_send_frame_inner(state, frame, AMQP_SF_NONE, + amqp_time_infinite()); +} + +int amqp_send_frame_inner(amqp_connection_state_t state, + const amqp_frame_t *frame, int flags, + amqp_time_t deadline) { + int res; + ssize_t sent; + amqp_bytes_t encoded; + amqp_time_t next_timeout; + + /* TODO: if the AMQP_SF_MORE socket optimization can be shown to work + * correctly, then this could be un-done so that body-frames are sent as 3 + * send calls, getting rid of the copy of the body content, some testing + * would need to be done to see if this would actually a win for performance. + * */ + res = amqp_frame_to_bytes(frame, state->outbound_buffer, &encoded); + if (AMQP_STATUS_OK != res) { + return res; + } + +start_send: + + next_timeout = amqp_time_first(deadline, state->next_recv_heartbeat); + + sent = amqp_try_send(state, encoded.bytes, encoded.len, next_timeout, flags); + if (0 > sent) { + return (int)sent; + } + + /* A partial send has occurred, because of a heartbeat timeout (so try recv + * something) or common timeout (so return AMQP_STATUS_TIMEOUT) */ + if ((ssize_t)encoded.len != sent) { + if (amqp_time_equal(next_timeout, deadline)) { + /* timeout of method was received, so return from method*/ + return AMQP_STATUS_TIMEOUT; + } + + res = amqp_try_recv(state); + + if (AMQP_STATUS_TIMEOUT == res) { + return AMQP_STATUS_HEARTBEAT_TIMEOUT; + } else if (AMQP_STATUS_OK != res) { + return res; + } + + encoded.bytes = (uint8_t *)encoded.bytes + sent; + encoded.len -= sent; + goto start_send; + } + + res = amqp_time_s_from_now(&state->next_send_heartbeat, + amqp_heartbeat_send(state)); + return res; +} + +amqp_table_t *amqp_get_server_properties(amqp_connection_state_t state) { + return &state->server_properties; +} + +amqp_table_t *amqp_get_client_properties(amqp_connection_state_t state) { + return &state->client_properties; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_consumer.c b/ext/librabbitmq/librabbitmq/amqp_consumer.c new file mode 100644 index 00000000..bb9095f9 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_consumer.c @@ -0,0 +1,307 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 + * Alan Antonuk. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ +#include "amqp.h" +#include "amqp_private.h" +#include "amqp_socket.h" + +#include +#include + +static int amqp_basic_properties_clone(amqp_basic_properties_t *original, + amqp_basic_properties_t *clone, + amqp_pool_t *pool) { + memset(clone, 0, sizeof(*clone)); + clone->_flags = original->_flags; + +#define CLONE_BYTES_POOL(original, clone, pool) \ + if (0 == original.len) { \ + clone = amqp_empty_bytes; \ + } else { \ + amqp_pool_alloc_bytes(pool, original.len, &clone); \ + if (NULL == clone.bytes) { \ + return AMQP_STATUS_NO_MEMORY; \ + } \ + memcpy(clone.bytes, original.bytes, clone.len); \ + } + + if (clone->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { + CLONE_BYTES_POOL(original->content_type, clone->content_type, pool) + } + + if (clone->_flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) { + CLONE_BYTES_POOL(original->content_encoding, clone->content_encoding, pool) + } + + if (clone->_flags & AMQP_BASIC_HEADERS_FLAG) { + int res = amqp_table_clone(&original->headers, &clone->headers, pool); + if (AMQP_STATUS_OK != res) { + return res; + } + } + + if (clone->_flags & AMQP_BASIC_DELIVERY_MODE_FLAG) { + clone->delivery_mode = original->delivery_mode; + } + + if (clone->_flags & AMQP_BASIC_PRIORITY_FLAG) { + clone->priority = original->priority; + } + + if (clone->_flags & AMQP_BASIC_CORRELATION_ID_FLAG) { + CLONE_BYTES_POOL(original->correlation_id, clone->correlation_id, pool) + } + + if (clone->_flags & AMQP_BASIC_REPLY_TO_FLAG) { + CLONE_BYTES_POOL(original->reply_to, clone->reply_to, pool) + } + + if (clone->_flags & AMQP_BASIC_EXPIRATION_FLAG) { + CLONE_BYTES_POOL(original->expiration, clone->expiration, pool) + } + + if (clone->_flags & AMQP_BASIC_MESSAGE_ID_FLAG) { + CLONE_BYTES_POOL(original->message_id, clone->message_id, pool) + } + + if (clone->_flags & AMQP_BASIC_TIMESTAMP_FLAG) { + clone->timestamp = original->timestamp; + } + + if (clone->_flags & AMQP_BASIC_TYPE_FLAG) { + CLONE_BYTES_POOL(original->type, clone->type, pool) + } + + if (clone->_flags & AMQP_BASIC_USER_ID_FLAG) { + CLONE_BYTES_POOL(original->user_id, clone->user_id, pool) + } + + if (clone->_flags & AMQP_BASIC_APP_ID_FLAG) { + CLONE_BYTES_POOL(original->app_id, clone->app_id, pool) + } + + if (clone->_flags & AMQP_BASIC_CLUSTER_ID_FLAG) { + CLONE_BYTES_POOL(original->cluster_id, clone->cluster_id, pool) + } + + return AMQP_STATUS_OK; +#undef CLONE_BYTES_POOL +} + +void amqp_destroy_message(amqp_message_t *message) { + empty_amqp_pool(&message->pool); + amqp_bytes_free(message->body); +} + +void amqp_destroy_envelope(amqp_envelope_t *envelope) { + amqp_destroy_message(&envelope->message); + amqp_bytes_free(envelope->routing_key); + amqp_bytes_free(envelope->exchange); + amqp_bytes_free(envelope->consumer_tag); +} + +static int amqp_bytes_malloc_dup_failed(amqp_bytes_t bytes) { + if (bytes.len != 0 && bytes.bytes == NULL) { + return 1; + } + return 0; +} + +amqp_rpc_reply_t amqp_consume_message(amqp_connection_state_t state, + amqp_envelope_t *envelope, + struct timeval *timeout, + AMQP_UNUSED int flags) { + int res; + amqp_frame_t frame; + amqp_basic_deliver_t *delivery_method; + amqp_rpc_reply_t ret; + + memset(&ret, 0, sizeof(ret)); + memset(envelope, 0, sizeof(*envelope)); + + res = amqp_simple_wait_frame_noblock(state, &frame, timeout); + if (AMQP_STATUS_OK != res) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = res; + goto error_out1; + } + + if (AMQP_FRAME_METHOD != frame.frame_type || + AMQP_BASIC_DELIVER_METHOD != frame.payload.method.id) { + amqp_put_back_frame(state, &frame); + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = AMQP_STATUS_UNEXPECTED_STATE; + goto error_out1; + } + + delivery_method = frame.payload.method.decoded; + + envelope->channel = frame.channel; + envelope->consumer_tag = amqp_bytes_malloc_dup(delivery_method->consumer_tag); + envelope->delivery_tag = delivery_method->delivery_tag; + envelope->redelivered = delivery_method->redelivered; + envelope->exchange = amqp_bytes_malloc_dup(delivery_method->exchange); + envelope->routing_key = amqp_bytes_malloc_dup(delivery_method->routing_key); + + if (amqp_bytes_malloc_dup_failed(envelope->consumer_tag) || + amqp_bytes_malloc_dup_failed(envelope->exchange) || + amqp_bytes_malloc_dup_failed(envelope->routing_key)) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = AMQP_STATUS_NO_MEMORY; + goto error_out2; + } + + ret = amqp_read_message(state, envelope->channel, &envelope->message, 0); + if (AMQP_RESPONSE_NORMAL != ret.reply_type) { + goto error_out2; + } + + ret.reply_type = AMQP_RESPONSE_NORMAL; + return ret; + +error_out2: + amqp_bytes_free(envelope->routing_key); + amqp_bytes_free(envelope->exchange); + amqp_bytes_free(envelope->consumer_tag); +error_out1: + return ret; +} + +amqp_rpc_reply_t amqp_read_message(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_message_t *message, + AMQP_UNUSED int flags) { + amqp_frame_t frame; + amqp_rpc_reply_t ret; + + size_t body_read; + char *body_read_ptr; + int res; + + memset(&ret, 0, sizeof(ret)); + memset(message, 0, sizeof(*message)); + + res = amqp_simple_wait_frame_on_channel(state, channel, &frame); + if (AMQP_STATUS_OK != res) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = res; + + goto error_out1; + } + + if (AMQP_FRAME_HEADER != frame.frame_type) { + if (AMQP_FRAME_METHOD == frame.frame_type && + (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id || + AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) { + + ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION; + ret.reply = frame.payload.method; + + } else { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = AMQP_STATUS_UNEXPECTED_STATE; + + amqp_put_back_frame(state, &frame); + } + goto error_out1; + } + + init_amqp_pool(&message->pool, 4096); + res = amqp_basic_properties_clone(frame.payload.properties.decoded, + &message->properties, &message->pool); + + if (AMQP_STATUS_OK != res) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = res; + goto error_out3; + } + + if (0 == frame.payload.properties.body_size) { + message->body = amqp_empty_bytes; + } else { + if (SIZE_MAX < frame.payload.properties.body_size) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = AMQP_STATUS_NO_MEMORY; + goto error_out1; + } + message->body = + amqp_bytes_malloc((size_t)frame.payload.properties.body_size); + if (NULL == message->body.bytes) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = AMQP_STATUS_NO_MEMORY; + goto error_out1; + } + } + + body_read = 0; + body_read_ptr = message->body.bytes; + + while (body_read < message->body.len) { + res = amqp_simple_wait_frame_on_channel(state, channel, &frame); + if (AMQP_STATUS_OK != res) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = res; + goto error_out2; + } + if (AMQP_FRAME_BODY != frame.frame_type) { + if (AMQP_FRAME_METHOD == frame.frame_type && + (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id || + AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) { + + ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION; + ret.reply = frame.payload.method; + } else { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = AMQP_STATUS_BAD_AMQP_DATA; + } + goto error_out2; + } + + if (body_read + frame.payload.body_fragment.len > message->body.len) { + ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + ret.library_error = AMQP_STATUS_BAD_AMQP_DATA; + goto error_out2; + } + + memcpy(body_read_ptr, frame.payload.body_fragment.bytes, + frame.payload.body_fragment.len); + + body_read += frame.payload.body_fragment.len; + body_read_ptr += frame.payload.body_fragment.len; + } + + ret.reply_type = AMQP_RESPONSE_NORMAL; + return ret; + +error_out2: + amqp_bytes_free(message->body); +error_out3: + empty_amqp_pool(&message->pool); +error_out1: + return ret; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_framing.c b/ext/librabbitmq/librabbitmq/amqp_framing.c new file mode 100644 index 00000000..bdeb01cd --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_framing.c @@ -0,0 +1,2876 @@ +/* Generated code. Do not edit. Edit and re-run codegen.py instead. + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp_private.h" +#include +#include +#include +#include + +char const *amqp_constant_name(int constantNumber) { + switch (constantNumber) { + case AMQP_FRAME_METHOD: + return "AMQP_FRAME_METHOD"; + case AMQP_FRAME_HEADER: + return "AMQP_FRAME_HEADER"; + case AMQP_FRAME_BODY: + return "AMQP_FRAME_BODY"; + case AMQP_FRAME_HEARTBEAT: + return "AMQP_FRAME_HEARTBEAT"; + case AMQP_FRAME_MIN_SIZE: + return "AMQP_FRAME_MIN_SIZE"; + case AMQP_FRAME_END: + return "AMQP_FRAME_END"; + case AMQP_REPLY_SUCCESS: + return "AMQP_REPLY_SUCCESS"; + case AMQP_CONTENT_TOO_LARGE: + return "AMQP_CONTENT_TOO_LARGE"; + case AMQP_NO_ROUTE: + return "AMQP_NO_ROUTE"; + case AMQP_NO_CONSUMERS: + return "AMQP_NO_CONSUMERS"; + case AMQP_ACCESS_REFUSED: + return "AMQP_ACCESS_REFUSED"; + case AMQP_NOT_FOUND: + return "AMQP_NOT_FOUND"; + case AMQP_RESOURCE_LOCKED: + return "AMQP_RESOURCE_LOCKED"; + case AMQP_PRECONDITION_FAILED: + return "AMQP_PRECONDITION_FAILED"; + case AMQP_CONNECTION_FORCED: + return "AMQP_CONNECTION_FORCED"; + case AMQP_INVALID_PATH: + return "AMQP_INVALID_PATH"; + case AMQP_FRAME_ERROR: + return "AMQP_FRAME_ERROR"; + case AMQP_SYNTAX_ERROR: + return "AMQP_SYNTAX_ERROR"; + case AMQP_COMMAND_INVALID: + return "AMQP_COMMAND_INVALID"; + case AMQP_CHANNEL_ERROR: + return "AMQP_CHANNEL_ERROR"; + case AMQP_UNEXPECTED_FRAME: + return "AMQP_UNEXPECTED_FRAME"; + case AMQP_RESOURCE_ERROR: + return "AMQP_RESOURCE_ERROR"; + case AMQP_NOT_ALLOWED: + return "AMQP_NOT_ALLOWED"; + case AMQP_NOT_IMPLEMENTED: + return "AMQP_NOT_IMPLEMENTED"; + case AMQP_INTERNAL_ERROR: + return "AMQP_INTERNAL_ERROR"; + default: + return "(unknown)"; + } +} + +amqp_boolean_t amqp_constant_is_hard_error(int constantNumber) { + switch (constantNumber) { + case AMQP_CONNECTION_FORCED: + return 1; + case AMQP_INVALID_PATH: + return 1; + case AMQP_FRAME_ERROR: + return 1; + case AMQP_SYNTAX_ERROR: + return 1; + case AMQP_COMMAND_INVALID: + return 1; + case AMQP_CHANNEL_ERROR: + return 1; + case AMQP_UNEXPECTED_FRAME: + return 1; + case AMQP_RESOURCE_ERROR: + return 1; + case AMQP_NOT_ALLOWED: + return 1; + case AMQP_NOT_IMPLEMENTED: + return 1; + case AMQP_INTERNAL_ERROR: + return 1; + default: + return 0; + } +} + +char const *amqp_method_name(amqp_method_number_t methodNumber) { + switch (methodNumber) { + case AMQP_CONNECTION_START_METHOD: + return "AMQP_CONNECTION_START_METHOD"; + case AMQP_CONNECTION_START_OK_METHOD: + return "AMQP_CONNECTION_START_OK_METHOD"; + case AMQP_CONNECTION_SECURE_METHOD: + return "AMQP_CONNECTION_SECURE_METHOD"; + case AMQP_CONNECTION_SECURE_OK_METHOD: + return "AMQP_CONNECTION_SECURE_OK_METHOD"; + case AMQP_CONNECTION_TUNE_METHOD: + return "AMQP_CONNECTION_TUNE_METHOD"; + case AMQP_CONNECTION_TUNE_OK_METHOD: + return "AMQP_CONNECTION_TUNE_OK_METHOD"; + case AMQP_CONNECTION_OPEN_METHOD: + return "AMQP_CONNECTION_OPEN_METHOD"; + case AMQP_CONNECTION_OPEN_OK_METHOD: + return "AMQP_CONNECTION_OPEN_OK_METHOD"; + case AMQP_CONNECTION_CLOSE_METHOD: + return "AMQP_CONNECTION_CLOSE_METHOD"; + case AMQP_CONNECTION_CLOSE_OK_METHOD: + return "AMQP_CONNECTION_CLOSE_OK_METHOD"; + case AMQP_CONNECTION_BLOCKED_METHOD: + return "AMQP_CONNECTION_BLOCKED_METHOD"; + case AMQP_CONNECTION_UNBLOCKED_METHOD: + return "AMQP_CONNECTION_UNBLOCKED_METHOD"; + case AMQP_CHANNEL_OPEN_METHOD: + return "AMQP_CHANNEL_OPEN_METHOD"; + case AMQP_CHANNEL_OPEN_OK_METHOD: + return "AMQP_CHANNEL_OPEN_OK_METHOD"; + case AMQP_CHANNEL_FLOW_METHOD: + return "AMQP_CHANNEL_FLOW_METHOD"; + case AMQP_CHANNEL_FLOW_OK_METHOD: + return "AMQP_CHANNEL_FLOW_OK_METHOD"; + case AMQP_CHANNEL_CLOSE_METHOD: + return "AMQP_CHANNEL_CLOSE_METHOD"; + case AMQP_CHANNEL_CLOSE_OK_METHOD: + return "AMQP_CHANNEL_CLOSE_OK_METHOD"; + case AMQP_ACCESS_REQUEST_METHOD: + return "AMQP_ACCESS_REQUEST_METHOD"; + case AMQP_ACCESS_REQUEST_OK_METHOD: + return "AMQP_ACCESS_REQUEST_OK_METHOD"; + case AMQP_EXCHANGE_DECLARE_METHOD: + return "AMQP_EXCHANGE_DECLARE_METHOD"; + case AMQP_EXCHANGE_DECLARE_OK_METHOD: + return "AMQP_EXCHANGE_DECLARE_OK_METHOD"; + case AMQP_EXCHANGE_DELETE_METHOD: + return "AMQP_EXCHANGE_DELETE_METHOD"; + case AMQP_EXCHANGE_DELETE_OK_METHOD: + return "AMQP_EXCHANGE_DELETE_OK_METHOD"; + case AMQP_EXCHANGE_BIND_METHOD: + return "AMQP_EXCHANGE_BIND_METHOD"; + case AMQP_EXCHANGE_BIND_OK_METHOD: + return "AMQP_EXCHANGE_BIND_OK_METHOD"; + case AMQP_EXCHANGE_UNBIND_METHOD: + return "AMQP_EXCHANGE_UNBIND_METHOD"; + case AMQP_EXCHANGE_UNBIND_OK_METHOD: + return "AMQP_EXCHANGE_UNBIND_OK_METHOD"; + case AMQP_QUEUE_DECLARE_METHOD: + return "AMQP_QUEUE_DECLARE_METHOD"; + case AMQP_QUEUE_DECLARE_OK_METHOD: + return "AMQP_QUEUE_DECLARE_OK_METHOD"; + case AMQP_QUEUE_BIND_METHOD: + return "AMQP_QUEUE_BIND_METHOD"; + case AMQP_QUEUE_BIND_OK_METHOD: + return "AMQP_QUEUE_BIND_OK_METHOD"; + case AMQP_QUEUE_PURGE_METHOD: + return "AMQP_QUEUE_PURGE_METHOD"; + case AMQP_QUEUE_PURGE_OK_METHOD: + return "AMQP_QUEUE_PURGE_OK_METHOD"; + case AMQP_QUEUE_DELETE_METHOD: + return "AMQP_QUEUE_DELETE_METHOD"; + case AMQP_QUEUE_DELETE_OK_METHOD: + return "AMQP_QUEUE_DELETE_OK_METHOD"; + case AMQP_QUEUE_UNBIND_METHOD: + return "AMQP_QUEUE_UNBIND_METHOD"; + case AMQP_QUEUE_UNBIND_OK_METHOD: + return "AMQP_QUEUE_UNBIND_OK_METHOD"; + case AMQP_BASIC_QOS_METHOD: + return "AMQP_BASIC_QOS_METHOD"; + case AMQP_BASIC_QOS_OK_METHOD: + return "AMQP_BASIC_QOS_OK_METHOD"; + case AMQP_BASIC_CONSUME_METHOD: + return "AMQP_BASIC_CONSUME_METHOD"; + case AMQP_BASIC_CONSUME_OK_METHOD: + return "AMQP_BASIC_CONSUME_OK_METHOD"; + case AMQP_BASIC_CANCEL_METHOD: + return "AMQP_BASIC_CANCEL_METHOD"; + case AMQP_BASIC_CANCEL_OK_METHOD: + return "AMQP_BASIC_CANCEL_OK_METHOD"; + case AMQP_BASIC_PUBLISH_METHOD: + return "AMQP_BASIC_PUBLISH_METHOD"; + case AMQP_BASIC_RETURN_METHOD: + return "AMQP_BASIC_RETURN_METHOD"; + case AMQP_BASIC_DELIVER_METHOD: + return "AMQP_BASIC_DELIVER_METHOD"; + case AMQP_BASIC_GET_METHOD: + return "AMQP_BASIC_GET_METHOD"; + case AMQP_BASIC_GET_OK_METHOD: + return "AMQP_BASIC_GET_OK_METHOD"; + case AMQP_BASIC_GET_EMPTY_METHOD: + return "AMQP_BASIC_GET_EMPTY_METHOD"; + case AMQP_BASIC_ACK_METHOD: + return "AMQP_BASIC_ACK_METHOD"; + case AMQP_BASIC_REJECT_METHOD: + return "AMQP_BASIC_REJECT_METHOD"; + case AMQP_BASIC_RECOVER_ASYNC_METHOD: + return "AMQP_BASIC_RECOVER_ASYNC_METHOD"; + case AMQP_BASIC_RECOVER_METHOD: + return "AMQP_BASIC_RECOVER_METHOD"; + case AMQP_BASIC_RECOVER_OK_METHOD: + return "AMQP_BASIC_RECOVER_OK_METHOD"; + case AMQP_BASIC_NACK_METHOD: + return "AMQP_BASIC_NACK_METHOD"; + case AMQP_TX_SELECT_METHOD: + return "AMQP_TX_SELECT_METHOD"; + case AMQP_TX_SELECT_OK_METHOD: + return "AMQP_TX_SELECT_OK_METHOD"; + case AMQP_TX_COMMIT_METHOD: + return "AMQP_TX_COMMIT_METHOD"; + case AMQP_TX_COMMIT_OK_METHOD: + return "AMQP_TX_COMMIT_OK_METHOD"; + case AMQP_TX_ROLLBACK_METHOD: + return "AMQP_TX_ROLLBACK_METHOD"; + case AMQP_TX_ROLLBACK_OK_METHOD: + return "AMQP_TX_ROLLBACK_OK_METHOD"; + case AMQP_CONFIRM_SELECT_METHOD: + return "AMQP_CONFIRM_SELECT_METHOD"; + case AMQP_CONFIRM_SELECT_OK_METHOD: + return "AMQP_CONFIRM_SELECT_OK_METHOD"; + default: + return NULL; + } +} + +amqp_boolean_t amqp_method_has_content(amqp_method_number_t methodNumber) { + switch (methodNumber) { + case AMQP_BASIC_PUBLISH_METHOD: + return 1; + case AMQP_BASIC_RETURN_METHOD: + return 1; + case AMQP_BASIC_DELIVER_METHOD: + return 1; + case AMQP_BASIC_GET_OK_METHOD: + return 1; + default: + return 0; + } +} + +int amqp_decode_method(amqp_method_number_t methodNumber, amqp_pool_t *pool, + amqp_bytes_t encoded, void **decoded) { + size_t offset = 0; + uint8_t bit_buffer; + + switch (methodNumber) { + case AMQP_CONNECTION_START_METHOD: { + amqp_connection_start_t *m = (amqp_connection_start_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_start_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_8(encoded, &offset, &m->version_major)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, &offset, &m->version_minor)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = + amqp_decode_table(encoded, pool, &(m->server_properties), &offset); + if (res < 0) return res; + } + { + uint32_t len; + if (!amqp_decode_32(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->mechanisms, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint32_t len; + if (!amqp_decode_32(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->locales, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CONNECTION_START_OK_METHOD: { + amqp_connection_start_ok_t *m = + (amqp_connection_start_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_start_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + int res = + amqp_decode_table(encoded, pool, &(m->client_properties), &offset); + if (res < 0) return res; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->mechanism, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint32_t len; + if (!amqp_decode_32(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->response, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->locale, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CONNECTION_SECURE_METHOD: { + amqp_connection_secure_t *m = (amqp_connection_secure_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_secure_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint32_t len; + if (!amqp_decode_32(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->challenge, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CONNECTION_SECURE_OK_METHOD: { + amqp_connection_secure_ok_t *m = + (amqp_connection_secure_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_secure_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint32_t len; + if (!amqp_decode_32(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->response, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CONNECTION_TUNE_METHOD: { + amqp_connection_tune_t *m = (amqp_connection_tune_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_tune_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->channel_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_32(encoded, &offset, &m->frame_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_16(encoded, &offset, &m->heartbeat)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_CONNECTION_TUNE_OK_METHOD: { + amqp_connection_tune_ok_t *m = + (amqp_connection_tune_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_tune_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->channel_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_32(encoded, &offset, &m->frame_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_16(encoded, &offset, &m->heartbeat)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_CONNECTION_OPEN_METHOD: { + amqp_connection_open_t *m = (amqp_connection_open_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_open_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->virtual_host, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->capabilities, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->insist = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_CONNECTION_OPEN_OK_METHOD: { + amqp_connection_open_ok_t *m = + (amqp_connection_open_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_open_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->known_hosts, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CONNECTION_CLOSE_METHOD: { + amqp_connection_close_t *m = (amqp_connection_close_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_close_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->reply_code)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->reply_text, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_16(encoded, &offset, &m->class_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_16(encoded, &offset, &m->method_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_CONNECTION_CLOSE_OK_METHOD: { + amqp_connection_close_ok_t *m = + (amqp_connection_close_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_close_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_CONNECTION_BLOCKED_METHOD: { + amqp_connection_blocked_t *m = + (amqp_connection_blocked_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_blocked_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->reason, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CONNECTION_UNBLOCKED_METHOD: { + amqp_connection_unblocked_t *m = + (amqp_connection_unblocked_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_unblocked_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_CHANNEL_OPEN_METHOD: { + amqp_channel_open_t *m = (amqp_channel_open_t *)amqp_pool_alloc( + pool, sizeof(amqp_channel_open_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->out_of_band, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CHANNEL_OPEN_OK_METHOD: { + amqp_channel_open_ok_t *m = (amqp_channel_open_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_channel_open_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint32_t len; + if (!amqp_decode_32(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->channel_id, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_CHANNEL_FLOW_METHOD: { + amqp_channel_flow_t *m = (amqp_channel_flow_t *)amqp_pool_alloc( + pool, sizeof(amqp_channel_flow_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->active = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_CHANNEL_FLOW_OK_METHOD: { + amqp_channel_flow_ok_t *m = (amqp_channel_flow_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_channel_flow_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->active = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_CHANNEL_CLOSE_METHOD: { + amqp_channel_close_t *m = (amqp_channel_close_t *)amqp_pool_alloc( + pool, sizeof(amqp_channel_close_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->reply_code)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->reply_text, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_16(encoded, &offset, &m->class_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_16(encoded, &offset, &m->method_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_CHANNEL_CLOSE_OK_METHOD: { + amqp_channel_close_ok_t *m = (amqp_channel_close_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_channel_close_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_ACCESS_REQUEST_METHOD: { + amqp_access_request_t *m = (amqp_access_request_t *)amqp_pool_alloc( + pool, sizeof(amqp_access_request_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->realm, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->exclusive = (bit_buffer & (1 << 0)) ? 1 : 0; + m->passive = (bit_buffer & (1 << 1)) ? 1 : 0; + m->active = (bit_buffer & (1 << 2)) ? 1 : 0; + m->write = (bit_buffer & (1 << 3)) ? 1 : 0; + m->read = (bit_buffer & (1 << 4)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_ACCESS_REQUEST_OK_METHOD: { + amqp_access_request_ok_t *m = (amqp_access_request_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_access_request_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_DECLARE_METHOD: { + amqp_exchange_declare_t *m = (amqp_exchange_declare_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_declare_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->type, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->passive = (bit_buffer & (1 << 0)) ? 1 : 0; + m->durable = (bit_buffer & (1 << 1)) ? 1 : 0; + m->auto_delete = (bit_buffer & (1 << 2)) ? 1 : 0; + m->internal = (bit_buffer & (1 << 3)) ? 1 : 0; + m->nowait = (bit_buffer & (1 << 4)) ? 1 : 0; + { + int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset); + if (res < 0) return res; + } + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_DECLARE_OK_METHOD: { + amqp_exchange_declare_ok_t *m = + (amqp_exchange_declare_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_declare_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_DELETE_METHOD: { + amqp_exchange_delete_t *m = (amqp_exchange_delete_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_delete_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->if_unused = (bit_buffer & (1 << 0)) ? 1 : 0; + m->nowait = (bit_buffer & (1 << 1)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_DELETE_OK_METHOD: { + amqp_exchange_delete_ok_t *m = + (amqp_exchange_delete_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_delete_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_BIND_METHOD: { + amqp_exchange_bind_t *m = (amqp_exchange_bind_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_bind_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->destination, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->source, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0; + { + int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset); + if (res < 0) return res; + } + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_BIND_OK_METHOD: { + amqp_exchange_bind_ok_t *m = (amqp_exchange_bind_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_bind_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_UNBIND_METHOD: { + amqp_exchange_unbind_t *m = (amqp_exchange_unbind_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_unbind_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->destination, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->source, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0; + { + int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset); + if (res < 0) return res; + } + *decoded = m; + return 0; + } + case AMQP_EXCHANGE_UNBIND_OK_METHOD: { + amqp_exchange_unbind_ok_t *m = + (amqp_exchange_unbind_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_unbind_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_QUEUE_DECLARE_METHOD: { + amqp_queue_declare_t *m = (amqp_queue_declare_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_declare_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->passive = (bit_buffer & (1 << 0)) ? 1 : 0; + m->durable = (bit_buffer & (1 << 1)) ? 1 : 0; + m->exclusive = (bit_buffer & (1 << 2)) ? 1 : 0; + m->auto_delete = (bit_buffer & (1 << 3)) ? 1 : 0; + m->nowait = (bit_buffer & (1 << 4)) ? 1 : 0; + { + int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset); + if (res < 0) return res; + } + *decoded = m; + return 0; + } + case AMQP_QUEUE_DECLARE_OK_METHOD: { + amqp_queue_declare_ok_t *m = (amqp_queue_declare_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_declare_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_32(encoded, &offset, &m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_32(encoded, &offset, &m->consumer_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_QUEUE_BIND_METHOD: { + amqp_queue_bind_t *m = + (amqp_queue_bind_t *)amqp_pool_alloc(pool, sizeof(amqp_queue_bind_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0; + { + int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset); + if (res < 0) return res; + } + *decoded = m; + return 0; + } + case AMQP_QUEUE_BIND_OK_METHOD: { + amqp_queue_bind_ok_t *m = (amqp_queue_bind_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_bind_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_QUEUE_PURGE_METHOD: { + amqp_queue_purge_t *m = (amqp_queue_purge_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_purge_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_QUEUE_PURGE_OK_METHOD: { + amqp_queue_purge_ok_t *m = (amqp_queue_purge_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_purge_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_32(encoded, &offset, &m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_QUEUE_DELETE_METHOD: { + amqp_queue_delete_t *m = (amqp_queue_delete_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_delete_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->if_unused = (bit_buffer & (1 << 0)) ? 1 : 0; + m->if_empty = (bit_buffer & (1 << 1)) ? 1 : 0; + m->nowait = (bit_buffer & (1 << 2)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_QUEUE_DELETE_OK_METHOD: { + amqp_queue_delete_ok_t *m = (amqp_queue_delete_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_delete_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_32(encoded, &offset, &m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_QUEUE_UNBIND_METHOD: { + amqp_queue_unbind_t *m = (amqp_queue_unbind_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_unbind_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset); + if (res < 0) return res; + } + *decoded = m; + return 0; + } + case AMQP_QUEUE_UNBIND_OK_METHOD: { + amqp_queue_unbind_ok_t *m = (amqp_queue_unbind_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_unbind_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_QOS_METHOD: { + amqp_basic_qos_t *m = + (amqp_basic_qos_t *)amqp_pool_alloc(pool, sizeof(amqp_basic_qos_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_32(encoded, &offset, &m->prefetch_size)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_16(encoded, &offset, &m->prefetch_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->global = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_QOS_OK_METHOD: { + amqp_basic_qos_ok_t *m = (amqp_basic_qos_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_qos_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_CONSUME_METHOD: { + amqp_basic_consume_t *m = (amqp_basic_consume_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_consume_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->no_local = (bit_buffer & (1 << 0)) ? 1 : 0; + m->no_ack = (bit_buffer & (1 << 1)) ? 1 : 0; + m->exclusive = (bit_buffer & (1 << 2)) ? 1 : 0; + m->nowait = (bit_buffer & (1 << 3)) ? 1 : 0; + { + int res = amqp_decode_table(encoded, pool, &(m->arguments), &offset); + if (res < 0) return res; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_CONSUME_OK_METHOD: { + amqp_basic_consume_ok_t *m = (amqp_basic_consume_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_consume_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_CANCEL_METHOD: { + amqp_basic_cancel_t *m = (amqp_basic_cancel_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_cancel_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_CANCEL_OK_METHOD: { + amqp_basic_cancel_ok_t *m = (amqp_basic_cancel_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_cancel_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_PUBLISH_METHOD: { + amqp_basic_publish_t *m = (amqp_basic_publish_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_publish_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->mandatory = (bit_buffer & (1 << 0)) ? 1 : 0; + m->immediate = (bit_buffer & (1 << 1)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_RETURN_METHOD: { + amqp_basic_return_t *m = (amqp_basic_return_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_return_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->reply_code)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->reply_text, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_DELIVER_METHOD: { + amqp_basic_deliver_t *m = (amqp_basic_deliver_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_deliver_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->consumer_tag, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->redelivered = (bit_buffer & (1 << 0)) ? 1 : 0; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_GET_METHOD: { + amqp_basic_get_t *m = + (amqp_basic_get_t *)amqp_pool_alloc(pool, sizeof(amqp_basic_get_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_16(encoded, &offset, &m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->queue, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->no_ack = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_GET_OK_METHOD: { + amqp_basic_get_ok_t *m = (amqp_basic_get_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_get_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->redelivered = (bit_buffer & (1 << 0)) ? 1 : 0; + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->exchange, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->routing_key, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (!amqp_decode_32(encoded, &offset, &m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + *decoded = m; + return 0; + } + case AMQP_BASIC_GET_EMPTY_METHOD: { + amqp_basic_get_empty_t *m = (amqp_basic_get_empty_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_get_empty_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &m->cluster_id, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_ACK_METHOD: { + amqp_basic_ack_t *m = + (amqp_basic_ack_t *)amqp_pool_alloc(pool, sizeof(amqp_basic_ack_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->multiple = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_REJECT_METHOD: { + amqp_basic_reject_t *m = (amqp_basic_reject_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_reject_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_RECOVER_ASYNC_METHOD: { + amqp_basic_recover_async_t *m = + (amqp_basic_recover_async_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_recover_async_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_RECOVER_METHOD: { + amqp_basic_recover_t *m = (amqp_basic_recover_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_recover_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->requeue = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_BASIC_RECOVER_OK_METHOD: { + amqp_basic_recover_ok_t *m = (amqp_basic_recover_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_recover_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_BASIC_NACK_METHOD: { + amqp_basic_nack_t *m = + (amqp_basic_nack_t *)amqp_pool_alloc(pool, sizeof(amqp_basic_nack_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_64(encoded, &offset, &m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->multiple = (bit_buffer & (1 << 0)) ? 1 : 0; + m->requeue = (bit_buffer & (1 << 1)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_TX_SELECT_METHOD: { + amqp_tx_select_t *m = + (amqp_tx_select_t *)amqp_pool_alloc(pool, sizeof(amqp_tx_select_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_TX_SELECT_OK_METHOD: { + amqp_tx_select_ok_t *m = (amqp_tx_select_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_tx_select_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_TX_COMMIT_METHOD: { + amqp_tx_commit_t *m = + (amqp_tx_commit_t *)amqp_pool_alloc(pool, sizeof(amqp_tx_commit_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_TX_COMMIT_OK_METHOD: { + amqp_tx_commit_ok_t *m = (amqp_tx_commit_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_tx_commit_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_TX_ROLLBACK_METHOD: { + amqp_tx_rollback_t *m = (amqp_tx_rollback_t *)amqp_pool_alloc( + pool, sizeof(amqp_tx_rollback_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_TX_ROLLBACK_OK_METHOD: { + amqp_tx_rollback_ok_t *m = (amqp_tx_rollback_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_tx_rollback_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + case AMQP_CONFIRM_SELECT_METHOD: { + amqp_confirm_select_t *m = (amqp_confirm_select_t *)amqp_pool_alloc( + pool, sizeof(amqp_confirm_select_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + if (!amqp_decode_8(encoded, &offset, &bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + m->nowait = (bit_buffer & (1 << 0)) ? 1 : 0; + *decoded = m; + return 0; + } + case AMQP_CONFIRM_SELECT_OK_METHOD: { + amqp_confirm_select_ok_t *m = (amqp_confirm_select_ok_t *)amqp_pool_alloc( + pool, sizeof(amqp_confirm_select_ok_t)); + if (m == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + *decoded = m; + return 0; + } + default: + return AMQP_STATUS_UNKNOWN_METHOD; + } +} + +int amqp_decode_properties(uint16_t class_id, amqp_pool_t *pool, + amqp_bytes_t encoded, void **decoded) { + size_t offset = 0; + + amqp_flags_t flags = 0; + int flagword_index = 0; + uint16_t partial_flags; + + do { + if (!amqp_decode_16(encoded, &offset, &partial_flags)) + return AMQP_STATUS_BAD_AMQP_DATA; + flags |= (partial_flags << (flagword_index * 16)); + flagword_index++; + } while (partial_flags & 1); + + switch (class_id) { + case 10: { + amqp_connection_properties_t *p = + (amqp_connection_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_connection_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + *decoded = p; + return 0; + } + case 20: { + amqp_channel_properties_t *p = + (amqp_channel_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_channel_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + *decoded = p; + return 0; + } + case 30: { + amqp_access_properties_t *p = (amqp_access_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_access_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + *decoded = p; + return 0; + } + case 40: { + amqp_exchange_properties_t *p = + (amqp_exchange_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_exchange_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + *decoded = p; + return 0; + } + case 50: { + amqp_queue_properties_t *p = (amqp_queue_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_queue_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + *decoded = p; + return 0; + } + case 60: { + amqp_basic_properties_t *p = (amqp_basic_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_basic_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + if (flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->content_type, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->content_encoding, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_HEADERS_FLAG) { + { + int res = amqp_decode_table(encoded, pool, &(p->headers), &offset); + if (res < 0) return res; + } + } + if (flags & AMQP_BASIC_DELIVERY_MODE_FLAG) { + if (!amqp_decode_8(encoded, &offset, &p->delivery_mode)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_PRIORITY_FLAG) { + if (!amqp_decode_8(encoded, &offset, &p->priority)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_CORRELATION_ID_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->correlation_id, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_REPLY_TO_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->reply_to, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_EXPIRATION_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->expiration, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_MESSAGE_ID_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->message_id, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_TIMESTAMP_FLAG) { + if (!amqp_decode_64(encoded, &offset, &p->timestamp)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_TYPE_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->type, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_USER_ID_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->user_id, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_APP_ID_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->app_id, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + if (flags & AMQP_BASIC_CLUSTER_ID_FLAG) { + { + uint8_t len; + if (!amqp_decode_8(encoded, &offset, &len) || + !amqp_decode_bytes(encoded, &offset, &p->cluster_id, len)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + } + *decoded = p; + return 0; + } + case 90: { + amqp_tx_properties_t *p = (amqp_tx_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_tx_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + *decoded = p; + return 0; + } + case 85: { + amqp_confirm_properties_t *p = + (amqp_confirm_properties_t *)amqp_pool_alloc( + pool, sizeof(amqp_confirm_properties_t)); + if (p == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + p->_flags = flags; + *decoded = p; + return 0; + } + default: + return AMQP_STATUS_UNKNOWN_CLASS; + } +} + +int amqp_encode_method(amqp_method_number_t methodNumber, void *decoded, + amqp_bytes_t encoded) { + size_t offset = 0; + uint8_t bit_buffer; + + switch (methodNumber) { + case AMQP_CONNECTION_START_METHOD: { + amqp_connection_start_t *m = (amqp_connection_start_t *)decoded; + if (!amqp_encode_8(encoded, &offset, m->version_major)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_8(encoded, &offset, m->version_minor)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->server_properties), &offset); + if (res < 0) return res; + } + if (UINT32_MAX < m->mechanisms.len || + !amqp_encode_32(encoded, &offset, (uint32_t)m->mechanisms.len) || + !amqp_encode_bytes(encoded, &offset, m->mechanisms)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT32_MAX < m->locales.len || + !amqp_encode_32(encoded, &offset, (uint32_t)m->locales.len) || + !amqp_encode_bytes(encoded, &offset, m->locales)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_START_OK_METHOD: { + amqp_connection_start_ok_t *m = (amqp_connection_start_ok_t *)decoded; + { + int res = amqp_encode_table(encoded, &(m->client_properties), &offset); + if (res < 0) return res; + } + if (UINT8_MAX < m->mechanism.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->mechanism.len) || + !amqp_encode_bytes(encoded, &offset, m->mechanism)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT32_MAX < m->response.len || + !amqp_encode_32(encoded, &offset, (uint32_t)m->response.len) || + !amqp_encode_bytes(encoded, &offset, m->response)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->locale.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->locale.len) || + !amqp_encode_bytes(encoded, &offset, m->locale)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_SECURE_METHOD: { + amqp_connection_secure_t *m = (amqp_connection_secure_t *)decoded; + if (UINT32_MAX < m->challenge.len || + !amqp_encode_32(encoded, &offset, (uint32_t)m->challenge.len) || + !amqp_encode_bytes(encoded, &offset, m->challenge)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_SECURE_OK_METHOD: { + amqp_connection_secure_ok_t *m = (amqp_connection_secure_ok_t *)decoded; + if (UINT32_MAX < m->response.len || + !amqp_encode_32(encoded, &offset, (uint32_t)m->response.len) || + !amqp_encode_bytes(encoded, &offset, m->response)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_TUNE_METHOD: { + amqp_connection_tune_t *m = (amqp_connection_tune_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->channel_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_32(encoded, &offset, m->frame_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_16(encoded, &offset, m->heartbeat)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_TUNE_OK_METHOD: { + amqp_connection_tune_ok_t *m = (amqp_connection_tune_ok_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->channel_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_32(encoded, &offset, m->frame_max)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_16(encoded, &offset, m->heartbeat)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_OPEN_METHOD: { + amqp_connection_open_t *m = (amqp_connection_open_t *)decoded; + if (UINT8_MAX < m->virtual_host.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->virtual_host.len) || + !amqp_encode_bytes(encoded, &offset, m->virtual_host)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->capabilities.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->capabilities.len) || + !amqp_encode_bytes(encoded, &offset, m->capabilities)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->insist) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_OPEN_OK_METHOD: { + amqp_connection_open_ok_t *m = (amqp_connection_open_ok_t *)decoded; + if (UINT8_MAX < m->known_hosts.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->known_hosts.len) || + !amqp_encode_bytes(encoded, &offset, m->known_hosts)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_CLOSE_METHOD: { + amqp_connection_close_t *m = (amqp_connection_close_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->reply_code)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->reply_text.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->reply_text.len) || + !amqp_encode_bytes(encoded, &offset, m->reply_text)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_16(encoded, &offset, m->class_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_16(encoded, &offset, m->method_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_CLOSE_OK_METHOD: { + return (int)offset; + } + case AMQP_CONNECTION_BLOCKED_METHOD: { + amqp_connection_blocked_t *m = (amqp_connection_blocked_t *)decoded; + if (UINT8_MAX < m->reason.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->reason.len) || + !amqp_encode_bytes(encoded, &offset, m->reason)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONNECTION_UNBLOCKED_METHOD: { + return (int)offset; + } + case AMQP_CHANNEL_OPEN_METHOD: { + amqp_channel_open_t *m = (amqp_channel_open_t *)decoded; + if (UINT8_MAX < m->out_of_band.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->out_of_band.len) || + !amqp_encode_bytes(encoded, &offset, m->out_of_band)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CHANNEL_OPEN_OK_METHOD: { + amqp_channel_open_ok_t *m = (amqp_channel_open_ok_t *)decoded; + if (UINT32_MAX < m->channel_id.len || + !amqp_encode_32(encoded, &offset, (uint32_t)m->channel_id.len) || + !amqp_encode_bytes(encoded, &offset, m->channel_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CHANNEL_FLOW_METHOD: { + amqp_channel_flow_t *m = (amqp_channel_flow_t *)decoded; + bit_buffer = 0; + if (m->active) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CHANNEL_FLOW_OK_METHOD: { + amqp_channel_flow_ok_t *m = (amqp_channel_flow_ok_t *)decoded; + bit_buffer = 0; + if (m->active) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CHANNEL_CLOSE_METHOD: { + amqp_channel_close_t *m = (amqp_channel_close_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->reply_code)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->reply_text.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->reply_text.len) || + !amqp_encode_bytes(encoded, &offset, m->reply_text)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_16(encoded, &offset, m->class_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_16(encoded, &offset, m->method_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CHANNEL_CLOSE_OK_METHOD: { + return (int)offset; + } + case AMQP_ACCESS_REQUEST_METHOD: { + amqp_access_request_t *m = (amqp_access_request_t *)decoded; + if (UINT8_MAX < m->realm.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->realm.len) || + !amqp_encode_bytes(encoded, &offset, m->realm)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->exclusive) bit_buffer |= (1 << 0); + if (m->passive) bit_buffer |= (1 << 1); + if (m->active) bit_buffer |= (1 << 2); + if (m->write) bit_buffer |= (1 << 3); + if (m->read) bit_buffer |= (1 << 4); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_ACCESS_REQUEST_OK_METHOD: { + amqp_access_request_ok_t *m = (amqp_access_request_ok_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_EXCHANGE_DECLARE_METHOD: { + amqp_exchange_declare_t *m = (amqp_exchange_declare_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->type.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->type.len) || + !amqp_encode_bytes(encoded, &offset, m->type)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->passive) bit_buffer |= (1 << 0); + if (m->durable) bit_buffer |= (1 << 1); + if (m->auto_delete) bit_buffer |= (1 << 2); + if (m->internal) bit_buffer |= (1 << 3); + if (m->nowait) bit_buffer |= (1 << 4); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->arguments), &offset); + if (res < 0) return res; + } + return (int)offset; + } + case AMQP_EXCHANGE_DECLARE_OK_METHOD: { + return (int)offset; + } + case AMQP_EXCHANGE_DELETE_METHOD: { + amqp_exchange_delete_t *m = (amqp_exchange_delete_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->if_unused) bit_buffer |= (1 << 0); + if (m->nowait) bit_buffer |= (1 << 1); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_EXCHANGE_DELETE_OK_METHOD: { + return (int)offset; + } + case AMQP_EXCHANGE_BIND_METHOD: { + amqp_exchange_bind_t *m = (amqp_exchange_bind_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->destination.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->destination.len) || + !amqp_encode_bytes(encoded, &offset, m->destination)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->source.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->source.len) || + !amqp_encode_bytes(encoded, &offset, m->source)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->nowait) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->arguments), &offset); + if (res < 0) return res; + } + return (int)offset; + } + case AMQP_EXCHANGE_BIND_OK_METHOD: { + return (int)offset; + } + case AMQP_EXCHANGE_UNBIND_METHOD: { + amqp_exchange_unbind_t *m = (amqp_exchange_unbind_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->destination.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->destination.len) || + !amqp_encode_bytes(encoded, &offset, m->destination)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->source.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->source.len) || + !amqp_encode_bytes(encoded, &offset, m->source)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->nowait) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->arguments), &offset); + if (res < 0) return res; + } + return (int)offset; + } + case AMQP_EXCHANGE_UNBIND_OK_METHOD: { + return (int)offset; + } + case AMQP_QUEUE_DECLARE_METHOD: { + amqp_queue_declare_t *m = (amqp_queue_declare_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->passive) bit_buffer |= (1 << 0); + if (m->durable) bit_buffer |= (1 << 1); + if (m->exclusive) bit_buffer |= (1 << 2); + if (m->auto_delete) bit_buffer |= (1 << 3); + if (m->nowait) bit_buffer |= (1 << 4); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->arguments), &offset); + if (res < 0) return res; + } + return (int)offset; + } + case AMQP_QUEUE_DECLARE_OK_METHOD: { + amqp_queue_declare_ok_t *m = (amqp_queue_declare_ok_t *)decoded; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_32(encoded, &offset, m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_32(encoded, &offset, m->consumer_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_QUEUE_BIND_METHOD: { + amqp_queue_bind_t *m = (amqp_queue_bind_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->nowait) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->arguments), &offset); + if (res < 0) return res; + } + return (int)offset; + } + case AMQP_QUEUE_BIND_OK_METHOD: { + return (int)offset; + } + case AMQP_QUEUE_PURGE_METHOD: { + amqp_queue_purge_t *m = (amqp_queue_purge_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->nowait) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_QUEUE_PURGE_OK_METHOD: { + amqp_queue_purge_ok_t *m = (amqp_queue_purge_ok_t *)decoded; + if (!amqp_encode_32(encoded, &offset, m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_QUEUE_DELETE_METHOD: { + amqp_queue_delete_t *m = (amqp_queue_delete_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->if_unused) bit_buffer |= (1 << 0); + if (m->if_empty) bit_buffer |= (1 << 1); + if (m->nowait) bit_buffer |= (1 << 2); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_QUEUE_DELETE_OK_METHOD: { + amqp_queue_delete_ok_t *m = (amqp_queue_delete_ok_t *)decoded; + if (!amqp_encode_32(encoded, &offset, m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_QUEUE_UNBIND_METHOD: { + amqp_queue_unbind_t *m = (amqp_queue_unbind_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->arguments), &offset); + if (res < 0) return res; + } + return (int)offset; + } + case AMQP_QUEUE_UNBIND_OK_METHOD: { + return (int)offset; + } + case AMQP_BASIC_QOS_METHOD: { + amqp_basic_qos_t *m = (amqp_basic_qos_t *)decoded; + if (!amqp_encode_32(encoded, &offset, m->prefetch_size)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_16(encoded, &offset, m->prefetch_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->global) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_QOS_OK_METHOD: { + return (int)offset; + } + case AMQP_BASIC_CONSUME_METHOD: { + amqp_basic_consume_t *m = (amqp_basic_consume_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->consumer_tag.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len) || + !amqp_encode_bytes(encoded, &offset, m->consumer_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->no_local) bit_buffer |= (1 << 0); + if (m->no_ack) bit_buffer |= (1 << 1); + if (m->exclusive) bit_buffer |= (1 << 2); + if (m->nowait) bit_buffer |= (1 << 3); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + { + int res = amqp_encode_table(encoded, &(m->arguments), &offset); + if (res < 0) return res; + } + return (int)offset; + } + case AMQP_BASIC_CONSUME_OK_METHOD: { + amqp_basic_consume_ok_t *m = (amqp_basic_consume_ok_t *)decoded; + if (UINT8_MAX < m->consumer_tag.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len) || + !amqp_encode_bytes(encoded, &offset, m->consumer_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_CANCEL_METHOD: { + amqp_basic_cancel_t *m = (amqp_basic_cancel_t *)decoded; + if (UINT8_MAX < m->consumer_tag.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len) || + !amqp_encode_bytes(encoded, &offset, m->consumer_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->nowait) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_CANCEL_OK_METHOD: { + amqp_basic_cancel_ok_t *m = (amqp_basic_cancel_ok_t *)decoded; + if (UINT8_MAX < m->consumer_tag.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len) || + !amqp_encode_bytes(encoded, &offset, m->consumer_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_PUBLISH_METHOD: { + amqp_basic_publish_t *m = (amqp_basic_publish_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->mandatory) bit_buffer |= (1 << 0); + if (m->immediate) bit_buffer |= (1 << 1); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_RETURN_METHOD: { + amqp_basic_return_t *m = (amqp_basic_return_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->reply_code)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->reply_text.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->reply_text.len) || + !amqp_encode_bytes(encoded, &offset, m->reply_text)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_DELIVER_METHOD: { + amqp_basic_deliver_t *m = (amqp_basic_deliver_t *)decoded; + if (UINT8_MAX < m->consumer_tag.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->consumer_tag.len) || + !amqp_encode_bytes(encoded, &offset, m->consumer_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->redelivered) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_GET_METHOD: { + amqp_basic_get_t *m = (amqp_basic_get_t *)decoded; + if (!amqp_encode_16(encoded, &offset, m->ticket)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->queue.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->queue.len) || + !amqp_encode_bytes(encoded, &offset, m->queue)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->no_ack) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_GET_OK_METHOD: { + amqp_basic_get_ok_t *m = (amqp_basic_get_ok_t *)decoded; + if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->redelivered) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->exchange.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->exchange.len) || + !amqp_encode_bytes(encoded, &offset, m->exchange)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (UINT8_MAX < m->routing_key.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->routing_key.len) || + !amqp_encode_bytes(encoded, &offset, m->routing_key)) + return AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_encode_32(encoded, &offset, m->message_count)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_GET_EMPTY_METHOD: { + amqp_basic_get_empty_t *m = (amqp_basic_get_empty_t *)decoded; + if (UINT8_MAX < m->cluster_id.len || + !amqp_encode_8(encoded, &offset, (uint8_t)m->cluster_id.len) || + !amqp_encode_bytes(encoded, &offset, m->cluster_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_ACK_METHOD: { + amqp_basic_ack_t *m = (amqp_basic_ack_t *)decoded; + if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->multiple) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_REJECT_METHOD: { + amqp_basic_reject_t *m = (amqp_basic_reject_t *)decoded; + if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->requeue) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_RECOVER_ASYNC_METHOD: { + amqp_basic_recover_async_t *m = (amqp_basic_recover_async_t *)decoded; + bit_buffer = 0; + if (m->requeue) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_RECOVER_METHOD: { + amqp_basic_recover_t *m = (amqp_basic_recover_t *)decoded; + bit_buffer = 0; + if (m->requeue) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_BASIC_RECOVER_OK_METHOD: { + return (int)offset; + } + case AMQP_BASIC_NACK_METHOD: { + amqp_basic_nack_t *m = (amqp_basic_nack_t *)decoded; + if (!amqp_encode_64(encoded, &offset, m->delivery_tag)) + return AMQP_STATUS_BAD_AMQP_DATA; + bit_buffer = 0; + if (m->multiple) bit_buffer |= (1 << 0); + if (m->requeue) bit_buffer |= (1 << 1); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_TX_SELECT_METHOD: { + return (int)offset; + } + case AMQP_TX_SELECT_OK_METHOD: { + return (int)offset; + } + case AMQP_TX_COMMIT_METHOD: { + return (int)offset; + } + case AMQP_TX_COMMIT_OK_METHOD: { + return (int)offset; + } + case AMQP_TX_ROLLBACK_METHOD: { + return (int)offset; + } + case AMQP_TX_ROLLBACK_OK_METHOD: { + return (int)offset; + } + case AMQP_CONFIRM_SELECT_METHOD: { + amqp_confirm_select_t *m = (amqp_confirm_select_t *)decoded; + bit_buffer = 0; + if (m->nowait) bit_buffer |= (1 << 0); + if (!amqp_encode_8(encoded, &offset, bit_buffer)) + return AMQP_STATUS_BAD_AMQP_DATA; + return (int)offset; + } + case AMQP_CONFIRM_SELECT_OK_METHOD: { + return (int)offset; + } + default: + return AMQP_STATUS_UNKNOWN_METHOD; + } +} + +int amqp_encode_properties(uint16_t class_id, void *decoded, + amqp_bytes_t encoded) { + size_t offset = 0; + + /* Cheat, and get the flags out generically, relying on the + similarity of structure between classes */ + amqp_flags_t flags = *(amqp_flags_t *)decoded; /* cheating! */ + + { + /* We take a copy of flags to avoid destroying it, as it is used + in the autogenerated code below. */ + amqp_flags_t remaining_flags = flags; + do { + amqp_flags_t remainder = remaining_flags >> 16; + uint16_t partial_flags = remaining_flags & 0xFFFE; + if (remainder != 0) { + partial_flags |= 1; + } + if (!amqp_encode_16(encoded, &offset, partial_flags)) + return AMQP_STATUS_BAD_AMQP_DATA; + remaining_flags = remainder; + } while (remaining_flags != 0); + } + + switch (class_id) { + case 10: { + return (int)offset; + } + case 20: { + return (int)offset; + } + case 30: { + return (int)offset; + } + case 40: { + return (int)offset; + } + case 50: { + return (int)offset; + } + case 60: { + amqp_basic_properties_t *p = (amqp_basic_properties_t *)decoded; + if (flags & AMQP_BASIC_CONTENT_TYPE_FLAG) { + if (UINT8_MAX < p->content_type.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->content_type.len) || + !amqp_encode_bytes(encoded, &offset, p->content_type)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_CONTENT_ENCODING_FLAG) { + if (UINT8_MAX < p->content_encoding.len || + !amqp_encode_8(encoded, &offset, + (uint8_t)p->content_encoding.len) || + !amqp_encode_bytes(encoded, &offset, p->content_encoding)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_HEADERS_FLAG) { + { + int res = amqp_encode_table(encoded, &(p->headers), &offset); + if (res < 0) return res; + } + } + if (flags & AMQP_BASIC_DELIVERY_MODE_FLAG) { + if (!amqp_encode_8(encoded, &offset, p->delivery_mode)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_PRIORITY_FLAG) { + if (!amqp_encode_8(encoded, &offset, p->priority)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_CORRELATION_ID_FLAG) { + if (UINT8_MAX < p->correlation_id.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->correlation_id.len) || + !amqp_encode_bytes(encoded, &offset, p->correlation_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_REPLY_TO_FLAG) { + if (UINT8_MAX < p->reply_to.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->reply_to.len) || + !amqp_encode_bytes(encoded, &offset, p->reply_to)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_EXPIRATION_FLAG) { + if (UINT8_MAX < p->expiration.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->expiration.len) || + !amqp_encode_bytes(encoded, &offset, p->expiration)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_MESSAGE_ID_FLAG) { + if (UINT8_MAX < p->message_id.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->message_id.len) || + !amqp_encode_bytes(encoded, &offset, p->message_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_TIMESTAMP_FLAG) { + if (!amqp_encode_64(encoded, &offset, p->timestamp)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_TYPE_FLAG) { + if (UINT8_MAX < p->type.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->type.len) || + !amqp_encode_bytes(encoded, &offset, p->type)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_USER_ID_FLAG) { + if (UINT8_MAX < p->user_id.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->user_id.len) || + !amqp_encode_bytes(encoded, &offset, p->user_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_APP_ID_FLAG) { + if (UINT8_MAX < p->app_id.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->app_id.len) || + !amqp_encode_bytes(encoded, &offset, p->app_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + if (flags & AMQP_BASIC_CLUSTER_ID_FLAG) { + if (UINT8_MAX < p->cluster_id.len || + !amqp_encode_8(encoded, &offset, (uint8_t)p->cluster_id.len) || + !amqp_encode_bytes(encoded, &offset, p->cluster_id)) + return AMQP_STATUS_BAD_AMQP_DATA; + } + return (int)offset; + } + case 90: { + return (int)offset; + } + case 85: { + return (int)offset; + } + default: + return AMQP_STATUS_UNKNOWN_CLASS; + } +} + +/** + * amqp_channel_open + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_channel_open_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_channel_open_ok_t *AMQP_CALL + amqp_channel_open(amqp_connection_state_t state, amqp_channel_t channel) { + amqp_channel_open_t req; + req.out_of_band = amqp_empty_bytes; + + return amqp_simple_rpc_decoded(state, channel, AMQP_CHANNEL_OPEN_METHOD, + AMQP_CHANNEL_OPEN_OK_METHOD, &req); +} + +/** + * amqp_channel_flow + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] active active + * @returns amqp_channel_flow_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_channel_flow_ok_t *AMQP_CALL + amqp_channel_flow(amqp_connection_state_t state, amqp_channel_t channel, + amqp_boolean_t active) { + amqp_channel_flow_t req; + req.active = active; + + return amqp_simple_rpc_decoded(state, channel, AMQP_CHANNEL_FLOW_METHOD, + AMQP_CHANNEL_FLOW_OK_METHOD, &req); +} + +/** + * amqp_exchange_declare + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] exchange exchange + * @param [in] type type + * @param [in] passive passive + * @param [in] durable durable + * @param [in] auto_delete auto_delete + * @param [in] internal internal + * @param [in] arguments arguments + * @returns amqp_exchange_declare_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_declare_ok_t *AMQP_CALL amqp_exchange_declare( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive, + amqp_boolean_t durable, amqp_boolean_t auto_delete, amqp_boolean_t internal, + amqp_table_t arguments) { + amqp_exchange_declare_t req; + req.ticket = 0; + req.exchange = exchange; + req.type = type; + req.passive = passive; + req.durable = durable; + req.auto_delete = auto_delete; + req.internal = internal; + req.nowait = 0; + req.arguments = arguments; + + return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_DECLARE_METHOD, + AMQP_EXCHANGE_DECLARE_OK_METHOD, &req); +} + +/** + * amqp_exchange_delete + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] exchange exchange + * @param [in] if_unused if_unused + * @returns amqp_exchange_delete_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_delete_ok_t *AMQP_CALL + amqp_exchange_delete(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_boolean_t if_unused) { + amqp_exchange_delete_t req; + req.ticket = 0; + req.exchange = exchange; + req.if_unused = if_unused; + req.nowait = 0; + + return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_DELETE_METHOD, + AMQP_EXCHANGE_DELETE_OK_METHOD, &req); +} + +/** + * amqp_exchange_bind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] destination destination + * @param [in] source source + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_exchange_bind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_bind_ok_t *AMQP_CALL + amqp_exchange_bind(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t destination, amqp_bytes_t source, + amqp_bytes_t routing_key, amqp_table_t arguments) { + amqp_exchange_bind_t req; + req.ticket = 0; + req.destination = destination; + req.source = source; + req.routing_key = routing_key; + req.nowait = 0; + req.arguments = arguments; + + return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_BIND_METHOD, + AMQP_EXCHANGE_BIND_OK_METHOD, &req); +} + +/** + * amqp_exchange_unbind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] destination destination + * @param [in] source source + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_exchange_unbind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_unbind_ok_t *AMQP_CALL + amqp_exchange_unbind(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t destination, amqp_bytes_t source, + amqp_bytes_t routing_key, amqp_table_t arguments) { + amqp_exchange_unbind_t req; + req.ticket = 0; + req.destination = destination; + req.source = source; + req.routing_key = routing_key; + req.nowait = 0; + req.arguments = arguments; + + return amqp_simple_rpc_decoded(state, channel, AMQP_EXCHANGE_UNBIND_METHOD, + AMQP_EXCHANGE_UNBIND_OK_METHOD, &req); +} + +/** + * amqp_queue_declare + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] passive passive + * @param [in] durable durable + * @param [in] exclusive exclusive + * @param [in] auto_delete auto_delete + * @param [in] arguments arguments + * @returns amqp_queue_declare_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_declare_ok_t *AMQP_CALL amqp_queue_declare( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, + amqp_boolean_t auto_delete, amqp_table_t arguments) { + amqp_queue_declare_t req; + req.ticket = 0; + req.queue = queue; + req.passive = passive; + req.durable = durable; + req.exclusive = exclusive; + req.auto_delete = auto_delete; + req.nowait = 0; + req.arguments = arguments; + + return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_DECLARE_METHOD, + AMQP_QUEUE_DECLARE_OK_METHOD, &req); +} + +/** + * amqp_queue_bind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] exchange exchange + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_queue_bind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_bind_ok_t *AMQP_CALL amqp_queue_bind( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments) { + amqp_queue_bind_t req; + req.ticket = 0; + req.queue = queue; + req.exchange = exchange; + req.routing_key = routing_key; + req.nowait = 0; + req.arguments = arguments; + + return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_BIND_METHOD, + AMQP_QUEUE_BIND_OK_METHOD, &req); +} + +/** + * amqp_queue_purge + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @returns amqp_queue_purge_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_purge_ok_t *AMQP_CALL amqp_queue_purge(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_bytes_t queue) { + amqp_queue_purge_t req; + req.ticket = 0; + req.queue = queue; + req.nowait = 0; + + return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_PURGE_METHOD, + AMQP_QUEUE_PURGE_OK_METHOD, &req); +} + +/** + * amqp_queue_delete + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] if_unused if_unused + * @param [in] if_empty if_empty + * @returns amqp_queue_delete_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_delete_ok_t *AMQP_CALL amqp_queue_delete( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_boolean_t if_unused, amqp_boolean_t if_empty) { + amqp_queue_delete_t req; + req.ticket = 0; + req.queue = queue; + req.if_unused = if_unused; + req.if_empty = if_empty; + req.nowait = 0; + + return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_DELETE_METHOD, + AMQP_QUEUE_DELETE_OK_METHOD, &req); +} + +/** + * amqp_queue_unbind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] exchange exchange + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_queue_unbind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_unbind_ok_t *AMQP_CALL amqp_queue_unbind( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments) { + amqp_queue_unbind_t req; + req.ticket = 0; + req.queue = queue; + req.exchange = exchange; + req.routing_key = routing_key; + req.arguments = arguments; + + return amqp_simple_rpc_decoded(state, channel, AMQP_QUEUE_UNBIND_METHOD, + AMQP_QUEUE_UNBIND_OK_METHOD, &req); +} + +/** + * amqp_basic_qos + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] prefetch_size prefetch_size + * @param [in] prefetch_count prefetch_count + * @param [in] global global + * @returns amqp_basic_qos_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_qos_ok_t *AMQP_CALL amqp_basic_qos(amqp_connection_state_t state, + amqp_channel_t channel, + uint32_t prefetch_size, + uint16_t prefetch_count, + amqp_boolean_t global) { + amqp_basic_qos_t req; + req.prefetch_size = prefetch_size; + req.prefetch_count = prefetch_count; + req.global = global; + + return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_QOS_METHOD, + AMQP_BASIC_QOS_OK_METHOD, &req); +} + +/** + * amqp_basic_consume + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] consumer_tag consumer_tag + * @param [in] no_local no_local + * @param [in] no_ack no_ack + * @param [in] exclusive exclusive + * @param [in] arguments arguments + * @returns amqp_basic_consume_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_consume_ok_t *AMQP_CALL amqp_basic_consume( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t consumer_tag, amqp_boolean_t no_local, amqp_boolean_t no_ack, + amqp_boolean_t exclusive, amqp_table_t arguments) { + amqp_basic_consume_t req; + req.ticket = 0; + req.queue = queue; + req.consumer_tag = consumer_tag; + req.no_local = no_local; + req.no_ack = no_ack; + req.exclusive = exclusive; + req.nowait = 0; + req.arguments = arguments; + + return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_CONSUME_METHOD, + AMQP_BASIC_CONSUME_OK_METHOD, &req); +} + +/** + * amqp_basic_cancel + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] consumer_tag consumer_tag + * @returns amqp_basic_cancel_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_cancel_ok_t *AMQP_CALL + amqp_basic_cancel(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t consumer_tag) { + amqp_basic_cancel_t req; + req.consumer_tag = consumer_tag; + req.nowait = 0; + + return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_CANCEL_METHOD, + AMQP_BASIC_CANCEL_OK_METHOD, &req); +} + +/** + * amqp_basic_recover + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] requeue requeue + * @returns amqp_basic_recover_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_recover_ok_t *AMQP_CALL + amqp_basic_recover(amqp_connection_state_t state, amqp_channel_t channel, + amqp_boolean_t requeue) { + amqp_basic_recover_t req; + req.requeue = requeue; + + return amqp_simple_rpc_decoded(state, channel, AMQP_BASIC_RECOVER_METHOD, + AMQP_BASIC_RECOVER_OK_METHOD, &req); +} + +/** + * amqp_tx_select + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_select_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_select_ok_t *AMQP_CALL amqp_tx_select(amqp_connection_state_t state, + amqp_channel_t channel) { + amqp_tx_select_t req; + + return amqp_simple_rpc_decoded(state, channel, AMQP_TX_SELECT_METHOD, + AMQP_TX_SELECT_OK_METHOD, &req); +} + +/** + * amqp_tx_commit + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_commit_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_commit_ok_t *AMQP_CALL amqp_tx_commit(amqp_connection_state_t state, + amqp_channel_t channel) { + amqp_tx_commit_t req; + + return amqp_simple_rpc_decoded(state, channel, AMQP_TX_COMMIT_METHOD, + AMQP_TX_COMMIT_OK_METHOD, &req); +} + +/** + * amqp_tx_rollback + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_rollback_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_rollback_ok_t *AMQP_CALL amqp_tx_rollback(amqp_connection_state_t state, + amqp_channel_t channel) { + amqp_tx_rollback_t req; + + return amqp_simple_rpc_decoded(state, channel, AMQP_TX_ROLLBACK_METHOD, + AMQP_TX_ROLLBACK_OK_METHOD, &req); +} + +/** + * amqp_confirm_select + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_confirm_select_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_confirm_select_ok_t *AMQP_CALL + amqp_confirm_select(amqp_connection_state_t state, amqp_channel_t channel) { + amqp_confirm_select_t req; + req.nowait = 0; + + return amqp_simple_rpc_decoded(state, channel, AMQP_CONFIRM_SELECT_METHOD, + AMQP_CONFIRM_SELECT_OK_METHOD, &req); +} diff --git a/ext/librabbitmq/centos_x64/include/amqp_framing.h b/ext/librabbitmq/librabbitmq/amqp_framing.h similarity index 100% rename from ext/librabbitmq/centos_x64/include/amqp_framing.h rename to ext/librabbitmq/librabbitmq/amqp_framing.h diff --git a/ext/librabbitmq/librabbitmq/amqp_hostcheck.c b/ext/librabbitmq/librabbitmq/amqp_hostcheck.c new file mode 100644 index 00000000..5a4f7339 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_hostcheck.c @@ -0,0 +1,195 @@ +/* + * Copyright 1996-2014 Daniel Stenberg . + * Copyright 2014 Michael Steinert + * + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization of the + * copyright holder. + */ + +#include "amqp_hostcheck.h" + +#include + +/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() + * because its behavior is altered by the current locale. + */ + +static char amqp_raw_toupper(char in) { + switch (in) { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + case 'g': + return 'G'; + case 'h': + return 'H'; + case 'i': + return 'I'; + case 'j': + return 'J'; + case 'k': + return 'K'; + case 'l': + return 'L'; + case 'm': + return 'M'; + case 'n': + return 'N'; + case 'o': + return 'O'; + case 'p': + return 'P'; + case 'q': + return 'Q'; + case 'r': + return 'R'; + case 's': + return 'S'; + case 't': + return 'T'; + case 'u': + return 'U'; + case 'v': + return 'V'; + case 'w': + return 'W'; + case 'x': + return 'X'; + case 'y': + return 'Y'; + case 'z': + return 'Z'; + } + return in; +} + +/* + * amqp_raw_equal() is for doing "raw" case insensitive strings. This is meant + * to be locale independent and only compare strings we know are safe for + * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for + * some further explanation to why this function is necessary. + * + * The function is capable of comparing a-z case insensitively even for + * non-ascii. + */ + +static int amqp_raw_equal(const char *first, const char *second) { + while (*first && *second) { + if (amqp_raw_toupper(*first) != amqp_raw_toupper(*second)) { + /* get out of the loop as soon as they don't match */ + break; + } + first++; + second++; + } + /* we do the comparison here (possibly again), just to make sure that if + * the loop above is skipped because one of the strings reached zero, we + * must not return this as a successful match + */ + return (amqp_raw_toupper(*first) == amqp_raw_toupper(*second)); +} + +static int amqp_raw_nequal(const char *first, const char *second, size_t max) { + while (*first && *second && max) { + if (amqp_raw_toupper(*first) != amqp_raw_toupper(*second)) { + break; + } + max--; + first++; + second++; + } + if (0 == max) { + return 1; /* they are equal this far */ + } + return amqp_raw_toupper(*first) == amqp_raw_toupper(*second); +} + +/* + * Match a hostname against a wildcard pattern. + * E.g. + * "foo.host.com" matches "*.host.com". + * + * We use the matching rule described in RFC6125, section 6.4.3. + * http://tools.ietf.org/html/rfc6125#section-6.4.3 + */ + +static amqp_hostcheck_result amqp_hostmatch(const char *hostname, + const char *pattern) { + const char *pattern_label_end, *pattern_wildcard, *hostname_label_end; + int wildcard_enabled; + size_t prefixlen, suffixlen; + pattern_wildcard = strchr(pattern, '*'); + if (pattern_wildcard == NULL) { + return amqp_raw_equal(pattern, hostname) ? AMQP_HCR_MATCH + : AMQP_HCR_NO_MATCH; + } + /* We require at least 2 dots in pattern to avoid too wide wildcard match. */ + wildcard_enabled = 1; + pattern_label_end = strchr(pattern, '.'); + if (pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL || + pattern_wildcard > pattern_label_end || + amqp_raw_nequal(pattern, "xn--", 4)) { + wildcard_enabled = 0; + } + if (!wildcard_enabled) { + return amqp_raw_equal(pattern, hostname) ? AMQP_HCR_MATCH + : AMQP_HCR_NO_MATCH; + } + hostname_label_end = strchr(hostname, '.'); + if (hostname_label_end == NULL || + !amqp_raw_equal(pattern_label_end, hostname_label_end)) { + return AMQP_HCR_NO_MATCH; + } + /* The wildcard must match at least one character, so the left-most + * label of the hostname is at least as large as the left-most label + * of the pattern. + */ + if (hostname_label_end - hostname < pattern_label_end - pattern) { + return AMQP_HCR_NO_MATCH; + } + prefixlen = pattern_wildcard - pattern; + suffixlen = pattern_label_end - (pattern_wildcard + 1); + return amqp_raw_nequal(pattern, hostname, prefixlen) && + amqp_raw_nequal(pattern_wildcard + 1, + hostname_label_end - suffixlen, suffixlen) + ? AMQP_HCR_MATCH + : AMQP_HCR_NO_MATCH; +} + +amqp_hostcheck_result amqp_hostcheck(const char *match_pattern, + const char *hostname) { + /* sanity check */ + if (!match_pattern || !*match_pattern || !hostname || !*hostname) { + return AMQP_HCR_NO_MATCH; + } + /* trivial case */ + if (amqp_raw_equal(hostname, match_pattern)) { + return AMQP_HCR_MATCH; + } + return amqp_hostmatch(hostname, match_pattern); +} diff --git a/ext/librabbitmq/librabbitmq/amqp_hostcheck.h b/ext/librabbitmq/librabbitmq/amqp_hostcheck.h new file mode 100644 index 00000000..7ab5c267 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_hostcheck.h @@ -0,0 +1,48 @@ +#ifndef librabbitmq_amqp_hostcheck_h +#define librabbitmq_amqp_hostcheck_h + +/* + * Copyright 1996-2014 Daniel Stenberg . + * Copyright 2014 Michael Steinert + * + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization of the + * copyright holder. + */ + +typedef enum { + AMQP_HCR_NO_MATCH = 0, + AMQP_HCR_MATCH = 1 +} amqp_hostcheck_result; + +/** + * Determine whether hostname matches match_pattern. + * + * match_pattern may include wildcards. + * + * Match is performed based on the rules set forth in RFC6125 section 6.4.3. + * http://tools.ietf.org/html/rfc6125#section-6.4.3 + * + * \param match_pattern RFC6125 compliant pattern + * \param hostname to match against + * \returns AMQP_HCR_MATCH if its a match, AMQP_HCR_NO_MATCH otherwise. + */ +amqp_hostcheck_result amqp_hostcheck(const char *match_pattern, + const char *hostname); + +#endif diff --git a/ext/librabbitmq/librabbitmq/amqp_mem.c b/ext/librabbitmq/librabbitmq/amqp_mem.c new file mode 100644 index 00000000..f0d47cc7 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_mem.c @@ -0,0 +1,242 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp_private.h" +#include +#include +#include +#include +#include +#include + +char const *amqp_version(void) { return AMQP_VERSION_STRING; } + +uint32_t amqp_version_number(void) { return AMQP_VERSION; } + +void init_amqp_pool(amqp_pool_t *pool, size_t pagesize) { + pool->pagesize = pagesize ? pagesize : 4096; + + pool->pages.num_blocks = 0; + pool->pages.blocklist = NULL; + + pool->large_blocks.num_blocks = 0; + pool->large_blocks.blocklist = NULL; + + pool->next_page = 0; + pool->alloc_block = NULL; + pool->alloc_used = 0; +} + +static void empty_blocklist(amqp_pool_blocklist_t *x) { + int i; + + if (x->blocklist != NULL) { + for (i = 0; i < x->num_blocks; i++) { + free(x->blocklist[i]); + } + free(x->blocklist); + } + x->num_blocks = 0; + x->blocklist = NULL; +} + +void recycle_amqp_pool(amqp_pool_t *pool) { + empty_blocklist(&pool->large_blocks); + pool->next_page = 0; + pool->alloc_block = NULL; + pool->alloc_used = 0; +} + +void empty_amqp_pool(amqp_pool_t *pool) { + recycle_amqp_pool(pool); + empty_blocklist(&pool->pages); +} + +/* Returns 1 on success, 0 on failure */ +static int record_pool_block(amqp_pool_blocklist_t *x, void *block) { + size_t blocklistlength = sizeof(void *) * (x->num_blocks + 1); + + if (x->blocklist == NULL) { + x->blocklist = malloc(blocklistlength); + if (x->blocklist == NULL) { + return 0; + } + } else { + void *newbl = realloc(x->blocklist, blocklistlength); + if (newbl == NULL) { + return 0; + } + x->blocklist = newbl; + } + + x->blocklist[x->num_blocks] = block; + x->num_blocks++; + return 1; +} + +void *amqp_pool_alloc(amqp_pool_t *pool, size_t amount) { + if (amount == 0) { + return NULL; + } + + amount = (amount + 7) & (~7); /* round up to nearest 8-byte boundary */ + + if (amount > pool->pagesize) { + void *result = calloc(1, amount); + if (result == NULL) { + return NULL; + } + if (!record_pool_block(&pool->large_blocks, result)) { + free(result); + return NULL; + } + return result; + } + + if (pool->alloc_block != NULL) { + assert(pool->alloc_used <= pool->pagesize); + + if (pool->alloc_used + amount <= pool->pagesize) { + void *result = pool->alloc_block + pool->alloc_used; + pool->alloc_used += amount; + return result; + } + } + + if (pool->next_page >= pool->pages.num_blocks) { + pool->alloc_block = calloc(1, pool->pagesize); + if (pool->alloc_block == NULL) { + return NULL; + } + if (!record_pool_block(&pool->pages, pool->alloc_block)) { + return NULL; + } + pool->next_page = pool->pages.num_blocks; + } else { + pool->alloc_block = pool->pages.blocklist[pool->next_page]; + pool->next_page++; + } + + pool->alloc_used = amount; + + return pool->alloc_block; +} + +void amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, + amqp_bytes_t *output) { + output->len = amount; + output->bytes = amqp_pool_alloc(pool, amount); +} + +amqp_bytes_t amqp_cstring_bytes(char const *cstr) { + amqp_bytes_t result; + result.len = strlen(cstr); + result.bytes = (void *)cstr; + return result; +} + +amqp_bytes_t amqp_bytes_malloc_dup(amqp_bytes_t src) { + amqp_bytes_t result; + result.len = src.len; + result.bytes = malloc(src.len); + if (result.bytes != NULL) { + memcpy(result.bytes, src.bytes, src.len); + } + return result; +} + +amqp_bytes_t amqp_bytes_malloc(size_t amount) { + amqp_bytes_t result; + result.len = amount; + result.bytes = malloc(amount); /* will return NULL if it fails */ + return result; +} + +void amqp_bytes_free(amqp_bytes_t bytes) { free(bytes.bytes); } + +amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t state, + amqp_channel_t channel) { + amqp_pool_table_entry_t *entry; + size_t index = channel % POOL_TABLE_SIZE; + + entry = state->pool_table[index]; + + for (; NULL != entry; entry = entry->next) { + if (channel == entry->channel) { + return &entry->pool; + } + } + + entry = malloc(sizeof(amqp_pool_table_entry_t)); + if (NULL == entry) { + return NULL; + } + + entry->channel = channel; + entry->next = state->pool_table[index]; + state->pool_table[index] = entry; + + init_amqp_pool(&entry->pool, state->frame_max); + + return &entry->pool; +} + +amqp_pool_t *amqp_get_channel_pool(amqp_connection_state_t state, + amqp_channel_t channel) { + amqp_pool_table_entry_t *entry; + size_t index = channel % POOL_TABLE_SIZE; + + entry = state->pool_table[index]; + + for (; NULL != entry; entry = entry->next) { + if (channel == entry->channel) { + return &entry->pool; + } + } + + return NULL; +} + +int amqp_bytes_equal(amqp_bytes_t r, amqp_bytes_t l) { + if (r.len == l.len && + (r.bytes == l.bytes || 0 == memcmp(r.bytes, l.bytes, r.len))) { + return 1; + } + return 0; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_openssl.c b/ext/librabbitmq/librabbitmq/amqp_openssl.c new file mode 100644 index 00000000..bcd5ba53 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_openssl.c @@ -0,0 +1,704 @@ +/* + * Portions created by Alan Antonuk are Copyright (c) 2012-2014 Alan Antonuk. + * All Rights Reserved. + * + * Portions created by Michael Steinert are Copyright (c) 2012-2014 Michael + * Steinert. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp_openssl_bio.h" +#include "amqp_openssl_hostname_validation.h" +#include "amqp_private.h" +#include "amqp_socket.h" +#include "amqp_ssl_socket.h" +#include "amqp_time.h" +#include "threads.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int initialize_ssl_and_increment_connections(void); +static int decrement_ssl_connections(void); + +static unsigned long ssl_threadid_callback(void); +static void ssl_locking_callback(int mode, int n, const char *file, int line); +static pthread_mutex_t *amqp_openssl_lockarray = NULL; + +static pthread_mutex_t openssl_init_mutex = PTHREAD_MUTEX_INITIALIZER; +static amqp_boolean_t do_initialize_openssl = 1; +static amqp_boolean_t openssl_initialized = 0; +static amqp_boolean_t openssl_bio_initialized = 0; +static int openssl_connections = 0; + +#define CHECK_SUCCESS(condition) \ + do { \ + int check_success_ret = (condition); \ + if (check_success_ret) { \ + amqp_abort("Check %s failed <%d>: %s", #condition, check_success_ret, \ + strerror(check_success_ret)); \ + } \ + } while (0) + +struct amqp_ssl_socket_t { + const struct amqp_socket_class_t *klass; + SSL_CTX *ctx; + int sockfd; + SSL *ssl; + amqp_boolean_t verify_peer; + amqp_boolean_t verify_hostname; + int internal_error; +}; + +static ssize_t amqp_ssl_socket_send(void *base, const void *buf, size_t len, + AMQP_UNUSED int flags) { + struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; + int res; + if (-1 == self->sockfd) { + return AMQP_STATUS_SOCKET_CLOSED; + } + + /* SSL_write takes an int for length of buffer, protect against len being + * larger than larger than what SSL_write can take */ + if (len > INT_MAX) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + ERR_clear_error(); + self->internal_error = 0; + + /* This will only return on error, or once the whole buffer has been + * written to the SSL stream. See SSL_MODE_ENABLE_PARTIAL_WRITE */ + res = SSL_write(self->ssl, buf, (int)len); + if (0 >= res) { + self->internal_error = SSL_get_error(self->ssl, res); + /* TODO: Close connection if it isn't already? */ + /* TODO: Possibly be more intelligent in reporting WHAT went wrong */ + switch (self->internal_error) { + case SSL_ERROR_WANT_READ: + res = AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD; + break; + case SSL_ERROR_WANT_WRITE: + res = AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE; + break; + case SSL_ERROR_ZERO_RETURN: + res = AMQP_STATUS_CONNECTION_CLOSED; + break; + default: + res = AMQP_STATUS_SSL_ERROR; + break; + } + } else { + self->internal_error = 0; + } + + return (ssize_t)res; +} + +static ssize_t amqp_ssl_socket_recv(void *base, void *buf, size_t len, + AMQP_UNUSED int flags) { + struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; + int received; + if (-1 == self->sockfd) { + return AMQP_STATUS_SOCKET_CLOSED; + } + + /* SSL_read takes an int for length of buffer, protect against len being + * larger than larger than what SSL_read can take */ + if (len > INT_MAX) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + ERR_clear_error(); + self->internal_error = 0; + + received = SSL_read(self->ssl, buf, (int)len); + if (0 >= received) { + self->internal_error = SSL_get_error(self->ssl, received); + switch (self->internal_error) { + case SSL_ERROR_WANT_READ: + received = AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD; + break; + case SSL_ERROR_WANT_WRITE: + received = AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE; + break; + case SSL_ERROR_ZERO_RETURN: + received = AMQP_STATUS_CONNECTION_CLOSED; + break; + default: + received = AMQP_STATUS_SSL_ERROR; + break; + } + } + + return (ssize_t)received; +} + +static int amqp_ssl_socket_open(void *base, const char *host, int port, + struct timeval *timeout) { + struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; + long result; + int status; + amqp_time_t deadline; + X509 *cert; + BIO *bio; + if (-1 != self->sockfd) { + return AMQP_STATUS_SOCKET_INUSE; + } + ERR_clear_error(); + + self->ssl = SSL_new(self->ctx); + if (!self->ssl) { + self->internal_error = ERR_peek_error(); + status = AMQP_STATUS_SSL_ERROR; + goto exit; + } + + status = amqp_time_from_now(&deadline, timeout); + if (AMQP_STATUS_OK != status) { + return status; + } + + self->sockfd = amqp_open_socket_inner(host, port, deadline); + if (0 > self->sockfd) { + status = self->sockfd; + self->internal_error = amqp_os_socket_error(); + self->sockfd = -1; + goto error_out1; + } + + bio = BIO_new(amqp_openssl_bio()); + if (!bio) { + status = AMQP_STATUS_NO_MEMORY; + goto error_out2; + } + + BIO_set_fd(bio, self->sockfd, BIO_NOCLOSE); + SSL_set_bio(self->ssl, bio, bio); + + status = SSL_set_tlsext_host_name(self->ssl, host); + if (!status) { + self->internal_error = SSL_get_error(self->ssl, status); + status = AMQP_STATUS_SSL_ERROR; + goto error_out2; + } + +start_connect: + status = SSL_connect(self->ssl); + if (status != 1) { + self->internal_error = SSL_get_error(self->ssl, status); + switch (self->internal_error) { + case SSL_ERROR_WANT_READ: + status = amqp_poll(self->sockfd, AMQP_SF_POLLIN, deadline); + break; + case SSL_ERROR_WANT_WRITE: + status = amqp_poll(self->sockfd, AMQP_SF_POLLOUT, deadline); + break; + default: + status = AMQP_STATUS_SSL_CONNECTION_FAILED; + } + if (AMQP_STATUS_OK == status) { + goto start_connect; + } + goto error_out2; + } + + cert = SSL_get_peer_certificate(self->ssl); + + if (self->verify_peer) { + if (!cert) { + self->internal_error = 0; + status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED; + goto error_out3; + } + + result = SSL_get_verify_result(self->ssl); + if (X509_V_OK != result) { + self->internal_error = result; + status = AMQP_STATUS_SSL_PEER_VERIFY_FAILED; + goto error_out4; + } + } + if (self->verify_hostname) { + if (!cert) { + self->internal_error = 0; + status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED; + goto error_out3; + } + + if (AMQP_HVR_MATCH_FOUND != amqp_ssl_validate_hostname(host, cert)) { + self->internal_error = 0; + status = AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED; + goto error_out4; + } + } + + X509_free(cert); + self->internal_error = 0; + status = AMQP_STATUS_OK; + +exit: + return status; + +error_out4: + X509_free(cert); +error_out3: + SSL_shutdown(self->ssl); +error_out2: + amqp_os_socket_close(self->sockfd); + self->sockfd = -1; +error_out1: + SSL_free(self->ssl); + self->ssl = NULL; + goto exit; +} + +static int amqp_ssl_socket_close(void *base, amqp_socket_close_enum force) { + struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; + + if (-1 == self->sockfd) { + return AMQP_STATUS_SOCKET_CLOSED; + } + + if (AMQP_SC_NONE == force) { + /* don't try too hard to shutdown the connection */ + SSL_shutdown(self->ssl); + } + + SSL_free(self->ssl); + self->ssl = NULL; + + if (amqp_os_socket_close(self->sockfd)) { + return AMQP_STATUS_SOCKET_ERROR; + } + self->sockfd = -1; + + return AMQP_STATUS_OK; +} + +static int amqp_ssl_socket_get_sockfd(void *base) { + struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; + return self->sockfd; +} + +static void amqp_ssl_socket_delete(void *base) { + struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base; + + if (self) { + amqp_ssl_socket_close(self, AMQP_SC_NONE); + + SSL_CTX_free(self->ctx); + free(self); + } + decrement_ssl_connections(); +} + +static const struct amqp_socket_class_t amqp_ssl_socket_class = { + amqp_ssl_socket_send, /* send */ + amqp_ssl_socket_recv, /* recv */ + amqp_ssl_socket_open, /* open */ + amqp_ssl_socket_close, /* close */ + amqp_ssl_socket_get_sockfd, /* get_sockfd */ + amqp_ssl_socket_delete /* delete */ +}; + +amqp_socket_t *amqp_ssl_socket_new(amqp_connection_state_t state) { + struct amqp_ssl_socket_t *self = calloc(1, sizeof(*self)); + int status; + if (!self) { + return NULL; + } + + self->sockfd = -1; + self->klass = &amqp_ssl_socket_class; + self->verify_peer = 1; + self->verify_hostname = 1; + + status = initialize_ssl_and_increment_connections(); + if (status) { + goto error; + } + + self->ctx = SSL_CTX_new(SSLv23_client_method()); + if (!self->ctx) { + goto error; + } + /* Disable SSLv2 and SSLv3 */ + SSL_CTX_set_options(self->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + + amqp_set_socket(state, (amqp_socket_t *)self); + + return (amqp_socket_t *)self; +error: + amqp_ssl_socket_delete((amqp_socket_t *)self); + return NULL; +} + +int amqp_ssl_socket_set_cacert(amqp_socket_t *base, const char *cacert) { + int status; + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + status = SSL_CTX_load_verify_locations(self->ctx, cacert, NULL); + if (1 != status) { + return AMQP_STATUS_SSL_ERROR; + } + return AMQP_STATUS_OK; +} + +int amqp_ssl_socket_set_key(amqp_socket_t *base, const char *cert, + const char *key) { + int status; + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); + if (1 != status) { + return AMQP_STATUS_SSL_ERROR; + } + status = SSL_CTX_use_PrivateKey_file(self->ctx, key, SSL_FILETYPE_PEM); + if (1 != status) { + return AMQP_STATUS_SSL_ERROR; + } + return AMQP_STATUS_OK; +} + +static int password_cb(AMQP_UNUSED char *buffer, AMQP_UNUSED int length, + AMQP_UNUSED int rwflag, AMQP_UNUSED void *user_data) { + amqp_abort("rabbitmq-c does not support password protected keys"); +} + +int amqp_ssl_socket_set_key_buffer(amqp_socket_t *base, const char *cert, + const void *key, size_t n) { + int status = AMQP_STATUS_OK; + BIO *buf = NULL; + RSA *rsa = NULL; + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + if (n > INT_MAX) { + return AMQP_STATUS_INVALID_PARAMETER; + } + self = (struct amqp_ssl_socket_t *)base; + status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); + if (1 != status) { + return AMQP_STATUS_SSL_ERROR; + } + buf = BIO_new_mem_buf((void *)key, (int)n); + if (!buf) { + goto error; + } + rsa = PEM_read_bio_RSAPrivateKey(buf, NULL, password_cb, NULL); + if (!rsa) { + goto error; + } + status = SSL_CTX_use_RSAPrivateKey(self->ctx, rsa); + if (1 != status) { + goto error; + } +exit: + BIO_vfree(buf); + RSA_free(rsa); + return status; +error: + status = AMQP_STATUS_SSL_ERROR; + goto exit; +} + +int amqp_ssl_socket_set_cert(amqp_socket_t *base, const char *cert) { + int status; + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + status = SSL_CTX_use_certificate_chain_file(self->ctx, cert); + if (1 != status) { + return AMQP_STATUS_SSL_ERROR; + } + return AMQP_STATUS_OK; +} + +void amqp_ssl_socket_set_verify(amqp_socket_t *base, amqp_boolean_t verify) { + amqp_ssl_socket_set_verify_peer(base, verify); + amqp_ssl_socket_set_verify_hostname(base, verify); +} + +void amqp_ssl_socket_set_verify_peer(amqp_socket_t *base, + amqp_boolean_t verify) { + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + self->verify_peer = verify; +} + +void amqp_ssl_socket_set_verify_hostname(amqp_socket_t *base, + amqp_boolean_t verify) { + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + self->verify_hostname = verify; +} + +int amqp_ssl_socket_set_ssl_versions(amqp_socket_t *base, + amqp_tls_version_t min, + amqp_tls_version_t max) { + struct amqp_ssl_socket_t *self; + if (base->klass != &amqp_ssl_socket_class) { + amqp_abort("<%p> is not of type amqp_ssl_socket_t", base); + } + self = (struct amqp_ssl_socket_t *)base; + + { + long clear_options; + long set_options = 0; +#if defined(SSL_OP_NO_TLSv1_2) + amqp_tls_version_t max_supported = AMQP_TLSv1_2; + clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2; +#elif defined(SSL_OP_NO_TLSv1_1) + amqp_tls_version_t max_supported = AMQP_TLSv1_1; + clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1; +#elif defined(SSL_OP_NO_TLSv1) + amqp_tls_version_t max_supported = AMQP_TLSv1; + clear_options = SSL_OP_NO_TLSv1; +#else +#error "Need a version of OpenSSL that can support TLSv1 or greater." +#endif + + if (AMQP_TLSvLATEST == max) { + max = max_supported; + } + if (AMQP_TLSvLATEST == min) { + min = max_supported; + } + + if (min > max) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + if (max > max_supported || min > max_supported) { + return AMQP_STATUS_UNSUPPORTED; + } + + if (min > AMQP_TLSv1) { + set_options |= SSL_OP_NO_TLSv1; + } +#ifdef SSL_OP_NO_TLSv1_1 + if (min > AMQP_TLSv1_1 || max < AMQP_TLSv1_1) { + set_options |= SSL_OP_NO_TLSv1_1; + } +#endif +#ifdef SSL_OP_NO_TLSv1_2 + if (max < AMQP_TLSv1_2) { + set_options |= SSL_OP_NO_TLSv1_2; + } +#endif + SSL_CTX_clear_options(self->ctx, clear_options); + SSL_CTX_set_options(self->ctx, set_options); + } + + return AMQP_STATUS_OK; +} + +void amqp_set_initialize_ssl_library(amqp_boolean_t do_initialize) { + CHECK_SUCCESS(pthread_mutex_lock(&openssl_init_mutex)); + + if (openssl_connections == 0 && !openssl_initialized) { + do_initialize_openssl = do_initialize; + } + CHECK_SUCCESS(pthread_mutex_unlock(&openssl_init_mutex)); +} + +static unsigned long ssl_threadid_callback(void) { + return (unsigned long)pthread_self(); +} + +static void ssl_locking_callback(int mode, int n, AMQP_UNUSED const char *file, + AMQP_UNUSED int line) { + if (mode & CRYPTO_LOCK) { + CHECK_SUCCESS(pthread_mutex_lock(&amqp_openssl_lockarray[n])); + } else { + CHECK_SUCCESS(pthread_mutex_unlock(&amqp_openssl_lockarray[n])); + } +} + +static int setup_openssl(void) { + int status; + + int i; + amqp_openssl_lockarray = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t)); + if (!amqp_openssl_lockarray) { + status = AMQP_STATUS_NO_MEMORY; + goto out; + } + for (i = 0; i < CRYPTO_num_locks(); i++) { + if (pthread_mutex_init(&amqp_openssl_lockarray[i], NULL)) { + int j; + for (j = 0; j < i; j++) { + pthread_mutex_destroy(&amqp_openssl_lockarray[j]); + } + free(amqp_openssl_lockarray); + status = AMQP_STATUS_SSL_ERROR; + goto out; + } + } + CRYPTO_set_id_callback(ssl_threadid_callback); + CRYPTO_set_locking_callback(ssl_locking_callback); + +#ifdef AMQP_OPENSSL_V110 + if (CONF_modules_load_file(NULL, "rabbitmq-c", CONF_MFLAGS_DEFAULT_SECTION) <= + 0) { + status = AMQP_STATUS_SSL_ERROR; + goto out; + } +#else + OPENSSL_config(NULL); +#endif + SSL_library_init(); + SSL_load_error_strings(); + + status = AMQP_STATUS_OK; +out: + return status; +} + +int amqp_initialize_ssl_library(void) { + int status; + CHECK_SUCCESS(pthread_mutex_lock(&openssl_init_mutex)); + + if (!openssl_initialized) { + status = setup_openssl(); + if (status) { + goto out; + } + openssl_initialized = 1; + } + + status = AMQP_STATUS_OK; +out: + CHECK_SUCCESS(pthread_mutex_unlock(&openssl_init_mutex)); + return status; +} + +static int initialize_ssl_and_increment_connections() { + int status; + CHECK_SUCCESS(pthread_mutex_lock(&openssl_init_mutex)); + + if (do_initialize_openssl && !openssl_initialized) { + status = setup_openssl(); + if (status) { + goto exit; + } + openssl_initialized = 1; + } + + if (!openssl_bio_initialized) { + status = amqp_openssl_bio_init(); + if (status) { + goto exit; + } + openssl_bio_initialized = 1; + } + + openssl_connections += 1; + status = AMQP_STATUS_OK; +exit: + CHECK_SUCCESS(pthread_mutex_unlock(&openssl_init_mutex)); + return status; +} + +static int decrement_ssl_connections(void) { + CHECK_SUCCESS(pthread_mutex_lock(&openssl_init_mutex)); + + if (openssl_connections > 0) { + openssl_connections--; + } + + CHECK_SUCCESS(pthread_mutex_unlock(&openssl_init_mutex)); + return AMQP_STATUS_OK; +} + +int amqp_uninitialize_ssl_library(void) { + int status; + CHECK_SUCCESS(pthread_mutex_lock(&openssl_init_mutex)); + + if (openssl_connections > 0) { + status = AMQP_STATUS_SOCKET_INUSE; + goto out; + } + + amqp_openssl_bio_destroy(); + openssl_bio_initialized = 0; + +#ifndef AMQP_OPENSSL_V110 + ERR_remove_state(0); +#endif + +#ifndef LIBRESSL_VERSION_NUMBER + FIPS_mode_set(0); +#endif + + CRYPTO_set_locking_callback(NULL); + CRYPTO_set_id_callback(NULL); + { + int i; + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_destroy(&amqp_openssl_lockarray[i]); + } + free(amqp_openssl_lockarray); + } + + ENGINE_cleanup(); + CONF_modules_free(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); +#if (OPENSSL_VERSION_NUMBER >= 0x10002003L) && !defined(LIBRESSL_VERSION_NUMBER) + SSL_COMP_free_compression_methods(); +#endif + + openssl_initialized = 0; + + status = AMQP_STATUS_OK; +out: + CHECK_SUCCESS(pthread_mutex_unlock(&openssl_init_mutex)); + return status; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_openssl_bio.c b/ext/librabbitmq/librabbitmq/amqp_openssl_bio.c new file mode 100644 index 00000000..3556d6f3 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_openssl_bio.c @@ -0,0 +1,193 @@ +/* + * Portions created by Alan Antonuk are Copyright (c) 2017 Alan Antonuk. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "amqp_openssl_bio.h" +#include "amqp_socket.h" + +#include +#include +#if ((defined(_WIN32)) || (defined(__MINGW32__)) || (defined(__MINGW64__))) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#include +#endif + +#ifdef MSG_NOSIGNAL +#define AMQP_USE_AMQP_BIO +#endif + +static int amqp_ssl_bio_initialized = 0; + +#ifdef AMQP_USE_AMQP_BIO + +static BIO_METHOD *amqp_bio_method; + +static int amqp_openssl_bio_should_retry(int res) { + if (res == -1) { + int err = amqp_os_socket_error(); + if ( +#ifdef EWOULDBLOCK + err == EWOULDBLOCK || +#endif +#ifdef WSAEWOULDBLOCK + err == WSAEWOULDBLOCK || +#endif +#ifdef ENOTCONN + err == ENOTCONN || +#endif +#ifdef EINTR + err == EINTR || +#endif +#ifdef EAGAIN + err == EAGAIN || +#endif +#ifdef EPROTO + err == EPROTO || +#endif +#ifdef EINPROGRESS + err == EINPROGRESS || +#endif +#ifdef EALREADY + err == EALREADY || +#endif + 0) { + return 1; + } + } + return 0; +} + +static int amqp_openssl_bio_write(BIO *b, const char *in, int inl) { + int flags = 0; + int fd; + int res; + +#ifdef MSG_NOSIGNAL + flags |= MSG_NOSIGNAL; +#endif + + BIO_get_fd(b, &fd); + res = send(fd, in, inl, flags); + + BIO_clear_retry_flags(b); + if (res <= 0 && amqp_openssl_bio_should_retry(res)) { + BIO_set_retry_write(b); + } + + return res; +} + +static int amqp_openssl_bio_read(BIO *b, char *out, int outl) { + int flags = 0; + int fd; + int res; + +#ifdef MSG_NOSIGNAL + flags |= MSG_NOSIGNAL; +#endif + + BIO_get_fd(b, &fd); + res = recv(fd, out, outl, flags); + + BIO_clear_retry_flags(b); + if (res <= 0 && amqp_openssl_bio_should_retry(res)) { + BIO_set_retry_read(b); + } + + return res; +} + +#ifndef AMQP_OPENSSL_V110 +static int BIO_meth_set_write(BIO_METHOD *biom, + int (*wfn)(BIO *, const char *, int)) { + biom->bwrite = wfn; + return 0; +} + +static int BIO_meth_set_read(BIO_METHOD *biom, int (*rfn)(BIO *, char *, int)) { + biom->bread = rfn; + return 0; +} +#endif /* AQP_OPENSSL_V110 */ +#endif /* AMQP_USE_AMQP_BIO */ + +int amqp_openssl_bio_init(void) { + assert(!amqp_ssl_bio_initialized); +#ifdef AMQP_USE_AMQP_BIO +#ifdef AMQP_OPENSSL_V110 + if (!(amqp_bio_method = BIO_meth_new(BIO_TYPE_SOCKET, "amqp_bio_method"))) { + return AMQP_STATUS_NO_MEMORY; + } + + // casting away const is necessary until + // https://github.com/openssl/openssl/pull/2181/, which is targeted for + // openssl 1.1.1 + BIO_METHOD *meth = (BIO_METHOD *)BIO_s_socket(); + BIO_meth_set_create(amqp_bio_method, BIO_meth_get_create(meth)); + BIO_meth_set_destroy(amqp_bio_method, BIO_meth_get_destroy(meth)); + BIO_meth_set_ctrl(amqp_bio_method, BIO_meth_get_ctrl(meth)); + BIO_meth_set_callback_ctrl(amqp_bio_method, BIO_meth_get_callback_ctrl(meth)); + BIO_meth_set_read(amqp_bio_method, BIO_meth_get_read(meth)); + BIO_meth_set_write(amqp_bio_method, BIO_meth_get_write(meth)); + BIO_meth_set_gets(amqp_bio_method, BIO_meth_get_gets(meth)); + BIO_meth_set_puts(amqp_bio_method, BIO_meth_get_puts(meth)); +#else + if (!(amqp_bio_method = OPENSSL_malloc(sizeof(BIO_METHOD)))) { + return AMQP_STATUS_NO_MEMORY; + } + + memcpy(amqp_bio_method, BIO_s_socket(), sizeof(BIO_METHOD)); +#endif + BIO_meth_set_write(amqp_bio_method, amqp_openssl_bio_write); + BIO_meth_set_read(amqp_bio_method, amqp_openssl_bio_read); +#endif + + amqp_ssl_bio_initialized = 1; + return AMQP_STATUS_OK; +} + +void amqp_openssl_bio_destroy(void) { + assert(amqp_ssl_bio_initialized); +#ifdef AMQP_USE_AMQP_BIO +#ifdef AMQP_OPENSSL_V110 + BIO_meth_free(amqp_bio_method); +#else + OPENSSL_free(amqp_bio_method); +#endif + amqp_bio_method = NULL; +#endif + amqp_ssl_bio_initialized = 0; +} + +BIO_METHOD_PTR amqp_openssl_bio(void) { + assert(amqp_ssl_bio_initialized); +#ifdef AMQP_USE_AMQP_BIO + return amqp_bio_method; +#else + return BIO_s_socket(); +#endif +} diff --git a/ext/librabbitmq/librabbitmq/amqp_openssl_bio.h b/ext/librabbitmq/librabbitmq/amqp_openssl_bio.h new file mode 100644 index 00000000..ec09c5e7 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_openssl_bio.h @@ -0,0 +1,44 @@ +/* + * Portions created by Alan Antonuk are Copyright (c) 2017 Alan Antonuk. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef AMQP_OPENSSL_BIO +#define AMQP_OPENSSL_BIO + +#include + +int amqp_openssl_bio_init(void); + +void amqp_openssl_bio_destroy(void); + +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) +#define AMQP_OPENSSL_V110 +#endif + +#ifdef AMQP_OPENSSL_V110 +typedef const BIO_METHOD *BIO_METHOD_PTR; +#else +typedef BIO_METHOD *BIO_METHOD_PTR; +#endif + +BIO_METHOD_PTR amqp_openssl_bio(void); + +#endif /* ifndef AMQP_OPENSSL_BIO */ diff --git a/ext/librabbitmq/librabbitmq/amqp_openssl_hostname_validation.c b/ext/librabbitmq/librabbitmq/amqp_openssl_hostname_validation.c new file mode 100644 index 00000000..133d73c8 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_openssl_hostname_validation.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2012, iSEC Partners. + * Copyright (C) 2015 Alan Antonuk. + * + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization of the + * copyright holder. + */ + +/* Originally from: + * https://github.com/iSECPartners/ssl-conservatory + * https://wiki.openssl.org/index.php/Hostname_validation + */ + +#include +#include + +#include "amqp_hostcheck.h" +#include "amqp_openssl_bio.h" +#include "amqp_openssl_hostname_validation.h" + +#include + +#define HOSTNAME_MAX_SIZE 255 + +/** + * Tries to find a match for hostname in the certificate's Common Name field. + * + * Returns AMQP_HVR_MATCH_FOUND if a match was found. + * Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. + * Returns AMQP_HVR_MALFORMED_CERTIFICATE if the Common Name had a NUL character + * embedded in it. + * Returns AMQP_HVR_ERROR if the Common Name could not be extracted. + */ +static amqp_hostname_validation_result amqp_matches_common_name( + const char *hostname, const X509 *server_cert) { + int common_name_loc = -1; + X509_NAME_ENTRY *common_name_entry = NULL; + ASN1_STRING *common_name_asn1 = NULL; + const char *common_name_str = NULL; + + // Find the position of the CN field in the Subject field of the certificate + common_name_loc = X509_NAME_get_index_by_NID( + X509_get_subject_name((X509 *)server_cert), NID_commonName, -1); + if (common_name_loc < 0) { + return AMQP_HVR_ERROR; + } + + // Extract the CN field + common_name_entry = X509_NAME_get_entry( + X509_get_subject_name((X509 *)server_cert), common_name_loc); + if (common_name_entry == NULL) { + return AMQP_HVR_ERROR; + } + + // Convert the CN field to a C string + common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); + if (common_name_asn1 == NULL) { + return AMQP_HVR_ERROR; + } + +#ifdef AMQP_OPENSSL_V110 + common_name_str = (const char *)ASN1_STRING_get0_data(common_name_asn1); +#else + common_name_str = (char *)ASN1_STRING_data(common_name_asn1); +#endif + + // Make sure there isn't an embedded NUL character in the CN + if ((size_t)ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) { + return AMQP_HVR_MALFORMED_CERTIFICATE; + } + + // Compare expected hostname with the CN + if (amqp_hostcheck(common_name_str, hostname) == AMQP_HCR_MATCH) { + return AMQP_HVR_MATCH_FOUND; + } else { + return AMQP_HVR_MATCH_NOT_FOUND; + } +} + +/** + * Tries to find a match for hostname in the certificate's Subject Alternative + * Name extension. + * + * Returns AMQP_HVR_MATCH_FOUND if a match was found. + * Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. + * Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL + * character embedded in it. + * Returns AMQP_HVR_NO_SAN_PRESENT if the SAN extension was not present in the + * certificate. + */ +static amqp_hostname_validation_result amqp_matches_subject_alternative_name( + const char *hostname, const X509 *server_cert) { + amqp_hostname_validation_result result = AMQP_HVR_MATCH_NOT_FOUND; + int i; + int san_names_nb = -1; + STACK_OF(GENERAL_NAME) *san_names = NULL; + + // Try to extract the names within the SAN extension from the certificate + san_names = + X509_get_ext_d2i((X509 *)server_cert, NID_subject_alt_name, NULL, NULL); + if (san_names == NULL) { + return AMQP_HVR_NO_SAN_PRESENT; + } + san_names_nb = sk_GENERAL_NAME_num(san_names); + + // Check each name within the extension + for (i = 0; i < san_names_nb; i++) { + const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i); + + if (current_name->type == GEN_DNS) { + // Current name is a DNS name, let's check it + const char *dns_name = (const char *) +#ifdef AMQP_OPENSSL_V110 + ASN1_STRING_get0_data(current_name->d.dNSName); +#else + ASN1_STRING_data(current_name->d.dNSName); +#endif + + // Make sure there isn't an embedded NUL character in the DNS name + if ((size_t)ASN1_STRING_length(current_name->d.dNSName) != + strlen(dns_name)) { + result = AMQP_HVR_MALFORMED_CERTIFICATE; + break; + } else { // Compare expected hostname with the DNS name + if (amqp_hostcheck(dns_name, hostname) == AMQP_HCR_MATCH) { + result = AMQP_HVR_MATCH_FOUND; + break; + } + } + } + } + sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free); + + return result; +} + +/** + * Validates the server's identity by looking for the expected hostname in the + * server's certificate. As described in RFC 6125, it first tries to find a + * match in the Subject Alternative Name extension. If the extension is not + * present in the certificate, it checks the Common Name instead. + * + * Returns AMQP_HVR_MATCH_FOUND if a match was found. + * Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. + * Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL + * character embedded in it. + * Returns AMQP_HVR_ERROR if there was an error. + */ +amqp_hostname_validation_result amqp_ssl_validate_hostname( + const char *hostname, const X509 *server_cert) { + amqp_hostname_validation_result result; + + if ((hostname == NULL) || (server_cert == NULL)) return AMQP_HVR_ERROR; + + // First try the Subject Alternative Names extension + result = amqp_matches_subject_alternative_name(hostname, server_cert); + if (result == AMQP_HVR_NO_SAN_PRESENT) { + // Extension was not found: try the Common Name + result = amqp_matches_common_name(hostname, server_cert); + } + + return result; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_openssl_hostname_validation.h b/ext/librabbitmq/librabbitmq/amqp_openssl_hostname_validation.h new file mode 100644 index 00000000..c9948711 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_openssl_hostname_validation.h @@ -0,0 +1,58 @@ +#ifndef librabbitmq_amqp_openssl_hostname_validation_h +#define librabbitmq_amqp_openssl_hostname_validation_h + +/* + * Copyright (C) 2012, iSEC Partners. + * Copyright (C) 2015 Alan Antonuk. + * + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization of the + * copyright holder. + */ + +/* Originally from: + * https://github.com/iSECPartners/ssl-conservatory + * https://wiki.openssl.org/index.php/Hostname_validation + */ + +#include + +typedef enum { + AMQP_HVR_MATCH_FOUND, + AMQP_HVR_MATCH_NOT_FOUND, + AMQP_HVR_NO_SAN_PRESENT, + AMQP_HVR_MALFORMED_CERTIFICATE, + AMQP_HVR_ERROR +} amqp_hostname_validation_result; + +/** +* Validates the server's identity by looking for the expected hostname in the +* server's certificate. As described in RFC 6125, it first tries to find a match +* in the Subject Alternative Name extension. If the extension is not present in +* the certificate, it checks the Common Name instead. +* +* Returns AMQP_HVR_MATCH_FOUND if a match was found. +* Returns AMQP_HVR_MATCH_NOT_FOUND if no matches were found. +* Returns AMQP_HVR_MALFORMED_CERTIFICATE if any of the hostnames had a NUL +* character embedded in it. +* Returns AMQP_HVR_ERROR if there was an error. +*/ +amqp_hostname_validation_result amqp_ssl_validate_hostname( + const char *hostname, const X509 *server_cert); + +#endif diff --git a/ext/librabbitmq/librabbitmq/amqp_private.h b/ext/librabbitmq/librabbitmq/amqp_private.h new file mode 100644 index 00000000..e73776c7 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_private.h @@ -0,0 +1,374 @@ +#ifndef librabbitmq_amqp_private_h +#define librabbitmq_amqp_private_h + +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2014 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define AMQ_COPYRIGHT \ + "Copyright (c) 2007-2014 VMWare Inc, Tony Garnock-Jones," \ + " and Alan Antonuk." + +#include "amqp.h" +#include "amqp_framing.h" +#include + +#if ((defined(_WIN32)) || (defined(__MINGW32__)) || (defined(__MINGW64__))) +#ifndef WINVER +/* WINVER 0x0502 is WinXP SP2+, Windows Server 2003 SP1+ + * See: + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx#macros_for_conditional_declarations + */ +#define WINVER 0x0502 +#endif +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#include +#endif + +/* GCC attributes */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define AMQP_NORETURN __attribute__((__noreturn__)) +#define AMQP_UNUSED __attribute__((__unused__)) +#elif defined(_MSC_VER) +#define AMQP_NORETURN __declspec(noreturn) +#define AMQP_UNUSED +#else +#define AMQP_NORETURN +#define AMQP_UNUSED +#endif + +#if __GNUC__ >= 4 +#define AMQP_PRIVATE __attribute__((visibility("hidden"))) +#else +#define AMQP_PRIVATE +#endif + +char *amqp_os_error_string(int err); + +#ifdef WITH_SSL +char *amqp_ssl_error_string(int err); +#endif + +#include "amqp_socket.h" +#include "amqp_time.h" + +/* + * Connection states: XXX FIX THIS + * + * - CONNECTION_STATE_INITIAL: The initial state, when we cannot be + * sure if the next thing we will get is the first AMQP frame, or a + * protocol header from the server. + * + * - CONNECTION_STATE_IDLE: The normal state between + * frames. Connections may only be reconfigured, and the + * connection's pools recycled, when in this state. Whenever we're + * in this state, the inbound_buffer's bytes pointer must be NULL; + * any other state, and it must point to a block of memory allocated + * from the frame_pool. + * + * - CONNECTION_STATE_HEADER: Some bytes of an incoming frame have + * been seen, but not a complete frame header's worth. + * + * - CONNECTION_STATE_BODY: A complete frame header has been seen, but + * the frame is not yet complete. When it is completed, it will be + * returned, and the connection will return to IDLE state. + * + */ +typedef enum amqp_connection_state_enum_ { + CONNECTION_STATE_IDLE = 0, + CONNECTION_STATE_INITIAL, + CONNECTION_STATE_HEADER, + CONNECTION_STATE_BODY +} amqp_connection_state_enum; + +typedef enum amqp_status_private_enum_ { + /* 0x00xx -> AMQP_STATUS_*/ + /* 0x01xx -> AMQP_STATUS_TCP_* */ + /* 0x02xx -> AMQP_STATUS_SSL_* */ + AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD = -0x1301, + AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE = -0x1302 +} amqp_status_private_enum; + +/* 7 bytes up front, then payload, then 1 byte footer */ +#define HEADER_SIZE 7 +#define FOOTER_SIZE 1 + +#define AMQP_PSEUDOFRAME_PROTOCOL_HEADER 'A' + +typedef struct amqp_link_t_ { + struct amqp_link_t_ *next; + void *data; +} amqp_link_t; + +#define POOL_TABLE_SIZE 16 + +typedef struct amqp_pool_table_entry_t_ { + struct amqp_pool_table_entry_t_ *next; + amqp_pool_t pool; + amqp_channel_t channel; +} amqp_pool_table_entry_t; + +struct amqp_connection_state_t_ { + amqp_pool_table_entry_t *pool_table[POOL_TABLE_SIZE]; + + amqp_connection_state_enum state; + + int channel_max; + int frame_max; + + /* Heartbeat interval in seconds. If this is <= 0, then heartbeats are not + * enabled, and next_recv_heartbeat and next_send_heartbeat are set to + * infinite */ + int heartbeat; + amqp_time_t next_recv_heartbeat; + amqp_time_t next_send_heartbeat; + + /* buffer for holding frame headers. Allows us to delay allocating + * the raw frame buffer until the type, channel, and size are all known + */ + char header_buffer[HEADER_SIZE + 1]; + amqp_bytes_t inbound_buffer; + + size_t inbound_offset; + size_t target_size; + + amqp_bytes_t outbound_buffer; + + amqp_socket_t *socket; + + amqp_bytes_t sock_inbound_buffer; + size_t sock_inbound_offset; + size_t sock_inbound_limit; + + amqp_link_t *first_queued_frame; + amqp_link_t *last_queued_frame; + + amqp_rpc_reply_t most_recent_api_result; + + amqp_table_t server_properties; + amqp_table_t client_properties; + amqp_pool_t properties_pool; + + struct timeval *handshake_timeout; + struct timeval internal_handshake_timeout; + struct timeval *rpc_timeout; + struct timeval internal_rpc_timeout; +}; + +amqp_pool_t *amqp_get_or_create_channel_pool(amqp_connection_state_t connection, + amqp_channel_t channel); +amqp_pool_t *amqp_get_channel_pool(amqp_connection_state_t state, + amqp_channel_t channel); + +static inline int amqp_heartbeat_send(amqp_connection_state_t state) { + return state->heartbeat; +} + +static inline int amqp_heartbeat_recv(amqp_connection_state_t state) { + return 2 * state->heartbeat; +} + +int amqp_try_recv(amqp_connection_state_t state); + +static inline void *amqp_offset(void *data, size_t offset) { + return (char *)data + offset; +} + +/* This macro defines the encoding and decoding functions associated with a + simple type. */ + +#define DECLARE_CODEC_BASE_TYPE(bits) \ + \ + static inline int amqp_encode_##bits(amqp_bytes_t encoded, size_t *offset, \ + uint##bits##_t input) { \ + size_t o = *offset; \ + if ((*offset = o + bits / 8) <= encoded.len) { \ + amqp_e##bits(input, amqp_offset(encoded.bytes, o)); \ + return 1; \ + } \ + return 0; \ + } \ + \ + static inline int amqp_decode_##bits(amqp_bytes_t encoded, size_t *offset, \ + uint##bits##_t *output) { \ + size_t o = *offset; \ + if ((*offset = o + bits / 8) <= encoded.len) { \ + *output = amqp_d##bits(amqp_offset(encoded.bytes, o)); \ + return 1; \ + } \ + return 0; \ + } + +static inline int is_bigendian(void) { + union { + uint32_t i; + char c[4]; + } bint = {0x01020304}; + return bint.c[0] == 1; +} + +static inline void amqp_e8(uint8_t val, void *data) { + memcpy(data, &val, sizeof(val)); +} + +static inline uint8_t amqp_d8(void *data) { + uint8_t val; + memcpy(&val, data, sizeof(val)); + return val; +} + +static inline void amqp_e16(uint16_t val, void *data) { + if (!is_bigendian()) { + val = ((val & 0xFF00u) >> 8u) | ((val & 0x00FFu) << 8u); + } + memcpy(data, &val, sizeof(val)); +} + +static inline uint16_t amqp_d16(void *data) { + uint16_t val; + memcpy(&val, data, sizeof(val)); + if (!is_bigendian()) { + val = ((val & 0xFF00u) >> 8u) | ((val & 0x00FFu) << 8u); + } + return val; +} + +static inline void amqp_e32(uint32_t val, void *data) { + if (!is_bigendian()) { + val = ((val & 0xFF000000u) >> 24u) | ((val & 0x00FF0000u) >> 8u) | + ((val & 0x0000FF00u) << 8u) | ((val & 0x000000FFu) << 24u); + } + memcpy(data, &val, sizeof(val)); +} + +static inline uint32_t amqp_d32(void *data) { + uint32_t val; + memcpy(&val, data, sizeof(val)); + if (!is_bigendian()) { + val = ((val & 0xFF000000u) >> 24u) | ((val & 0x00FF0000u) >> 8u) | + ((val & 0x0000FF00u) << 8u) | ((val & 0x000000FFu) << 24u); + } + return val; +} + +static inline void amqp_e64(uint64_t val, void *data) { + if (!is_bigendian()) { + val = ((val & 0xFF00000000000000u) >> 56u) | + ((val & 0x00FF000000000000u) >> 40u) | + ((val & 0x0000FF0000000000u) >> 24u) | + ((val & 0x000000FF00000000u) >> 8u) | + ((val & 0x00000000FF000000u) << 8u) | + ((val & 0x0000000000FF0000u) << 24u) | + ((val & 0x000000000000FF00u) << 40u) | + ((val & 0x00000000000000FFu) << 56u); + } + memcpy(data, &val, sizeof(val)); +} + +static inline uint64_t amqp_d64(void *data) { + uint64_t val; + memcpy(&val, data, sizeof(val)); + if (!is_bigendian()) { + val = ((val & 0xFF00000000000000u) >> 56u) | + ((val & 0x00FF000000000000u) >> 40u) | + ((val & 0x0000FF0000000000u) >> 24u) | + ((val & 0x000000FF00000000u) >> 8u) | + ((val & 0x00000000FF000000u) << 8u) | + ((val & 0x0000000000FF0000u) << 24u) | + ((val & 0x000000000000FF00u) << 40u) | + ((val & 0x00000000000000FFu) << 56u); + } + return val; +} + +DECLARE_CODEC_BASE_TYPE(8) +DECLARE_CODEC_BASE_TYPE(16) +DECLARE_CODEC_BASE_TYPE(32) +DECLARE_CODEC_BASE_TYPE(64) + +static inline int amqp_encode_bytes(amqp_bytes_t encoded, size_t *offset, + amqp_bytes_t input) { + size_t o = *offset; + /* The memcpy below has undefined behavior if the input is NULL. It is valid + * for a 0-length amqp_bytes_t to have .bytes == NULL. Thus we should check + * before encoding. + */ + if (input.len == 0) { + return 1; + } + if ((*offset = o + input.len) <= encoded.len) { + memcpy(amqp_offset(encoded.bytes, o), input.bytes, input.len); + return 1; + } else { + return 0; + } +} + +static inline int amqp_decode_bytes(amqp_bytes_t encoded, size_t *offset, + amqp_bytes_t *output, size_t len) { + size_t o = *offset; + if ((*offset = o + len) <= encoded.len) { + output->bytes = amqp_offset(encoded.bytes, o); + output->len = len; + return 1; + } else { + return 0; + } +} + +AMQP_NORETURN +void amqp_abort(const char *fmt, ...); + +int amqp_bytes_equal(amqp_bytes_t r, amqp_bytes_t l); + +static inline amqp_rpc_reply_t amqp_rpc_reply_error(amqp_status_enum status) { + amqp_rpc_reply_t reply; + reply.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION; + reply.library_error = status; + return reply; +} + +int amqp_send_frame_inner(amqp_connection_state_t state, + const amqp_frame_t *frame, int flags, + amqp_time_t deadline); +#endif diff --git a/ext/librabbitmq/librabbitmq/amqp_socket.c b/ext/librabbitmq/librabbitmq/amqp_socket.c new file mode 100644 index 00000000..061192ea --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_socket.c @@ -0,0 +1,1492 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2014 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "amqp_private.h" +#include "amqp_socket.h" +#include "amqp_table.h" +#include "amqp_time.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if ((defined(_WIN32)) || (defined(__MINGW32__)) || (defined(__MINGW64__))) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#else +#include +/* On older BSD types.h must come before net includes */ +#include +#include +#ifdef HAVE_SELECT +#include +#endif +#include +#include +#include +#include +#ifdef HAVE_POLL +#include +#endif +#include +#endif + +static int amqp_id_in_reply_list(amqp_method_number_t expected, + amqp_method_number_t *list); + +static int amqp_os_socket_init(void) { +#ifdef _WIN32 + static int called_wsastartup = 0; + if (!called_wsastartup) { + WSADATA data; + int res = WSAStartup(0x0202, &data); + if (res) { + return AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR; + } + + called_wsastartup = 1; + } + return AMQP_STATUS_OK; + +#else + return AMQP_STATUS_OK; +#endif +} + +int amqp_os_socket_error(void) { +#ifdef _WIN32 + return WSAGetLastError(); +#else + return errno; +#endif +} + +int amqp_os_socket_close(int sockfd) { +#ifdef _WIN32 + return closesocket(sockfd); +#else + return close(sockfd); +#endif +} + +ssize_t amqp_socket_send(amqp_socket_t *self, const void *buf, size_t len, + int flags) { + assert(self); + assert(self->klass->send); + return self->klass->send(self, buf, len, flags); +} + +ssize_t amqp_socket_recv(amqp_socket_t *self, void *buf, size_t len, + int flags) { + assert(self); + assert(self->klass->recv); + return self->klass->recv(self, buf, len, flags); +} + +int amqp_socket_open(amqp_socket_t *self, const char *host, int port) { + assert(self); + assert(self->klass->open); + return self->klass->open(self, host, port, NULL); +} + +int amqp_socket_open_noblock(amqp_socket_t *self, const char *host, int port, + struct timeval *timeout) { + assert(self); + assert(self->klass->open); + return self->klass->open(self, host, port, timeout); +} + +int amqp_socket_close(amqp_socket_t *self, amqp_socket_close_enum force) { + assert(self); + assert(self->klass->close); + return self->klass->close(self, force); +} + +void amqp_socket_delete(amqp_socket_t *self) { + if (self) { + assert(self->klass->delete); + self->klass->delete (self); + } +} + +int amqp_socket_get_sockfd(amqp_socket_t *self) { + assert(self); + assert(self->klass->get_sockfd); + return self->klass->get_sockfd(self); +} + +int amqp_poll(int fd, int event, amqp_time_t deadline) { +#ifdef HAVE_POLL + struct pollfd pfd; + int res; + int timeout_ms; + + /* Function should only ever be called with one of these two */ + assert(event == AMQP_SF_POLLIN || event == AMQP_SF_POLLOUT); + +start_poll: + pfd.fd = fd; + switch (event) { + case AMQP_SF_POLLIN: + pfd.events = POLLIN; + break; + case AMQP_SF_POLLOUT: + pfd.events = POLLOUT; + break; + } + + timeout_ms = amqp_time_ms_until(deadline); + if (-1 > timeout_ms) { + return timeout_ms; + } + + res = poll(&pfd, 1, timeout_ms); + + if (0 < res) { + /* TODO: optimize this a bit by returning the AMQP_STATUS_SOCKET_ERROR or + * equivalent when pdf.revent is POLLHUP or POLLERR, so an extra syscall + * doesn't need to be made. */ + return AMQP_STATUS_OK; + } else if (0 == res) { + return AMQP_STATUS_TIMEOUT; + } else { + switch (amqp_os_socket_error()) { + case EINTR: + goto start_poll; + default: + return AMQP_STATUS_SOCKET_ERROR; + } + } + return AMQP_STATUS_OK; +#elif defined(HAVE_SELECT) + fd_set fds; + fd_set exceptfds; + fd_set *exceptfdsp; + int res; + struct timeval tv; + struct timeval *tvp; + + assert((0 != (event & AMQP_SF_POLLIN)) || (0 != (event & AMQP_SF_POLLOUT))); +#ifndef _WIN32 + /* On Win32 connect() failure is indicated through the exceptfds, it does not + * make any sense to allow POLLERR on any other platform or condition */ + assert(0 == (event & AMQP_SF_POLLERR)); +#endif + +start_select: + FD_ZERO(&fds); + FD_SET(fd, &fds); + + if (event & AMQP_SF_POLLERR) { + FD_ZERO(&exceptfds); + FD_SET(fd, &exceptfds); + exceptfdsp = &exceptfds; + } else { + exceptfdsp = NULL; + } + + res = amqp_time_tv_until(deadline, &tv, &tvp); + if (res != AMQP_STATUS_OK) { + return res; + } + + if (event & AMQP_SF_POLLIN) { + res = select(fd + 1, &fds, NULL, exceptfdsp, tvp); + } else if (event & AMQP_SF_POLLOUT) { + res = select(fd + 1, NULL, &fds, exceptfdsp, tvp); + } + + if (0 < res) { + return AMQP_STATUS_OK; + } else if (0 == res) { + return AMQP_STATUS_TIMEOUT; + } else { + switch (amqp_os_socket_error()) { + case EINTR: + goto start_select; + default: + return AMQP_STATUS_SOCKET_ERROR; + } + } +#else +#error "poll() or select() is needed to compile rabbitmq-c" +#endif +} + +static ssize_t do_poll(amqp_connection_state_t state, ssize_t res, + amqp_time_t deadline) { + int fd = amqp_get_sockfd(state); + if (-1 == fd) { + return AMQP_STATUS_SOCKET_CLOSED; + } + switch (res) { + case AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD: + res = amqp_poll(fd, AMQP_SF_POLLIN, deadline); + break; + case AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE: + res = amqp_poll(fd, AMQP_SF_POLLOUT, deadline); + break; + } + return res; +} + +ssize_t amqp_try_send(amqp_connection_state_t state, const void *buf, + size_t len, amqp_time_t deadline, int flags) { + ssize_t res; + void *buf_left = (void *)buf; + /* Assume that len is not going to be larger than ssize_t can hold. */ + ssize_t len_left = (size_t)len; + +start_send: + res = amqp_socket_send(state->socket, buf_left, len_left, flags); + + if (res > 0) { + len_left -= res; + buf_left = (char *)buf_left + res; + if (0 == len_left) { + return (ssize_t)len; + } + goto start_send; + } + res = do_poll(state, res, deadline); + if (AMQP_STATUS_OK == res) { + goto start_send; + } + if (AMQP_STATUS_TIMEOUT == res) { + return (ssize_t)len - len_left; + } + return res; +} + +int amqp_open_socket(char const *hostname, int portnumber) { + return amqp_open_socket_inner(hostname, portnumber, amqp_time_infinite()); +} + +int amqp_open_socket_noblock(char const *hostname, int portnumber, + struct timeval *timeout) { + amqp_time_t deadline; + int res = amqp_time_from_now(&deadline, timeout); + if (AMQP_STATUS_OK != res) { + return res; + } + return amqp_open_socket_inner(hostname, portnumber, deadline); +} + +#ifdef _WIN32 +static int connect_socket(struct addrinfo *addr, amqp_time_t deadline) { + int one = 1; + SOCKET sockfd; + int last_error; + + /* + * This cast is to squash warnings on Win64, see: + * http://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64 + */ + + sockfd = (int)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (INVALID_SOCKET == sockfd) { + return AMQP_STATUS_SOCKET_ERROR; + } + + /* Set the socket to be non-blocking */ + if (SOCKET_ERROR == ioctlsocket(sockfd, FIONBIO, &one)) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + /* Disable nagle */ + if (SOCKET_ERROR == setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, + (const char *)&one, sizeof(one))) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + /* Enable TCP keepalives */ + if (SOCKET_ERROR == setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, + (const char *)&one, sizeof(one))) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + if (SOCKET_ERROR != connect(sockfd, addr->ai_addr, (int)addr->ai_addrlen)) { + return (int)sockfd; + } + + if (WSAEWOULDBLOCK != WSAGetLastError()) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + last_error = + amqp_poll((int)sockfd, AMQP_SF_POLLOUT | AMQP_SF_POLLERR, deadline); + if (AMQP_STATUS_OK != last_error) { + goto err; + } + + { + int result; + int result_len = sizeof(result); + + if (SOCKET_ERROR == getsockopt(sockfd, SOL_SOCKET, SO_ERROR, + (char *)&result, &result_len) || + result != 0) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + } + + return (int)sockfd; + +err: + closesocket(sockfd); + return last_error; +} +#else +static int connect_socket(struct addrinfo *addr, amqp_time_t deadline) { + int one = 1; + int sockfd; + int flags; + int last_error; + + sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (-1 == sockfd) { + return AMQP_STATUS_SOCKET_ERROR; + } + + /* Enable CLOEXEC on socket */ + flags = fcntl(sockfd, F_GETFD); + if (flags == -1 || fcntl(sockfd, F_SETFD, (long)(flags | FD_CLOEXEC)) == -1) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + /* Set the socket as non-blocking */ + flags = fcntl(sockfd, F_GETFL); + if (flags == -1 || fcntl(sockfd, F_SETFL, (long)(flags | O_NONBLOCK)) == -1) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + +#ifdef SO_NOSIGPIPE + /* Turn off SIGPIPE on platforms that support it, BSD, MacOSX */ + if (0 != setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } +#endif /* SO_NOSIGPIPE */ + + /* Disable nagle */ + if (0 != setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one))) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + /* Enable TCP keepalives */ + if (0 != setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one))) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + if (0 == connect(sockfd, addr->ai_addr, addr->ai_addrlen)) { + return sockfd; + } + + if (EINPROGRESS != errno) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + + last_error = amqp_poll(sockfd, AMQP_SF_POLLOUT, deadline); + if (AMQP_STATUS_OK != last_error) { + goto err; + } + + { + int result; + socklen_t result_len = sizeof(result); + + if (-1 == getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &result, &result_len) || + result != 0) { + last_error = AMQP_STATUS_SOCKET_ERROR; + goto err; + } + } + + return sockfd; + +err: + close(sockfd); + return last_error; +} +#endif + +int amqp_open_socket_inner(char const *hostname, int portnumber, + amqp_time_t deadline) { + struct addrinfo hint; + struct addrinfo *address_list; + struct addrinfo *addr; + char portnumber_string[33]; + int sockfd = -1; + int last_error; + + last_error = amqp_os_socket_init(); + if (AMQP_STATUS_OK != last_error) { + return last_error; + } + + memset(&hint, 0, sizeof(hint)); + hint.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */ + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; + + (void)sprintf(portnumber_string, "%d", portnumber); + + last_error = getaddrinfo(hostname, portnumber_string, &hint, &address_list); + if (0 != last_error) { + return AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED; + } + + for (addr = address_list; addr; addr = addr->ai_next) { + sockfd = connect_socket(addr, deadline); + + if (sockfd >= 0) { + last_error = AMQP_STATUS_OK; + break; + } else if (sockfd == AMQP_STATUS_TIMEOUT) { + last_error = sockfd; + break; + } + } + + freeaddrinfo(address_list); + if (last_error != AMQP_STATUS_OK || sockfd == -1) { + return last_error; + } + return sockfd; +} + +static int send_header_inner(amqp_connection_state_t state, + amqp_time_t deadline) { + ssize_t res; + static const uint8_t header[8] = {'A', + 'M', + 'Q', + 'P', + 0, + AMQP_PROTOCOL_VERSION_MAJOR, + AMQP_PROTOCOL_VERSION_MINOR, + AMQP_PROTOCOL_VERSION_REVISION}; + res = amqp_try_send(state, header, sizeof(header), deadline, AMQP_SF_NONE); + if (sizeof(header) == res) { + return AMQP_STATUS_OK; + } + return (int)res; +} + +int amqp_send_header(amqp_connection_state_t state) { + return send_header_inner(state, amqp_time_infinite()); +} + +static amqp_bytes_t sasl_method_name(amqp_sasl_method_enum method) { + amqp_bytes_t res; + + switch (method) { + case AMQP_SASL_METHOD_PLAIN: + res = amqp_cstring_bytes("PLAIN"); + break; + case AMQP_SASL_METHOD_EXTERNAL: + res = amqp_cstring_bytes("EXTERNAL"); + break; + + default: + amqp_abort("Invalid SASL method: %d", (int)method); + } + + return res; +} + +static int bytes_equal(amqp_bytes_t l, amqp_bytes_t r) { + if (l.len == r.len) { + if (l.bytes && r.bytes) { + if (0 == memcmp(l.bytes, r.bytes, l.len)) { + return 1; + } + } + } + return 0; +} + +int sasl_mechanism_in_list(amqp_bytes_t mechanisms, + amqp_sasl_method_enum method) { + amqp_bytes_t mechanism; + amqp_bytes_t supported_mechanism; + uint8_t *start; + uint8_t *end; + uint8_t *current; + + assert(NULL != mechanisms.bytes); + + mechanism = sasl_method_name(method); + + start = (uint8_t *)mechanisms.bytes; + current = start; + end = start + mechanisms.len; + + for (; current != end; start = current + 1) { + /* HACK: SASL states that we should be parsing this string as a UTF-8 + * string, which we're plainly not doing here. At this point its not worth + * dragging an entire UTF-8 parser for this one case, and this should work + * most of the time */ + current = memchr(start, ' ', end - start); + if (NULL == current) { + current = end; + } + supported_mechanism.bytes = start; + supported_mechanism.len = current - start; + if (bytes_equal(mechanism, supported_mechanism)) { + return 1; + } + } + + return 0; +} + +static amqp_bytes_t sasl_response(amqp_pool_t *pool, + amqp_sasl_method_enum method, va_list args) { + amqp_bytes_t response; + + switch (method) { + case AMQP_SASL_METHOD_PLAIN: { + char *username = va_arg(args, char *); + size_t username_len = strlen(username); + char *password = va_arg(args, char *); + size_t password_len = strlen(password); + char *response_buf; + + amqp_pool_alloc_bytes(pool, strlen(username) + strlen(password) + 2, + &response); + if (response.bytes == NULL) + /* We never request a zero-length block, because of the +2 + above, so a NULL here really is ENOMEM. */ + { + return response; + } + + response_buf = response.bytes; + response_buf[0] = 0; + memcpy(response_buf + 1, username, username_len); + response_buf[username_len + 1] = 0; + memcpy(response_buf + username_len + 2, password, password_len); + break; + } + case AMQP_SASL_METHOD_EXTERNAL: { + char *identity = va_arg(args, char *); + size_t identity_len = strlen(identity); + + amqp_pool_alloc_bytes(pool, identity_len, &response); + if (response.bytes == NULL) { + return response; + } + + memcpy(response.bytes, identity, identity_len); + break; + } + default: + amqp_abort("Invalid SASL method: %d", (int)method); + } + + return response; +} + +amqp_boolean_t amqp_frames_enqueued(amqp_connection_state_t state) { + return (state->first_queued_frame != NULL); +} + +/* + * Check to see if we have data in our buffer. If this returns 1, we + * will avoid an immediate blocking read in amqp_simple_wait_frame. + */ +amqp_boolean_t amqp_data_in_buffer(amqp_connection_state_t state) { + return (state->sock_inbound_offset < state->sock_inbound_limit); +} + +static int consume_one_frame(amqp_connection_state_t state, + amqp_frame_t *decoded_frame) { + int res; + + amqp_bytes_t buffer; + buffer.len = state->sock_inbound_limit - state->sock_inbound_offset; + buffer.bytes = + ((char *)state->sock_inbound_buffer.bytes) + state->sock_inbound_offset; + + res = amqp_handle_input(state, buffer, decoded_frame); + if (res < 0) { + return res; + } + + state->sock_inbound_offset += res; + + return AMQP_STATUS_OK; +} + +static int recv_with_timeout(amqp_connection_state_t state, + amqp_time_t timeout) { + ssize_t res; + int fd; + +start_recv: + res = amqp_socket_recv(state->socket, state->sock_inbound_buffer.bytes, + state->sock_inbound_buffer.len, 0); + + if (res < 0) { + fd = amqp_get_sockfd(state); + if (-1 == fd) { + return AMQP_STATUS_CONNECTION_CLOSED; + } + switch (res) { + default: + return (int)res; + case AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD: + res = amqp_poll(fd, AMQP_SF_POLLIN, timeout); + break; + case AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE: + res = amqp_poll(fd, AMQP_SF_POLLOUT, timeout); + break; + } + if (AMQP_STATUS_OK == res) { + goto start_recv; + } + return (int)res; + } + + state->sock_inbound_limit = res; + state->sock_inbound_offset = 0; + + res = amqp_time_s_from_now(&state->next_recv_heartbeat, + amqp_heartbeat_recv(state)); + if (AMQP_STATUS_OK != res) { + return (int)res; + } + return AMQP_STATUS_OK; +} + +int amqp_try_recv(amqp_connection_state_t state) { + amqp_time_t timeout; + + while (amqp_data_in_buffer(state)) { + amqp_frame_t frame; + int res = consume_one_frame(state, &frame); + + if (AMQP_STATUS_OK != res) { + return res; + } + + if (frame.frame_type != 0) { + amqp_pool_t *channel_pool; + amqp_frame_t *frame_copy; + amqp_link_t *link; + + channel_pool = amqp_get_or_create_channel_pool(state, frame.channel); + if (NULL == channel_pool) { + return AMQP_STATUS_NO_MEMORY; + } + + frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t)); + link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t)); + + if (frame_copy == NULL || link == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + + *frame_copy = frame; + + link->next = NULL; + link->data = frame_copy; + + if (state->last_queued_frame == NULL) { + state->first_queued_frame = link; + } else { + state->last_queued_frame->next = link; + } + state->last_queued_frame = link; + } + } + timeout = amqp_time_immediate(); + + return recv_with_timeout(state, timeout); +} + +static int wait_frame_inner(amqp_connection_state_t state, + amqp_frame_t *decoded_frame, + amqp_time_t timeout_deadline) { + amqp_time_t deadline; + int res; + + for (;;) { + while (amqp_data_in_buffer(state)) { + res = consume_one_frame(state, decoded_frame); + + if (AMQP_STATUS_OK != res) { + return res; + } + + if (AMQP_FRAME_HEARTBEAT == decoded_frame->frame_type) { + amqp_maybe_release_buffers_on_channel(state, 0); + continue; + } + + if (decoded_frame->frame_type != 0) { + /* Complete frame was read. Return it. */ + return AMQP_STATUS_OK; + } + } + + beginrecv: + res = amqp_time_has_past(state->next_send_heartbeat); + if (AMQP_STATUS_TIMER_FAILURE == res) { + return res; + } else if (AMQP_STATUS_TIMEOUT == res) { + amqp_frame_t heartbeat; + heartbeat.channel = 0; + heartbeat.frame_type = AMQP_FRAME_HEARTBEAT; + + res = amqp_send_frame(state, &heartbeat); + if (AMQP_STATUS_OK != res) { + return res; + } + } + deadline = amqp_time_first(timeout_deadline, + amqp_time_first(state->next_recv_heartbeat, + state->next_send_heartbeat)); + + /* TODO this needs to wait for a _frame_ and not anything written from the + * socket */ + res = recv_with_timeout(state, deadline); + + if (AMQP_STATUS_TIMEOUT == res) { + if (amqp_time_equal(deadline, state->next_recv_heartbeat)) { + amqp_socket_close(state->socket, AMQP_SC_FORCE); + return AMQP_STATUS_HEARTBEAT_TIMEOUT; + } else if (amqp_time_equal(deadline, timeout_deadline)) { + return AMQP_STATUS_TIMEOUT; + } else if (amqp_time_equal(deadline, state->next_send_heartbeat)) { + /* send heartbeat happens before we do recv_with_timeout */ + goto beginrecv; + } else { + amqp_abort("Internal error: unable to determine timeout reason"); + } + } else if (AMQP_STATUS_OK != res) { + return res; + } + } +} + +static amqp_link_t *amqp_create_link_for_frame(amqp_connection_state_t state, + amqp_frame_t *frame) { + amqp_link_t *link; + amqp_frame_t *frame_copy; + + amqp_pool_t *channel_pool = + amqp_get_or_create_channel_pool(state, frame->channel); + + if (NULL == channel_pool) { + return NULL; + } + + link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t)); + frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t)); + + if (NULL == link || NULL == frame_copy) { + return NULL; + } + + *frame_copy = *frame; + link->data = frame_copy; + + return link; +} + +int amqp_queue_frame(amqp_connection_state_t state, amqp_frame_t *frame) { + amqp_link_t *link = amqp_create_link_for_frame(state, frame); + if (NULL == link) { + return AMQP_STATUS_NO_MEMORY; + } + + if (NULL == state->first_queued_frame) { + state->first_queued_frame = link; + } else { + state->last_queued_frame->next = link; + } + + link->next = NULL; + state->last_queued_frame = link; + + return AMQP_STATUS_OK; +} + +int amqp_put_back_frame(amqp_connection_state_t state, amqp_frame_t *frame) { + amqp_link_t *link = amqp_create_link_for_frame(state, frame); + if (NULL == link) { + return AMQP_STATUS_NO_MEMORY; + } + + if (NULL == state->first_queued_frame) { + state->first_queued_frame = link; + state->last_queued_frame = link; + link->next = NULL; + } else { + link->next = state->first_queued_frame; + state->first_queued_frame = link; + } + + return AMQP_STATUS_OK; +} + +int amqp_simple_wait_frame_on_channel(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_frame_t *decoded_frame) { + amqp_frame_t *frame_ptr; + amqp_link_t *cur; + int res; + + for (cur = state->first_queued_frame; NULL != cur; cur = cur->next) { + frame_ptr = cur->data; + + if (channel == frame_ptr->channel) { + state->first_queued_frame = cur->next; + if (NULL == state->first_queued_frame) { + state->last_queued_frame = NULL; + } + + *decoded_frame = *frame_ptr; + + return AMQP_STATUS_OK; + } + } + + for (;;) { + res = wait_frame_inner(state, decoded_frame, amqp_time_infinite()); + + if (AMQP_STATUS_OK != res) { + return res; + } + + if (channel == decoded_frame->channel) { + return AMQP_STATUS_OK; + } else { + res = amqp_queue_frame(state, decoded_frame); + if (res != AMQP_STATUS_OK) { + return res; + } + } + } +} + +int amqp_simple_wait_frame(amqp_connection_state_t state, + amqp_frame_t *decoded_frame) { + return amqp_simple_wait_frame_noblock(state, decoded_frame, NULL); +} + +int amqp_simple_wait_frame_noblock(amqp_connection_state_t state, + amqp_frame_t *decoded_frame, + struct timeval *timeout) { + amqp_time_t deadline; + + int res = amqp_time_from_now(&deadline, timeout); + if (AMQP_STATUS_OK != res) { + return res; + } + + if (state->first_queued_frame != NULL) { + amqp_frame_t *f = (amqp_frame_t *)state->first_queued_frame->data; + state->first_queued_frame = state->first_queued_frame->next; + if (state->first_queued_frame == NULL) { + state->last_queued_frame = NULL; + } + *decoded_frame = *f; + return AMQP_STATUS_OK; + } else { + return wait_frame_inner(state, decoded_frame, deadline); + } +} + +static int amqp_simple_wait_method_list(amqp_connection_state_t state, + amqp_channel_t expected_channel, + amqp_method_number_t *expected_methods, + amqp_time_t deadline, + amqp_method_t *output) { + amqp_frame_t frame; + struct timeval tv; + struct timeval *tvp; + + int res = amqp_time_tv_until(deadline, &tv, &tvp); + if (res != AMQP_STATUS_OK) { + return res; + } + + res = amqp_simple_wait_frame_noblock(state, &frame, tvp); + if (AMQP_STATUS_OK != res) { + return res; + } + + if (AMQP_FRAME_METHOD != frame.frame_type || + expected_channel != frame.channel || + !amqp_id_in_reply_list(frame.payload.method.id, expected_methods)) { + return AMQP_STATUS_WRONG_METHOD; + } + *output = frame.payload.method; + return AMQP_STATUS_OK; +} + +static int simple_wait_method_inner(amqp_connection_state_t state, + amqp_channel_t expected_channel, + amqp_method_number_t expected_method, + amqp_time_t deadline, + amqp_method_t *output) { + amqp_method_number_t expected_methods[] = {expected_method, 0}; + return amqp_simple_wait_method_list(state, expected_channel, expected_methods, + deadline, output); +} + +int amqp_simple_wait_method(amqp_connection_state_t state, + amqp_channel_t expected_channel, + amqp_method_number_t expected_method, + amqp_method_t *output) { + return simple_wait_method_inner(state, expected_channel, expected_method, + amqp_time_infinite(), output); +} + +int amqp_send_method(amqp_connection_state_t state, amqp_channel_t channel, + amqp_method_number_t id, void *decoded) { + return amqp_send_method_inner(state, channel, id, decoded, AMQP_SF_NONE, + amqp_time_infinite()); +} + +int amqp_send_method_inner(amqp_connection_state_t state, + amqp_channel_t channel, amqp_method_number_t id, + void *decoded, int flags, amqp_time_t deadline) { + amqp_frame_t frame; + + frame.frame_type = AMQP_FRAME_METHOD; + frame.channel = channel; + frame.payload.method.id = id; + frame.payload.method.decoded = decoded; + return amqp_send_frame_inner(state, &frame, flags, deadline); +} + +static int amqp_id_in_reply_list(amqp_method_number_t expected, + amqp_method_number_t *list) { + while (*list != 0) { + if (*list == expected) { + return 1; + } + list++; + } + return 0; +} + +static amqp_rpc_reply_t simple_rpc_inner( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_method_number_t request_id, amqp_method_number_t *expected_reply_ids, + void *decoded_request_method, amqp_time_t deadline) { + int status; + amqp_rpc_reply_t result; + + memset(&result, 0, sizeof(result)); + + status = amqp_send_method(state, channel, request_id, decoded_request_method); + if (status < 0) { + return amqp_rpc_reply_error(status); + } + + { + amqp_frame_t frame; + + retry: + status = wait_frame_inner(state, &frame, deadline); + if (status < 0) { + if (status == AMQP_STATUS_TIMEOUT) { + amqp_socket_close(state->socket, AMQP_SC_FORCE); + } + return amqp_rpc_reply_error(status); + } + + /* + * We store the frame for later processing unless it's something + * that directly affects us here, namely a method frame that is + * either + * - on the channel we want, and of the expected type, or + * - on the channel we want, and a channel.close frame, or + * - on channel zero, and a connection.close frame. + */ + if (!((frame.frame_type == AMQP_FRAME_METHOD) && + (((frame.channel == channel) && + (amqp_id_in_reply_list(frame.payload.method.id, + expected_reply_ids) || + (frame.payload.method.id == AMQP_CHANNEL_CLOSE_METHOD))) || + ((frame.channel == 0) && + (frame.payload.method.id == AMQP_CONNECTION_CLOSE_METHOD))))) { + amqp_pool_t *channel_pool; + amqp_frame_t *frame_copy; + amqp_link_t *link; + + channel_pool = amqp_get_or_create_channel_pool(state, frame.channel); + if (NULL == channel_pool) { + return amqp_rpc_reply_error(AMQP_STATUS_NO_MEMORY); + } + + frame_copy = amqp_pool_alloc(channel_pool, sizeof(amqp_frame_t)); + link = amqp_pool_alloc(channel_pool, sizeof(amqp_link_t)); + + if (frame_copy == NULL || link == NULL) { + return amqp_rpc_reply_error(AMQP_STATUS_NO_MEMORY); + } + + *frame_copy = frame; + + link->next = NULL; + link->data = frame_copy; + + if (state->last_queued_frame == NULL) { + state->first_queued_frame = link; + } else { + state->last_queued_frame->next = link; + } + state->last_queued_frame = link; + + goto retry; + } + + result.reply_type = + (amqp_id_in_reply_list(frame.payload.method.id, expected_reply_ids)) + ? AMQP_RESPONSE_NORMAL + : AMQP_RESPONSE_SERVER_EXCEPTION; + + result.reply = frame.payload.method; + return result; + } +} + +amqp_rpc_reply_t amqp_simple_rpc(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_method_number_t request_id, + amqp_method_number_t *expected_reply_ids, + void *decoded_request_method) { + amqp_time_t deadline; + int res; + + res = amqp_time_from_now(&deadline, state->rpc_timeout); + if (res != AMQP_STATUS_OK) { + return amqp_rpc_reply_error(res); + } + + return simple_rpc_inner(state, channel, request_id, expected_reply_ids, + decoded_request_method, deadline); +} + +void *amqp_simple_rpc_decoded(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_method_number_t request_id, + amqp_method_number_t reply_id, + void *decoded_request_method) { + amqp_time_t deadline; + int res; + amqp_method_number_t replies[2]; + + res = amqp_time_from_now(&deadline, state->rpc_timeout); + if (res != AMQP_STATUS_OK) { + state->most_recent_api_result = amqp_rpc_reply_error(res); + return NULL; + } + + replies[0] = reply_id; + replies[1] = 0; + + state->most_recent_api_result = simple_rpc_inner( + state, channel, request_id, replies, decoded_request_method, deadline); + + if (state->most_recent_api_result.reply_type == AMQP_RESPONSE_NORMAL) { + return state->most_recent_api_result.reply.decoded; + } else { + return NULL; + } +} + +amqp_rpc_reply_t amqp_get_rpc_reply(amqp_connection_state_t state) { + return state->most_recent_api_result; +} + +/* + * Merge base and add tables. If the two tables contain an entry with the same + * key, the entry from the add table takes precedence. For entries that are both + * tables with the same key, the table is recursively merged. + */ +int amqp_merge_capabilities(const amqp_table_t *base, const amqp_table_t *add, + amqp_table_t *result, amqp_pool_t *pool) { + int i; + int res; + amqp_pool_t temp_pool; + amqp_table_t temp_result; + assert(base != NULL); + assert(result != NULL); + assert(pool != NULL); + + if (NULL == add) { + return amqp_table_clone(base, result, pool); + } + + init_amqp_pool(&temp_pool, 4096); + temp_result.num_entries = 0; + temp_result.entries = + amqp_pool_alloc(&temp_pool, sizeof(amqp_table_entry_t) * + (base->num_entries + add->num_entries)); + if (NULL == temp_result.entries) { + res = AMQP_STATUS_NO_MEMORY; + goto error_out; + } + for (i = 0; i < base->num_entries; ++i) { + temp_result.entries[temp_result.num_entries] = base->entries[i]; + temp_result.num_entries++; + } + for (i = 0; i < add->num_entries; ++i) { + amqp_table_entry_t *e = + amqp_table_get_entry_by_key(&temp_result, add->entries[i].key); + if (NULL != e) { + if (AMQP_FIELD_KIND_TABLE == add->entries[i].value.kind && + AMQP_FIELD_KIND_TABLE == e->value.kind) { + amqp_table_entry_t *be = + amqp_table_get_entry_by_key(base, add->entries[i].key); + + res = amqp_merge_capabilities(&be->value.value.table, + &add->entries[i].value.value.table, + &e->value.value.table, &temp_pool); + if (AMQP_STATUS_OK != res) { + goto error_out; + } + } else { + e->value = add->entries[i].value; + } + } else { + temp_result.entries[temp_result.num_entries] = add->entries[i]; + temp_result.num_entries++; + } + } + res = amqp_table_clone(&temp_result, result, pool); +error_out: + empty_amqp_pool(&temp_pool); + return res; +} + +static amqp_rpc_reply_t amqp_login_inner( + amqp_connection_state_t state, char const *vhost, int channel_max, + int frame_max, int heartbeat, const amqp_table_t *client_properties, + struct timeval *timeout, amqp_sasl_method_enum sasl_method, va_list vl) { + int res; + amqp_method_t method; + + uint16_t client_channel_max; + uint32_t client_frame_max; + uint16_t client_heartbeat; + + uint16_t server_channel_max; + uint32_t server_frame_max; + uint16_t server_heartbeat; + + amqp_rpc_reply_t result; + amqp_time_t deadline; + + if (channel_max < 0 || channel_max > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + client_channel_max = (uint16_t)channel_max; + + if (frame_max < 0) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + client_frame_max = (uint32_t)frame_max; + + if (heartbeat < 0 || heartbeat > UINT16_MAX) { + return amqp_rpc_reply_error(AMQP_STATUS_INVALID_PARAMETER); + } + client_heartbeat = (uint16_t)heartbeat; + + res = amqp_time_from_now(&deadline, timeout); + if (AMQP_STATUS_OK != res) { + goto error_res; + } + + res = send_header_inner(state, deadline); + if (AMQP_STATUS_OK != res) { + goto error_res; + } + + res = simple_wait_method_inner(state, 0, AMQP_CONNECTION_START_METHOD, + deadline, &method); + if (AMQP_STATUS_OK != res) { + goto error_res; + } + + { + amqp_connection_start_t *s = (amqp_connection_start_t *)method.decoded; + if ((s->version_major != AMQP_PROTOCOL_VERSION_MAJOR) || + (s->version_minor != AMQP_PROTOCOL_VERSION_MINOR)) { + res = AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION; + goto error_res; + } + + res = amqp_table_clone(&s->server_properties, &state->server_properties, + &state->properties_pool); + + if (AMQP_STATUS_OK != res) { + goto error_res; + } + + /* TODO: check that our chosen SASL mechanism is in the list of + acceptable mechanisms. Or even let the application choose from + the list! */ + if (!sasl_mechanism_in_list(s->mechanisms, sasl_method)) { + res = AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD; + goto error_res; + } + } + + { + amqp_table_entry_t default_properties[6]; + amqp_table_t default_table; + amqp_table_entry_t client_capabilities[2]; + amqp_table_t client_capabilities_table; + amqp_connection_start_ok_t s; + amqp_pool_t *channel_pool; + amqp_bytes_t response_bytes; + + channel_pool = amqp_get_or_create_channel_pool(state, 0); + if (NULL == channel_pool) { + res = AMQP_STATUS_NO_MEMORY; + goto error_res; + } + + response_bytes = sasl_response(channel_pool, sasl_method, vl); + if (response_bytes.bytes == NULL) { + res = AMQP_STATUS_NO_MEMORY; + goto error_res; + } + + client_capabilities[0] = + amqp_table_construct_bool_entry("authentication_failure_close", 1); + client_capabilities[1] = + amqp_table_construct_bool_entry("exchange_exchange_bindings", 1); + + client_capabilities_table.entries = client_capabilities; + client_capabilities_table.num_entries = + sizeof(client_capabilities) / sizeof(amqp_table_entry_t); + + default_properties[0] = + amqp_table_construct_utf8_entry("product", "rabbitmq-c"); + default_properties[1] = + amqp_table_construct_utf8_entry("version", AMQP_VERSION_STRING); + default_properties[2] = + amqp_table_construct_utf8_entry("platform", AMQ_PLATFORM); + default_properties[3] = + amqp_table_construct_utf8_entry("copyright", AMQ_COPYRIGHT); + default_properties[4] = amqp_table_construct_utf8_entry( + "information", "See https://github.com/alanxz/rabbitmq-c"); + default_properties[5] = amqp_table_construct_table_entry( + "capabilities", &client_capabilities_table); + + default_table.entries = default_properties; + default_table.num_entries = + sizeof(default_properties) / sizeof(amqp_table_entry_t); + + res = amqp_merge_capabilities(&default_table, client_properties, + &state->client_properties, channel_pool); + if (AMQP_STATUS_OK != res) { + goto error_res; + } + + s.client_properties = state->client_properties; + s.mechanism = sasl_method_name(sasl_method); + s.response = response_bytes; + s.locale = amqp_cstring_bytes("en_US"); + + res = amqp_send_method_inner(state, 0, AMQP_CONNECTION_START_OK_METHOD, &s, + AMQP_SF_NONE, deadline); + if (res < 0) { + goto error_res; + } + } + + amqp_release_buffers(state); + + { + amqp_method_number_t expected[] = {AMQP_CONNECTION_TUNE_METHOD, + AMQP_CONNECTION_CLOSE_METHOD, 0}; + + res = amqp_simple_wait_method_list(state, 0, expected, deadline, &method); + if (AMQP_STATUS_OK != res) { + goto error_res; + } + } + + if (AMQP_CONNECTION_CLOSE_METHOD == method.id) { + result.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION; + result.reply = method; + result.library_error = 0; + goto out; + } + + { + amqp_connection_tune_t *s = (amqp_connection_tune_t *)method.decoded; + server_channel_max = s->channel_max; + server_frame_max = s->frame_max; + server_heartbeat = s->heartbeat; + } + + if (server_channel_max != 0 && + (server_channel_max < client_channel_max || client_channel_max == 0)) { + client_channel_max = server_channel_max; + } else if (server_channel_max == 0 && client_channel_max == 0) { + client_channel_max = UINT16_MAX; + } + + if (server_frame_max != 0 && server_frame_max < client_frame_max) { + client_frame_max = server_frame_max; + } + + if (server_heartbeat != 0 && server_heartbeat < client_heartbeat) { + client_heartbeat = server_heartbeat; + } + + res = amqp_tune_connection(state, client_channel_max, client_frame_max, + client_heartbeat); + if (res < 0) { + goto error_res; + } + + { + amqp_connection_tune_ok_t s; + s.frame_max = client_frame_max; + s.channel_max = client_channel_max; + s.heartbeat = client_heartbeat; + + res = amqp_send_method_inner(state, 0, AMQP_CONNECTION_TUNE_OK_METHOD, &s, + AMQP_SF_NONE, deadline); + if (res < 0) { + goto error_res; + } + } + + amqp_release_buffers(state); + + { + amqp_method_number_t replies[] = {AMQP_CONNECTION_OPEN_OK_METHOD, 0}; + amqp_connection_open_t s; + s.virtual_host = amqp_cstring_bytes(vhost); + s.capabilities = amqp_empty_bytes; + s.insist = 1; + + result = simple_rpc_inner(state, 0, AMQP_CONNECTION_OPEN_METHOD, replies, + &s, deadline); + if (result.reply_type != AMQP_RESPONSE_NORMAL) { + goto out; + } + } + + result.reply_type = AMQP_RESPONSE_NORMAL; + result.reply.id = 0; + result.reply.decoded = NULL; + result.library_error = 0; + amqp_maybe_release_buffers(state); + +out: + return result; + +error_res: + amqp_socket_close(state->socket, AMQP_SC_FORCE); + result = amqp_rpc_reply_error(res); + + goto out; +} + +amqp_rpc_reply_t amqp_login(amqp_connection_state_t state, char const *vhost, + int channel_max, int frame_max, int heartbeat, + int sasl_method, ...) { + va_list vl; + amqp_rpc_reply_t ret; + + va_start(vl, sasl_method); + + ret = amqp_login_inner(state, vhost, channel_max, frame_max, heartbeat, + &amqp_empty_table, state->handshake_timeout, + sasl_method, vl); + + va_end(vl); + + return ret; +} + +amqp_rpc_reply_t amqp_login_with_properties( + amqp_connection_state_t state, char const *vhost, int channel_max, + int frame_max, int heartbeat, const amqp_table_t *client_properties, + int sasl_method, ...) { + va_list vl; + amqp_rpc_reply_t ret; + + va_start(vl, sasl_method); + + ret = amqp_login_inner(state, vhost, channel_max, frame_max, heartbeat, + client_properties, state->handshake_timeout, + sasl_method, vl); + + va_end(vl); + + return ret; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_socket.h b/ext/librabbitmq/librabbitmq/amqp_socket.h new file mode 100644 index 00000000..3101cf60 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_socket.h @@ -0,0 +1,188 @@ +/* + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk. + * All Rights Reserved. + * + * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael + * Steinert. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * An abstract socket interface. + */ + +#ifndef AMQP_SOCKET_H +#define AMQP_SOCKET_H + +#include "amqp_private.h" +#include "amqp_time.h" + +AMQP_BEGIN_DECLS + +typedef enum { + AMQP_SF_NONE = 0, + AMQP_SF_MORE = 1, + AMQP_SF_POLLIN = 2, + AMQP_SF_POLLOUT = 4, + AMQP_SF_POLLERR = 8 +} amqp_socket_flag_enum; + +typedef enum { AMQP_SC_NONE = 0, AMQP_SC_FORCE = 1 } amqp_socket_close_enum; + +int amqp_os_socket_error(void); + +int amqp_os_socket_close(int sockfd); + +/* Socket callbacks. */ +typedef ssize_t (*amqp_socket_send_fn)(void *, const void *, size_t, int); +typedef ssize_t (*amqp_socket_recv_fn)(void *, void *, size_t, int); +typedef int (*amqp_socket_open_fn)(void *, const char *, int, struct timeval *); +typedef int (*amqp_socket_close_fn)(void *, amqp_socket_close_enum); +typedef int (*amqp_socket_get_sockfd_fn)(void *); +typedef void (*amqp_socket_delete_fn)(void *); + +/** V-table for amqp_socket_t */ +struct amqp_socket_class_t { + amqp_socket_send_fn send; + amqp_socket_recv_fn recv; + amqp_socket_open_fn open; + amqp_socket_close_fn close; + amqp_socket_get_sockfd_fn get_sockfd; + amqp_socket_delete_fn delete; +}; + +/** Abstract base class for amqp_socket_t */ +struct amqp_socket_t_ { + const struct amqp_socket_class_t *klass; +}; + +/** + * Set set the socket object for a connection + * + * This assigns a socket object to the connection, closing and deleting any + * existing socket + * + * \param [in] state The connection object to add the socket to + * \param [in] socket The socket object to assign to the connection + */ +void amqp_set_socket(amqp_connection_state_t state, amqp_socket_t *socket); + +/** + * Send a message from a socket. + * + * This function wraps send(2) functionality. + * + * This function will only return on error, or when all of the bytes in buf + * have been sent, or when an error occurs. + * + * \param [in,out] self A socket object. + * \param [in] buf A buffer to read from. + * \param [in] len The number of bytes in \e buf. + * \param [in] + * + * \return AMQP_STATUS_OK on success. amqp_status_enum value otherwise + */ +ssize_t amqp_socket_send(amqp_socket_t *self, const void *buf, size_t len, + int flags); + +ssize_t amqp_try_send(amqp_connection_state_t state, const void *buf, + size_t len, amqp_time_t deadline, int flags); + +/** + * Receive a message from a socket. + * + * This function wraps recv(2) functionality. + * + * \param [in,out] self A socket object. + * \param [out] buf A buffer to write to. + * \param [in] len The number of bytes at \e buf. + * \param [in] flags Receive flags, implementation specific. + * + * \return The number of bytes received, or < 0 on error (\ref amqp_status_enum) + */ +ssize_t amqp_socket_recv(amqp_socket_t *self, void *buf, size_t len, int flags); + +/** + * Close a socket connection and free resources. + * + * This function closes a socket connection and releases any resources used by + * the object. After calling this function the specified socket should no + * longer be referenced. + * + * \param [in,out] self A socket object. + * \param [in] force, if set, just close the socket, don't attempt a TLS + * shutdown. + * + * \return Zero upon success, non-zero otherwise. + */ +int amqp_socket_close(amqp_socket_t *self, amqp_socket_close_enum force); + +/** + * Destroy a socket object + * + * \param [in] self the socket object to delete + */ +void amqp_socket_delete(amqp_socket_t *self); + +/** + * Open a socket connection. + * + * This function opens a socket connection returned from amqp_tcp_socket_new() + * or amqp_ssl_socket_new(). This function should be called after setting + * socket options and prior to assigning the socket to an AMQP connection with + * amqp_set_socket(). + * + * \param [in] host Connect to this host. + * \param [in] port Connect on this remote port. + * \param [in] timeout Max allowed time to spent on opening. If NULL - run in + * blocking mode + * + * \return File descriptor upon success, non-zero negative error code otherwise. + */ +int amqp_open_socket_noblock(char const *hostname, int portnumber, + struct timeval *timeout); + +int amqp_open_socket_inner(char const *hostname, int portnumber, + amqp_time_t deadline); + +/* Wait up to dealline for fd to become readable or writeable depending on + * event (AMQP_SF_POLLIN, AMQP_SF_POLLOUT) */ +int amqp_poll(int fd, int event, amqp_time_t deadline); + +int amqp_send_method_inner(amqp_connection_state_t state, + amqp_channel_t channel, amqp_method_number_t id, + void *decoded, int flags, amqp_time_t deadline); + +int amqp_queue_frame(amqp_connection_state_t state, amqp_frame_t *frame); + +int amqp_put_back_frame(amqp_connection_state_t state, amqp_frame_t *frame); + +int amqp_simple_wait_frame_on_channel(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_frame_t *decoded_frame); + +int sasl_mechanism_in_list(amqp_bytes_t mechanisms, + amqp_sasl_method_enum method); + +int amqp_merge_capabilities(const amqp_table_t *base, const amqp_table_t *add, + amqp_table_t *result, amqp_pool_t *pool); +AMQP_END_DECLS + +#endif /* AMQP_SOCKET_H */ diff --git a/ext/librabbitmq/librabbitmq/amqp_ssl_socket.h b/ext/librabbitmq/librabbitmq/amqp_ssl_socket.h new file mode 100644 index 00000000..9977ae4b --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_ssl_socket.h @@ -0,0 +1,239 @@ +/** \file */ +/* + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk. + * All Rights Reserved. + * + * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael + * Steinert. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AMQP_SSL_H +#define AMQP_SSL_H + +#include + +AMQP_BEGIN_DECLS + +/** + * Create a new SSL/TLS socket object. + * + * The returned socket object is owned by the \ref amqp_connection_state_t + * object and will be destroyed when the state object is destroyed or a new + * socket object is created. + * + * If the socket object creation fails, the \ref amqp_connection_state_t object + * will not be changed. + * + * The object returned by this function can be retrieved from the + * amqp_connection_state_t object later using the amqp_get_socket() function. + * + * Calling this function may result in the underlying SSL library being + * initialized. + * \sa amqp_set_initialize_ssl_library() + * + * \param [in,out] state The connection object that owns the SSL/TLS socket + * \return A new socket object or NULL if an error occurred. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_socket_t *AMQP_CALL amqp_ssl_socket_new(amqp_connection_state_t state); + +/** + * Set the CA certificate. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] cacert Path to the CA cert file in PEM format. + * + * \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on + * failure. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_ssl_socket_set_cacert(amqp_socket_t *self, + const char *cacert); + +/** + * Set the client key. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] cert Path to the client certificate in PEM foramt. + * \param [in] key Path to the client key in PEM format. + * + * \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on + * failure. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_ssl_socket_set_key(amqp_socket_t *self, const char *cert, + const char *key); + +/** + * Set the client key from a buffer. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] cert Path to the client certificate in PEM foramt. + * \param [in] key A buffer containing client key in PEM format. + * \param [in] n The length of the buffer. + * + * \return \ref AMQP_STATUS_OK on success an \ref amqp_status_enum value on + * failure. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_ssl_socket_set_key_buffer(amqp_socket_t *self, + const char *cert, const void *key, + size_t n); + +/** + * Enable or disable peer verification. + * + * \deprecated use \amqp_ssl_socket_set_verify_peer and + * \amqp_ssl_socket_set_verify_hostname instead. + * + * If peer verification is enabled then the common name in the server + * certificate must match the server name. Peer verification is enabled by + * default. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] verify Enable or disable peer verification. + * + * \since v0.4.0 + */ +AMQP_DEPRECATED(AMQP_PUBLIC_FUNCTION void AMQP_CALL amqp_ssl_socket_set_verify( + amqp_socket_t *self, amqp_boolean_t verify)); + +/** + * Enable or disable peer verification. + * + * Peer verification validates the certificate chain that is sent by the broker. + * Hostname validation is controlled by \amqp_ssl_socket_set_verify_peer. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] verify enable or disable peer validation + * + * \since v0.8.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_ssl_socket_set_verify_peer(amqp_socket_t *self, + amqp_boolean_t verify); + +/** + * Enable or disable hostname verification. + * + * Hostname verification checks the broker cert for a CN or SAN that matches the + * hostname that amqp_socket_open() is presented. Peer verification is + * controlled by \amqp_ssl_socket_set_verify_peer + * + * \since v0.8.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_ssl_socket_set_verify_hostname(amqp_socket_t *self, + amqp_boolean_t verify); + +typedef enum { + AMQP_TLSv1 = 1, + AMQP_TLSv1_1 = 2, + AMQP_TLSv1_2 = 3, + AMQP_TLSvLATEST = 0xFFFF +} amqp_tls_version_t; + +/** + * Set min and max TLS versions. + * + * Set the oldest and newest acceptable TLS versions that are acceptable when + * connecting to the broker. Set min == max to restrict to just that + * version. + * + * \param [in,out] self An SSL/TLS socket object. + * \param [in] min the minimum acceptable TLS version + * \param [in] max the maxmium acceptable TLS version + * \returns AMQP_STATUS_OK on success, AMQP_STATUS_UNSUPPORTED if OpenSSL does + * not support the requested TLS version, AMQP_STATUS_INVALID_PARAMETER if an + * invalid combination of parameters is passed. + * + * \since v0.8.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_ssl_socket_set_ssl_versions(amqp_socket_t *self, + amqp_tls_version_t min, + amqp_tls_version_t max); + +/** + * Sets whether rabbitmq-c will initialize OpenSSL. + * + * OpenSSL requires a one-time initialization across a whole program, this sets + * whether or not rabbitmq-c will initialize the SSL library when the first call + * to amqp_ssl_socket_new() is made. You should call this function with + * do_init = 0 if the underlying SSL library is initialized somewhere else + * the program. + * + * Failing to initialize or double initialization of the SSL library will + * result in undefined behavior + * + * By default rabbitmq-c will initialize the underlying SSL library. + * + * NOTE: calling this function after the first socket has been opened with + * amqp_open_socket() will not have any effect. + * + * \param [in] do_initialize If 0 rabbitmq-c will not initialize the SSL + * library, otherwise rabbitmq-c will initialize the + * SSL library + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_set_initialize_ssl_library(amqp_boolean_t do_initialize); + +/** + * Initialize the underlying SSL/TLS library. + * + * The OpenSSL library requires a one-time initialization across the whole + * program. + * + * This function unconditionally initializes OpenSSL so that rabbitmq-c may + * use it. + * + * This function is thread-safe, and may be called more than once. + * + * \return AMQP_STATUS_OK on success. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_initialize_ssl_library(void); + +/** + * Uninitialize the underlying SSL/TLS library. + * + * \return AMQP_STATUS_OK on success. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_uninitialize_ssl_library(void); + +AMQP_END_DECLS + +#endif /* AMQP_SSL_H */ diff --git a/ext/librabbitmq/librabbitmq/amqp_table.c b/ext/librabbitmq/librabbitmq/amqp_table.c new file mode 100644 index 00000000..24b087cc --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_table.c @@ -0,0 +1,668 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp_private.h" +#include "amqp_table.h" +#include +#include +#include +#include +#include + +#define INITIAL_ARRAY_SIZE 16 +#define INITIAL_TABLE_SIZE 16 + +static int amqp_decode_field_value(amqp_bytes_t encoded, amqp_pool_t *pool, + amqp_field_value_t *entry, size_t *offset); + +static int amqp_encode_field_value(amqp_bytes_t encoded, + amqp_field_value_t *entry, size_t *offset); + +/*---------------------------------------------------------------------------*/ + +static int amqp_decode_array(amqp_bytes_t encoded, amqp_pool_t *pool, + amqp_array_t *output, size_t *offset) { + uint32_t arraysize; + int num_entries = 0; + int allocated_entries = INITIAL_ARRAY_SIZE; + amqp_field_value_t *entries; + size_t limit; + int res; + + if (!amqp_decode_32(encoded, offset, &arraysize)) { + return AMQP_STATUS_BAD_AMQP_DATA; + } + + if (arraysize + *offset > encoded.len) { + return AMQP_STATUS_BAD_AMQP_DATA; + } + + entries = malloc(allocated_entries * sizeof(amqp_field_value_t)); + if (entries == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + + limit = *offset + arraysize; + while (*offset < limit) { + if (num_entries >= allocated_entries) { + void *newentries; + allocated_entries = allocated_entries * 2; + newentries = + realloc(entries, allocated_entries * sizeof(amqp_field_value_t)); + res = AMQP_STATUS_NO_MEMORY; + if (newentries == NULL) { + goto out; + } + + entries = newentries; + } + + res = amqp_decode_field_value(encoded, pool, &entries[num_entries], offset); + if (res < 0) { + goto out; + } + + num_entries++; + } + + output->num_entries = num_entries; + output->entries = + amqp_pool_alloc(pool, num_entries * sizeof(amqp_field_value_t)); + /* NULL is legitimate if we requested a zero-length block. */ + if (output->entries == NULL) { + if (num_entries == 0) { + res = AMQP_STATUS_OK; + } else { + res = AMQP_STATUS_NO_MEMORY; + } + goto out; + } + + memcpy(output->entries, entries, num_entries * sizeof(amqp_field_value_t)); + res = AMQP_STATUS_OK; + +out: + free(entries); + return res; +} + +int amqp_decode_table(amqp_bytes_t encoded, amqp_pool_t *pool, + amqp_table_t *output, size_t *offset) { + uint32_t tablesize; + int num_entries = 0; + amqp_table_entry_t *entries; + int allocated_entries = INITIAL_TABLE_SIZE; + size_t limit; + int res; + + if (!amqp_decode_32(encoded, offset, &tablesize)) { + return AMQP_STATUS_BAD_AMQP_DATA; + } + + if (tablesize + *offset > encoded.len) { + return AMQP_STATUS_BAD_AMQP_DATA; + } + + entries = malloc(allocated_entries * sizeof(amqp_table_entry_t)); + if (entries == NULL) { + return AMQP_STATUS_NO_MEMORY; + } + + limit = *offset + tablesize; + while (*offset < limit) { + uint8_t keylen; + + res = AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_8(encoded, offset, &keylen)) { + goto out; + } + + if (num_entries >= allocated_entries) { + void *newentries; + allocated_entries = allocated_entries * 2; + newentries = + realloc(entries, allocated_entries * sizeof(amqp_table_entry_t)); + res = AMQP_STATUS_NO_MEMORY; + if (newentries == NULL) { + goto out; + } + + entries = newentries; + } + + res = AMQP_STATUS_BAD_AMQP_DATA; + if (!amqp_decode_bytes(encoded, offset, &entries[num_entries].key, + keylen)) { + goto out; + } + + res = amqp_decode_field_value(encoded, pool, &entries[num_entries].value, + offset); + if (res < 0) { + goto out; + } + + num_entries++; + } + + output->num_entries = num_entries; + output->entries = + amqp_pool_alloc(pool, num_entries * sizeof(amqp_table_entry_t)); + /* NULL is legitimate if we requested a zero-length block. */ + if (output->entries == NULL) { + if (num_entries == 0) { + res = AMQP_STATUS_OK; + } else { + res = AMQP_STATUS_NO_MEMORY; + } + goto out; + } + + memcpy(output->entries, entries, num_entries * sizeof(amqp_table_entry_t)); + res = AMQP_STATUS_OK; + +out: + free(entries); + return res; +} + +static int amqp_decode_field_value(amqp_bytes_t encoded, amqp_pool_t *pool, + amqp_field_value_t *entry, size_t *offset) { + int res = AMQP_STATUS_BAD_AMQP_DATA; + + if (!amqp_decode_8(encoded, offset, &entry->kind)) { + goto out; + } + +#define TRIVIAL_FIELD_DECODER(bits) \ + if (!amqp_decode_##bits(encoded, offset, &entry->value.u##bits)) goto out; \ + break +#define SIMPLE_FIELD_DECODER(bits, dest, how) \ + { \ + uint##bits##_t val; \ + if (!amqp_decode_##bits(encoded, offset, &val)) goto out; \ + entry->value.dest = how; \ + } \ + break + + switch (entry->kind) { + case AMQP_FIELD_KIND_BOOLEAN: + SIMPLE_FIELD_DECODER(8, boolean, val ? 1 : 0); + + case AMQP_FIELD_KIND_I8: + SIMPLE_FIELD_DECODER(8, i8, (int8_t)val); + case AMQP_FIELD_KIND_U8: + TRIVIAL_FIELD_DECODER(8); + + case AMQP_FIELD_KIND_I16: + SIMPLE_FIELD_DECODER(16, i16, (int16_t)val); + case AMQP_FIELD_KIND_U16: + TRIVIAL_FIELD_DECODER(16); + + case AMQP_FIELD_KIND_I32: + SIMPLE_FIELD_DECODER(32, i32, (int32_t)val); + case AMQP_FIELD_KIND_U32: + TRIVIAL_FIELD_DECODER(32); + + case AMQP_FIELD_KIND_I64: + SIMPLE_FIELD_DECODER(64, i64, (int64_t)val); + case AMQP_FIELD_KIND_U64: + TRIVIAL_FIELD_DECODER(64); + + case AMQP_FIELD_KIND_F32: + TRIVIAL_FIELD_DECODER(32); + /* and by punning, f32 magically gets the right value...! */ + + case AMQP_FIELD_KIND_F64: + TRIVIAL_FIELD_DECODER(64); + /* and by punning, f64 magically gets the right value...! */ + + case AMQP_FIELD_KIND_DECIMAL: + if (!amqp_decode_8(encoded, offset, &entry->value.decimal.decimals) || + !amqp_decode_32(encoded, offset, &entry->value.decimal.value)) { + goto out; + } + break; + + case AMQP_FIELD_KIND_UTF8: + /* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the + same implementation, but different interpretations. */ + /* fall through */ + case AMQP_FIELD_KIND_BYTES: { + uint32_t len; + if (!amqp_decode_32(encoded, offset, &len) || + !amqp_decode_bytes(encoded, offset, &entry->value.bytes, len)) { + goto out; + } + break; + } + + case AMQP_FIELD_KIND_ARRAY: + res = amqp_decode_array(encoded, pool, &(entry->value.array), offset); + goto out; + + case AMQP_FIELD_KIND_TIMESTAMP: + TRIVIAL_FIELD_DECODER(64); + + case AMQP_FIELD_KIND_TABLE: + res = amqp_decode_table(encoded, pool, &(entry->value.table), offset); + goto out; + + case AMQP_FIELD_KIND_VOID: + break; + + default: + goto out; + } + + res = AMQP_STATUS_OK; + +out: + return res; +} + +/*---------------------------------------------------------------------------*/ + +static int amqp_encode_array(amqp_bytes_t encoded, amqp_array_t *input, + size_t *offset) { + size_t start = *offset; + int i, res; + + *offset += 4; /* size of the array gets filled in later on */ + + for (i = 0; i < input->num_entries; i++) { + res = amqp_encode_field_value(encoded, &input->entries[i], offset); + if (res < 0) { + goto out; + } + } + + if (!amqp_encode_32(encoded, &start, (uint32_t)(*offset - start - 4))) { + res = AMQP_STATUS_TABLE_TOO_BIG; + goto out; + } + + res = AMQP_STATUS_OK; + +out: + return res; +} + +int amqp_encode_table(amqp_bytes_t encoded, amqp_table_t *input, + size_t *offset) { + size_t start = *offset; + int i, res; + + *offset += 4; /* size of the table gets filled in later on */ + + for (i = 0; i < input->num_entries; i++) { + if (!amqp_encode_8(encoded, offset, (uint8_t)input->entries[i].key.len)) { + res = AMQP_STATUS_TABLE_TOO_BIG; + goto out; + } + + if (!amqp_encode_bytes(encoded, offset, input->entries[i].key)) { + res = AMQP_STATUS_TABLE_TOO_BIG; + goto out; + } + + res = amqp_encode_field_value(encoded, &input->entries[i].value, offset); + if (res < 0) { + goto out; + } + } + + if (!amqp_encode_32(encoded, &start, (uint32_t)(*offset - start - 4))) { + res = AMQP_STATUS_TABLE_TOO_BIG; + goto out; + } + + res = AMQP_STATUS_OK; + +out: + return res; +} + +static int amqp_encode_field_value(amqp_bytes_t encoded, + amqp_field_value_t *entry, size_t *offset) { + int res = AMQP_STATUS_BAD_AMQP_DATA; + + if (!amqp_encode_8(encoded, offset, entry->kind)) { + goto out; + } + +#define FIELD_ENCODER(bits, val) \ + if (!amqp_encode_##bits(encoded, offset, val)) { \ + res = AMQP_STATUS_TABLE_TOO_BIG; \ + goto out; \ + } \ + break + + switch (entry->kind) { + case AMQP_FIELD_KIND_BOOLEAN: + FIELD_ENCODER(8, entry->value.boolean ? 1 : 0); + + case AMQP_FIELD_KIND_I8: + FIELD_ENCODER(8, entry->value.i8); + case AMQP_FIELD_KIND_U8: + FIELD_ENCODER(8, entry->value.u8); + + case AMQP_FIELD_KIND_I16: + FIELD_ENCODER(16, entry->value.i16); + case AMQP_FIELD_KIND_U16: + FIELD_ENCODER(16, entry->value.u16); + + case AMQP_FIELD_KIND_I32: + FIELD_ENCODER(32, entry->value.i32); + case AMQP_FIELD_KIND_U32: + FIELD_ENCODER(32, entry->value.u32); + + case AMQP_FIELD_KIND_I64: + FIELD_ENCODER(64, entry->value.i64); + case AMQP_FIELD_KIND_U64: + FIELD_ENCODER(64, entry->value.u64); + + case AMQP_FIELD_KIND_F32: + /* by punning, u32 magically gets the right value...! */ + FIELD_ENCODER(32, entry->value.u32); + + case AMQP_FIELD_KIND_F64: + /* by punning, u64 magically gets the right value...! */ + FIELD_ENCODER(64, entry->value.u64); + + case AMQP_FIELD_KIND_DECIMAL: + if (!amqp_encode_8(encoded, offset, entry->value.decimal.decimals) || + !amqp_encode_32(encoded, offset, entry->value.decimal.value)) { + res = AMQP_STATUS_TABLE_TOO_BIG; + goto out; + } + break; + + case AMQP_FIELD_KIND_UTF8: + /* AMQP_FIELD_KIND_UTF8 and AMQP_FIELD_KIND_BYTES have the + same implementation, but different interpretations. */ + /* fall through */ + case AMQP_FIELD_KIND_BYTES: + if (!amqp_encode_32(encoded, offset, (uint32_t)entry->value.bytes.len) || + !amqp_encode_bytes(encoded, offset, entry->value.bytes)) { + res = AMQP_STATUS_TABLE_TOO_BIG; + goto out; + } + break; + + case AMQP_FIELD_KIND_ARRAY: + res = amqp_encode_array(encoded, &entry->value.array, offset); + goto out; + + case AMQP_FIELD_KIND_TIMESTAMP: + FIELD_ENCODER(64, entry->value.u64); + + case AMQP_FIELD_KIND_TABLE: + res = amqp_encode_table(encoded, &entry->value.table, offset); + goto out; + + case AMQP_FIELD_KIND_VOID: + break; + + default: + res = AMQP_STATUS_INVALID_PARAMETER; + goto out; + } + + res = AMQP_STATUS_OK; + +out: + return res; +} + +/*---------------------------------------------------------------------------*/ + +int amqp_table_entry_cmp(void const *entry1, void const *entry2) { + amqp_table_entry_t const *p1 = (amqp_table_entry_t const *)entry1; + amqp_table_entry_t const *p2 = (amqp_table_entry_t const *)entry2; + + int d; + size_t minlen; + + minlen = p1->key.len; + if (p2->key.len < minlen) { + minlen = p2->key.len; + } + + d = memcmp(p1->key.bytes, p2->key.bytes, minlen); + if (d != 0) { + return d; + } + + return (int)p1->key.len - (int)p2->key.len; +} + +static int amqp_field_value_clone(const amqp_field_value_t *original, + amqp_field_value_t *clone, + amqp_pool_t *pool) { + int i; + int res; + clone->kind = original->kind; + + switch (clone->kind) { + case AMQP_FIELD_KIND_BOOLEAN: + clone->value.boolean = original->value.boolean; + break; + + case AMQP_FIELD_KIND_I8: + clone->value.i8 = original->value.i8; + break; + + case AMQP_FIELD_KIND_U8: + clone->value.u8 = original->value.u8; + break; + + case AMQP_FIELD_KIND_I16: + clone->value.i16 = original->value.i16; + break; + + case AMQP_FIELD_KIND_U16: + clone->value.u16 = original->value.u16; + break; + + case AMQP_FIELD_KIND_I32: + clone->value.i32 = original->value.i32; + break; + + case AMQP_FIELD_KIND_U32: + clone->value.u32 = original->value.u32; + break; + + case AMQP_FIELD_KIND_I64: + clone->value.i64 = original->value.i64; + break; + + case AMQP_FIELD_KIND_U64: + case AMQP_FIELD_KIND_TIMESTAMP: + clone->value.u64 = original->value.u64; + break; + + case AMQP_FIELD_KIND_F32: + clone->value.f32 = original->value.f32; + break; + + case AMQP_FIELD_KIND_F64: + clone->value.f64 = original->value.f64; + break; + + case AMQP_FIELD_KIND_DECIMAL: + clone->value.decimal = original->value.decimal; + break; + + case AMQP_FIELD_KIND_UTF8: + case AMQP_FIELD_KIND_BYTES: + if (0 == original->value.bytes.len) { + clone->value.bytes = amqp_empty_bytes; + } else { + amqp_pool_alloc_bytes(pool, original->value.bytes.len, + &clone->value.bytes); + if (NULL == clone->value.bytes.bytes) { + return AMQP_STATUS_NO_MEMORY; + } + memcpy(clone->value.bytes.bytes, original->value.bytes.bytes, + clone->value.bytes.len); + } + break; + + case AMQP_FIELD_KIND_ARRAY: + if (0 == original->value.array.entries) { + clone->value.array = amqp_empty_array; + } else { + clone->value.array.num_entries = original->value.array.num_entries; + clone->value.array.entries = amqp_pool_alloc( + pool, clone->value.array.num_entries * sizeof(amqp_field_value_t)); + if (NULL == clone->value.array.entries) { + return AMQP_STATUS_NO_MEMORY; + } + + for (i = 0; i < clone->value.array.num_entries; ++i) { + res = amqp_field_value_clone(&original->value.array.entries[i], + &clone->value.array.entries[i], pool); + if (AMQP_STATUS_OK != res) { + return res; + } + } + } + break; + + case AMQP_FIELD_KIND_TABLE: + return amqp_table_clone(&original->value.table, &clone->value.table, + pool); + + case AMQP_FIELD_KIND_VOID: + break; + + default: + return AMQP_STATUS_INVALID_PARAMETER; + } + + return AMQP_STATUS_OK; +} + +static int amqp_table_entry_clone(const amqp_table_entry_t *original, + amqp_table_entry_t *clone, + amqp_pool_t *pool) { + if (0 == original->key.len) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + amqp_pool_alloc_bytes(pool, original->key.len, &clone->key); + if (NULL == clone->key.bytes) { + return AMQP_STATUS_NO_MEMORY; + } + + memcpy(clone->key.bytes, original->key.bytes, clone->key.len); + + return amqp_field_value_clone(&original->value, &clone->value, pool); +} + +int amqp_table_clone(const amqp_table_t *original, amqp_table_t *clone, + amqp_pool_t *pool) { + int i; + int res; + clone->num_entries = original->num_entries; + if (0 == clone->num_entries) { + *clone = amqp_empty_table; + return AMQP_STATUS_OK; + } + + clone->entries = + amqp_pool_alloc(pool, clone->num_entries * sizeof(amqp_table_entry_t)); + + if (NULL == clone->entries) { + return AMQP_STATUS_NO_MEMORY; + } + + for (i = 0; i < clone->num_entries; ++i) { + res = + amqp_table_entry_clone(&original->entries[i], &clone->entries[i], pool); + if (AMQP_STATUS_OK != res) { + goto error_out1; + } + } + + return AMQP_STATUS_OK; + +error_out1: + return res; +} + +amqp_table_entry_t amqp_table_construct_utf8_entry(const char *key, + const char *value) { + amqp_table_entry_t ret; + ret.key = amqp_cstring_bytes(key); + ret.value.kind = AMQP_FIELD_KIND_UTF8; + ret.value.value.bytes = amqp_cstring_bytes(value); + return ret; +} + +amqp_table_entry_t amqp_table_construct_table_entry(const char *key, + const amqp_table_t *value) { + amqp_table_entry_t ret; + ret.key = amqp_cstring_bytes(key); + ret.value.kind = AMQP_FIELD_KIND_TABLE; + ret.value.value.table = *value; + return ret; +} + +amqp_table_entry_t amqp_table_construct_bool_entry(const char *key, + const int value) { + amqp_table_entry_t ret; + ret.key = amqp_cstring_bytes(key); + ret.value.kind = AMQP_FIELD_KIND_BOOLEAN; + ret.value.value.boolean = value; + return ret; +} + +amqp_table_entry_t *amqp_table_get_entry_by_key(const amqp_table_t *table, + const amqp_bytes_t key) { + int i; + assert(table != NULL); + for (i = 0; i < table->num_entries; ++i) { + if (amqp_bytes_equal(table->entries[i].key, key)) { + return &table->entries[i]; + } + } + return NULL; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_table.h b/ext/librabbitmq/librabbitmq/amqp_table.h new file mode 100644 index 00000000..7b009a99 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_table.h @@ -0,0 +1,81 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2014 Alan Antonuk. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ +#ifndef AMQP_TABLE_H +#define AMQP_TABLE_H + +#include "amqp.h" +#include "amqp_private.h" + +/** + * Initializes a table entry with utf-8 string type value. + * + * \param [in] key the table entry key. The string must remain valid for the + * life of the resulting amqp_table_entry_t. + * \param [in] value the string value. The string must remain valid for the life + * of the resulting amqp_table_entry_t. + * \returns An initialized table entry. + */ +amqp_table_entry_t amqp_table_construct_utf8_entry(const char *key, + const char *value); + +/** + * Initializes a table entry with table type value. + * + * \param [in] key the table entry key. The string must remain value for the + * life of the resulting amqp_table_entry_t. + * \param [in] value the amqp_table_t value. The table must remain valid for the + * life of the resulting amqp_table_entry_t. + * \returns An initialized table entry. + */ +amqp_table_entry_t amqp_table_construct_table_entry(const char *key, + const amqp_table_t *value); + +/** + * Initializes a table entry with boolean type value. + * + * \param [in] key the table entry key. The string must remain value for the + * life of the resulting amqp_table_entry_t. + * \param [in] value the boolean value. 0 means false, any other value is true. + * \returns An initialized table entry. + */ +amqp_table_entry_t amqp_table_construct_bool_entry(const char *key, + const int value); + +/** + * Searches a table for an entry with a matching key. + * + * \param [in] table the table to search. + * \param [in] key the string to search with. + * \returns a pointer to the table entry in the table if a matching key can be + * found, NULL otherwise. + */ +amqp_table_entry_t *amqp_table_get_entry_by_key(const amqp_table_t *table, + const amqp_bytes_t key); + +#endif /* AMQP_TABLE_H */ diff --git a/ext/librabbitmq/librabbitmq/amqp_tcp_socket.c b/ext/librabbitmq/librabbitmq/amqp_tcp_socket.c new file mode 100644 index 00000000..12e02cd2 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_tcp_socket.c @@ -0,0 +1,238 @@ +/* + * Copyright 2012-2013 Michael Steinert + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp_private.h" +#include "amqp_tcp_socket.h" + +#include +#if ((defined(_WIN32)) || (defined(__MINGW32__)) || (defined(__MINGW64__))) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#include +#include +#endif +#include +#include + +struct amqp_tcp_socket_t { + const struct amqp_socket_class_t *klass; + int sockfd; + int internal_error; + int state; +}; + +static ssize_t amqp_tcp_socket_send(void *base, const void *buf, size_t len, + int flags) { + struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; + ssize_t res; + int flagz = 0; + + if (-1 == self->sockfd) { + return AMQP_STATUS_SOCKET_CLOSED; + } + +#ifdef MSG_NOSIGNAL + flagz |= MSG_NOSIGNAL; +#endif + +#if defined(MSG_MORE) + if (flags & AMQP_SF_MORE) { + flagz |= MSG_MORE; + } +/* Cygwin defines TCP_NOPUSH, but trying to use it will return not + * implemented. Disable it here. */ +#elif defined(TCP_NOPUSH) && !defined(__CYGWIN__) + if (flags & AMQP_SF_MORE && !(self->state & AMQP_SF_MORE)) { + int one = 1; + res = setsockopt(self->sockfd, IPPROTO_TCP, TCP_NOPUSH, &one, sizeof(one)); + if (0 != res) { + self->internal_error = res; + return AMQP_STATUS_SOCKET_ERROR; + } + self->state |= AMQP_SF_MORE; + } else if (!(flags & AMQP_SF_MORE) && self->state & AMQP_SF_MORE) { + int zero = 0; + res = + setsockopt(self->sockfd, IPPROTO_TCP, TCP_NOPUSH, &zero, sizeof(&zero)); + if (0 != res) { + self->internal_error = res; + res = AMQP_STATUS_SOCKET_ERROR; + } else { + self->state &= ~AMQP_SF_MORE; + } + } +#endif + +start: +#ifdef _WIN32 + res = send(self->sockfd, buf, (int)len, flagz); +#else + res = send(self->sockfd, buf, len, flagz); +#endif + + if (res < 0) { + self->internal_error = amqp_os_socket_error(); + switch (self->internal_error) { + case EINTR: + goto start; +#ifdef _WIN32 + case WSAEWOULDBLOCK: +#else + case EWOULDBLOCK: +#endif +#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK + case EAGAIN: +#endif + res = AMQP_PRIVATE_STATUS_SOCKET_NEEDWRITE; + break; + default: + res = AMQP_STATUS_SOCKET_ERROR; + } + } else { + self->internal_error = 0; + } + + return res; +} + +static ssize_t amqp_tcp_socket_recv(void *base, void *buf, size_t len, + int flags) { + struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; + ssize_t ret; + if (-1 == self->sockfd) { + return AMQP_STATUS_SOCKET_CLOSED; + } + +start: +#ifdef _WIN32 + ret = recv(self->sockfd, buf, (int)len, flags); +#else + ret = recv(self->sockfd, buf, len, flags); +#endif + + if (0 > ret) { + self->internal_error = amqp_os_socket_error(); + switch (self->internal_error) { + case EINTR: + goto start; +#ifdef _WIN32 + case WSAEWOULDBLOCK: +#else + case EWOULDBLOCK: +#endif +#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK + case EAGAIN: +#endif + ret = AMQP_PRIVATE_STATUS_SOCKET_NEEDREAD; + break; + default: + ret = AMQP_STATUS_SOCKET_ERROR; + } + } else if (0 == ret) { + ret = AMQP_STATUS_CONNECTION_CLOSED; + } + + return ret; +} + +static int amqp_tcp_socket_open(void *base, const char *host, int port, + struct timeval *timeout) { + struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; + if (-1 != self->sockfd) { + return AMQP_STATUS_SOCKET_INUSE; + } + self->sockfd = amqp_open_socket_noblock(host, port, timeout); + if (0 > self->sockfd) { + int err = self->sockfd; + self->sockfd = -1; + return err; + } + return AMQP_STATUS_OK; +} + +static int amqp_tcp_socket_close(void *base, + AMQP_UNUSED amqp_socket_close_enum force) { + struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; + if (-1 == self->sockfd) { + return AMQP_STATUS_SOCKET_CLOSED; + } + + if (amqp_os_socket_close(self->sockfd)) { + return AMQP_STATUS_SOCKET_ERROR; + } + self->sockfd = -1; + + return AMQP_STATUS_OK; +} + +static int amqp_tcp_socket_get_sockfd(void *base) { + struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; + return self->sockfd; +} + +static void amqp_tcp_socket_delete(void *base) { + struct amqp_tcp_socket_t *self = (struct amqp_tcp_socket_t *)base; + + if (self) { + amqp_tcp_socket_close(self, AMQP_SC_NONE); + free(self); + } +} + +static const struct amqp_socket_class_t amqp_tcp_socket_class = { + amqp_tcp_socket_send, /* send */ + amqp_tcp_socket_recv, /* recv */ + amqp_tcp_socket_open, /* open */ + amqp_tcp_socket_close, /* close */ + amqp_tcp_socket_get_sockfd, /* get_sockfd */ + amqp_tcp_socket_delete /* delete */ +}; + +amqp_socket_t *amqp_tcp_socket_new(amqp_connection_state_t state) { + struct amqp_tcp_socket_t *self = calloc(1, sizeof(*self)); + if (!self) { + return NULL; + } + self->klass = &amqp_tcp_socket_class; + self->sockfd = -1; + + amqp_set_socket(state, (amqp_socket_t *)self); + + return (amqp_socket_t *)self; +} + +void amqp_tcp_socket_set_sockfd(amqp_socket_t *base, int sockfd) { + struct amqp_tcp_socket_t *self; + if (base->klass != &amqp_tcp_socket_class) { + amqp_abort("<%p> is not of type amqp_tcp_socket_t", base); + } + self = (struct amqp_tcp_socket_t *)base; + self->sockfd = sockfd; +} diff --git a/ext/librabbitmq/centos_x64/include/amqp_tcp_socket.h b/ext/librabbitmq/librabbitmq/amqp_tcp_socket.h similarity index 100% rename from ext/librabbitmq/centos_x64/include/amqp_tcp_socket.h rename to ext/librabbitmq/librabbitmq/amqp_tcp_socket.h diff --git a/ext/librabbitmq/librabbitmq/amqp_time.c b/ext/librabbitmq/librabbitmq/amqp_time.c new file mode 100644 index 00000000..7b0a42d0 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_time.c @@ -0,0 +1,265 @@ +/* + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include "amqp_time.h" +#include "amqp.h" +#include +#include +#include + +#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || \ + defined(__MINGW32__) || defined(__MINGW64__)) +#define AMQP_WIN_TIMER_API +#elif (defined(machintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) +#define AMQP_MAC_TIMER_API +#else +#define AMQP_POSIX_TIMER_API +#endif + +#ifdef AMQP_WIN_TIMER_API +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +uint64_t amqp_get_monotonic_timestamp(void) { + static double NS_PER_COUNT = 0; + LARGE_INTEGER perf_count; + + if (0 == NS_PER_COUNT) { + LARGE_INTEGER perf_frequency; + if (!QueryPerformanceFrequency(&perf_frequency)) { + return 0; + } + NS_PER_COUNT = (double)AMQP_NS_PER_S / perf_frequency.QuadPart; + } + + if (!QueryPerformanceCounter(&perf_count)) { + return 0; + } + + return (uint64_t)(perf_count.QuadPart * NS_PER_COUNT); +} +#endif /* AMQP_WIN_TIMER_API */ + +#ifdef AMQP_MAC_TIMER_API +#include + +uint64_t amqp_get_monotonic_timestamp(void) { + static mach_timebase_info_data_t s_timebase = {0, 0}; + uint64_t timestamp; + + timestamp = mach_absolute_time(); + + if (s_timebase.denom == 0) { + mach_timebase_info(&s_timebase); + if (0 == s_timebase.denom) { + return 0; + } + } + + timestamp *= (uint64_t)s_timebase.numer; + timestamp /= (uint64_t)s_timebase.denom; + + return timestamp; +} +#endif /* AMQP_MAC_TIMER_API */ + +#ifdef AMQP_POSIX_TIMER_API +#include + +uint64_t amqp_get_monotonic_timestamp(void) { +#ifdef __hpux + return (uint64_t)gethrtime(); +#else + struct timespec tp; + if (-1 == clock_gettime(CLOCK_MONOTONIC, &tp)) { + return 0; + } + + return ((uint64_t)tp.tv_sec * AMQP_NS_PER_S + (uint64_t)tp.tv_nsec); +#endif +} +#endif /* AMQP_POSIX_TIMER_API */ + +int amqp_time_from_now(amqp_time_t *time, struct timeval *timeout) { + uint64_t now_ns; + uint64_t delta_ns; + + assert(NULL != time); + + if (NULL == timeout) { + *time = amqp_time_infinite(); + return AMQP_STATUS_OK; + } + if (0 == timeout->tv_sec && 0 == timeout->tv_usec) { + *time = amqp_time_immediate(); + return AMQP_STATUS_OK; + } + + if (timeout->tv_sec < 0 || timeout->tv_usec < 0) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + delta_ns = (uint64_t)timeout->tv_sec * AMQP_NS_PER_S + + (uint64_t)timeout->tv_usec * AMQP_NS_PER_US; + + now_ns = amqp_get_monotonic_timestamp(); + if (0 == now_ns) { + return AMQP_STATUS_TIMER_FAILURE; + } + + time->time_point_ns = now_ns + delta_ns; + if (now_ns > time->time_point_ns || delta_ns > time->time_point_ns) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + return AMQP_STATUS_OK; +} + +int amqp_time_s_from_now(amqp_time_t *time, int seconds) { + uint64_t now_ns; + uint64_t delta_ns; + assert(NULL != time); + + if (0 >= seconds) { + *time = amqp_time_infinite(); + return AMQP_STATUS_OK; + } + + now_ns = amqp_get_monotonic_timestamp(); + if (0 == now_ns) { + return AMQP_STATUS_TIMER_FAILURE; + } + + delta_ns = (uint64_t)seconds * AMQP_NS_PER_S; + time->time_point_ns = now_ns + delta_ns; + if (now_ns > time->time_point_ns || delta_ns > time->time_point_ns) { + return AMQP_STATUS_INVALID_PARAMETER; + } + + return AMQP_STATUS_OK; +} + +amqp_time_t amqp_time_immediate(void) { + amqp_time_t time; + time.time_point_ns = 0; + return time; +} + +amqp_time_t amqp_time_infinite(void) { + amqp_time_t time; + time.time_point_ns = UINT64_MAX; + return time; +} + +int amqp_time_ms_until(amqp_time_t time) { + uint64_t now_ns; + uint64_t delta_ns; + int left_ms; + + if (UINT64_MAX == time.time_point_ns) { + return -1; + } + if (0 == time.time_point_ns) { + return 0; + } + + now_ns = amqp_get_monotonic_timestamp(); + if (0 == now_ns) { + return AMQP_STATUS_TIMER_FAILURE; + } + + if (now_ns >= time.time_point_ns) { + return 0; + } + + delta_ns = time.time_point_ns - now_ns; + left_ms = (int)(delta_ns / AMQP_NS_PER_MS); + + return left_ms; +} + +int amqp_time_tv_until(amqp_time_t time, struct timeval *in, + struct timeval **out) { + uint64_t now_ns; + uint64_t delta_ns; + + assert(in != NULL); + if (UINT64_MAX == time.time_point_ns) { + *out = NULL; + return AMQP_STATUS_OK; + } + if (0 == time.time_point_ns) { + in->tv_sec = 0; + in->tv_usec = 0; + *out = in; + return AMQP_STATUS_OK; + } + + now_ns = amqp_get_monotonic_timestamp(); + if (0 == now_ns) { + return AMQP_STATUS_TIMER_FAILURE; + } + + if (now_ns >= time.time_point_ns) { + in->tv_sec = 0; + in->tv_usec = 0; + *out = in; + return AMQP_STATUS_OK; + } + + delta_ns = time.time_point_ns - now_ns; + in->tv_sec = (int)(delta_ns / AMQP_NS_PER_S); + in->tv_usec = (int)((delta_ns % AMQP_NS_PER_S) / AMQP_NS_PER_US); + *out = in; + + return AMQP_STATUS_OK; +} + +int amqp_time_has_past(amqp_time_t time) { + uint64_t now_ns; + if (UINT64_MAX == time.time_point_ns) { + return AMQP_STATUS_OK; + } + + now_ns = amqp_get_monotonic_timestamp(); + if (0 == now_ns) { + return AMQP_STATUS_TIMER_FAILURE; + } + + if (now_ns > time.time_point_ns) { + return AMQP_STATUS_TIMEOUT; + } + return AMQP_STATUS_OK; +} + +amqp_time_t amqp_time_first(amqp_time_t l, amqp_time_t r) { + if (l.time_point_ns < r.time_point_ns) { + return l; + } + return r; +} + +int amqp_time_equal(amqp_time_t l, amqp_time_t r) { + return l.time_point_ns == r.time_point_ns; +} diff --git a/ext/librabbitmq/librabbitmq/amqp_time.h b/ext/librabbitmq/librabbitmq/amqp_time.h new file mode 100644 index 00000000..194bf671 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_time.h @@ -0,0 +1,130 @@ +/* + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef AMQP_TIMER_H +#define AMQP_TIMER_H + +#include + +#if ((defined(_WIN32)) || (defined(__MINGW32__)) || (defined(__MINGW64__))) +#ifndef WINVER +#define WINVER 0x0502 +#endif +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#endif + +#define AMQP_MS_PER_S 1000 +#define AMQP_US_PER_MS 1000 +#define AMQP_NS_PER_S 1000000000 +#define AMQP_NS_PER_MS 1000000 +#define AMQP_NS_PER_US 1000 + +/* This represents a point in time in reference to a monotonic clock. + * + * The internal representation is ns, relative to the monotonic clock. + * + * There are two 'special' values: + * - 0: means 'this instant', its meant for polls with a 0-timeout, or + * non-blocking option + * - UINT64_MAX: means 'at infinity', its mean for polls with an infinite + * timeout + */ +typedef struct amqp_time_t_ { uint64_t time_point_ns; } amqp_time_t; + +/* Gets a monotonic timestamp. This will return 0 if the underlying call to the + * system fails. + */ +uint64_t amqp_get_monotonic_timestamp(void); + +/* Get a amqp_time_t that is timeout from now. + * If timeout is NULL, an amqp_time_infinite() is created. + * If timeout = {0, 0}, an amqp_time_immediate() is created. + * + * Returns AMQP_STATUS_OK on success. + * AMQP_STATUS_INVALID_PARAMETER if timeout is invalid + * AMQP_STATUS_TIMER_FAILURE if the underlying call to get the current timestamp + * fails. + */ +int amqp_time_from_now(amqp_time_t *time, struct timeval *timeout); + +/* Get a amqp_time_t that is seconds from now. + * If seconds <= 0, then amqp_time_infinite() is created. + * + * Returns AMQP_STATUS_OK on success. + * AMQP_STATUS_TIMER_FAILURE if the underlying call to get the current timestamp + * fails. + */ +int amqp_time_s_from_now(amqp_time_t *time, int seconds); + +/* Create an immediate amqp_time_t */ +amqp_time_t amqp_time_immediate(void); + +/* Create an infinite amqp_time_t */ +amqp_time_t amqp_time_infinite(void); + +/* Gets the number of ms until the amqp_time_t, suitable for the timeout + * parameter in poll(). + * + * -1 will be returned for amqp_time_infinite values. + * 0 will be returned for amqp_time_immediate values. + * AMQP_STATUS_TIMEOUT will be returned if time was in the past. + * AMQP_STATUS_TIMER_FAILURE will be returned if the underlying call to get the + * current timestamp fails. + */ +int amqp_time_ms_until(amqp_time_t time); + +/* Gets a timeval filled in with the time until amqp_time_t. Suitable for the + * parameter in select(). + * + * The in parameter specifies a storage location for *out. + * If time is an inf timeout, then *out = NULL. + * If time is a 0-timeout or the timer has expired, then *out = {0, 0} + * Otherwise *out is set to the time left on the time. + * + * AMQP_STATUS_OK will be returned if successfully filled. + * AMQP_STATUS_TIMER_FAILURE is returned when the underlying call to get the + * current timestamp fails. + */ +int amqp_time_tv_until(amqp_time_t time, struct timeval *in, + struct timeval **out); + +/* Test whether current time is past the provided time. + * + * TODO: this isn't a great interface to use. Fix this. + * + * Return AMQP_STATUS_OK if time has not past + * Return AMQP_STATUS_TIMEOUT if time has past + * Return AMQP_STATUS_TIMER_FAILURE if the underlying call to get the current + * timestamp fails. + */ +int amqp_time_has_past(amqp_time_t time); + +/* Return the time value that happens first */ +amqp_time_t amqp_time_first(amqp_time_t l, amqp_time_t r); + +int amqp_time_equal(amqp_time_t l, amqp_time_t r); +#endif /* AMQP_TIMER_H */ diff --git a/ext/librabbitmq/librabbitmq/amqp_url.c b/ext/librabbitmq/librabbitmq/amqp_url.c new file mode 100644 index 00000000..b5304e54 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/amqp_url.c @@ -0,0 +1,220 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "amqp_private.h" +#include +#include +#include +#include +#include + +void amqp_default_connection_info(struct amqp_connection_info *ci) { + /* Apply defaults */ + ci->user = "guest"; + ci->password = "guest"; + ci->host = "localhost"; + ci->port = 5672; + ci->vhost = "/"; + ci->ssl = 0; +} + +/* Scan for the next delimiter, handling percent-encodings on the way. */ +static char find_delim(char **pp, int colon_and_at_sign_are_delims) { + char *from = *pp; + char *to = from; + + for (;;) { + char ch = *from++; + + switch (ch) { + case ':': + case '@': + if (!colon_and_at_sign_are_delims) { + *to++ = ch; + break; + } + + /* fall through */ + case 0: + case '/': + case '?': + case '#': + case '[': + case ']': + *to = 0; + *pp = from; + return ch; + + case '%': { + unsigned int val; + int chars; + int res = sscanf(from, "%2x%n", &val, &chars); + + if (res == EOF || res < 1 || chars != 2 || val > CHAR_MAX) + /* Return a surprising delimiter to + force an error. */ + { + return '%'; + } + + *to++ = (char)val; + from += 2; + break; + } + + default: + *to++ = ch; + break; + } + } +} + +/* Parse an AMQP URL into its component parts. */ +int amqp_parse_url(char *url, struct amqp_connection_info *parsed) { + int res = AMQP_STATUS_BAD_URL; + char delim; + char *start; + char *host; + char *port = NULL; + + amqp_default_connection_info(parsed); + + /* check the prefix */ + if (!strncmp(url, "amqp://", 7)) { + /* do nothing */ + } else if (!strncmp(url, "amqps://", 8)) { + parsed->port = 5671; + parsed->ssl = 1; + } else { + goto out; + } + + host = start = url += (parsed->ssl ? 8 : 7); + delim = find_delim(&url, 1); + + if (delim == ':') { + /* The colon could be introducing the port or the + password part of the userinfo. We don't know yet, + so stash the preceding component. */ + port = start = url; + delim = find_delim(&url, 1); + } + + if (delim == '@') { + /* What might have been the host and port were in fact + the username and password */ + parsed->user = host; + if (port) { + parsed->password = port; + } + + port = NULL; + host = start = url; + delim = find_delim(&url, 1); + } + + if (delim == '[') { + /* IPv6 address. The bracket should be the first + character in the host. */ + if (host != start || *host != 0) { + goto out; + } + + start = url; + delim = find_delim(&url, 0); + + if (delim != ']') { + goto out; + } + + parsed->host = start; + start = url; + delim = find_delim(&url, 1); + + /* Closing bracket should be the last character in the + host. */ + if (*start != 0) { + goto out; + } + } else { + /* If we haven't seen the host yet, this is it. */ + if (*host != 0) { + parsed->host = host; + } + } + + if (delim == ':') { + port = start = url; + delim = find_delim(&url, 1); + } + + if (port) { + char *end; + long portnum = strtol(port, &end, 10); + + if (port == end || *end != 0 || portnum < 0 || portnum > 65535) { + goto out; + } + + parsed->port = portnum; + } + + if (delim == '/') { + start = url; + delim = find_delim(&url, 1); + + if (delim != 0) { + goto out; + } + + parsed->vhost = start; + res = AMQP_STATUS_OK; + } else if (delim == 0) { + res = AMQP_STATUS_OK; + } + +/* Any other delimiter is bad, and we will return AMQP_STATUS_BAD_AMQP_URL. */ + +out: + return res; +} diff --git a/ext/librabbitmq/librabbitmq/codegen.py b/ext/librabbitmq/librabbitmq/codegen.py new file mode 100644 index 00000000..3ae24b63 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/codegen.py @@ -0,0 +1,785 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MIT +# +# Portions created by Alan Antonuk are Copyright (c) 2012-2013 +# Alan Antonuk. All Rights Reserved. +# +# Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. +# All Rights Reserved. +# +# Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 +# VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# ***** END LICENSE BLOCK ***** + +from __future__ import nested_scopes +from __future__ import division + +from amqp_codegen import * +import string +import re + + +class Emitter(object): + """An object the trivially emits generated code lines. + + This largely exists to be wrapped by more sophisticated emitter + classes. + """ + + def __init__(self, prefix): + self.prefix = prefix + + def emit(self, line): + """Emit a line of generated code.""" + print self.prefix + line + + +class BitDecoder(object): + """An emitter object that keeps track of the state involved in + decoding the AMQP bit type.""" + + def __init__(self, emitter): + self.emitter = emitter + self.bit = 0 + + def emit(self, line): + self.bit = 0 + self.emitter.emit(line) + + def decode_bit(self, lvalue): + """Generate code to decode a value of the AMQP bit type into + the given lvalue.""" + if self.bit == 0: + self.emitter.emit("if (!amqp_decode_8(encoded, &offset, &bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;") + + self.emitter.emit("%s = (bit_buffer & (1 << %d)) ? 1 : 0;" + % (lvalue, self.bit)) + self.bit += 1 + if self.bit == 8: + self.bit = 0 + + +class BitEncoder(object): + """An emitter object that keeps track of the state involved in + encoding the AMQP bit type.""" + + def __init__(self, emitter): + self.emitter = emitter + self.bit = 0 + + def flush(self): + """Flush the state associated with AMQP bit types.""" + if self.bit: + self.emitter.emit("if (!amqp_encode_8(encoded, &offset, bit_buffer)) return AMQP_STATUS_BAD_AMQP_DATA;") + self.bit = 0 + + def emit(self, line): + self.flush() + self.emitter.emit(line) + + def encode_bit(self, value): + """Generate code to encode a value of the AMQP bit type from + the given value.""" + if self.bit == 0: + self.emitter.emit("bit_buffer = 0;") + + self.emitter.emit("if (%s) bit_buffer |= (1 << %d);" + % (value, self.bit)) + self.bit += 1 + if self.bit == 8: + self.flush() + + +class SimpleType(object): + """A AMQP type that corresponds to a simple scalar C value of a + certain width.""" + + def __init__(self, bits): + self.bits = bits + self.ctype = "uint%d_t" % (bits,) + + def decode(self, emitter, lvalue): + emitter.emit("if (!amqp_decode_%d(encoded, &offset, &%s)) return AMQP_STATUS_BAD_AMQP_DATA;" % (self.bits, lvalue)) + + def encode(self, emitter, value): + emitter.emit("if (!amqp_encode_%d(encoded, &offset, %s)) return AMQP_STATUS_BAD_AMQP_DATA;" % (self.bits, value)) + + def literal(self, value): + return value + +class StrType(object): + """The AMQP shortstr or longstr types.""" + + def __init__(self, lenbits): + self.lenbits = lenbits + self.ctype = "amqp_bytes_t" + + def decode(self, emitter, lvalue): + emitter.emit("{") + emitter.emit(" uint%d_t len;" % (self.lenbits,)) + emitter.emit(" if (!amqp_decode_%d(encoded, &offset, &len)" % (self.lenbits,)) + emitter.emit(" || !amqp_decode_bytes(encoded, &offset, &%s, len))" % (lvalue,)) + emitter.emit(" return AMQP_STATUS_BAD_AMQP_DATA;") + emitter.emit("}") + + def encode(self, emitter, value): + emitter.emit("if (UINT%d_MAX < %s.len" % (self.lenbits, value)) + emitter.emit(" || !amqp_encode_%d(encoded, &offset, (uint%d_t)%s.len)" % + (self.lenbits, self.lenbits, value)) + emitter.emit(" || !amqp_encode_bytes(encoded, &offset, %s))" % (value,)) + emitter.emit(" return AMQP_STATUS_BAD_AMQP_DATA;") + + def literal(self, value): + if value != '': + raise NotImplementedError() + + return "amqp_empty_bytes" + +class BitType(object): + """The AMQP bit type.""" + + def __init__(self): + self.ctype = "amqp_boolean_t" + + def decode(self, emitter, lvalue): + emitter.decode_bit(lvalue) + + def encode(self, emitter, value): + emitter.encode_bit(value) + + def literal(self, value): + return {True: 1, False: 0}[value] + +class TableType(object): + """The AMQP table type.""" + + def __init__(self): + self.ctype = "amqp_table_t" + + def decode(self, emitter, lvalue): + emitter.emit("{") + emitter.emit(" int res = amqp_decode_table(encoded, pool, &(%s), &offset);" % (lvalue,)) + emitter.emit(" if (res < 0) return res;") + emitter.emit("}") + + def encode(self, emitter, value): + emitter.emit("{") + emitter.emit(" int res = amqp_encode_table(encoded, &(%s), &offset);" % (value,)) + emitter.emit(" if (res < 0) return res;") + emitter.emit("}") + + def literal(self, value): + raise NotImplementedError() + +types = { + 'octet': SimpleType(8), + 'short': SimpleType(16), + 'long': SimpleType(32), + 'longlong': SimpleType(64), + 'shortstr': StrType(8), + 'longstr': StrType(32), + 'bit': BitType(), + 'table': TableType(), + 'timestamp': SimpleType(64), +} + +def typeFor(spec, f): + """Get a representation of the AMQP type of a field.""" + return types[spec.resolveDomain(f.domain)] + +def c_ize(s): + s = s.replace('-', '_') + s = s.replace(' ', '_') + return s + +# When generating API functions corresponding to synchronous methods, +# we need some information that isn't in the protocol def: Some +# methods should not be exposed, indicated here by a False value. +# Some methods should be exposed but certain fields should not be +# exposed as parameters. +apiMethodInfo = { + "amqp_connection_start": False, # application code should not use this + "amqp_connection_secure": False, # application code should not use this + "amqp_connection_tune": False, # application code should not use this + "amqp_connection_open": False, # application code should not use this + "amqp_connection_close": False, # needs special handling + "amqp_channel_open": ["out_of_band"], + "amqp_channel_close": False, # needs special handling + "amqp_access_request": False, # huh? + "amqp_basic_get": False, # get-ok has content +} + +# When generating API functions corresponding to synchronous methods, +# some fields should be suppressed everywhere. This dict names those +# fields, and the fixed values to use for them. +apiMethodsSuppressArgs = {"ticket": 0, "nowait": False} + +AmqpMethod.defName = lambda m: cConstantName(c_ize(m.klass.name) + '_' + c_ize(m.name) + "_method") +AmqpMethod.fullName = lambda m: "amqp_%s_%s" % (c_ize(m.klass.name), c_ize(m.name)) +AmqpMethod.structName = lambda m: m.fullName() + "_t" + +AmqpClass.structName = lambda c: "amqp_" + c_ize(c.name) + "_properties_t" + +def methodApiPrototype(m): + fn = m.fullName() + info = apiMethodInfo.get(fn, []) + + docs = "/**\n * %s\n *\n" % (fn) + docs += " * @param [in] state connection state\n" + docs += " * @param [in] channel the channel to do the RPC on\n" + + args = [] + for f in m.arguments: + n = c_ize(f.name) + if n in apiMethodsSuppressArgs or n in info: + continue + + args.append(", ") + args.append(typeFor(m.klass.spec, f).ctype) + args.append(" ") + args.append(n) + docs += " * @param [in] %s %s\n" % (n, n) + + docs += " * @returns %s_ok_t\n" % (fn) + docs += " */\n" + + return "%sAMQP_PUBLIC_FUNCTION\n%s_ok_t *\nAMQP_CALL %s(amqp_connection_state_t state, amqp_channel_t channel%s)" % (docs, fn, fn, ''.join(args)) + +AmqpMethod.apiPrototype = methodApiPrototype + +def cConstantName(s): + return 'AMQP_' + '_'.join(re.split('[- ]', s.upper())) + +def cFlagName(c, f): + return cConstantName(c.name + '_' + f.name) + '_FLAG' + +def genErl(spec): + def fieldTempList(fields): + return '[' + ', '.join(['F' + str(f.index) for f in fields]) + ']' + + def fieldMapList(fields): + return ', '.join([c_ize(f.name) + " = F" + str(f.index) for f in fields]) + + def genLookupMethodName(m): + print ' case %s: return "%s";' % (m.defName(), m.defName()) + + def genDecodeMethodFields(m): + print " case %s: {" % (m.defName(),) + print " %s *m = (%s *) amqp_pool_alloc(pool, sizeof(%s));" % \ + (m.structName(), m.structName(), m.structName()) + print " if (m == NULL) { return AMQP_STATUS_NO_MEMORY; }" + + emitter = BitDecoder(Emitter(" ")) + for f in m.arguments: + typeFor(spec, f).decode(emitter, "m->"+c_ize(f.name)) + + print " *decoded = m;" + print " return 0;" + print " }" + + def genDecodeProperties(c): + print " case %d: {" % (c.index,) + print " %s *p = (%s *) amqp_pool_alloc(pool, sizeof(%s));" % \ + (c.structName(), c.structName(), c.structName()) + print " if (p == NULL) { return AMQP_STATUS_NO_MEMORY; }" + print " p->_flags = flags;" + + emitter = Emitter(" ") + for f in c.fields: + emitter.emit("if (flags & %s) {" % (cFlagName(c, f),)) + typeFor(spec, f).decode(emitter, "p->"+c_ize(f.name)) + emitter.emit("}") + + print " *decoded = p;" + print " return 0;" + print " }" + + def genEncodeMethodFields(m): + print " case %s: {" % (m.defName(),) + if m.arguments: + print " %s *m = (%s *) decoded;" % (m.structName(), m.structName()) + + emitter = BitEncoder(Emitter(" ")) + for f in m.arguments: + typeFor(spec, f).encode(emitter, "m->"+c_ize(f.name)) + emitter.flush() + + print " return (int)offset;" + print " }" + + def genEncodeProperties(c): + print " case %d: {" % (c.index,) + if c.fields: + print " %s *p = (%s *) decoded;" % (c.structName(), c.structName()) + + emitter = Emitter(" ") + for f in c.fields: + emitter.emit(" if (flags & %s) {" % (cFlagName(c, f),)) + typeFor(spec, f).encode(emitter, "p->"+c_ize(f.name)) + emitter.emit("}") + + print " return (int)offset;" + print " }" + + methods = spec.allMethods() + + print """/* Generated code. Do not edit. Edit and re-run codegen.py instead. + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp_private.h" +#include +#include +#include +#include +""" + + print """ +char const *amqp_constant_name(int constantNumber) { + switch (constantNumber) {""" + for (c,v,cls) in spec.constants: + print " case %s: return \"%s\";" % (cConstantName(c), cConstantName(c)) + print """ default: return "(unknown)"; + } +}""" + + print """ +amqp_boolean_t amqp_constant_is_hard_error(int constantNumber) { + switch (constantNumber) {""" + for (c,v,cls) in spec.constants: + if cls == 'hard-error': + print " case %s: return 1;" % (cConstantName(c),) + print """ default: return 0; + } +}""" + + print """ +char const *amqp_method_name(amqp_method_number_t methodNumber) { + switch (methodNumber) {""" + for m in methods: genLookupMethodName(m) + print """ default: return NULL; + } +}""" + + print """ +amqp_boolean_t amqp_method_has_content(amqp_method_number_t methodNumber) { + switch (methodNumber) {""" + for m in methods: + if m.hasContent: + print ' case %s: return 1;' % (m.defName()) + print """ default: return 0; + } +}""" + + print """ +int amqp_decode_method(amqp_method_number_t methodNumber, + amqp_pool_t *pool, + amqp_bytes_t encoded, + void **decoded) +{ + size_t offset = 0; + uint8_t bit_buffer; + + switch (methodNumber) {""" + for m in methods: genDecodeMethodFields(m) + print """ default: return AMQP_STATUS_UNKNOWN_METHOD; + } +}""" + + print """ +int amqp_decode_properties(uint16_t class_id, + amqp_pool_t *pool, + amqp_bytes_t encoded, + void **decoded) +{ + size_t offset = 0; + + amqp_flags_t flags = 0; + int flagword_index = 0; + uint16_t partial_flags; + + do { + if (!amqp_decode_16(encoded, &offset, &partial_flags)) + return AMQP_STATUS_BAD_AMQP_DATA; + flags |= (partial_flags << (flagword_index * 16)); + flagword_index++; + } while (partial_flags & 1); + + switch (class_id) {""" + for c in spec.allClasses(): genDecodeProperties(c) + print """ default: return AMQP_STATUS_UNKNOWN_CLASS; + } +}""" + + print """ +int amqp_encode_method(amqp_method_number_t methodNumber, + void *decoded, + amqp_bytes_t encoded) +{ + size_t offset = 0; + uint8_t bit_buffer; + + switch (methodNumber) {""" + for m in methods: genEncodeMethodFields(m) + print """ default: return AMQP_STATUS_UNKNOWN_METHOD; + } +}""" + + print """ +int amqp_encode_properties(uint16_t class_id, + void *decoded, + amqp_bytes_t encoded) +{ + size_t offset = 0; + + /* Cheat, and get the flags out generically, relying on the + similarity of structure between classes */ + amqp_flags_t flags = * (amqp_flags_t *) decoded; /* cheating! */ + + { + /* We take a copy of flags to avoid destroying it, as it is used + in the autogenerated code below. */ + amqp_flags_t remaining_flags = flags; + do { + amqp_flags_t remainder = remaining_flags >> 16; + uint16_t partial_flags = remaining_flags & 0xFFFE; + if (remainder != 0) { partial_flags |= 1; } + if (!amqp_encode_16(encoded, &offset, partial_flags)) + return AMQP_STATUS_BAD_AMQP_DATA; + remaining_flags = remainder; + } while (remaining_flags != 0); + } + + switch (class_id) {""" + for c in spec.allClasses(): genEncodeProperties(c) + print """ default: return AMQP_STATUS_UNKNOWN_CLASS; + } +}""" + + for m in methods: + if not m.isSynchronous: + continue + + info = apiMethodInfo.get(m.fullName(), []) + if info is False: + continue + + print + print m.apiPrototype() + print "{" + print " %s req;" % (m.structName(),) + + for f in m.arguments: + n = c_ize(f.name) + + val = apiMethodsSuppressArgs.get(n) + if val is None and n in info: + val = f.defaultvalue + + if val is None: + val = n + else: + val = typeFor(spec, f).literal(val) + + + print " req.%s = %s;" % (n, val) + + reply = cConstantName(c_ize(m.klass.name) + '_' + c_ize(m.name) + + "_ok_method") + print """ + return amqp_simple_rpc_decoded(state, channel, %s, %s, &req); +} +""" % (m.defName(), reply) + +def genHrl(spec): + def fieldDeclList(fields): + if fields: + return ''.join([" %s %s; /**< %s */\n" % (typeFor(spec, f).ctype, + c_ize(f.name), f.name) + for f in fields]) + else: + return " char dummy; /**< Dummy field to avoid empty struct */\n" + + def propDeclList(fields): + return ''.join([" %s %s;\n" % (typeFor(spec, f).ctype, c_ize(f.name)) + for f in fields + if spec.resolveDomain(f.domain) != 'bit']) + + methods = spec.allMethods() + + print """/* Generated code. Do not edit. Edit and re-run codegen.py instead. + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +/** @file amqp_framing.h */ +#ifndef AMQP_FRAMING_H +#define AMQP_FRAMING_H + +#include + +AMQP_BEGIN_DECLS +""" + print "#define AMQP_PROTOCOL_VERSION_MAJOR %d /**< AMQP protocol version major */" % (spec.major) + print "#define AMQP_PROTOCOL_VERSION_MINOR %d /**< AMQP protocol version minor */" % (spec.minor) + print "#define AMQP_PROTOCOL_VERSION_REVISION %d /**< AMQP protocol version revision */" % (spec.revision) + print "#define AMQP_PROTOCOL_PORT %d /**< Default AMQP Port */" % (spec.port) + + for (c,v,cls) in spec.constants: + print "#define %s %s /**< Constant: %s */" % (cConstantName(c), v, c) + print + + print """/* Function prototypes. */ + +/** + * Get constant name string from constant + * + * @param [in] constantNumber constant to get the name of + * @returns string describing the constant. String is managed by + * the library and should not be free()'d by the program + */ +AMQP_PUBLIC_FUNCTION +char const * +AMQP_CALL amqp_constant_name(int constantNumber); + +/** + * Checks to see if a constant is a hard error + * + * A hard error occurs when something severe enough + * happens that the connection must be closed. + * + * @param [in] constantNumber the error constant + * @returns true if its a hard error, false otherwise + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t +AMQP_CALL amqp_constant_is_hard_error(int constantNumber); + +/** + * Get method name string from method number + * + * @param [in] methodNumber the method number + * @returns method name string. String is managed by the library + * and should not be freed()'d by the program + */ +AMQP_PUBLIC_FUNCTION +char const * +AMQP_CALL amqp_method_name(amqp_method_number_t methodNumber); + +/** + * Check whether a method has content + * + * A method that has content will receive the method frame + * a properties frame, then 1 to N body frames + * + * @param [in] methodNumber the method number + * @returns true if method has content, false otherwise + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t +AMQP_CALL amqp_method_has_content(amqp_method_number_t methodNumber); + +/** + * Decodes a method from AMQP wireformat + * + * @param [in] methodNumber the method number for the decoded parameter + * @param [in] pool the memory pool to allocate the decoded method from + * @param [in] encoded the encoded byte string buffer + * @param [out] decoded pointer to the decoded method struct + * @returns 0 on success, an error code otherwise + */ +AMQP_PUBLIC_FUNCTION +int +AMQP_CALL amqp_decode_method(amqp_method_number_t methodNumber, + amqp_pool_t *pool, + amqp_bytes_t encoded, + void **decoded); + +/** + * Decodes a header frame properties structure from AMQP wireformat + * + * @param [in] class_id the class id for the decoded parameter + * @param [in] pool the memory pool to allocate the decoded properties from + * @param [in] encoded the encoded byte string buffer + * @param [out] decoded pointer to the decoded properties struct + * @returns 0 on success, an error code otherwise + */ +AMQP_PUBLIC_FUNCTION +int +AMQP_CALL amqp_decode_properties(uint16_t class_id, + amqp_pool_t *pool, + amqp_bytes_t encoded, + void **decoded); + +/** + * Encodes a method structure in AMQP wireformat + * + * @param [in] methodNumber the method number for the decoded parameter + * @param [in] decoded the method structure (e.g., amqp_connection_start_t) + * @param [in] encoded an allocated byte buffer for the encoded method + * structure to be written to. If the buffer isn't large enough + * to hold the encoded method, an error code will be returned. + * @returns 0 on success, an error code otherwise. + */ +AMQP_PUBLIC_FUNCTION +int +AMQP_CALL amqp_encode_method(amqp_method_number_t methodNumber, + void *decoded, + amqp_bytes_t encoded); + +/** + * Encodes a properties structure in AMQP wireformat + * + * @param [in] class_id the class id for the decoded parameter + * @param [in] decoded the properties structure (e.g., amqp_basic_properties_t) + * @param [in] encoded an allocated byte buffer for the encoded properties to written to. + * If the buffer isn't large enough to hold the encoded method, an + * an error code will be returned + * @returns 0 on success, an error code otherwise. + */ +AMQP_PUBLIC_FUNCTION +int +AMQP_CALL amqp_encode_properties(uint16_t class_id, + void *decoded, + amqp_bytes_t encoded); +""" + + print "/* Method field records. */\n" + for m in methods: + methodid = m.klass.index << 16 | m.index + print "#define %s ((amqp_method_number_t) 0x%.08X) /**< %s.%s method id @internal %d, %d; %d */" % \ + (m.defName(), + methodid, + m.klass.name, + m.name, + m.klass.index, + m.index, + methodid) + print "/** %s.%s method fields */\ntypedef struct %s_ {\n%s} %s;\n" % \ + (m.klass.name, m.name, m.structName(), fieldDeclList(m.arguments), m.structName()) + + print "/* Class property records. */" + for c in spec.allClasses(): + print "#define %s (0x%.04X) /**< %s class id @internal %d */" % \ + (cConstantName(c.name + "_class"), c.index, c.name, c.index) + index = 0 + for f in c.fields: + if index % 16 == 15: + index = index + 1 + shortnum = index // 16 + partialindex = 15 - (index % 16) + bitindex = shortnum * 16 + partialindex + print '#define %s (1 << %d) /**< %s.%s property flag */' % (cFlagName(c, f), bitindex, c.name, f.name) + index = index + 1 + print "/** %s class properties */\ntypedef struct %s_ {\n amqp_flags_t _flags; /**< bit-mask of set fields */\n%s} %s;\n" % \ + (c.name, + c.structName(), + fieldDeclList(c.fields), + c.structName()) + + print "/* API functions for methods */\n" + + for m in methods: + if m.isSynchronous and apiMethodInfo.get(m.fullName()) is not False: + print "%s;" % (m.apiPrototype(),) + + print """ +AMQP_END_DECLS + +#endif /* AMQP_FRAMING_H */""" + +def generateErl(specPath): + genErl(AmqpSpec(specPath)) + +def generateHrl(specPath): + genHrl(AmqpSpec(specPath)) + +if __name__ == "__main__": + do_main(generateHrl, generateErl) diff --git a/ext/librabbitmq/librabbitmq/unix/threads.h b/ext/librabbitmq/librabbitmq/unix/threads.h new file mode 100644 index 00000000..8a2623bb --- /dev/null +++ b/ext/librabbitmq/librabbitmq/unix/threads.h @@ -0,0 +1,28 @@ +/* + * Copyright 2012-2013 Michael Steinert + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AMQP_THREADS_H +#define AMQP_THREADS_H + +#include + +#endif /* AMQP_THREADS_H */ diff --git a/ext/librabbitmq/librabbitmq/win32/msinttypes/stdint.h b/ext/librabbitmq/librabbitmq/win32/msinttypes/stdint.h new file mode 100644 index 00000000..a7437be6 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/win32/msinttypes/stdint.h @@ -0,0 +1,245 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// 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. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +#define _W64 __w64 +#else +#define _W64 +#endif +#endif + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#else +typedef signed __int8 int8_t; +typedef signed __int16 int16_t; +typedef signed __int32 int32_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ +typedef signed __int64 intptr_t; +typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ +typedef _W64 signed int intptr_t; +typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || \ + defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and + // footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +#define PTRDIFF_MIN _I64_MIN +#define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +#define PTRDIFF_MIN _I32_MIN +#define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +#ifdef _WIN64 // [ +#define SIZE_MAX _UI64_MAX +#else // _WIN64 ][ +#define SIZE_MAX _UI32_MAX +#endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +#define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +#define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || \ + defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_STDINT_H_ ] diff --git a/ext/librabbitmq/librabbitmq/win32/threads.c b/ext/librabbitmq/librabbitmq/win32/threads.c new file mode 100644 index 00000000..cce31586 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/win32/threads.c @@ -0,0 +1,56 @@ +/* + * Copyright 2012-2013 Michael Steinert + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "threads.h" + +#include + +DWORD pthread_self(void) { return GetCurrentThreadId(); } + +int pthread_mutex_init(pthread_mutex_t *mutex, void *attr) { + if (!mutex) { + return 1; + } + InitializeSRWLock(mutex); + return 0; +} + +int pthread_mutex_lock(pthread_mutex_t *mutex) { + if (!mutex) { + return 1; + } + AcquireSRWLockExclusive(mutex); + return 0; +} + +int pthread_mutex_unlock(pthread_mutex_t *mutex) { + if (!mutex) { + return 1; + } + ReleaseSRWLockExclusive(mutex); + return 0; +} + +int pthread_mutex_destroy(pthread_mutex_t *mutex) { + /* SRW's do not require destruction. */ + return 0; +} diff --git a/ext/librabbitmq/librabbitmq/win32/threads.h b/ext/librabbitmq/librabbitmq/win32/threads.h new file mode 100644 index 00000000..69371f39 --- /dev/null +++ b/ext/librabbitmq/librabbitmq/win32/threads.h @@ -0,0 +1,52 @@ +/* + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk. + * All Rights Reserved. + * + * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael + * Steinert. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AMQP_THREAD_H +#define AMQP_THREAD_H + +#if !defined(WINVER) || defined(__MINGW32__) || defined(__MINGW64__) +#ifdef WINVER +#undef WINVER +#endif +/* Windows Vista or newer */ +#define WINVER 0x0600 +#endif +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include + +typedef SRWLOCK pthread_mutex_t; +#define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT; + +DWORD pthread_self(void); + +int pthread_mutex_init(pthread_mutex_t *, void *attr); +int pthread_mutex_lock(pthread_mutex_t *); +int pthread_mutex_unlock(pthread_mutex_t *); +int pthread_mutex_destroy(pthread_mutex_t *); + +#endif /* AMQP_THREAD_H */ diff --git a/ext/librabbitmq/tests/CMakeLists.txt b/ext/librabbitmq/tests/CMakeLists.txt new file mode 100644 index 00000000..cf042b04 --- /dev/null +++ b/ext/librabbitmq/tests/CMakeLists.txt @@ -0,0 +1,47 @@ +include_directories(${LIBRABBITMQ_INCLUDE_DIRS}) + +if (MSVC) + # No version of MSVC has inttypes.h, this uses the msinttypes + # Note this includes stdint.h which is either in + # ../librabbitmq/win32/msinttypes or in a standard location + include_directories(win32/msinttypes) +endif (MSVC) + +add_definitions(-DHAVE_CONFIG_H) +add_definitions(-DAMQP_STATIC) + +add_executable(test_parse_url test_parse_url.c) +target_link_libraries(test_parse_url rabbitmq-static) +add_test(parse_url test_parse_url) + +add_executable(test_tables test_tables.c) +target_link_libraries(test_tables rabbitmq-static) +add_test(tables test_tables) +configure_file(test_tables.expected ${CMAKE_CURRENT_BINARY_DIR}/tests/test_tables.expected COPYONLY) + +add_executable(test_hostcheck + test_hostcheck.c + ../librabbitmq/amqp_hostcheck.c) +add_test(hostcheck test_hostcheck) + +add_executable(test_status_enum + test_status_enum.c) +target_link_libraries(test_status_enum rabbitmq-static) +add_test(status_enum test_status_enum) + +add_executable(test_basic + test_basic.c) +target_link_libraries(test_basic rabbitmq-static) + +if (NOT APPLE) + add_test(basic test_basic) +endif() + +add_executable(test_sasl_mechanism test_sasl_mechanism.c) +target_link_libraries(test_sasl_mechanism rabbitmq-static) +add_test(sasl_mechanism test_sasl_mechanism) + +add_executable(test_merge_capabilities test_merge_capabilities.c) +target_link_libraries(test_merge_capabilities rabbitmq-static) +add_test(merge_capabilities test_merge_capabilities) + diff --git a/ext/librabbitmq/tests/test_basic.c b/ext/librabbitmq/tests/test_basic.c new file mode 100644 index 00000000..a7de0446 --- /dev/null +++ b/ext/librabbitmq/tests/test_basic.c @@ -0,0 +1,207 @@ +/* + * Copyright 2017 Simon Giesecke + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "amqp.h" +#include "amqp_tcp_socket.h" +#include "amqp_time.h" + +#include +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif + +#ifdef NDEBUG +#undef NDEBUG +#endif +#include + +static const int fixed_channel_id = 1; +static const char test_queue_name[] = "test_queue"; + +amqp_connection_state_t setup_connection_and_channel(void) { + amqp_connection_state_t connection_state_ = amqp_new_connection(); + + amqp_socket_t *socket = amqp_tcp_socket_new(connection_state_); + assert(socket); + + int rc = amqp_socket_open(socket, "localhost", AMQP_PROTOCOL_PORT); + assert(rc == AMQP_STATUS_OK); + + amqp_rpc_reply_t rpc_reply = amqp_login( + connection_state_, "/", 1, AMQP_DEFAULT_FRAME_SIZE, + AMQP_DEFAULT_HEARTBEAT, AMQP_SASL_METHOD_PLAIN, "guest", "guest"); + assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL); + + amqp_channel_open_ok_t *res = + amqp_channel_open(connection_state_, fixed_channel_id); + assert(res != NULL); + + return connection_state_; +} + +void close_and_destroy_connection(amqp_connection_state_t connection_state_) { + amqp_rpc_reply_t rpc_reply = + amqp_connection_close(connection_state_, AMQP_REPLY_SUCCESS); + assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL); + + int rc = amqp_destroy_connection(connection_state_); + assert(rc == AMQP_STATUS_OK); +} + +void basic_publish(amqp_connection_state_t connectionState_, + const char *message_) { + amqp_bytes_t message_bytes = amqp_cstring_bytes(message_); + + amqp_basic_properties_t properties; + properties._flags = 0; + + properties._flags |= AMQP_BASIC_DELIVERY_MODE_FLAG; + properties.delivery_mode = AMQP_DELIVERY_NONPERSISTENT; + + int retval = amqp_basic_publish( + connectionState_, fixed_channel_id, amqp_cstring_bytes(""), + amqp_cstring_bytes(test_queue_name), + /* mandatory=*/1, + /* immediate=*/0, /* RabbitMQ 3.x does not support the "immediate" flag + according to + https://www.rabbitmq.com/specification.html */ + &properties, message_bytes); + + assert(retval == 0); +} + +void queue_declare(amqp_connection_state_t connection_state_, + const char *queue_name_) { + amqp_queue_declare_ok_t *res = amqp_queue_declare( + connection_state_, fixed_channel_id, amqp_cstring_bytes(queue_name_), + /*passive*/ 0, + /*durable*/ 0, + /*exclusive*/ 0, + /*auto_delete*/ 1, amqp_empty_table); + assert(res != NULL); +} + +char *basic_get(amqp_connection_state_t connection_state_, + const char *queue_name_, uint64_t *out_body_size_) { + amqp_rpc_reply_t rpc_reply; + amqp_time_t deadline; + struct timeval timeout = {5, 0}; + int time_rc = amqp_time_from_now(&deadline, &timeout); + assert(time_rc == AMQP_STATUS_OK); + + do { + rpc_reply = amqp_basic_get(connection_state_, fixed_channel_id, + amqp_cstring_bytes(queue_name_), /*no_ack*/ 1); + } while (rpc_reply.reply_type == AMQP_RESPONSE_NORMAL && + rpc_reply.reply.id == AMQP_BASIC_GET_EMPTY_METHOD && + amqp_time_has_past(deadline) == AMQP_STATUS_OK); + + assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL); + assert(rpc_reply.reply.id == AMQP_BASIC_GET_OK_METHOD); + + amqp_message_t message; + rpc_reply = + amqp_read_message(connection_state_, fixed_channel_id, &message, 0); + assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL); + + char *body = malloc(message.body.len); + memcpy(body, message.body.bytes, message.body.len); + *out_body_size_ = message.body.len; + amqp_destroy_message(&message); + + return body; +} + +void publish_and_basic_get_message(const char *msg_to_publish) { + amqp_connection_state_t connection_state = setup_connection_and_channel(); + + queue_declare(connection_state, test_queue_name); + basic_publish(connection_state, msg_to_publish); + + uint64_t body_size; + char *msg = basic_get(connection_state, test_queue_name, &body_size); + + assert(body_size == strlen(msg_to_publish)); + assert(strncmp(msg_to_publish, msg, body_size) == 0); + free(msg); + + close_and_destroy_connection(connection_state); +} + +char *consume_message(amqp_connection_state_t connection_state_, + const char *queue_name_, uint64_t *out_body_size_) { + amqp_basic_consume_ok_t *result = + amqp_basic_consume(connection_state_, fixed_channel_id, + amqp_cstring_bytes(queue_name_), amqp_empty_bytes, + /*no_local*/ 0, + /*no_ack*/ 1, + /*exclusive*/ 0, amqp_empty_table); + assert(result != NULL); + + amqp_envelope_t envelope; + struct timeval timeout = {5, 0}; + amqp_rpc_reply_t rpc_reply = + amqp_consume_message(connection_state_, &envelope, &timeout, 0); + assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL); + + *out_body_size_ = envelope.message.body.len; + char *body = malloc(*out_body_size_); + if (*out_body_size_) { + memcpy(body, envelope.message.body.bytes, *out_body_size_); + } + + amqp_destroy_envelope(&envelope); + return body; +} + +void publish_and_consume_message(const char *msg_to_publish) { + amqp_connection_state_t connection_state = setup_connection_and_channel(); + + queue_declare(connection_state, test_queue_name); + basic_publish(connection_state, msg_to_publish); + + uint64_t body_size; + char *msg = consume_message(connection_state, test_queue_name, &body_size); + + assert(body_size == strlen(msg_to_publish)); + assert(strncmp(msg_to_publish, msg, body_size) == 0); + free(msg); + + close_and_destroy_connection(connection_state); +} + +int main(void) { + publish_and_basic_get_message(""); + publish_and_basic_get_message("TEST"); + + publish_and_consume_message(""); + publish_and_consume_message("TEST"); + + return 0; +} diff --git a/ext/librabbitmq/tests/test_hostcheck.c b/ext/librabbitmq/tests/test_hostcheck.c new file mode 100644 index 00000000..24c0d6c2 --- /dev/null +++ b/ext/librabbitmq/tests/test_hostcheck.c @@ -0,0 +1,71 @@ +/* + * Copyright 2014 Michael Steinert + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp_hostcheck.h" + +#include +#include + +static void hostcheck_success(const char *match_pattern, const char *url) { + int ok; + + ok = amqp_hostcheck(match_pattern, url); + if (!ok) { + fprintf(stderr, "Expected hostname check to pass, but didn't: %s (%s)\n", + url, match_pattern); + abort(); + } + + fprintf(stdout, "ok: [success] %s, %s\n", url, match_pattern); +} + +static void hostcheck_fail(const char *match_pattern, const char *url) { + int ok; + + ok = amqp_hostcheck(match_pattern, url); + if (ok) { + fprintf(stderr, "Expected hostname check to fail, but didn't: %s (%s)\n", + url, match_pattern); + abort(); + } + + fprintf(stdout, "ok: [fail] %s, %s\n", url, match_pattern); +} + +int main(void) { + hostcheck_success("www.rabbitmq.com", "www.rabbitmq.com"); + hostcheck_success("www.rabbitmq.com", "wWw.RaBbItMq.CoM"); + hostcheck_success("*.rabbitmq.com", "wWw.RaBbItMq.CoM"); + hostcheck_fail("rabbitmq.com", "www.rabbitmq.com"); + hostcheck_success("*.rabbitmq.com", "www.rabbitmq.com"); + hostcheck_fail("*.com", "www.rabbitmq.com"); + hostcheck_fail("*.rabbitmq.com", "long.url.rabbitmq.com"); + hostcheck_success("*.url.rabbitmq.com", "long.url.rabbitmq.com"); + + return 0; +} diff --git a/ext/librabbitmq/tests/test_merge_capabilities.c b/ext/librabbitmq/tests/test_merge_capabilities.c new file mode 100644 index 00000000..d62fcd31 --- /dev/null +++ b/ext/librabbitmq/tests/test_merge_capabilities.c @@ -0,0 +1,203 @@ +/* + * Copyright 2015 Alan Antonuk. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "amqp_socket.h" +#include "amqp_table.h" + +#include +#include + +static int compare_bytes(amqp_bytes_t l, amqp_bytes_t r); +static int compare_amqp_table_entry(amqp_table_entry_t result, + amqp_table_entry_t expect); +static int compare_field_value(amqp_field_value_t result, + amqp_field_value_t expect); +static int compare_amqp_table(amqp_table_t* result, amqp_table_t* expect); + +static int compare_bytes(amqp_bytes_t l, amqp_bytes_t r) { + if (l.len == r.len && + (l.bytes == r.bytes || 0 == memcmp(l.bytes, r.bytes, l.len))) { + return 1; + } + return 0; +} + +static int compare_amqp_table_entry(amqp_table_entry_t result, + amqp_table_entry_t expect) { + if (!compare_bytes(result.key, expect.key)) { + return 0; + } + return compare_field_value(result.value, expect.value); +} + +static int compare_field_value(amqp_field_value_t result, + amqp_field_value_t expect) { + if (result.kind != expect.kind) { + return 0; + } + switch (result.kind) { + case AMQP_FIELD_KIND_BOOLEAN: + return result.value.boolean == expect.value.boolean; + case AMQP_FIELD_KIND_I8: + return result.value.i8 == expect.value.i8; + case AMQP_FIELD_KIND_U8: + return result.value.u8 == expect.value.u8; + case AMQP_FIELD_KIND_I16: + return result.value.i16 == expect.value.i16; + case AMQP_FIELD_KIND_U16: + return result.value.u16 == expect.value.u16; + case AMQP_FIELD_KIND_I32: + return result.value.i32 == expect.value.i32; + case AMQP_FIELD_KIND_U32: + return result.value.u32 == expect.value.u32; + case AMQP_FIELD_KIND_I64: + return result.value.i64 == expect.value.i64; + case AMQP_FIELD_KIND_U64: + case AMQP_FIELD_KIND_TIMESTAMP: + return result.value.u64 == expect.value.u64; + case AMQP_FIELD_KIND_F32: + return result.value.f32 == expect.value.f32; + case AMQP_FIELD_KIND_F64: + return result.value.f64 == expect.value.f64; + case AMQP_FIELD_KIND_DECIMAL: + return !memcmp(&result.value.decimal, &expect.value.decimal, + sizeof(expect.value.decimal)); + case AMQP_FIELD_KIND_UTF8: + case AMQP_FIELD_KIND_BYTES: + return compare_bytes(result.value.bytes, expect.value.bytes); + case AMQP_FIELD_KIND_ARRAY: { + int i; + if (result.value.array.num_entries != expect.value.array.num_entries) { + return 0; + } + for (i = 0; i < result.value.array.num_entries; ++i) { + if (!compare_field_value(result.value.array.entries[i], + expect.value.array.entries[i])) { + return 0; + } + } + return 1; + } + case AMQP_FIELD_KIND_TABLE: + return compare_amqp_table(&result.value.table, &expect.value.table); + case AMQP_FIELD_KIND_VOID: + return 1; + } + return 1; +} + +static int compare_amqp_table(amqp_table_t* result, amqp_table_t* expect) { + int i; + + if (result->num_entries != expect->num_entries) { + return 0; + } + + for (i = 0; i < expect->num_entries; ++i) { + if (!compare_amqp_table_entry(expect->entries[i], result->entries[i])) { + return 0; + } + } + return 1; +} + +static void test_merge_capabilities(amqp_table_t* base, amqp_table_t* add, + amqp_table_t* expect) { + amqp_pool_t pool; + amqp_table_t result; + int res; + init_amqp_pool(&pool, 4096); + + res = amqp_merge_capabilities(base, add, &result, &pool); + if (AMQP_STATUS_OK != res) { + fprintf(stderr, "amqp_merge_capabilities returned !ok: %d\n", res); + abort(); + } + + if (!compare_amqp_table(&result, expect)) { + fprintf(stderr, "amqp_merge_capabilities incorrect result.\n"); + abort(); + } + empty_amqp_pool(&pool); + return; +} + +int main(void) { + { + amqp_table_t sub_base; + amqp_table_t sub_add; + amqp_table_t sub_expect; + amqp_table_t base; + amqp_table_t add; + amqp_table_t expect; + + amqp_table_entry_t sub_base_entries[1]; + amqp_table_entry_t sub_add_entries[2]; + amqp_table_entry_t sub_expect_entries[2]; + + amqp_table_entry_t base_entries[3]; + amqp_table_entry_t add_entries[3]; + amqp_table_entry_t expect_entries[4]; + + sub_base_entries[0] = amqp_table_construct_utf8_entry("foo", "bar"); + sub_base.num_entries = + sizeof(sub_base_entries) / sizeof(amqp_table_entry_t); + sub_base.entries = sub_base_entries; + + sub_add_entries[0] = amqp_table_construct_utf8_entry("something", "else"); + sub_add_entries[1] = amqp_table_construct_utf8_entry("foo", "baz"); + sub_add.num_entries = sizeof(sub_add_entries) / sizeof(amqp_table_entry_t); + sub_add.entries = sub_add_entries; + + sub_expect_entries[0] = amqp_table_construct_utf8_entry("foo", "baz"); + sub_expect_entries[1] = + amqp_table_construct_utf8_entry("something", "else"); + sub_expect.num_entries = + sizeof(sub_expect_entries) / sizeof(amqp_table_entry_t); + sub_expect.entries = sub_expect_entries; + + base_entries[0] = amqp_table_construct_utf8_entry("product", "1.0"); + base_entries[1] = amqp_table_construct_utf8_entry("nooverride", "yeah"); + base_entries[2] = amqp_table_construct_table_entry("props", &sub_base); + base.num_entries = sizeof(base_entries) / sizeof(amqp_table_entry_t); + base.entries = base_entries; + + add_entries[0] = amqp_table_construct_bool_entry("bool_entry", 1); + add_entries[1] = amqp_table_construct_utf8_entry("product", "2.0"); + add_entries[2] = amqp_table_construct_table_entry("props", &sub_add); + add.num_entries = sizeof(add_entries) / sizeof(amqp_table_entry_t); + add.entries = add_entries; + + expect_entries[0] = amqp_table_construct_utf8_entry("product", "2.0"), + expect_entries[1] = amqp_table_construct_utf8_entry("nooverride", "yeah"), + expect_entries[2] = amqp_table_construct_table_entry("props", &sub_expect); + expect_entries[3] = amqp_table_construct_bool_entry("bool_entry", 1); + expect.num_entries = sizeof(expect_entries) / sizeof(amqp_table_entry_t); + expect.entries = expect_entries; + + test_merge_capabilities(&base, &add, &expect); + } + fprintf(stderr, "ok\n"); + return 0; +} diff --git a/ext/librabbitmq/tests/test_parse_url.c b/ext/librabbitmq/tests/test_parse_url.c new file mode 100644 index 00000000..9cdc87c1 --- /dev/null +++ b/ext/librabbitmq/tests/test_parse_url.c @@ -0,0 +1,220 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include "config.h" + +#ifdef _MSC_VER +/* MSVC complains about strdup being deprecated in favor of _strdup */ +#define _CRT_NONSTDC_NO_DEPRECATE +#endif + +#include +#include +#include + +#include + +#include + +static void match_string(const char *what, const char *expect, + const char *got) { + if (strcmp(got, expect)) { + fprintf(stderr, "Expected %s '%s', got '%s'\n", what, expect, got); + abort(); + } +} + +static void match_int(const char *what, int expect, int got) { + if (got != expect) { + fprintf(stderr, "Expected %s '%d', got '%d'\n", what, expect, got); + abort(); + } +} + +static void parse_success(const char *url, const char *user, + const char *password, const char *host, int port, + const char *vhost) { + char *s = strdup(url); + struct amqp_connection_info ci; + int res; + + res = amqp_parse_url(s, &ci); + if (res) { + fprintf(stderr, "Expected to successfully parse URL, but didn't: %s (%s)\n", + url, amqp_error_string2(res)); + abort(); + } + + match_string("user", user, ci.user); + match_string("password", password, ci.password); + match_string("host", host, ci.host); + match_int("port", port, ci.port); + match_string("vhost", vhost, ci.vhost); + + free(s); +} + +static void parse_fail(const char *url) { + char *s = strdup(url); + struct amqp_connection_info ci; + + amqp_default_connection_info(&ci); + if (amqp_parse_url(s, &ci) >= 0) { + fprintf(stderr, "Expected to fail parsing URL, but didn't: %s\n", url); + abort(); + } + + free(s); +} + +int main(void) { + /* From the spec */ + parse_success("amqp://user:pass@host:10000/vhost", "user", "pass", "host", + 10000, "vhost"); + parse_success("amqps://user:pass@host:10000/vhost", "user", "pass", "host", + 10000, "vhost"); + + parse_success("amqp://user%61:%61pass@ho%61st:10000/v%2fhost", "usera", + "apass", "hoast", 10000, "v/host"); + parse_success("amqps://user%61:%61pass@ho%61st:10000/v%2fhost", "usera", + "apass", "hoast", 10000, "v/host"); + + parse_success("amqp://", "guest", "guest", "localhost", 5672, "/"); + parse_success("amqps://", "guest", "guest", "localhost", 5671, "/"); + + parse_success("amqp://:@/", "", "", "localhost", 5672, ""); + parse_success("amqps://:@/", "", "", "localhost", 5671, ""); + + parse_success("amqp://user@", "user", "guest", "localhost", 5672, "/"); + parse_success("amqps://user@", "user", "guest", "localhost", 5671, "/"); + + parse_success("amqp://user:pass@", "user", "pass", "localhost", 5672, "/"); + parse_success("amqps://user:pass@", "user", "pass", "localhost", 5671, "/"); + + parse_success("amqp://host", "guest", "guest", "host", 5672, "/"); + parse_success("amqps://host", "guest", "guest", "host", 5671, "/"); + + parse_success("amqp://:10000", "guest", "guest", "localhost", 10000, "/"); + parse_success("amqps://:10000", "guest", "guest", "localhost", 10000, "/"); + + parse_success("amqp:///vhost", "guest", "guest", "localhost", 5672, "vhost"); + parse_success("amqps:///vhost", "guest", "guest", "localhost", 5671, "vhost"); + + parse_success("amqp://host/", "guest", "guest", "host", 5672, ""); + parse_success("amqps://host/", "guest", "guest", "host", 5671, ""); + + parse_success("amqp://host/%2f", "guest", "guest", "host", 5672, "/"); + parse_success("amqps://host/%2f", "guest", "guest", "host", 5671, "/"); + + parse_success("amqp://[::1]", "guest", "guest", "::1", 5672, "/"); + parse_success("amqps://[::1]", "guest", "guest", "::1", 5671, "/"); + + /* Various other success cases */ + parse_success("amqp://host:100", "guest", "guest", "host", 100, "/"); + parse_success("amqps://host:100", "guest", "guest", "host", 100, "/"); + + parse_success("amqp://[::1]:100", "guest", "guest", "::1", 100, "/"); + parse_success("amqps://[::1]:100", "guest", "guest", "::1", 100, "/"); + + parse_success("amqp://host/blah", "guest", "guest", "host", 5672, "blah"); + parse_success("amqps://host/blah", "guest", "guest", "host", 5671, "blah"); + + parse_success("amqp://host:100/blah", "guest", "guest", "host", 100, "blah"); + parse_success("amqps://host:100/blah", "guest", "guest", "host", 100, "blah"); + + parse_success("amqp://:100/blah", "guest", "guest", "localhost", 100, "blah"); + parse_success("amqps://:100/blah", "guest", "guest", "localhost", 100, + "blah"); + + parse_success("amqp://[::1]/blah", "guest", "guest", "::1", 5672, "blah"); + parse_success("amqps://[::1]/blah", "guest", "guest", "::1", 5671, "blah"); + + parse_success("amqp://[::1]:100/blah", "guest", "guest", "::1", 100, "blah"); + parse_success("amqps://[::1]:100/blah", "guest", "guest", "::1", 100, "blah"); + + parse_success("amqp://user:pass@host", "user", "pass", "host", 5672, "/"); + parse_success("amqps://user:pass@host", "user", "pass", "host", 5671, "/"); + + parse_success("amqp://user:pass@host:100", "user", "pass", "host", 100, "/"); + parse_success("amqps://user:pass@host:100", "user", "pass", "host", 100, "/"); + + parse_success("amqp://user:pass@:100", "user", "pass", "localhost", 100, "/"); + parse_success("amqps://user:pass@:100", "user", "pass", "localhost", 100, + "/"); + + parse_success("amqp://user:pass@[::1]", "user", "pass", "::1", 5672, "/"); + parse_success("amqps://user:pass@[::1]", "user", "pass", "::1", 5671, "/"); + + parse_success("amqp://user:pass@[::1]:100", "user", "pass", "::1", 100, "/"); + parse_success("amqps://user:pass@[::1]:100", "user", "pass", "::1", 100, "/"); + + /* Various failure cases */ + parse_fail("http://www.rabbitmq.com"); + + parse_fail("amqp://foo:bar:baz"); + parse_fail("amqps://foo:bar:baz"); + + parse_fail("amqp://foo[::1]"); + parse_fail("amqps://foo[::1]"); + + parse_fail("amqp://foo[::1]"); + parse_fail("amqps://foo[::1]"); + + parse_fail("amqp://foo:[::1]"); + parse_fail("amqps://foo:[::1]"); + + parse_fail("amqp://[::1]foo"); + parse_fail("amqps://[::1]foo"); + + parse_fail("amqp://foo:1000xyz"); + parse_fail("amqps://foo:1000xyz"); + + parse_fail("amqp://foo:1000000"); + parse_fail("amqps://foo:1000000"); + + parse_fail("amqp://foo/bar/baz"); + parse_fail("amqps://foo/bar/baz"); + + parse_fail("amqp://foo%1"); + parse_fail("amqps://foo%1"); + + parse_fail("amqp://foo%1x"); + parse_fail("amqps://foo%1x"); + + parse_fail("amqp://foo%xy"); + parse_fail("amqps://foo%xy"); + + return 0; +} diff --git a/ext/librabbitmq/tests/test_sasl_mechanism.c b/ext/librabbitmq/tests/test_sasl_mechanism.c new file mode 100644 index 00000000..78482198 --- /dev/null +++ b/ext/librabbitmq/tests/test_sasl_mechanism.c @@ -0,0 +1,70 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include + +static void parse_success(amqp_bytes_t mechanisms, + amqp_sasl_method_enum method) { + if (!sasl_mechanism_in_list(mechanisms, method)) { + fprintf(stderr, "Expected to find mechanism in list, but didn't: %s\n", + (char *)mechanisms.bytes); + abort(); + } +} + +static void parse_fail(amqp_bytes_t mechanisms, amqp_sasl_method_enum method) { + if (sasl_mechanism_in_list(mechanisms, method)) { + fprintf(stderr, + "Expected the mechanism not on the list, but it was present: %s\n", + (char *)mechanisms.bytes); + abort(); + } +} + +int main(void) { + parse_success(amqp_cstring_bytes("DIGEST-MD5 CRAM-MD5 LOGIN PLAIN"), + AMQP_SASL_METHOD_PLAIN); + parse_fail(amqp_cstring_bytes("DIGEST-MD5 CRAM-MD5 LOGIN PLAIN"), + AMQP_SASL_METHOD_EXTERNAL); + parse_success(amqp_cstring_bytes("DIGEST-MD5 CRAM-MD5 EXTERNAL"), + AMQP_SASL_METHOD_EXTERNAL); + parse_fail(amqp_cstring_bytes("DIGEST-MD5 CRAM-MD5 EXTERNAL"), + AMQP_SASL_METHOD_PLAIN); + return 0; +} diff --git a/ext/librabbitmq/tests/test_status_enum.c b/ext/librabbitmq/tests/test_status_enum.c new file mode 100644 index 00000000..2f2dbd7f --- /dev/null +++ b/ext/librabbitmq/tests/test_status_enum.c @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Alan Antonuk + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "amqp.h" + +#include +#include +#include + +static void check_errorstrings(amqp_status_enum start, amqp_status_enum end) { + int i; + for (i = start; i > end; --i) { + const char* err = amqp_error_string2(i); + if (0 == strcmp(err, "(unknown error)")) { + printf("amqp_status_enum value %s%X", i < 0 ? "-" : "", (unsigned)i); + abort(); + } + } +} + +int main(void) { + check_errorstrings(AMQP_STATUS_OK, _AMQP_STATUS_NEXT_VALUE); + check_errorstrings(AMQP_STATUS_TCP_ERROR, _AMQP_STATUS_TCP_NEXT_VALUE); + check_errorstrings(AMQP_STATUS_SSL_ERROR, _AMQP_STATUS_SSL_NEXT_VALUE); + + return 0; +} diff --git a/ext/librabbitmq/tests/test_tables.c b/ext/librabbitmq/tests/test_tables.c new file mode 100644 index 00000000..89ece6b4 --- /dev/null +++ b/ext/librabbitmq/tests/test_tables.c @@ -0,0 +1,466 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef _MSC_VER +#define _USE_MATH_DEFINES +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +void die(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + abort(); +} + +static void dump_indent(int indent, FILE *out) { + int i; + + for (i = 0; i < indent; i++) { + fputc(' ', out); + } +} + +static void dump_value(int indent, amqp_field_value_t v, FILE *out) { + int i; + + dump_indent(indent, out); + fputc(v.kind, out); + + switch (v.kind) { + case AMQP_FIELD_KIND_BOOLEAN: + fputs(v.value.boolean ? " true\n" : " false\n", out); + break; + + case AMQP_FIELD_KIND_I8: + fprintf(out, " %" PRId8 "\n", v.value.i8); + break; + + case AMQP_FIELD_KIND_U8: + fprintf(out, " %" PRIu8 "\n", v.value.u8); + break; + + case AMQP_FIELD_KIND_I16: + fprintf(out, " %" PRId16 "\n", v.value.i16); + break; + + case AMQP_FIELD_KIND_U16: + fprintf(out, " %" PRIu16 "\n", v.value.u16); + break; + + case AMQP_FIELD_KIND_I32: + fprintf(out, " %" PRId32 "\n", v.value.i32); + break; + + case AMQP_FIELD_KIND_U32: + fprintf(out, " %" PRIu32 "\n", v.value.u32); + break; + + case AMQP_FIELD_KIND_I64: + fprintf(out, " %" PRId64 "\n", v.value.i64); + break; + + case AMQP_FIELD_KIND_F32: + fprintf(out, " %g\n", (double)v.value.f32); + break; + + case AMQP_FIELD_KIND_F64: + fprintf(out, " %g\n", v.value.f64); + break; + + case AMQP_FIELD_KIND_DECIMAL: + fprintf(out, " %u:::%u\n", v.value.decimal.decimals, + v.value.decimal.value); + break; + + case AMQP_FIELD_KIND_UTF8: + fprintf(out, " %.*s\n", (int)v.value.bytes.len, + (char *)v.value.bytes.bytes); + break; + + case AMQP_FIELD_KIND_BYTES: + fputc(' ', out); + for (i = 0; i < (int)v.value.bytes.len; i++) { + fprintf(out, "%02x", ((char *)v.value.bytes.bytes)[i]); + } + + fputc('\n', out); + break; + + case AMQP_FIELD_KIND_ARRAY: + fputc('\n', out); + for (i = 0; i < v.value.array.num_entries; i++) { + dump_value(indent + 2, v.value.array.entries[i], out); + } + + break; + + case AMQP_FIELD_KIND_TIMESTAMP: + fprintf(out, " %" PRIu64 "\n", v.value.u64); + break; + + case AMQP_FIELD_KIND_TABLE: + fputc('\n', out); + for (i = 0; i < v.value.table.num_entries; i++) { + dump_indent(indent + 2, out); + fprintf(out, "%.*s ->\n", (int)v.value.table.entries[i].key.len, + (char *)v.value.table.entries[i].key.bytes); + dump_value(indent + 4, v.value.table.entries[i].value, out); + } + + break; + + case AMQP_FIELD_KIND_VOID: + fputc('\n', out); + break; + + default: + fprintf(out, "???\n"); + break; + } +} + +static void test_dump_value(FILE *out) { + amqp_table_entry_t entries[8]; + amqp_table_t table; + amqp_field_value_t val; + + entries[0].key = amqp_cstring_bytes("zebra"); + entries[0].value.kind = AMQP_FIELD_KIND_UTF8; + entries[0].value.value.bytes = amqp_cstring_bytes("last"); + + entries[1].key = amqp_cstring_bytes("aardvark"); + entries[1].value.kind = AMQP_FIELD_KIND_UTF8; + entries[1].value.value.bytes = amqp_cstring_bytes("first"); + + entries[2].key = amqp_cstring_bytes("middle"); + entries[2].value.kind = AMQP_FIELD_KIND_UTF8; + entries[2].value.value.bytes = amqp_cstring_bytes("third"); + + entries[3].key = amqp_cstring_bytes("number"); + entries[3].value.kind = AMQP_FIELD_KIND_I32; + entries[3].value.value.i32 = 1234; + + entries[4].key = amqp_cstring_bytes("decimal"); + entries[4].value.kind = AMQP_FIELD_KIND_DECIMAL; + entries[4].value.value.decimal.decimals = 2; + entries[4].value.value.decimal.value = 1234; + + entries[5].key = amqp_cstring_bytes("time"); + entries[5].value.kind = AMQP_FIELD_KIND_TIMESTAMP; + entries[5].value.value.u64 = 1234123412341234; + + entries[6].key = amqp_cstring_bytes("beta"); + entries[6].value.kind = AMQP_FIELD_KIND_UTF8; + entries[6].value.value.bytes = amqp_cstring_bytes("second"); + + entries[7].key = amqp_cstring_bytes("wombat"); + entries[7].value.kind = AMQP_FIELD_KIND_UTF8; + entries[7].value.value.bytes = amqp_cstring_bytes("fourth"); + + table.num_entries = 8; + table.entries = entries; + + qsort(table.entries, table.num_entries, sizeof(amqp_table_entry_t), + &amqp_table_entry_cmp); + + val.kind = AMQP_FIELD_KIND_TABLE; + val.value.table = table; + + dump_value(0, val, out); +} + +static uint8_t pre_encoded_table[] = { + 0x00, 0x00, 0x00, 0xff, 0x07, 0x6c, 0x6f, 0x6e, 0x67, 0x73, 0x74, 0x72, + 0x53, 0x00, 0x00, 0x00, 0x15, 0x48, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, + 0x20, 0x61, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x69, 0x6e, 0x74, + 0x49, 0x00, 0x00, 0x30, 0x39, 0x07, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, + 0x6c, 0x44, 0x03, 0x00, 0x01, 0xe2, 0x40, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x54, 0x00, 0x00, 0x63, 0xee, 0xa0, 0x53, + 0xc1, 0x94, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x00, 0x00, 0x00, + 0x1f, 0x03, 0x6f, 0x6e, 0x65, 0x49, 0x00, 0x00, 0xd4, 0x31, 0x03, 0x74, + 0x77, 0x6f, 0x53, 0x00, 0x00, 0x00, 0x0d, 0x41, 0x20, 0x6c, 0x6f, 0x6e, + 0x67, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x04, 0x62, 0x79, 0x74, + 0x65, 0x62, 0xff, 0x04, 0x6c, 0x6f, 0x6e, 0x67, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x96, 0x02, 0xd2, 0x05, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x73, + 0x02, 0x8f, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x74, 0x01, 0x06, 0x62, 0x69, + 0x6e, 0x61, 0x72, 0x79, 0x78, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x20, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x04, 0x76, 0x6f, 0x69, 0x64, 0x56, 0x05, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x41, 0x00, 0x00, 0x00, 0x17, 0x49, 0x00, 0x00, 0xd4, 0x31, 0x53, 0x00, + 0x00, 0x00, 0x0d, 0x41, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x66, 0x40, + 0x49, 0x0f, 0xdb, 0x06, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x64, 0x40, + 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}; + +static void test_table_codec(FILE *out) { + amqp_pool_t pool; + int result; + + amqp_table_entry_t inner_entries[2]; + amqp_table_t inner_table; + + amqp_field_value_t inner_values[2]; + amqp_array_t inner_array; + + amqp_table_entry_t entries[14]; + amqp_table_t table; + + inner_entries[0].key = amqp_cstring_bytes("one"); + inner_entries[0].value.kind = AMQP_FIELD_KIND_I32; + inner_entries[0].value.value.i32 = 54321; + + inner_entries[1].key = amqp_cstring_bytes("two"); + inner_entries[1].value.kind = AMQP_FIELD_KIND_UTF8; + inner_entries[1].value.value.bytes = amqp_cstring_bytes("A long string"); + + inner_table.num_entries = 2; + inner_table.entries = inner_entries; + + inner_values[0].kind = AMQP_FIELD_KIND_I32; + inner_values[0].value.i32 = 54321; + + inner_values[1].kind = AMQP_FIELD_KIND_UTF8; + inner_values[1].value.bytes = amqp_cstring_bytes("A long string"); + + inner_array.num_entries = 2; + inner_array.entries = inner_values; + + entries[0].key = amqp_cstring_bytes("longstr"); + entries[0].value.kind = AMQP_FIELD_KIND_UTF8; + entries[0].value.value.bytes = amqp_cstring_bytes("Here is a long string"); + + entries[1].key = amqp_cstring_bytes("signedint"); + entries[1].value.kind = AMQP_FIELD_KIND_I32; + entries[1].value.value.i32 = 12345; + + entries[2].key = amqp_cstring_bytes("decimal"); + entries[2].value.kind = AMQP_FIELD_KIND_DECIMAL; + entries[2].value.value.decimal.decimals = 3; + entries[2].value.value.decimal.value = 123456; + + entries[3].key = amqp_cstring_bytes("timestamp"); + entries[3].value.kind = AMQP_FIELD_KIND_TIMESTAMP; + entries[3].value.value.u64 = 109876543209876; + + entries[4].key = amqp_cstring_bytes("table"); + entries[4].value.kind = AMQP_FIELD_KIND_TABLE; + entries[4].value.value.table = inner_table; + + entries[5].key = amqp_cstring_bytes("byte"); + entries[5].value.kind = AMQP_FIELD_KIND_I8; + entries[5].value.value.i8 = (int8_t)-1; + + entries[6].key = amqp_cstring_bytes("long"); + entries[6].value.kind = AMQP_FIELD_KIND_I64; + entries[6].value.value.i64 = 1234567890; + + entries[7].key = amqp_cstring_bytes("short"); + entries[7].value.kind = AMQP_FIELD_KIND_I16; + entries[7].value.value.i16 = 655; + + entries[8].key = amqp_cstring_bytes("bool"); + entries[8].value.kind = AMQP_FIELD_KIND_BOOLEAN; + entries[8].value.value.boolean = 1; + + entries[9].key = amqp_cstring_bytes("binary"); + entries[9].value.kind = AMQP_FIELD_KIND_BYTES; + entries[9].value.value.bytes = amqp_cstring_bytes("a binary string"); + + entries[10].key = amqp_cstring_bytes("void"); + entries[10].value.kind = AMQP_FIELD_KIND_VOID; + + entries[11].key = amqp_cstring_bytes("array"); + entries[11].value.kind = AMQP_FIELD_KIND_ARRAY; + entries[11].value.value.array = inner_array; + + entries[12].key = amqp_cstring_bytes("float"); + entries[12].value.kind = AMQP_FIELD_KIND_F32; + entries[12].value.value.f32 = (float)M_PI; + + entries[13].key = amqp_cstring_bytes("double"); + entries[13].value.kind = AMQP_FIELD_KIND_F64; + entries[13].value.value.f64 = M_PI; + + table.num_entries = 14; + table.entries = entries; + + fprintf(out, "AAAAAAAAAA\n"); + + { + amqp_field_value_t val; + val.kind = AMQP_FIELD_KIND_TABLE; + val.value.table = table; + dump_value(0, val, out); + } + + init_amqp_pool(&pool, 4096); + + { + amqp_table_t decoded; + size_t decoding_offset = 0; + amqp_bytes_t decoding_bytes; + decoding_bytes.len = sizeof(pre_encoded_table); + decoding_bytes.bytes = pre_encoded_table; + + result = + amqp_decode_table(decoding_bytes, &pool, &decoded, &decoding_offset); + if (result < 0) { + die("Table decoding failed: %s", amqp_error_string2(result)); + } + + fprintf(out, "BBBBBBBBBB\n"); + + { + amqp_field_value_t val; + val.kind = AMQP_FIELD_KIND_TABLE; + val.value.table = decoded; + + dump_value(0, val, out); + } + } + + { + uint8_t encoding_buffer[4096]; + amqp_bytes_t encoding_result; + size_t offset = 0; + + memset(&encoding_buffer[0], 0, sizeof(encoding_buffer)); + encoding_result.len = sizeof(encoding_buffer); + encoding_result.bytes = &encoding_buffer[0]; + + result = amqp_encode_table(encoding_result, &table, &offset); + if (result < 0) { + die("Table encoding failed: %s", amqp_error_string2(result)); + } + + if (offset != sizeof(pre_encoded_table)) + die("Offset should be %ld, was %ld", (long)sizeof(pre_encoded_table), + (long)offset); + + result = memcmp(pre_encoded_table, encoding_buffer, offset); + if (result != 0) { + die("Table encoding differed", result); + } + } + + empty_amqp_pool(&pool); +} + +#define CHUNK_SIZE 4096 + +static int compare_files(FILE *f1_in, FILE *f2_in) { + char f1_buf[CHUNK_SIZE]; + char f2_buf[CHUNK_SIZE]; + int res; + + rewind(f1_in); + rewind(f2_in); + + for (;;) { + size_t f1_got = fread(f1_buf, 1, CHUNK_SIZE, f1_in); + size_t f2_got = fread(f2_buf, 1, CHUNK_SIZE, f2_in); + res = memcmp(f1_buf, f2_buf, f1_got < f2_got ? f1_got : f2_got); + + if (res) { + break; + } + + if (f1_got < CHUNK_SIZE || f2_got < CHUNK_SIZE) { + if (f1_got != f2_got) { + res = (f1_got < f2_got ? -1 : 1); + } + break; + } + } + + return res; +} + +const char *expected_file_name = "tests/test_tables.expected"; + +int main(void) { + char *srcdir = getenv("srcdir"); + FILE *out, *expected = NULL; + char *expected_path; + + out = tmpfile(); + if (out == NULL) { + die("failed to create temporary file: %s", strerror(errno)); + } + + test_table_codec(out); + fprintf(out, "----------\n"); + test_dump_value(out); + + if (srcdir == NULL) { + srcdir = "."; + } + + expected_path = malloc(strlen(srcdir) + strlen(expected_file_name) + 2); + if (!expected_path) { + die("out of memory"); + } + sprintf(expected_path, "%s/%s", srcdir, expected_file_name); + expected = fopen(expected_path, "r"); + if (!expected) { + die("failed to open %s: %s", expected_path, strerror(errno)); + } + + if (compare_files(expected, out)) { + die("output file did not have expected contents"); + } + + fclose(expected); + free(expected_path); + fclose(out); + + return 0; +} diff --git a/ext/librabbitmq/tests/test_tables.expected b/ext/librabbitmq/tests/test_tables.expected new file mode 100644 index 00000000..44d20852 --- /dev/null +++ b/ext/librabbitmq/tests/test_tables.expected @@ -0,0 +1,90 @@ +AAAAAAAAAA +F + longstr -> + S Here is a long string + signedint -> + I 12345 + decimal -> + D 3:::123456 + timestamp -> + T 109876543209876 + table -> + F + one -> + I 54321 + two -> + S A long string + byte -> + b -1 + long -> + l 1234567890 + short -> + s 655 + bool -> + t true + binary -> + x 612062696e61727920737472696e67 + void -> + V + array -> + A + I 54321 + S A long string + float -> + f 3.14159 + double -> + d 3.14159 +BBBBBBBBBB +F + longstr -> + S Here is a long string + signedint -> + I 12345 + decimal -> + D 3:::123456 + timestamp -> + T 109876543209876 + table -> + F + one -> + I 54321 + two -> + S A long string + byte -> + b -1 + long -> + l 1234567890 + short -> + s 655 + bool -> + t true + binary -> + x 612062696e61727920737472696e67 + void -> + V + array -> + A + I 54321 + S A long string + float -> + f 3.14159 + double -> + d 3.14159 +---------- +F + aardvark -> + S first + beta -> + S second + decimal -> + D 2:::1234 + middle -> + S third + number -> + I 1234 + time -> + T 1234123412341234 + wombat -> + S fourth + zebra -> + S last diff --git a/ext/librabbitmq/tests/win32/msinttypes/inttypes.h b/ext/librabbitmq/tests/win32/msinttypes/inttypes.h new file mode 100644 index 00000000..f437cf45 --- /dev/null +++ b/ext/librabbitmq/tests/win32/msinttypes/inttypes.h @@ -0,0 +1,304 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// 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. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || \ + defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +#define SCNdPTR "I64d" +#define SCNiPTR "I64i" +#else // _WIN64 ][ +#define SCNdPTR "ld" +#define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +#define SCNoPTR "I64o" +#define SCNuPTR "I64u" +#define SCNxPTR "I64x" +#define SCNXPTR "I64X" +#else // _WIN64 ][ +#define SCNoPTR "lo" +#define SCNuPTR "lu" +#define SCNxPTR "lx" +#define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] + imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) { + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + +#endif // _MSC_INTTYPES_H_ ] diff --git a/ext/librabbitmq/tools/CMakeLists.txt b/ext/librabbitmq/tools/CMakeLists.txt new file mode 100644 index 00000000..1471043c --- /dev/null +++ b/ext/librabbitmq/tools/CMakeLists.txt @@ -0,0 +1,82 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${LIBRABBITMQ_INCLUDE_DIRS} ${POPT_INCLUDE_DIR}) + +if (WIN32) + set(PLATFORM_DIR win32) + set(PLATFORM_SRCS + win32/compat.c + ) +else (WIN32) + set(PLATFORM_DIR unix) +endif (WIN32) + +include_directories(${PLATFORM_DIR}) + +set(COMMON_SRCS + common.h + common.c + ${PLATFORM_SRCS} + ) + +add_executable(amqp-publish publish.c ${COMMON_SRCS}) +target_link_libraries(amqp-publish ${RMQ_LIBRARY_TARGET} ${POPT_LIBRARY}) + +add_executable(amqp-get get.c ${COMMON_SRCS}) +target_link_libraries(amqp-get ${RMQ_LIBRARY_TARGET} ${POPT_LIBRARY}) + +add_executable(amqp-consume consume.c ${PLATFORM_DIR}/process.c ${COMMON_SRCS}) +target_link_libraries(amqp-consume ${RMQ_LIBRARY_TARGET} ${POPT_LIBRARY}) + +add_executable(amqp-declare-queue declare_queue.c ${COMMON_SRCS}) +target_link_libraries(amqp-declare-queue ${RMQ_LIBRARY_TARGET} ${POPT_LIBRARY}) + +add_executable(amqp-delete-queue delete_queue.c ${COMMON_SRCS}) +target_link_libraries(amqp-delete-queue ${RMQ_LIBRARY_TARGET} ${POPT_LIBRARY}) + +if (BUILD_TOOLS_DOCS) + if (XMLTO_FOUND) + set(DOCS_SRCS + doc/amqp-consume.xml + doc/amqp-declare-queue.xml + doc/amqp-delete-queue.xml + doc/amqp-get.xml + doc/amqp-publish.xml + doc/librabbitmq-tools.xml + ) + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc) + set(XMLTO_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doc/man-date.ent) + add_custom_command( + OUTPUT ${XMLTO_DEPENDS} + COMMAND date +'%Y-%m-%d' > ${XMLTO_DEPENDS} + VERBATIM + ) + + set(XMLTO_COMMAND_ARGS --skip-validation --searchpath "${CMAKE_CURRENT_BINARY_DIR}/doc") + + XMLTO(${DOCS_SRCS} + MODES man + ALL) + + foreach(file ${XMLTO_FILES_man}) + get_filename_component(fileExt ${file} EXT) + string( REGEX REPLACE "^[.]" "" fileExt ${fileExt} ) + install( + FILES ${file} + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man${fileExt} + ) + endforeach() + + else(XMLTO_FOUND) + message(WARNING "xmlto not found, will not build tools documentation") + endif(XMLTO_FOUND) +endif() + +if (ENABLE_SSL_SUPPORT) + add_definitions(-DWITH_SSL=1) +endif() + +install(TARGETS amqp-publish amqp-get amqp-consume amqp-declare-queue amqp-delete-queue + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include) diff --git a/ext/librabbitmq/tools/common.c b/ext/librabbitmq/tools/common.c new file mode 100644 index 00000000..13839a88 --- /dev/null +++ b/ext/librabbitmq/tools/common.c @@ -0,0 +1,444 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "common.h" +#ifdef WITH_SSL +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WINDOWS +#include "compat.h" +#endif + +void die(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(1); +} + +void die_errno(int err, const char *fmt, ...) { + va_list ap; + + if (err == 0) { + return; + } + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, ": %s\n", strerror(err)); + exit(1); +} + +void die_amqp_error(int err, const char *fmt, ...) { + va_list ap; + + if (err >= 0) { + return; + } + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, ": %s\n", amqp_error_string2(err)); + exit(1); +} + +const char *amqp_server_exception_string(amqp_rpc_reply_t r) { + int res; + static char s[512]; + + switch (r.reply.id) { + case AMQP_CONNECTION_CLOSE_METHOD: { + amqp_connection_close_t *m = (amqp_connection_close_t *)r.reply.decoded; + res = snprintf(s, sizeof(s), "server connection error %d, message: %.*s", + m->reply_code, (int)m->reply_text.len, + (char *)m->reply_text.bytes); + break; + } + + case AMQP_CHANNEL_CLOSE_METHOD: { + amqp_channel_close_t *m = (amqp_channel_close_t *)r.reply.decoded; + res = snprintf(s, sizeof(s), "server channel error %d, message: %.*s", + m->reply_code, (int)m->reply_text.len, + (char *)m->reply_text.bytes); + break; + } + + default: + res = snprintf(s, sizeof(s), "unknown server error, method id 0x%08X", + r.reply.id); + break; + } + + return res >= 0 ? s : NULL; +} + +const char *amqp_rpc_reply_string(amqp_rpc_reply_t r) { + switch (r.reply_type) { + case AMQP_RESPONSE_NORMAL: + return "normal response"; + + case AMQP_RESPONSE_NONE: + return "missing RPC reply type"; + + case AMQP_RESPONSE_LIBRARY_EXCEPTION: + return amqp_error_string2(r.library_error); + + case AMQP_RESPONSE_SERVER_EXCEPTION: + return amqp_server_exception_string(r); + + default: + abort(); + } +} + +void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...) { + va_list ap; + + if (r.reply_type == AMQP_RESPONSE_NORMAL) { + return; + } + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, ": %s\n", amqp_rpc_reply_string(r)); + exit(1); +} + +static char *amqp_url; +static char *amqp_server; +static int amqp_port = -1; +static char *amqp_vhost; +static char *amqp_username; +static char *amqp_password; +static int amqp_heartbeat = 0; +#ifdef WITH_SSL +static int amqp_ssl = 0; +static char *amqp_cacert = "/etc/ssl/certs/cacert.pem"; +static char *amqp_key = NULL; +static char *amqp_cert = NULL; +#endif /* WITH_SSL */ + +const char *connect_options_title = "Connection options"; +struct poptOption connect_options[] = { + {"url", 'u', POPT_ARG_STRING, &amqp_url, 0, "the AMQP URL to connect to", + "amqp://..."}, + {"server", 's', POPT_ARG_STRING, &amqp_server, 0, + "the AMQP server to connect to", "hostname"}, + {"port", 0, POPT_ARG_INT, &amqp_port, 0, "the port to connect on", "port"}, + {"vhost", 0, POPT_ARG_STRING, &amqp_vhost, 0, + "the vhost to use when connecting", "vhost"}, + {"username", 0, POPT_ARG_STRING, &amqp_username, 0, + "the username to login with", "username"}, + {"password", 0, POPT_ARG_STRING, &amqp_password, 0, + "the password to login with", "password"}, + {"heartbeat", 0, POPT_ARG_INT, &amqp_heartbeat, 0, + "heartbeat interval, set to 0 to disable", "heartbeat"}, +#ifdef WITH_SSL + {"ssl", 0, POPT_ARG_NONE, &amqp_ssl, 0, "connect over SSL/TLS", NULL}, + {"cacert", 0, POPT_ARG_STRING, &amqp_cacert, 0, + "path to the CA certificate file", "cacert.pem"}, + {"key", 0, POPT_ARG_STRING, &amqp_key, 0, + "path to the client private key file", "key.pem"}, + {"cert", 0, POPT_ARG_STRING, &amqp_cert, 0, + "path to the client certificate file", "cert.pem"}, +#endif /* WITH_SSL */ + {NULL, '\0', 0, NULL, 0, NULL, NULL}}; + +static void init_connection_info(struct amqp_connection_info *ci) { + ci->user = NULL; + ci->password = NULL; + ci->host = NULL; + ci->port = -1; + ci->vhost = NULL; + ci->user = NULL; + + amqp_default_connection_info(ci); + + if (amqp_url) + die_amqp_error(amqp_parse_url(strdup(amqp_url), ci), "Parsing URL '%s'", + amqp_url); + + if (amqp_server) { + char *colon; + if (amqp_url) { + die("--server and --url options cannot be used at the same time"); + } + + /* parse the server string into a hostname and a port */ + colon = strchr(amqp_server, ':'); + if (colon) { + char *port_end; + size_t host_len; + + /* Deprecate specifying the port number with the + --server option, because it is not ipv6 friendly. + --url now allows connection options to be + specified concisely. */ + fprintf(stderr, + "Specifying the port number with --server is deprecated\n"); + + host_len = colon - amqp_server; + ci->host = malloc(host_len + 1); + memcpy(ci->host, amqp_server, host_len); + ci->host[host_len] = 0; + + if (amqp_port >= 0) { + die("both --server and --port options specify server port"); + } + + ci->port = strtol(colon + 1, &port_end, 10); + if (ci->port < 0 || ci->port > 65535 || port_end == colon + 1 || + *port_end != 0) + die("bad server port number in '%s'", amqp_server); + } + +#if WITH_SSL + if (amqp_ssl && !ci->ssl) { + die("the --ssl option specifies an SSL connection" + " but the --url option does not"); + } +#endif + } + + if (amqp_port >= 0) { + if (amqp_url) { + die("--port and --url options cannot be used at the same time"); + } + + ci->port = amqp_port; + } + + if (amqp_username) { + if (amqp_url) { + die("--username and --url options cannot be used at the same time"); + } + + ci->user = amqp_username; + } + + if (amqp_password) { + if (amqp_url) { + die("--password and --url options cannot be used at the same time"); + } + + ci->password = amqp_password; + } + + if (amqp_vhost) { + if (amqp_url) { + die("--vhost and --url options cannot be used at the same time"); + } + + ci->vhost = amqp_vhost; + } + + if (amqp_heartbeat < 0) { + die("--heartbeat must be a positive value"); + } +} + +amqp_connection_state_t make_connection(void) { + int status; + amqp_socket_t *socket = NULL; + struct amqp_connection_info ci; + amqp_connection_state_t conn; + + init_connection_info(&ci); + conn = amqp_new_connection(); + if (ci.ssl) { +#ifdef WITH_SSL + socket = amqp_ssl_socket_new(conn); + if (!socket) { + die("creating SSL/TLS socket"); + } + if (amqp_cacert) { + amqp_ssl_socket_set_cacert(socket, amqp_cacert); + } + if (amqp_key) { + amqp_ssl_socket_set_key(socket, amqp_cert, amqp_key); + } +#else + die("librabbitmq was not built with SSL/TLS support"); +#endif + } else { + socket = amqp_tcp_socket_new(conn); + if (!socket) { + die("creating TCP socket (out of memory)"); + } + } + status = amqp_socket_open(socket, ci.host, ci.port); + if (status) { + die("opening socket to %s:%d", ci.host, ci.port); + } + die_rpc(amqp_login(conn, ci.vhost, 0, 131072, amqp_heartbeat, + AMQP_SASL_METHOD_PLAIN, ci.user, ci.password), + "logging in to AMQP server"); + if (!amqp_channel_open(conn, 1)) { + die_rpc(amqp_get_rpc_reply(conn), "opening channel"); + } + return conn; +} + +void close_connection(amqp_connection_state_t conn) { + int res; + die_rpc(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "closing channel"); + die_rpc(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), + "closing connection"); + + res = amqp_destroy_connection(conn); + die_amqp_error(res, "closing connection"); +} + +amqp_bytes_t read_all(int fd) { + size_t space = 4096; + amqp_bytes_t bytes; + + bytes.bytes = malloc(space); + bytes.len = 0; + + for (;;) { + ssize_t res = read(fd, (char *)bytes.bytes + bytes.len, space - bytes.len); + if (res == 0) { + break; + } + + if (res < 0) { + if (errno == EINTR) { + continue; + } + + die_errno(errno, "reading"); + } + + bytes.len += res; + if (bytes.len == space) { + space *= 2; + bytes.bytes = realloc(bytes.bytes, space); + } + } + + return bytes; +} + +void write_all(int fd, amqp_bytes_t data) { + while (data.len > 0) { + ssize_t res = write(fd, data.bytes, data.len); + if (res < 0) { + die_errno(errno, "write"); + } + + data.len -= res; + data.bytes = (char *)data.bytes + res; + } +} + +void copy_body(amqp_connection_state_t conn, int fd) { + size_t body_remaining; + amqp_frame_t frame; + + int res = amqp_simple_wait_frame(conn, &frame); + die_amqp_error(res, "waiting for header frame"); + if (frame.frame_type != AMQP_FRAME_HEADER) { + die("expected header, got frame type 0x%X", frame.frame_type); + } + + body_remaining = frame.payload.properties.body_size; + while (body_remaining) { + res = amqp_simple_wait_frame(conn, &frame); + die_amqp_error(res, "waiting for body frame"); + if (frame.frame_type != AMQP_FRAME_BODY) { + die("expected body, got frame type 0x%X", frame.frame_type); + } + + write_all(fd, frame.payload.body_fragment); + body_remaining -= frame.payload.body_fragment.len; + } +} + +poptContext process_options(int argc, const char **argv, + struct poptOption *options, const char *help) { + int c; + poptContext opts = poptGetContext(NULL, argc, argv, options, 0); + poptSetOtherOptionHelp(opts, help); + + while ((c = poptGetNextOpt(opts)) >= 0) { + /* no options require explicit handling */ + } + + if (c < -1) { + fprintf(stderr, "%s: %s\n", poptBadOption(opts, POPT_BADOPTION_NOALIAS), + poptStrerror(c)); + poptPrintUsage(opts, stderr, 0); + exit(1); + } + + return opts; +} + +void process_all_options(int argc, const char **argv, + struct poptOption *options) { + poptContext opts = process_options(argc, argv, options, "[OPTIONS]..."); + const char *opt = poptPeekArg(opts); + + if (opt) { + fprintf(stderr, "unexpected operand: %s\n", opt); + poptPrintUsage(opts, stderr, 0); + exit(1); + } + + poptFreeContext(opts); +} + +amqp_bytes_t cstring_bytes(const char *str) { + return str ? amqp_cstring_bytes(str) : amqp_empty_bytes; +} diff --git a/ext/librabbitmq/tools/common.h b/ext/librabbitmq/tools/common.h new file mode 100644 index 00000000..36b51539 --- /dev/null +++ b/ext/librabbitmq/tools/common.h @@ -0,0 +1,73 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include + +#include + +#include +#include + +extern const char *amqp_server_exception_string(amqp_rpc_reply_t r); +extern const char *amqp_rpc_reply_string(amqp_rpc_reply_t r); + +extern void die(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +extern void die_errno(int err, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +extern void die_amqp_error(int err, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +extern void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); + +extern const char *connect_options_title; +extern struct poptOption connect_options[]; +extern amqp_connection_state_t make_connection(void); +extern void close_connection(amqp_connection_state_t conn); + +extern amqp_bytes_t read_all(int fd); +extern void write_all(int fd, amqp_bytes_t data); + +extern void copy_body(amqp_connection_state_t conn, int fd); + +#define INCLUDE_OPTIONS(options) \ + { NULL, 0, POPT_ARG_INCLUDE_TABLE, options, 0, options##_title, NULL } + +extern poptContext process_options(int argc, const char **argv, + struct poptOption *options, + const char *help); +extern void process_all_options(int argc, const char **argv, + struct poptOption *options); + +extern amqp_bytes_t cstring_bytes(const char *str); diff --git a/ext/librabbitmq/tools/consume.c b/ext/librabbitmq/tools/consume.c new file mode 100644 index 00000000..dbc164a3 --- /dev/null +++ b/ext/librabbitmq/tools/consume.c @@ -0,0 +1,250 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "common.h" +#include "process.h" + +#define MAX_LISTEN_KEYS 1024 +#define LISTEN_KEYS_DELIMITER "," + +/* Convert a amqp_bytes_t to an escaped string form for printing. We + use the same escaping conventions as rabbitmqctl. */ +static char *stringify_bytes(amqp_bytes_t bytes) { + /* We will need up to 4 chars per byte, plus the terminating 0 */ + char *res = malloc(bytes.len * 4 + 1); + uint8_t *data = bytes.bytes; + char *p = res; + size_t i; + + for (i = 0; i < bytes.len; i++) { + if (data[i] >= 32 && data[i] != 127) { + *p++ = data[i]; + } else { + *p++ = '\\'; + *p++ = '0' + (data[i] >> 6); + *p++ = '0' + (data[i] >> 3 & 0x7); + *p++ = '0' + (data[i] & 0x7); + } + } + + *p = 0; + return res; +} + +static amqp_bytes_t setup_queue(amqp_connection_state_t conn, char *queue, + char *exchange, char *routing_key, int declare, + int exclusive) { + amqp_bytes_t queue_bytes = cstring_bytes(queue); + + char *routing_key_rest; + char *routing_key_token; + char *routing_tmp; + int routing_key_count = 0; + + /* if an exchange name wasn't provided, check that we don't have options that + * require it. */ + if (!exchange && routing_key) { + fprintf(stderr, + "--routing-key option requires an exchange name to be provided " + "with --exchange\n"); + exit(1); + } + + if (!queue || exchange || declare || exclusive) { + /* Declare the queue as auto-delete. */ + amqp_queue_declare_ok_t *res = amqp_queue_declare( + conn, 1, queue_bytes, 0, 0, exclusive, 1, amqp_empty_table); + if (!res) { + die_rpc(amqp_get_rpc_reply(conn), "queue.declare"); + } + + if (!queue) { + /* the server should have provided a queue name */ + char *sq; + queue_bytes = amqp_bytes_malloc_dup(res->queue); + sq = stringify_bytes(queue_bytes); + fprintf(stderr, "Server provided queue name: %s\n", sq); + free(sq); + } + + /* Bind to an exchange if requested */ + if (exchange) { + amqp_bytes_t eb = amqp_cstring_bytes(exchange); + + routing_tmp = strdup(routing_key); + if (NULL == routing_tmp) { + fprintf(stderr, "could not allocate memory to parse routing key\n"); + exit(1); + } + + for (routing_key_token = + strtok_r(routing_tmp, LISTEN_KEYS_DELIMITER, &routing_key_rest); + NULL != routing_key_token && routing_key_count < MAX_LISTEN_KEYS - 1; + routing_key_token = + strtok_r(NULL, LISTEN_KEYS_DELIMITER, &routing_key_rest)) { + + if (!amqp_queue_bind(conn, 1, queue_bytes, eb, + cstring_bytes(routing_key_token), + amqp_empty_table)) { + die_rpc(amqp_get_rpc_reply(conn), "queue.bind"); + } + } + free(routing_tmp); + } + } + + return queue_bytes; +} + +#define AMQP_CONSUME_MAX_PREFETCH_COUNT 65535 + +static void do_consume(amqp_connection_state_t conn, amqp_bytes_t queue, + int no_ack, int count, int prefetch_count, + const char *const *argv) { + int i; + + /* If there is a limit, set the qos to match */ + if (count > 0 && count <= AMQP_CONSUME_MAX_PREFETCH_COUNT && + !amqp_basic_qos(conn, 1, 0, count, 0)) { + die_rpc(amqp_get_rpc_reply(conn), "basic.qos"); + } + + /* if there is a maximum number of messages to be received at a time, set the + * qos to match */ + if (prefetch_count > 0 && prefetch_count <= AMQP_CONSUME_MAX_PREFETCH_COUNT) { + /* the maximum number of messages to be received at a time must be less + * than the global maximum number of messages. */ + if (!(count > 0 && count <= AMQP_CONSUME_MAX_PREFETCH_COUNT && + prefetch_count >= count)) { + if (!amqp_basic_qos(conn, 1, 0, prefetch_count, 0)) { + die_rpc(amqp_get_rpc_reply(conn), "basic.qos"); + } + } + } + + if (!amqp_basic_consume(conn, 1, queue, amqp_empty_bytes, 0, no_ack, 0, + amqp_empty_table)) { + die_rpc(amqp_get_rpc_reply(conn), "basic.consume"); + } + + for (i = 0; count < 0 || i < count; i++) { + amqp_frame_t frame; + struct pipeline pl; + uint64_t delivery_tag; + amqp_basic_deliver_t *deliver; + int res = amqp_simple_wait_frame(conn, &frame); + die_amqp_error(res, "waiting for header frame"); + + if (frame.frame_type != AMQP_FRAME_METHOD || + frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { + continue; + } + + deliver = (amqp_basic_deliver_t *)frame.payload.method.decoded; + delivery_tag = deliver->delivery_tag; + + pipeline(argv, &pl); + copy_body(conn, pl.infd); + + if (finish_pipeline(&pl) && !no_ack) + die_amqp_error(amqp_basic_ack(conn, 1, delivery_tag, 0), "basic.ack"); + + amqp_maybe_release_buffers(conn); + } +} + +int main(int argc, const char **argv) { + poptContext opts; + amqp_connection_state_t conn; + const char *const *cmd_argv; + static char *queue = NULL; + static char *exchange = NULL; + static char *routing_key = NULL; + static int declare = 0; + static int exclusive = 0; + static int no_ack = 0; + static int count = -1; + static int prefetch_count = -1; + amqp_bytes_t queue_bytes; + + struct poptOption options[] = { + INCLUDE_OPTIONS(connect_options), + {"queue", 'q', POPT_ARG_STRING, &queue, 0, "the queue to consume from", + "queue"}, + {"exchange", 'e', POPT_ARG_STRING, &exchange, 0, + "bind the queue to this exchange", "exchange"}, + {"routing-key", 'r', POPT_ARG_STRING, &routing_key, 0, + "the routing key to bind with", "routing key"}, + {"declare", 'd', POPT_ARG_NONE, &declare, 0, + "declare an exclusive queue (deprecated, use --exclusive instead)", + NULL}, + {"exclusive", 'x', POPT_ARG_NONE, &exclusive, 0, + "declare the queue as exclusive", NULL}, + {"no-ack", 'A', POPT_ARG_NONE, &no_ack, 0, "consume in no-ack mode", + NULL}, + {"count", 'c', POPT_ARG_INT, &count, 0, + "stop consuming after this many messages are consumed", "limit"}, + {"prefetch-count", 'p', POPT_ARG_INT, &prefetch_count, 0, + "receive only this many message at a time from the server", "limit"}, + POPT_AUTOHELP{NULL, '\0', 0, NULL, 0, NULL, NULL}}; + + opts = process_options(argc, argv, options, "[OPTIONS]... "); + + cmd_argv = poptGetArgs(opts); + if (!cmd_argv || !cmd_argv[0]) { + fprintf(stderr, "consuming command not specified\n"); + poptPrintUsage(opts, stderr, 0); + goto error; + } + + conn = make_connection(); + queue_bytes = + setup_queue(conn, queue, exchange, routing_key, declare, exclusive); + do_consume(conn, queue_bytes, no_ack, count, prefetch_count, cmd_argv); + close_connection(conn); + return 0; + +error: + poptFreeContext(opts); + return 1; +} diff --git a/ext/librabbitmq/tools/declare_queue.c b/ext/librabbitmq/tools/declare_queue.c new file mode 100644 index 00000000..0b985805 --- /dev/null +++ b/ext/librabbitmq/tools/declare_queue.c @@ -0,0 +1,79 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "common.h" + +int main(int argc, const char **argv) { + amqp_connection_state_t conn; + static char *queue = NULL; + static int durable = 0; + + struct poptOption options[] = { + INCLUDE_OPTIONS(connect_options), + {"queue", 'q', POPT_ARG_STRING, &queue, 0, + "the queue name to declare, or the empty string", "queue"}, + {"durable", 'd', POPT_ARG_VAL, &durable, 1, "declare a durable queue", + NULL}, + POPT_AUTOHELP{NULL, '\0', 0, NULL, 0, NULL, NULL}}; + + process_all_options(argc, argv, options); + + if (queue == NULL) { + fprintf(stderr, "queue name not specified\n"); + return 1; + } + + conn = make_connection(); + { + amqp_queue_declare_ok_t *reply = amqp_queue_declare( + conn, 1, cstring_bytes(queue), 0, durable, 0, 0, amqp_empty_table); + if (reply == NULL) { + die_rpc(amqp_get_rpc_reply(conn), "queue.declare"); + } + + printf("%.*s\n", (int)reply->queue.len, (char *)reply->queue.bytes); + } + close_connection(conn); + return 0; +} diff --git a/ext/librabbitmq/tools/delete_queue.c b/ext/librabbitmq/tools/delete_queue.c new file mode 100644 index 00000000..f9d01ab1 --- /dev/null +++ b/ext/librabbitmq/tools/delete_queue.c @@ -0,0 +1,81 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "common.h" + +int main(int argc, const char **argv) { + amqp_connection_state_t conn; + static char *queue = NULL; + static int if_unused = 0; + static int if_empty = 0; + + struct poptOption options[] = { + INCLUDE_OPTIONS(connect_options), + {"queue", 'q', POPT_ARG_STRING, &queue, 0, "the queue name to delete", + "queue"}, + {"if-unused", 'u', POPT_ARG_VAL, &if_unused, 1, + "do not delete unless queue is unused", NULL}, + {"if-empty", 'e', POPT_ARG_VAL, &if_empty, 1, + "do not delete unless queue is empty", NULL}, + POPT_AUTOHELP{NULL, '\0', 0, NULL, 0, NULL, NULL}}; + + process_all_options(argc, argv, options); + + if (queue == NULL || *queue == '\0') { + fprintf(stderr, "queue name not specified\n"); + return 1; + } + + conn = make_connection(); + { + amqp_queue_delete_ok_t *reply = + amqp_queue_delete(conn, 1, cstring_bytes(queue), if_unused, if_empty); + if (reply == NULL) { + die_rpc(amqp_get_rpc_reply(conn), "queue.delete"); + } + printf("%u\n", reply->message_count); + } + close_connection(conn); + return 0; +} diff --git a/ext/librabbitmq/tools/doc/amqp-consume.xml b/ext/librabbitmq/tools/doc/amqp-consume.xml new file mode 100644 index 00000000..9ee12e89 --- /dev/null +++ b/ext/librabbitmq/tools/doc/amqp-consume.xml @@ -0,0 +1,223 @@ + + +] +> + + + RabbitMQ C Client + + The RabbitMQ Team <info@rabbitmq.com> + + &date; + + + + amqp-consume + 1 + RabbitMQ C Client + + + + amqp-consume + Consume messages from a queue on an AMQP server + + + + + amqp-consume + + OPTION + + + command + + + args + + + + + + Description + + amqp-consume consumes messages from a + queue on an AMQP server. For each message that arrives, a + receiving command is run, with the message body supplied + to it on standard input. + + + amqp-consume can consume from an + existing queue, or it can create a new queue. It can + optionally bind the queue to an existing exchange. + + + By default, messages will be consumed with explicit + acknowledgements. A message will only be acknowledged if + the receiving command exits successfully (i.e. with an + exit code of zero). The AMQP no ack mode + (a.k.a. auto-ack mode) can be enable with the + option. + + + + + Options + + + + =queue name + + + The name of the queue to consume messages + from. + + + + If the option is + omitted, the AMQP server will assign a unique + name to the queue, and that server-assigned + name will be dixsplayed on stderr; this case + implies that an exclusive queue should be + declared. + + + + + + =exchange name + + + Specifies that an exclusive queue should + be declared, and bound to the given exchange. + The specified exchange should already exist + unless the + option is used to request the creation of an + exchange. + + + + + + =routing key + + + The routing key for binding. If omitted, an + empty routing key is assumed. + + + + + + + + + Forces an exclusive queue to be declared, + even when it otherwise would not be. That is, + when a queue name is specified with the + option, but no + binding to an exchange is requested with the + option. + Note: this option is deprecated and may be + removed in a future version, use the + option to + explicitly declare an exclusive queue. + + + + + + + + + Declared queues are non-exclusive by default, + this option forces declaration of exclusive + queues. + + + + + + =routing key + + + Enable no ack mode: The AMQP + server will unconditionally acknowledge each + message that is delivered, regardless of + whether the target command exits successfully + or not. + + + + + + =limit + + + Stop consuming after the given number of + messages have been received. + + + + + + =limit + + + Request the server to only send + limit + messages at a time. + + + If any value was passed to , + the value passed to + should be smaller than that, or otherwise it will be + ignored. + + + If / is + passed, this option has no effect. + + + + + + + + Examples + + + Consume messages from an existing queue + myqueue, and + output the message bodies on standard output via + cat: + + $ amqp-publish -q myqueue cat + + + + + Bind a new exclusive queue to an + exchange myexch, and send + each message body to the script + myscript, automatically + acknowledging them on the server: + + $ amqp-consume -A -e myexch ./myscript + + + + + + + See also + + librabbitmq-tools7 + describes connection-related options common to all the + RabbitMQ C Client tools. + + + diff --git a/ext/librabbitmq/tools/doc/amqp-declare-queue.xml b/ext/librabbitmq/tools/doc/amqp-declare-queue.xml new file mode 100644 index 00000000..0fc04407 --- /dev/null +++ b/ext/librabbitmq/tools/doc/amqp-declare-queue.xml @@ -0,0 +1,122 @@ + + +] +> + + + RabbitMQ C Client + + The RabbitMQ Team <info@rabbitmq.com> + + &date; + + + + amqp-declare-queue + 1 + RabbitMQ C Client + + + + amqp-declare-queue + Declare (create or assert the existence of) a queue on an AMQP server + + + + + amqp-declare-queue + + OPTION + + -d + -q queue name + + + + + Description + + amqp-declare-queue attempts to create a + queue on an AMQP server, and exits. If the empty-string is + supplied as the queue name, a fresh queue name is + generated by the server and returned. In all cases, if a + queue was successfully declared, the (raw binary) name of + the queue is printed to standard output, followed by a + newline. + + + + + Options + + + + =queue name + + + The name of the queue to declare. If the + empty string is supplied, a fresh queue name + is generated by the server. + + + + + + + + + Causes the queue to be declared with the + "durable" flag set. Durable queues survive + server restarts. By default, queues are declared + in "transient" mode. + + + + + + + + Exit Status + + If the queue was successfully declared, the exit status is + 0. If an error occurs, the exit status is 1. + + + + + Examples + + + Declare the durable queue myqueue, and + display the name of the queue on standard output: + + $ amqp-declare-queue -d -q myqueue +myqueue + + + + Declare a fresh, server-named transient queue, + and display the name of the queue on standard output + (use amqp-delete-queue + 1 to delete + it from the server once you're done): + + $ amqp-declare-queue -q "" +amq.gen-BW/wvociA8g6LFpb1PlqOA== + + + + + + + See also + + librabbitmq-tools7 + describes connection-related options common to all the + RabbitMQ C Client tools. + + + diff --git a/ext/librabbitmq/tools/doc/amqp-delete-queue.xml b/ext/librabbitmq/tools/doc/amqp-delete-queue.xml new file mode 100644 index 00000000..040a384d --- /dev/null +++ b/ext/librabbitmq/tools/doc/amqp-delete-queue.xml @@ -0,0 +1,94 @@ + + +] +> + + + RabbitMQ C Client + + The RabbitMQ Team <info@rabbitmq.com> + + &date; + + + + amqp-delete-queue + 1 + RabbitMQ C Client + + + + amqp-delete-queue + Delete a queue from an AMQP server + + + + + amqp-delete-queue + + OPTION + + -q queue name + + + + + Description + + amqp-delete-queue deletes a queue from + an AMQP server, and exits after printing to standard + output the number of messages that were in the queue at + the time of its deletion. + + + + + Options + + + + =queue name + + + The name of the queue to delete. + + + + + + + + Exit Status + + If the queue was successfully deleted, the exit status is + 0. If an error occurs, the exit status is 1. + + + + + Examples + + + Delete the + queue myqueue + at a moment when it has 123 messages waiting on + it: + + $ amqp-delete-queue -q myqueue +123 + + + + + + + See also + + librabbitmq-tools7 + describes connection-related options common to all the + RabbitMQ C Client tools. + + + diff --git a/ext/librabbitmq/tools/doc/amqp-get.xml b/ext/librabbitmq/tools/doc/amqp-get.xml new file mode 100644 index 00000000..08abe2bd --- /dev/null +++ b/ext/librabbitmq/tools/doc/amqp-get.xml @@ -0,0 +1,95 @@ + + +] +> + + + RabbitMQ C Client + + The RabbitMQ Team <info@rabbitmq.com> + + &date; + + + + amqp-get + 1 + RabbitMQ C Client + + + + amqp-get + Get a message from a queue on an AMQP server + + + + + amqp-get + + OPTION + + -q queue name + + + + + Description + + amqp-get attempts to consume a single + message from a queue on an AMQP server, and exits. Unless + the queue was empty, the body of the resulting message is + sent to standard output. + + + + + Options + + + + =queue name + + + The name of the queue to consume messages + from. + + + + + + + + Exit Status + + If the queue is not empty, and a message is successfully + retrieved, the exit status is 0. If an error occurs, the + exit status is 1. If the queue is found to be empty, the + exit status is 2. + + + + + Examples + + + Get a message from the queue myqueue, and + display its body on standard output: + + $ amqp-get -q myqueue + + + + + + + See also + + librabbitmq-tools7 + describes connection-related options common to all the + RabbitMQ C Client tools. + + + diff --git a/ext/librabbitmq/tools/doc/amqp-publish.xml b/ext/librabbitmq/tools/doc/amqp-publish.xml new file mode 100644 index 00000000..aae07f47 --- /dev/null +++ b/ext/librabbitmq/tools/doc/amqp-publish.xml @@ -0,0 +1,169 @@ + + +] +> + + + RabbitMQ C Client + + The RabbitMQ Team <info@rabbitmq.com> + + &date; + + + + amqp-publish + 1 + RabbitMQ C Client + + + + amqp-publish + Publish a message on an AMQP server + + + + + amqp-publish + + OPTION + + + + + + Description + + Publishes a message to an exchange on an AMQP server. + Options allow the various properties of the message and + parameters of the AMQP basic.publish + method to be specified. + + + By default, the message body is read from standard input. + Alternatively, the option allows the message + body to be provided as part of the command. + + + + + Options + + + + =exchange name + + + The name of the exchange to publish to. If + omitted, the default exchange (also known as + the nameless exchange) is used. + + + + + + =routing key + + + The routing key to publish with. If omitted, + an empty routing key is assumed. A routing + key must be specified when publishing to the + default exchange; in that case, accoding to + the AMQP specification, the routing key + corresponds to a queue name. + + + + + + + + + Use the persistent delivery mode. Without + this option, non-persistent delivery is used. + + + + + + =MIME type + + + Specifies the content-type property for the + message. If omitted, the content-type + property is not set on the message. + + + + + + =content coding + + + Specifies the content-encoding property for + the message. If omitted, the content-encoding + property is not set on the message. + + + + + + =message body + + + Specifies the message body. If omitted, the + message body is read from standard input. + + + + + + =header + + + Specifies an optional header in the form "key: value". + + + + + + + + Examples + + + Send a short message, consisting of the word + Hello to the queue + myqueue via the + default exchange: + + $ amqp-publish -r myqueue -b Hello + + + + + Send some XML data from a file to the exchange + events, with + persistent delivery mode, setting the content-type + property on the message to make the data format + explicit: + + $ amqp-publish -e events -p -C text/xml <event.xml + + + + + + + See also + + librabbitmq-tools7 + describes connection-related options common to all the + RabbitMQ C Client tools. + + + diff --git a/ext/librabbitmq/tools/doc/librabbitmq-tools.xml b/ext/librabbitmq/tools/doc/librabbitmq-tools.xml new file mode 100644 index 00000000..e7e98aa7 --- /dev/null +++ b/ext/librabbitmq/tools/doc/librabbitmq-tools.xml @@ -0,0 +1,90 @@ + + +] +> + + + RabbitMQ C Client + + The RabbitMQ Team <info@rabbitmq.com> + + &date; + + + + librabbitmq-tools + 7 + RabbitMQ C Client + + + + librabbitmq-tools + Command line AMQP tools + + + + Description + + A set of command line AMQP tools based on librabbitmq. This page + describes common options and conventions used by all of + the tools. + + + + + Common Options + + + + =hostname:port + + + The host name (or address) to connect to. + Defaults to localhost. The port number may + also be specified; if omitted, it defaults to + the standard AMQP port number (5672). + + + + + =vhost + + + The AMQP vhost to specify when connecting. + Defaults to /. + + + + + =username + + + The username to authenticate to the AMQP server with. Defaults to guest. + + + + + =password + + + The password to authenticate to the AMQP server with. Defaults to guest. + + + + + + + + See also + + + amqp-publish1 + amqp-consume1 + amqp-get1 + + + + diff --git a/ext/librabbitmq/tools/get.c b/ext/librabbitmq/tools/get.c new file mode 100644 index 00000000..f418e2fd --- /dev/null +++ b/ext/librabbitmq/tools/get.c @@ -0,0 +1,78 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "common.h" + +static int do_get(amqp_connection_state_t conn, char *queue) { + amqp_rpc_reply_t r = amqp_basic_get(conn, 1, cstring_bytes(queue), 1); + die_rpc(r, "basic.get"); + + if (r.reply.id == AMQP_BASIC_GET_EMPTY_METHOD) { + return 0; + } + + copy_body(conn, 1); + return 1; +} + +int main(int argc, const char **argv) { + amqp_connection_state_t conn; + static char *queue = NULL; + int got_something; + + struct poptOption options[] = { + INCLUDE_OPTIONS(connect_options), + {"queue", 'q', POPT_ARG_STRING, &queue, 0, "the queue to consume from", + "queue"}, + POPT_AUTOHELP{NULL, '\0', 0, NULL, 0, NULL, NULL}}; + + process_all_options(argc, argv, options); + + if (!queue) { + fprintf(stderr, "queue not specified\n"); + return 1; + } + + conn = make_connection(); + got_something = do_get(conn, queue); + close_connection(conn); + return got_something ? 0 : 2; +} diff --git a/ext/librabbitmq/tools/publish.c b/ext/librabbitmq/tools/publish.c new file mode 100644 index 00000000..b2a2a1ef --- /dev/null +++ b/ext/librabbitmq/tools/publish.c @@ -0,0 +1,180 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "common.h" + +#define MAX_LINE_LENGTH 1024 * 32 + +static void do_publish(amqp_connection_state_t conn, char *exchange, + char *routing_key, amqp_basic_properties_t *props, + amqp_bytes_t body) { + int res = amqp_basic_publish(conn, 1, cstring_bytes(exchange), + cstring_bytes(routing_key), 0, 0, props, body); + die_amqp_error(res, "basic.publish"); +} + +int main(int argc, const char **argv) { + amqp_connection_state_t conn; + static char *exchange = NULL; + static char *routing_key = NULL; + static char *content_type = NULL; + static char *content_encoding = NULL; + static char **headers = NULL; + static char *reply_to = NULL; + static char *body = NULL; + amqp_basic_properties_t props; + amqp_bytes_t body_bytes; + static int delivery = 1; /* non-persistent by default */ + static int line_buffered = 0; + static char **pos; + + struct poptOption options[] = { + INCLUDE_OPTIONS(connect_options), + {"exchange", 'e', POPT_ARG_STRING, &exchange, 0, + "the exchange to publish to", "exchange"}, + {"routing-key", 'r', POPT_ARG_STRING, &routing_key, 0, + "the routing key to publish with", "routing key"}, + {"persistent", 'p', POPT_ARG_VAL, &delivery, 2, + "use the persistent delivery mode", NULL}, + {"content-type", 'C', POPT_ARG_STRING, &content_type, 0, + "the content-type for the message", "content type"}, + {"reply-to", 't', POPT_ARG_STRING, &reply_to, 0, + "the replyTo to use for the message", "reply to"}, + {"line-buffered", 'l', POPT_ARG_VAL, &line_buffered, 2, + "treat each line from standard in as a separate message", NULL}, + {"content-encoding", 'E', POPT_ARG_STRING, &content_encoding, 0, + "the content-encoding for the message", "content encoding"}, + {"header", 'H', POPT_ARG_ARGV, &headers, 0, + "set a message header (may be specified multiple times)", + "\"key: value\""}, + {"body", 'b', POPT_ARG_STRING, &body, 0, "specify the message body", + "body"}, + POPT_AUTOHELP{NULL, '\0', 0, NULL, 0, NULL, NULL}}; + + process_all_options(argc, argv, options); + + if (!exchange && !routing_key) { + fprintf(stderr, "neither exchange nor routing key specified\n"); + return 1; + } + + memset(&props, 0, sizeof props); + props._flags = AMQP_BASIC_DELIVERY_MODE_FLAG; + props.delivery_mode = delivery; + + if (content_type) { + props._flags |= AMQP_BASIC_CONTENT_TYPE_FLAG; + props.content_type = amqp_cstring_bytes(content_type); + } + + if (content_encoding) { + props._flags |= AMQP_BASIC_CONTENT_ENCODING_FLAG; + props.content_encoding = amqp_cstring_bytes(content_encoding); + } + + if (reply_to) { + props._flags |= AMQP_BASIC_REPLY_TO_FLAG; + props.reply_to = amqp_cstring_bytes(reply_to); + } + + if (headers) { + int num = 0; + for (pos = headers; *pos; pos++) { + num++; + } + + if (num > 0) { + amqp_table_t *table = &props.headers; + table->num_entries = num; + table->entries = calloc(num, sizeof(amqp_table_entry_t)); + int i = 0; + for (pos = headers; *pos; pos++) { + char *colon = strchr(*pos, ':'); + if (colon) { + *colon++ = '\0'; + while (*colon == ' ') colon++; + table->entries[i].key = amqp_cstring_bytes(*pos); + table->entries[i].value.kind = AMQP_FIELD_KIND_UTF8; + table->entries[i].value.value.bytes = amqp_cstring_bytes(colon); + i++; + } else { + fprintf(stderr, + "Ignored header definition missing ':' delimiter in \"%s\"\n", + *pos); + } + } + props._flags |= AMQP_BASIC_HEADERS_FLAG; + } + } + + conn = make_connection(); + + if (body) { + body_bytes = amqp_cstring_bytes(body); + } else { + if (line_buffered) { + body_bytes.bytes = (char *)malloc(MAX_LINE_LENGTH); + while (fgets(body_bytes.bytes, MAX_LINE_LENGTH, stdin)) { + body_bytes.len = strlen(body_bytes.bytes); + do_publish(conn, exchange, routing_key, &props, body_bytes); + } + } else { + body_bytes = read_all(0); + } + } + + if (!line_buffered) { + do_publish(conn, exchange, routing_key, &props, body_bytes); + } + + if (props.headers.num_entries > 0) { + free(props.headers.entries); + } + + if (!body) { + free(body_bytes.bytes); + } + + close_connection(conn); + return 0; +} diff --git a/ext/librabbitmq/tools/unix/process.c b/ext/librabbitmq/tools/unix/process.c new file mode 100644 index 00000000..596f40a8 --- /dev/null +++ b/ext/librabbitmq/tools/unix/process.c @@ -0,0 +1,91 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "common.h" +#include "process.h" + +extern char **environ; + +void pipeline(const char *const *argv, struct pipeline *pl) { + posix_spawn_file_actions_t file_acts; + + int pipefds[2]; + if (pipe(pipefds)) { + die_errno(errno, "pipe"); + } + + die_errno(posix_spawn_file_actions_init(&file_acts), + "posix_spawn_file_actions_init"); + die_errno(posix_spawn_file_actions_adddup2(&file_acts, pipefds[0], 0), + "posix_spawn_file_actions_adddup2"); + die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[0]), + "posix_spawn_file_actions_addclose"); + die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[1]), + "posix_spawn_file_actions_addclose"); + + die_errno(posix_spawnp(&pl->pid, argv[0], &file_acts, NULL, + (char *const *)argv, environ), + "posix_spawnp: %s", argv[0]); + + die_errno(posix_spawn_file_actions_destroy(&file_acts), + "posix_spawn_file_actions_destroy"); + + if (close(pipefds[0])) { + die_errno(errno, "close"); + } + + pl->infd = pipefds[1]; +} + +int finish_pipeline(struct pipeline *pl) { + int status; + + if (close(pl->infd)) { + die_errno(errno, "close"); + } + if (waitpid(pl->pid, &status, 0) < 0) { + die_errno(errno, "waitpid"); + } + return WIFEXITED(status) && WEXITSTATUS(status) == 0; +} diff --git a/ext/librabbitmq/tools/unix/process.h b/ext/librabbitmq/tools/unix/process.h new file mode 100644 index 00000000..59673f2c --- /dev/null +++ b/ext/librabbitmq/tools/unix/process.h @@ -0,0 +1,42 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +struct pipeline { + int pid; + int infd; +}; + +extern void pipeline(const char *const *argv, struct pipeline *pl); +extern int finish_pipeline(struct pipeline *pl); diff --git a/ext/librabbitmq/tools/win32/compat.c b/ext/librabbitmq/tools/win32/compat.c new file mode 100644 index 00000000..10828a6d --- /dev/null +++ b/ext/librabbitmq/tools/win32/compat.c @@ -0,0 +1,65 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "compat.h" + +int asprintf(char **strp, const char *fmt, ...) { + va_list ap; + int len; + + va_start(ap, fmt); + len = _vscprintf(fmt, ap); + va_end(ap); + + *strp = malloc(len + 1); + if (!*strp) { + return -1; + } + + va_start(ap, fmt); + _vsnprintf(*strp, len + 1, fmt, ap); + va_end(ap); + + (*strp)[len] = 0; + return len; +} diff --git a/ext/librabbitmq/tools/win32/compat.h b/ext/librabbitmq/tools/win32/compat.h new file mode 100644 index 00000000..d08532be --- /dev/null +++ b/ext/librabbitmq/tools/win32/compat.h @@ -0,0 +1,36 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +extern int asprintf(char **strp, const char *fmt, ...); diff --git a/ext/librabbitmq/tools/win32/process.c b/ext/librabbitmq/tools/win32/process.c new file mode 100644 index 00000000..fbb68f04 --- /dev/null +++ b/ext/librabbitmq/tools/win32/process.c @@ -0,0 +1,227 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "common.h" +#include "process.h" + +void die_windows_error(const char *fmt, ...) { + char *msg; + + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (!FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, + GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&msg, 0, NULL)) { + msg = "(failed to retrieve Windows error message)"; + } + + fprintf(stderr, ": %s\n", msg); + exit(1); +} + +static char *make_command_line(const char *const *argv) { + int i; + size_t len = 1; /* initial quotes */ + char *buf; + char *dest; + + /* calculate the length of the required buffer, making worst + case assumptions for simplicity */ + for (i = 0;;) { + /* each character could need escaping */ + len += strlen(argv[i]) * 2; + + if (!argv[++i]) { + break; + } + + len += 3; /* quotes, space, quotes */ + } + + len += 2; /* final quotes and the terminating zero */ + + dest = buf = malloc(len); + if (!buf) { + die("allocating memory for subprocess command line"); + } + + /* Here we perform the inverse of the CommandLineToArgvW + function. Note that its rules are slightly crazy: A + sequence of backslashes only act to escape if followed by + double quotes. A sequence of backslashes not followed by + double quotes is untouched. */ + + for (i = 0;;) { + const char *src = argv[i]; + int backslashes = 0; + + *dest++ = '\"'; + + for (;;) { + switch (*src) { + case 0: + goto done; + + case '\"': + for (; backslashes; backslashes--) { + *dest++ = '\\'; + } + + *dest++ = '\\'; + *dest++ = '\"'; + break; + + case '\\': + backslashes++; + *dest++ = '\\'; + break; + + default: + backslashes = 0; + *dest++ = *src; + break; + } + + src++; + } + done: + for (; backslashes; backslashes--) { + *dest++ = '\\'; + } + + *dest++ = '\"'; + + if (!argv[++i]) { + break; + } + + *dest++ = ' '; + } + + *dest++ = 0; + return buf; +} + +void pipeline(const char *const *argv, struct pipeline *pl) { + HANDLE in_read_handle, in_write_handle; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION proc_info; + STARTUPINFO start_info; + char *cmdline = make_command_line(argv); + + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = TRUE; + sec_attr.lpSecurityDescriptor = NULL; + + if (!CreatePipe(&in_read_handle, &in_write_handle, &sec_attr, 0)) { + die_windows_error("CreatePipe"); + } + + if (!SetHandleInformation(in_write_handle, HANDLE_FLAG_INHERIT, 0)) { + die_windows_error("SetHandleInformation"); + } + + /* when in Rome... */ + ZeroMemory(&proc_info, sizeof proc_info); + ZeroMemory(&start_info, sizeof start_info); + + start_info.cb = sizeof start_info; + start_info.dwFlags |= STARTF_USESTDHANDLES; + + if ((start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE)) == + INVALID_HANDLE_VALUE || + (start_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE)) == + INVALID_HANDLE_VALUE) { + die_windows_error("GetStdHandle"); + } + + start_info.hStdInput = in_read_handle; + + if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, + &start_info, &proc_info)) { + die_windows_error("CreateProcess"); + } + + free(cmdline); + + if (!CloseHandle(proc_info.hThread)) { + die_windows_error("CloseHandle for thread"); + } + if (!CloseHandle(in_read_handle)) { + die_windows_error("CloseHandle"); + } + + pl->proc_handle = proc_info.hProcess; + pl->infd = _open_osfhandle((intptr_t)in_write_handle, 0); +} + +int finish_pipeline(struct pipeline *pl) { + DWORD code; + + if (close(pl->infd)) { + die_errno(errno, "close"); + } + + for (;;) { + if (!GetExitCodeProcess(pl->proc_handle, &code)) { + die_windows_error("GetExitCodeProcess"); + } + if (code != STILL_ACTIVE) { + break; + } + + if (WaitForSingleObject(pl->proc_handle, INFINITE) == WAIT_FAILED) { + die_windows_error("WaitForSingleObject"); + } + } + + if (!CloseHandle(pl->proc_handle)) { + die_windows_error("CloseHandle for process"); + } + + return code; +} diff --git a/ext/librabbitmq/tools/win32/process.h b/ext/librabbitmq/tools/win32/process.h new file mode 100644 index 00000000..0dd05fbf --- /dev/null +++ b/ext/librabbitmq/tools/win32/process.h @@ -0,0 +1,44 @@ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#include + +struct pipeline { + HANDLE proc_handle; + int infd; +}; + +extern void pipeline(const char *const *argv, struct pipeline *pl); +extern int finish_pipeline(struct pipeline *pl); diff --git a/ext/librabbitmq/travis.sh b/ext/librabbitmq/travis.sh new file mode 100644 index 00000000..c21993b0 --- /dev/null +++ b/ext/librabbitmq/travis.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +build_cmake() { + mkdir $PWD/_build && cd $PWD/_build + cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/../_install -DCMAKE_C_FLAGS="-Werror" \ + ${_CMAKE_OPENSSL_FLAG} + cmake --build . --target install + ctest -V . +} + +build_format() { + ./travis/run-clang-format/run-clang-format.py \ + --clang-format-executable="${PWD}/travis/clang-format.sh" \ + --recursive examples librabbitmq tests tools +} + +build_coverage() { + mkdir $PWD/_build && cd $PWD/_build + cmake .. -DCMAKE_BUILD_TYPE=Coverage -DCMAKE_INSTALL_PREFIX=$PWD/../_install \ + -DCMAKE_C_FLAGS="-Werror -fprofile-arcs -ftest-coverage" \ + ${_CMAKE_OPENSSL_FLAG} + cmake --build . --target install + ctest -V . + + pip install --user cpp-coveralls + coveralls --exclude tests --build-root . --root .. --gcov-options '\-lp' +} + +build_asan() { + mkdir $PWD/_build && cd $PWD/_build + cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/../_install \ + -DCMAKE_C_FLAGS="-Werror -fsanitize=address,undefined -O1" + cmake --build . --target install + ctest -V . +} + +build_tsan() { + mkdir $PWD/_build && cd $PWD/_build + cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/../_install \ + -DCMAKE_C_FLAGS="-Werror -fsanitize=thread,undefined -O1" + cmake --build . --target install + ctest -V . +} + +build_scan-build() { + mkdir $PWD/_build && cd $PWD/_build + scan-build-3.9 cmake .. -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=$PWD/../_install \ + -DCMAKE_C_FLAGS="-Werror" + scan-build-3.9 make install +} + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 {cmake|asan|tsan|scan-build}" + exit 1 +fi + +set -e # exit on error. +set -x # echo commands. + +case $TRAVIS_OS_NAME in +osx) + # This prints out a long list of updated packages, which isn't useful. + brew update > /dev/null + brew install popt + brew outdated openssl || brew install openssl + export _CMAKE_OPENSSL_FLAG="-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl" + ;; +esac + +eval "build_$1" diff --git a/ext/librabbitmq/travis/clang-format.sh b/ext/librabbitmq/travis/clang-format.sh new file mode 100644 index 00000000..3b48c3be --- /dev/null +++ b/ext/librabbitmq/travis/clang-format.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -e + +exec clang-format-3.9 -style=file $@ diff --git a/ext/miniupnpc/Changelog.txt b/ext/miniupnpc/Changelog.txt deleted file mode 100644 index 37562c6a..00000000 --- a/ext/miniupnpc/Changelog.txt +++ /dev/null @@ -1,691 +0,0 @@ -$Id: Changelog.txt,v 1.229 2017/12/12 11:26:25 nanard Exp $ -miniUPnP client Changelog. - -2017/12/11: - Fix buffer over run in minixml.c - Fix uninitialized variable access in upnpreplyparse.c - -2017/05/05: - Fix CVE-2017-8798 Thanks to tin/Team OSTStrom - -2016/11/11: - check strlen before memcmp in XML parsing portlistingparse.c - fix build under SOLARIS and CYGWIN - -2016/10/11: - Add python 3 compatibility to IGD test - -VERSION 2.0 : released 2016/04/19 - -2016/01/24: - change miniwget to return HTTP status code - increments API_VERSION to 16 - -2016/01/22: - Improve UPNPIGD_IsConnected() to check if WAN address is not private. - parse HTTP response status line in miniwget.c - -2015/10/26: - snprintf() overflow check. check overflow in simpleUPnPcommand2() - -2015/10/25: - fix compilation with old macs - fix compilation with mingw32 (for Appveyor) - fix python module for python <= 2.3 - -2015/10/08: - Change sameport to localport - see https://github.com/miniupnp/miniupnp/pull/120 - increments API_VERSION to 15 - -2015/09/15: - Fix buffer overflow in igd_desc_parse.c/IGDstartelt() - Discovered by Aleksandar Nikolic of Cisco Talos - -2015/08/28: - move ssdpDiscoverDevices() to minissdpc.c - -2015/08/27: - avoid unix socket leak in getDevicesFromMiniSSDPD() - -2015/08/16: - Also accept "Up" as ConnectionStatus value - -2015/07/23: - split getDevicesFromMiniSSDPD - add ttl argument to upnpDiscover() functions - increments API_VERSION to 14 - -2015/07/22: - Read USN from SSDP messages. - -2015/07/15: - Check malloc/calloc - -2015/06/16: - update getDevicesFromMiniSSDPD() to process longer minissdpd - responses - -2015/05/22: - add searchalltypes param to upnpDiscoverDevices() - increments API_VERSION to 13 - -2015/04/30: - upnpc: output version on the terminal - -2015/04/27: - _BSD_SOURCE is deprecated in favor of _DEFAULT_SOURCE - fix CMakeLists.txt COMPILE_DEFINITIONS - fix getDevicesFromMiniSSDPD() not setting scope_id - improve -r command of upnpc command line tool - -2014/11/17: - search all : - upnpDiscoverDevices() / upnpDiscoverAll() functions - listdevices executable - increment API_VERSION to 12 - validate igd_desc_parse - -2014/11/13: - increment API_VERSION to 11 - -2014/11/05: - simplified function GetUPNPUrls() - -2014/09/11: - use remoteHost arg of DeletePortMapping - -2014/09/06: - Fix python3 build - -2014/07/01: - Fix parsing of IGD2 root descriptions - -2014/06/10: - rename LIBSPEC to MINIUPNP_LIBSPEC - -2014/05/15: - Add support for IGD2 AddAnyPortMapping and DeletePortMappingRange - -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/ext/miniupnpc/LICENSE b/ext/miniupnpc/LICENSE deleted file mode 100644 index 08167337..00000000 --- a/ext/miniupnpc/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -MiniUPnPc -Copyright (c) 2005-2016, 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/ext/miniupnpc/README b/ext/miniupnpc/README deleted file mode 100644 index 0d3b8054..00000000 --- a/ext/miniupnpc/README +++ /dev/null @@ -1,63 +0,0 @@ -Project: miniupnp -Project web page: http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ -github: https://github.com/miniupnp/miniupnp -Author: Thomas Bernard -Copyright (c) 2005-2017 Thomas Bernard -This software is subject to the conditions detailed in the -LICENSE file provided within this distribution. - - -* 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() -- UPNP_GetValidIGD() -- 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 : -https://miniupnp.tuxfamily.org/forum/ - -Bugs should be reported on github : -https://github.com/miniupnp/miniupnp/issues diff --git a/ext/miniupnpc/VERSION b/ext/miniupnpc/VERSION deleted file mode 100644 index cd5ac039..00000000 --- a/ext/miniupnpc/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.0 diff --git a/ext/miniupnpc/codelength.h b/ext/miniupnpc/codelength.h deleted file mode 100644 index f5f8e30f..00000000 --- a/ext/miniupnpc/codelength.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $Id: codelength.h,v 1.5 2015/07/09 12:40:18 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2005-2015 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 */ - -/* n : unsigned - * p : unsigned char * - */ -#define DECODELENGTH(n, p) n = 0; \ - do { n = (n << 7) | (*p & 0x7f); } \ - while((*(p++)&0x80) && (n<(1<<25))); - -/* n : unsigned - * READ : function/macro to read one byte (unsigned char) - */ -#define DECODELENGTH_READ(n, READ) \ - n = 0; \ - do { \ - unsigned char c; \ - READ(c); \ - n = (n << 7) | (c & 0x07f); \ - if(!(c&0x80)) break; \ - } while(n<(1<<25)); - -/* n : unsigned - * p : unsigned char * - * p_limit : unsigned char * - */ -#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))); - - -/* n : unsigned - * p : unsigned char * - */ -#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 /* CODELENGTH_H_INCLUDED */ diff --git a/ext/miniupnpc/connecthostport.c b/ext/miniupnpc/connecthostport.c deleted file mode 100644 index aed62c76..00000000 --- a/ext/miniupnpc/connecthostport.c +++ /dev/null @@ -1,262 +0,0 @@ -/* $Id: connecthostport.c,v 1.17 2017/04/21 09:58:30 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2010-2017 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 -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT -#include -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ -#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 -#include -#include -#endif /* #else _WIN32 */ - -/* definition of PRINT_SOCKET_ERROR */ -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "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 SO_RCVTIMEO"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO"); - } -#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/ext/miniupnpc/connecthostport.h b/ext/miniupnpc/connecthostport.h deleted file mode 100644 index 56941d6f..00000000 --- a/ext/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/ext/miniupnpc/igd_desc_parse.c b/ext/miniupnpc/igd_desc_parse.c deleted file mode 100644 index d2999ad0..00000000 --- a/ext/miniupnpc/igd_desc_parse.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id: igd_desc_parse.c,v 1.17 2015/09/15 13:30:04 nanard Exp $ */ -/* Project : miniupnp - * http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2015 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; - if(l >= MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE-1; - 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'; - } -} - -#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) - -/* 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(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) { - memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) { - memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPConnection:") - || COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANPPPConnection:") ) { - 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'; - } -} - -#ifdef DEBUG -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); -} -#endif /* DEBUG */ - diff --git a/ext/miniupnpc/igd_desc_parse.h b/ext/miniupnpc/igd_desc_parse.h deleted file mode 100644 index 0de546b6..00000000 --- a/ext/miniupnpc/igd_desc_parse.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $Id: igd_desc_parse.h,v 1.12 2014/11/17 17:19:13 nanard Exp $ */ -/* Project : miniupnp - * 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. - * */ -#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); -#ifdef DEBUG -void printIGD(struct IGDdatas *); -#endif /* DEBUG */ - -#endif /* IGD_DESC_PARSE_H_INCLUDED */ diff --git a/ext/miniupnpc/listdevices.c b/ext/miniupnpc/listdevices.c deleted file mode 100644 index a93c29ff..00000000 --- a/ext/miniupnpc/listdevices.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $Id: listdevices.c,v 1.7 2015/10/08 16:15:47 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2013-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#include -#ifdef _WIN32 -#include -#endif /* _WIN32 */ -#include "miniupnpc.h" - -int main(int argc, char * * argv) -{ - const char * searched_device = NULL; - const char * * searched_devices = NULL; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int ipv6 = 0; - unsigned char ttl = 2; - int error = 0; - struct UPNPDev * devlist = 0; - struct UPNPDev * dev; - int i; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - - for(i = 1; i < argc; i++) { - if(strcmp(argv[i], "-6") == 0) - ipv6 = 1; - else if(strcmp(argv[i], "-d") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-d"); - return 1; - } - searched_device = argv[i]; - } else if(strcmp(argv[i], "-t") == 0) { - if(++i >= argc) { - fprintf(stderr, "%s option needs one argument\n", "-t"); - return 1; - } - ttl = (unsigned char)atoi(argv[i]); - } else if(strcmp(argv[i], "-l") == 0) { - if(++i >= argc) { - fprintf(stderr, "-l option needs at least one argument\n"); - return 1; - } - searched_devices = (const char * *)(argv + i); - break; - } else if(strcmp(argv[i], "-m") == 0) { - if(++i >= argc) { - fprintf(stderr, "-m option needs one argument\n"); - return 1; - } - multicastif = argv[i]; - } else { - printf("usage : %s [options] [-l ...]\n", argv[0]); - printf("options :\n"); - printf(" -6 : use IPv6\n"); - printf(" -m address/ifname : network interface to use for multicast\n"); - printf(" -d : search only for this type of device\n"); - printf(" -l ... : search only for theses types of device\n"); - printf(" -t ttl : set multicast TTL. Default value is 2.\n"); - printf(" -h : this help\n"); - return 1; - } - } - - if(searched_device) { - printf("searching UPnP device type %s\n", searched_device); - devlist = upnpDiscoverDevice(searched_device, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } else if(searched_devices) { - printf("searching UPnP device types :\n"); - for(i = 0; searched_devices[i]; i++) - printf("\t%s\n", searched_devices[i]); - devlist = upnpDiscoverDevices(searched_devices, - 2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error, 1); - } else { - printf("searching all UPnP devices\n"); - devlist = upnpDiscoverAll(2000, multicastif, minissdpdpath, - 0/*localport*/, ipv6, ttl, &error); - } - if(devlist) { - for(dev = devlist, i = 1; dev != NULL; dev = dev->pNext, i++) { - printf("%3d: %-48s\n", i, dev->st); - printf(" %s\n", dev->descURL); - printf(" %s\n", dev->usn); - } - freeUPNPDevlist(devlist); - } else { - printf("no device found.\n"); - } - - return 0; -} - diff --git a/ext/miniupnpc/minisoap.c b/ext/miniupnpc/minisoap.c deleted file mode 100644 index 5b8c0784..00000000 --- a/ext/miniupnpc/minisoap.c +++ /dev/null @@ -1,134 +0,0 @@ -/* $Id: minisoap.c,v 1.25 2017/04/21 10:03:24 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2015 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" - -#ifdef _WIN32 -#define OS_STRING "Win32" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#ifdef __ANDROID__ -#define OS_STRING "Android" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -/* only for malloc */ -#include - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "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, we could use writev() for that */ - p = malloc(headerssize+bodysize); - if(!p) - return -1; - 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_VERSION_STRING ", 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); - if ((unsigned int)headerssize >= sizeof(headerbuf)) - return -1; -#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/ext/miniupnpc/minisoap.h b/ext/miniupnpc/minisoap.h deleted file mode 100644 index 14c859d1..00000000 --- a/ext/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/ext/miniupnpc/minissdpc.c b/ext/miniupnpc/minissdpc.c deleted file mode 100644 index 3479de8e..00000000 --- a/ext/miniupnpc/minissdpc.c +++ /dev/null @@ -1,893 +0,0 @@ -/* $Id: minissdpc.c,v 1.35 2017/11/02 15:34:36 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2017 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -/*#include */ -#include -#include -#include -#include -#if defined (__NetBSD__) -#include -#endif -#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) -#ifdef _WIN32 -#include -#include -#include -#include -#include -#define snprintf _snprintf -#if !defined(_MSC_VER) -#include -#else /* !defined(_MSC_VER) */ -typedef unsigned short uint16_t; -#endif /* !defined(_MSC_VER) */ -#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 */ -#endif /* _WIN32 */ -#if defined(__amigaos__) || defined(__amigaos4__) -#include -#endif /* defined(__amigaos__) || defined(__amigaos4__) */ -#if defined(__amigaos__) -#define uint16_t unsigned short -#endif /* defined(__amigaos__) */ -/* Hack */ -#define UNIX_PATH_LEN 108 -struct sockaddr_un { - uint16_t sun_family; - char sun_path[UNIX_PATH_LEN]; -}; -#else /* defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define closesocket close -#endif - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__) -#define HAS_IP_MREQN -#endif - -#if !defined(HAS_IP_MREQN) && !defined(_WIN32) -#include -#if defined(__sun) -#include -#endif -#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 - -#if defined(__amigaos__) || defined(__amigaos4__) -/* Amiga OS specific stuff */ -#define TIMEVAL struct timeval -#endif - -#include "minissdpc.h" -#include "miniupnpc.h" -#include "receivedata.h" - -#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) - -#include "codelength.h" - -struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error) -{ - struct UPNPDev * devlist = NULL; - int s; - int res; - - s = connectToMiniSSDPD(socketpath); - if (s < 0) { - if (error) - *error = s; - return NULL; - } - res = requestDevicesFromMiniSSDPD(s, devtype); - if (res < 0) { - if (error) - *error = res; - } else { - devlist = receiveDevicesFromMiniSSDPD(s, error); - } - disconnectFromMiniSSDPD(s); - return devlist; -} - -/* macros used to read from unix socket */ -#define READ_BYTE_BUFFER(c) \ - if((int)bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - c = buffer[bufferindex++]; - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif /* MIN */ - -#define READ_COPY_BUFFER(dst, len) \ - for(l = len, p = (unsigned char *)dst; l > 0; ) { \ - unsigned int lcopy; \ - if((int)bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - lcopy = MIN(l, (n - bufferindex)); \ - memcpy(p, buffer + bufferindex, lcopy); \ - l -= lcopy; \ - p += lcopy; \ - bufferindex += lcopy; \ - } - -#define READ_DISCARD_BUFFER(len) \ - for(l = len; l > 0; ) { \ - unsigned int lcopy; \ - if(bufferindex >= n) { \ - n = read(s, buffer, sizeof(buffer)); \ - if(n<=0) break; \ - bufferindex = 0; \ - } \ - lcopy = MIN(l, (n - bufferindex)); \ - l -= lcopy; \ - bufferindex += lcopy; \ - } - -int -connectToMiniSSDPD(const char * socketpath) -{ - int s; - struct sockaddr_un addr; -#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) - struct timeval timeout; -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - - s = socket(AF_UNIX, SOCK_STREAM, 0); - if(s < 0) - { - /*syslog(LOG_ERR, "socket(unix): %m");*/ - perror("socket(unix)"); - return MINISSDPC_SOCKET_ERROR; - } -#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) - /* setting a 3 seconds timeout */ - /* not supported for AF_UNIX sockets under Solaris */ - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - perror("setsockopt SO_RCVTIMEO unix"); - } - timeout.tv_sec = 3; - timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { - perror("setsockopt SO_SNDTIMEO unix"); - } -#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - if(!socketpath) - socketpath = "/var/run/minissdpd.sock"; - memset(&addr, 0, sizeof(addr)); - 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 MINISSDPC_SOCKET_ERROR; - } - return s; -} - -int -disconnectFromMiniSSDPD(int s) -{ - if (close(s) < 0) - return MINISSDPC_SOCKET_ERROR; - return MINISSDPC_SUCCESS; -} - -int -requestDevicesFromMiniSSDPD(int s, const char * devtype) -{ - unsigned char buffer[256]; - unsigned char * p; - unsigned int stsize, l; - - stsize = strlen(devtype); - if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8)) - { - buffer[0] = 3; /* request type 3 : everything */ - } - else - { - 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 ! */ -#ifdef DEBUG - fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n", - stsize, (unsigned)sizeof(buffer)); -#endif /* DEBUG */ - return MINISSDPC_INVALID_INPUT; - } - memcpy(p, devtype, stsize); - p += stsize; - if(write(s, buffer, p - buffer) < 0) - { - /*syslog(LOG_ERR, "write(): %m");*/ - perror("minissdpc.c: write()"); - return MINISSDPC_SOCKET_ERROR; - } - return MINISSDPC_SUCCESS; -} - -struct UPNPDev * -receiveDevicesFromMiniSSDPD(int s, int * error) -{ - struct UPNPDev * tmp; - struct UPNPDev * devlist = NULL; - unsigned char buffer[256]; - ssize_t n; - unsigned char * p; - unsigned char * url; - unsigned char * st; - unsigned int bufferindex; - unsigned int i, ndev; - unsigned int urlsize, stsize, usnsize, l; - - n = read(s, buffer, sizeof(buffer)); - if(n<=0) - { - perror("minissdpc.c: read()"); - if (error) - *error = MINISSDPC_SOCKET_ERROR; - return NULL; - } - ndev = buffer[0]; - bufferindex = 1; - for(i = 0; i < ndev; i++) - { - DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - return devlist; - } -#ifdef DEBUG - printf(" urlsize=%u", urlsize); -#endif /* DEBUG */ - url = malloc(urlsize); - if(url == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - return devlist; - } - READ_COPY_BUFFER(url, urlsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_return; - } - DECODELENGTH_READ(stsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_return; - } -#ifdef DEBUG - printf(" stsize=%u", stsize); -#endif /* DEBUG */ - st = malloc(stsize); - if (st == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - goto free_url_and_return; - } - READ_COPY_BUFFER(st, stsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_st_and_return; - } - DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_url_and_st_and_return; - } -#ifdef DEBUG - printf(" usnsize=%u\n", usnsize); -#endif /* DEBUG */ - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(tmp == NULL) { - if (error) - *error = MINISSDPC_MEMORY_ERROR; - goto free_url_and_st_and_return; - } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - memcpy(tmp->buffer, url, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - free(url); - free(st); - url = NULL; - st = NULL; - tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize; - READ_COPY_BUFFER(tmp->usn, usnsize); - if(n<=0) { - if (error) - *error = MINISSDPC_INVALID_SERVER_REPLY; - goto free_tmp_and_return; - } - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = 0; /* default value. scope_id is not available with MiniSSDPd */ - devlist = tmp; - } - if (error) - *error = MINISSDPC_SUCCESS; - return devlist; - -free_url_and_st_and_return: - free(st); -free_url_and_return: - free(url); - return devlist; - -free_tmp_and_return: - free(tmp); - return devlist; -} - -#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ - -/* 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, - const char * * usn, int * usnsize) -{ - 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(localport > 0 && localport < 65536) - p->sin6_port = htons((unsigned short)localport); - 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(localport > 0 && localport < 65536) - p->sin_port = htons((unsigned short)localport); - 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(pIPAddrTable) { - if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { - free(pIPAddrTable); - pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); - } - } - if(pIPAddrTable) { - dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 ); - if (dwRetVal == NO_ERROR) { -#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 /* _WIN32 */ - -#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 = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("setsockopt(SO_REUSEADDR,...)"); - return NULL; - } - - if(ipv6) { -#ifdef _WIN32 - DWORD mcastHops = ttl; - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char *)&mcastHops, sizeof(mcastHops)) < 0) -#else /* _WIN32 */ - int mcastHops = ttl; - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastHops, sizeof(mcastHops)) < 0) -#endif /* _WIN32 */ - { - PRINT_SOCKET_ERROR("setsockopt(IPV6_MULTICAST_HOPS,...)"); - } - } else { -#ifdef _WIN32 - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0) -#else /* _WIN32 */ - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) -#endif /* _WIN32 */ - { - /* not a fatal error */ - PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)"); - } - } - - 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 IPV6_MULTICAST_IF"); - } -#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 IP_MULTICAST_IF"); - } - } 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 IP_MULTICAST_IF"); - } -#elif !defined(_WIN32) - struct ifreq ifr; - int ifrlen = sizeof(ifr); - strncpy(ifr.ifr_name, multicastif, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; - if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0) - { - PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)"); - } - mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) - { - PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); - } -#else /* _WIN32 */ -#ifdef DEBUG - printf("Setting of multicast interface not supported with interface name.\n"); -#endif -#endif /* #ifdef HAS_IP_MREQN / !defined(_WIN32) */ - } - } - } - - /* 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 = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("bind"); - closesocket(sudp); - return NULL; - } - - if(error) - *error = MINISSDPC_SUCCESS; - /* Calculating maximum response time in seconds */ - mx = ((unsigned int)delay) / 1000u; - if(mx == 0) { - mx = 1; - delay = 1000; - } - /* receiving SSDP response packet */ - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { - sentok = 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, - deviceTypes[deviceIndex], mx); - if ((unsigned int)n >= sizeof(bufr)) { - if(error) - *error = MINISSDPC_MEMORY_ERROR; - goto error; - } -#ifdef DEBUG - /*printf("Sending %s", bufr);*/ - printf("Sending M-SEARCH request to %s with ST: %s\n", - ipv6 ? - (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") - : UPNP_MCAST_ADDR, - deviceTypes[deviceIndex]); -#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(SSDP_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(SSDP_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 = MINISSDPC_SOCKET_ERROR; - PRINT_SOCKET_ERROR("sendto"); - } else { - sentok = 1; - } -#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(SSDP_PORT), &hints, &servinfo)) != 0) { - if(error) - *error = MINISSDPC_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; - } else { - sentok = 1; - } - } - freeaddrinfo(servinfo); - if(!sentok) { - if(error) - *error = MINISSDPC_SOCKET_ERROR; - } -#endif /* #ifdef NO_GETADDRINFO */ - /* Waiting for SSDP REPLY packet to M-SEARCH - * if searchalltypes is set, enter the loop only - * when the last deviceType is reached */ - if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do { - n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); - if (n < 0) { - /* error */ - if(error) - *error = MINISSDPC_SOCKET_ERROR; - goto error; - } else if (n == 0) { - /* no data or Time Out */ -#ifdef DEBUG - printf("NODATA or TIMEOUT\n"); -#endif /* DEBUG */ - if (devlist && !searchalltypes) { - /* found some devices, stop now*/ - if(error) - *error = MINISSDPC_SUCCESS; - goto error; - } - } else { - const char * descURL=NULL; - int urlsize=0; - const char * st=NULL; - int stsize=0; - const char * usn=NULL; - int usnsize=0; - parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); - if(st&&descURL) { -#ifdef DEBUG - printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", - stsize, st, usnsize, (usn?usn:""), urlsize, descURL); -#endif /* DEBUG */ - 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' && - (usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) && - tmp->usn[usnsize] == '\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+usnsize); - if(!tmp) { - /* memory allocation error */ - if(error) - *error = MINISSDPC_MEMORY_ERROR; - goto error; - } - tmp->pNext = devlist; - tmp->descURL = tmp->buffer; - tmp->st = tmp->buffer + 1 + urlsize; - tmp->usn = tmp->st + 1 + stsize; - memcpy(tmp->buffer, descURL, urlsize); - tmp->buffer[urlsize] = '\0'; - memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - if(usn != NULL) - memcpy(tmp->usn, usn, usnsize); - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; - tmp->scope_id = scope_id; - devlist = tmp; - } - } - } while(n > 0); - if(ipv6) { - /* switch linklocal flag */ - if(linklocal) { - linklocal = 0; - --deviceIndex; - } else { - linklocal = 1; - } - } - } -error: - closesocket(sudp); - return devlist; -} - diff --git a/ext/miniupnpc/minissdpc.h b/ext/miniupnpc/minissdpc.h deleted file mode 100644 index a5c622b2..00000000 --- a/ext/miniupnpc/minissdpc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* $Id: minissdpc.h,v 1.7 2015/10/08 16:15:47 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2015 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 - -#include "miniupnpc_declspec.h" -#include "upnpdev.h" - -/* error codes : */ -#define MINISSDPC_SUCCESS (0) -#define MINISSDPC_UNKNOWN_ERROR (-1) -#define MINISSDPC_SOCKET_ERROR (-101) -#define MINISSDPC_MEMORY_ERROR (-102) -#define MINISSDPC_INVALID_INPUT (-103) -#define MINISSDPC_INVALID_SERVER_REPLY (-104) - -#ifdef __cplusplus -extern "C" { -#endif - -#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) - -MINIUPNP_LIBSPEC struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error); - -MINIUPNP_LIBSPEC int -connectToMiniSSDPD(const char * socketpath); - -MINIUPNP_LIBSPEC int -disconnectFromMiniSSDPD(int fd); - -MINIUPNP_LIBSPEC int -requestDevicesFromMiniSSDPD(int fd, const char * devtype); - -MINIUPNP_LIBSPEC struct UPNPDev * -receiveDevicesFromMiniSSDPD(int fd, int * error); - -#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ - -MINIUPNP_LIBSPEC struct UPNPDev * -ssdpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/ext/miniupnpc/miniupnpc.c b/ext/miniupnpc/miniupnpc.c deleted file mode 100644 index 2dc5c95c..00000000 --- a/ext/miniupnpc/miniupnpc.c +++ /dev/null @@ -1,722 +0,0 @@ -/* $Id: miniupnpc.c,v 1.149 2016/02/09 09:50:46 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2016 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#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 __GNU__ -#define MAXHOSTNAMELEN 64 -#endif - - -#include "miniupnpc.h" -#include "minissdpc.h" -#include "miniwget.h" -#include "minisoap.h" -#include "minixml.h" -#include "upnpcommands.h" -#include "connecthostport.h" - -/* compare the begining of a string with a constant string */ -#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -#define SOAPPREFIX "s" -#define SERVICEPREFIX "u" -#define SERVICEPREFIX2 'u' - -/* check if an ip address is a private (LAN) address - * see https://tools.ietf.org/html/rfc1918 */ -static int is_rfc1918addr(const char * addr) -{ - /* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ - if(COMPARE(addr, "192.168.")) - return 1; - /* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */ - if(COMPARE(addr, "10.")) - return 1; - /* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */ - if(COMPARE(addr, "172.")) { - int i = atoi(addr + 4); - if((16 <= i) && (i <= 31)) - return 1; - } - return 0; -} - -/* root description parsing */ -MINIUPNP_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]; - int soapbodylen; - char * buf; - int n; - int status_code; - - *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\">" - "" - "" - "\r\n", action, service, action); - if ((unsigned int)soapbodylen >= sizeof(soapbody)) - return NULL; - } - else - { - char * p; - const char * pe, * pv; - const char * const pend = soapbody + sizeof(soapbody); - 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); - if ((unsigned int)soapbodylen >= sizeof(soapbody)) - return NULL; - p = soapbody + soapbodylen; - while(args->elt) - { - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '<'; - - pe = args->elt; - while(p < pend && *pe) - *(p++) = *(pe++); - - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '>'; - - if((pv = args->val)) - { - while(p < pend && *pv) - *(p++) = *(pv++); - } - - if((p+2) > pend) /* check for space to write next 2 bytes */ - return NULL; - *(p++) = '<'; - *(p++) = '/'; - - pe = args->elt; - while(p < pend && *pe) - *(p++) = *(pe++); - - if(p >= pend) /* check for space to write next byte */ - return NULL; - *(p++) = '>'; - - args++; - } - if((p+4) > pend) /* check for space to write next 4 bytes */ - return NULL; - *(p++) = '<'; - *(p++) = '/'; - *(p++) = SERVICEPREFIX2; - *(p++) = ':'; - - pe = action; - while(p < pend && *pe) - *(p++) = *(pe++); - - strncpy(p, ">\r\n", - pend - p); - if(soapbody[sizeof(soapbody)-1]) /* strncpy pads buffer with 0s, so if it doesn't end in 0, could not fit full string */ - return NULL; - } - 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, &status_code); -#ifdef DEBUG - if(*bufsize > 0 && buf) - { - printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf); - } - else - { - printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize); - } -#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; -} - -/* upnpDiscoverDevices() : - * return a chained list of all devices found or NULL if - * no devices was found. - * It is up to the caller to free the chained list - * delay is in millisecond (poll). - * UDA v1.1 says : - * The TTL for the IP packet SHOULD default to 2 and - * SHOULD be configurable. */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes) -{ - struct UPNPDev * tmp; - struct UPNPDev * devlist = 0; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - int deviceIndex; -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - - if(error) - *error = UPNPDISCOVER_UNKNOWN_ERROR; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - /* first try to get infos from minissdpd ! */ - if(!minissdpdsock) - minissdpdsock = "/var/run/minissdpd.sock"; - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { - struct UPNPDev * minissdpd_devlist; - int only_rootdevice = 1; - minissdpd_devlist = getDevicesFromMiniSSDPD(deviceTypes[deviceIndex], - minissdpdsock, 0); - if(minissdpd_devlist) { -#ifdef DEBUG - printf("returned by MiniSSDPD: %s\t%s\n", - minissdpd_devlist->st, minissdpd_devlist->descURL); -#endif /* DEBUG */ - if(!strstr(minissdpd_devlist->st, "rootdevice")) - only_rootdevice = 0; - for(tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) { -#ifdef DEBUG - printf("returned by MiniSSDPD: %s\t%s\n", - tmp->pNext->st, tmp->pNext->descURL); -#endif /* DEBUG */ - if(!strstr(tmp->st, "rootdevice")) - only_rootdevice = 0; - } - tmp->pNext = devlist; - devlist = minissdpd_devlist; - if(!searchalltypes && !only_rootdevice) - break; - } - } - for(tmp = devlist; tmp != NULL; tmp = tmp->pNext) { - /* We return what we have found if it was not only a rootdevice */ - if(!strstr(tmp->st, "rootdevice")) { - if(error) - *error = UPNPDISCOVER_SUCCESS; - return devlist; - } - } -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - - /* direct discovery if minissdpd responses are not sufficient */ - { - struct UPNPDev * discovered_devlist; - discovered_devlist = ssdpDiscoverDevices(deviceTypes, delay, multicastif, localport, - ipv6, ttl, error, searchalltypes); - if(devlist == NULL) - devlist = discovered_devlist; - else { - for(tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext); - tmp->pNext = discovered_devlist; - } - } - return devlist; -} - -/* upnpDiscover() Discover IGD device */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - static const char * const deviceList[] = { -#if 0 - "urn:schemas-upnp-org:device:InternetGatewayDevice:2", - "urn:schemas-upnp-org:service:WANIPConnection:2", -#endif - "urn:schemas-upnp-org:device:InternetGatewayDevice:1", - "urn:schemas-upnp-org:service:WANIPConnection:1", - "urn:schemas-upnp-org:service:WANPPPConnection:1", - "upnp:rootdevice", - /*"ssdp:all",*/ - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -/* upnpDiscoverAll() Discover all UPnP devices */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - static const char * const deviceList[] = { - /*"upnp:rootdevice",*/ - "ssdp:all", - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -/* upnpDiscoverDevice() Discover a specific device */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ - const char * const deviceList[] = { - device, - 0 - }; - return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); -} - -static char * -build_absolute_url(const char * baseurl, const char * descURL, - const char * url, unsigned int scope_id) -{ - int l, n; - char * s; - const char * base; - char * p; -#if defined(IF_NAMESIZE) && !defined(_WIN32) - char ifname[IF_NAMESIZE]; -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - char scope_str[8]; -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - - if( (url[0] == 'h') - &&(url[1] == 't') - &&(url[2] == 't') - &&(url[3] == 'p') - &&(url[4] == ':') - &&(url[5] == '/') - &&(url[6] == '/')) - return strdup(url); - base = (baseurl[0] == '\0') ? descURL : baseurl; - n = strlen(base); - if(n > 7) { - p = strchr(base + 7, '/'); - if(p) - n = p - base; - } - l = n + strlen(url) + 1; - if(url[0] != '/') - l++; - if(scope_id != 0) { -#if defined(IF_NAMESIZE) && !defined(_WIN32) - if(if_indextoname(scope_id, ifname)) { - l += 3 + strlen(ifname); /* 3 == strlen(%25) */ - } -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - /* under windows, scope is numerical */ - l += 3 + snprintf(scope_str, sizeof(scope_str), "%u", scope_id); -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - } - s = malloc(l); - if(s == NULL) return NULL; - memcpy(s, base, n); - if(scope_id != 0) { - s[n] = '\0'; - if(0 == memcmp(s, "http://[fe80:", 13)) { - /* this is a linklocal IPv6 address */ - p = strchr(s, ']'); - if(p) { - /* insert %25 into URL */ -#if defined(IF_NAMESIZE) && !defined(_WIN32) - memmove(p + 3 + strlen(ifname), p, strlen(p) + 1); - memcpy(p, "%25", 3); - memcpy(p + 3, ifname, strlen(ifname)); - n += 3 + strlen(ifname); -#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1); - memcpy(p, "%25", 3); - memcpy(p + 3, scope_str, strlen(scope_str)); - n += 3 + strlen(scope_str); -#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - } - } - } - if(url[0] != '/') - s[n++] = '/'; - memcpy(s + n, url, l - n); - return s; -} - -/* Prepare the Urls for usage... - */ -MINIUPNP_LIBSPEC void -GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, - const char * descURL, unsigned int scope_id) -{ - /* strdup descURL */ - urls->rootdescURL = strdup(descURL); - - /* get description of WANIPConnection */ - urls->ipcondescURL = build_absolute_url(data->urlbase, descURL, - data->first.scpdurl, scope_id); - urls->controlURL = build_absolute_url(data->urlbase, descURL, - data->first.controlurl, scope_id); - urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL, - data->CIF.controlurl, scope_id); - urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL, - data->IPv6FC.controlurl, scope_id); - -#ifdef DEBUG - printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL); - printf("urls->controlURL='%s'\n", urls->controlURL); - printf("urls->controlURL_CIF='%s'\n", urls->controlURL_CIF); - printf("urls->controlURL_6FC='%s'\n", urls->controlURL_6FC); -#endif -} - -MINIUPNP_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 if(0 == strcmp("Up", status)) /* Also accept "Up" */ - 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. Dont forget to call FreeUPNPUrls(urls) to - * free allocated memory. - */ -MINIUPNP_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]; - char myLanAddr[40]; - int status_code = -1; - - 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), - myLanAddr, sizeof(myLanAddr), - dev->scope_id, &status_code); -#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(COMPARE(data->CIF.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) - { - desc[i].is_igd = 1; - n_igd++; - if(lanaddr) - strncpy(lanaddr, myLanAddr, lanaddrlen); - } - } - } - /* 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 ) - { - int is_connected; - - 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; - is_connected = UPNPIGD_IsConnected(urls, data); -#ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, is_connected); -#endif - /* checks that status is connected AND there is a external IP address assigned */ - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.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); - is_connected = UPNPIGD_IsConnected(urls, data); -#ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, is_connected); -#endif - if(is_connected && - (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { - if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') - && (0 != strcmp(extIpAddr, "0.0.0.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, NULL); - 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/ext/miniupnpc/miniupnpc.def b/ext/miniupnpc/miniupnpc.def deleted file mode 100644 index 60e0bbe4..00000000 --- a/ext/miniupnpc/miniupnpc.def +++ /dev/null @@ -1,45 +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_AddAnyPortMapping - UPNP_DeletePortMapping - UPNP_DeletePortMappingRange - 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/ext/miniupnpc/miniupnpc.h b/ext/miniupnpc/miniupnpc.h deleted file mode 100644 index 4a805b11..00000000 --- a/ext/miniupnpc/miniupnpc.h +++ /dev/null @@ -1,152 +0,0 @@ -/* $Id: miniupnpc.h,v 1.50 2016/04/19 21:06:21 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ - * Author: Thomas Bernard - * Copyright (c) 2005-2016 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 "miniupnpc_declspec.h" -#include "igd_desc_parse.h" -#include "upnpdev.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 "2.0.20171212" -#define MINIUPNPC_API_VERSION 16 - -/* Source port: - Using "1" as an alias for 1900 for backwards compatability - (presuming one would have used that for the "sameport" parameter) */ -#define UPNP_LOCAL_PORT_ANY 0 -#define UPNP_LOCAL_PORT_SAME 1 - -#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 *); - -/* 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 localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent - * from the source port 1900 (same as destination port), if set to - * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will - * be attempted as the source port. - * "searchalltypes" parameter is useful when searching several types, - * if 0, the discovery will stop with the first type returning results. - * TTL should default to 2. */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); - -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); - -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); - -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes); - -/* parserootdesc() : - * parse root XML description of a UPnP device and fill the IGDdatas - * structure. */ -MINIUPNP_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. - */ -MINIUPNP_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. - * When succeding, urls, data, and lanaddr arguments are set. - * return value : - * 0 - Not ok - * 1 - OK */ -MINIUPNP_LIBSPEC int -UPNP_GetIGDFromUrl(const char * rootdescurl, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen); - -MINIUPNP_LIBSPEC void -GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, - const char *, unsigned int); - -MINIUPNP_LIBSPEC void -FreeUPNPUrls(struct UPNPUrls *); - -/* return 0 or 1 */ -MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/ext/miniupnpc/miniupnpc_declspec.h b/ext/miniupnpc/miniupnpc_declspec.h deleted file mode 100644 index 40adb922..00000000 --- a/ext/miniupnpc/miniupnpc_declspec.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef MINIUPNPC_DECLSPEC_H_INCLUDED -#define MINIUPNPC_DECLSPEC_H_INCLUDED - -#if defined(_WIN32) && !defined(MINIUPNP_STATICLIB) - /* for windows dll */ - #ifdef MINIUPNP_EXPORTS - #define MINIUPNP_LIBSPEC __declspec(dllexport) - #else - #define MINIUPNP_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 MINIUPNP_LIBSPEC __attribute__ ((visibility ("default"))) - #else - #define MINIUPNP_LIBSPEC - #endif -#endif - -#endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */ - diff --git a/ext/miniupnpc/miniupnpcmodule.c b/ext/miniupnpc/miniupnpcmodule.c deleted file mode 100644 index bbff0738..00000000 --- a/ext/miniupnpc/miniupnpcmodule.c +++ /dev/null @@ -1,703 +0,0 @@ -/* $Id: miniupnpcmodule.c,v 1.31 2017/11/02 15:37:28 nanard Exp $*/ -/* Project : miniupnp - * Author : Thomas BERNARD - * website : http://miniupnp.tuxfamily.org/ - * copyright (c) 2007-2016 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include -#define MINIUPNP_STATICLIB -#include "structmember.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" - -#ifdef _WIN32 -#include -#endif - -/* 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() */ - unsigned int localport; /* 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" - }, - {"localport", T_UINT, offsetof(UPnPObject, localport), - 0/*READWRITE*/, - "If localport is set to UPNP_LOCAL_PORT_SAME(1) " - "SSDP packets will be sent from the source port " - "1900 (same as destination port), if set to " - "UPNP_LOCAL_PORT_ANY(0) system assign a source " - "port, any other value will be attempted as the " - "source port" - }, - /* 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, minissdpdsocket), - 0, "path of the MiniSSDPd unix socket" - }, - {NULL} -}; - - -static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds) -{ - char* multicastif = NULL; - char* minissdpdsocket = NULL; - static char *kwlist[] = { - "multicastif", "minissdpdsocket", "discoverdelay", - "localport", NULL - }; - - if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist, - &multicastif, - &minissdpdsocket, - &self->discoverdelay, - &self->localport)) - return -1; - - if(self->localport>1 && - (self->localport>65534||self->localport<1024)) { - PyErr_SetString(PyExc_Exception, "Invalid localport value"); - return -1; - } - if(multicastif) - self->multicastif = strdup(multicastif); - if(minissdpdsocket) - self->minissdpdsocket = strdup(minissdpdsocket); - - return 0; -} - -static void -UPnPObject_dealloc(UPnPObject *self) -{ - freeUPNPDevlist(self->devlist); - FreeUPNPUrls(&self->urls); - free(self->multicastif); - free(self->minissdpdsocket); - 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*/, - self->multicastif, - self->minissdpdsocket, - (int)self->localport, - 0/*ip v6*/, - 2/* TTL */, - 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 -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -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 -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -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 -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -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 -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", i); -#else - return Py_BuildValue("i", (int)i); -#endif -} - -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) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror); -#else - return Py_BuildValue("(s,i,s)", status, (int)uptime, lastconnerror); -#endif - } 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, "HssHzz", &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; - } -} - -/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc, - * remoteHost) - * protocol is 'UDP' or 'TCP' */ -static PyObject * -UPnP_addanyportmapping(UPnPObject *self, PyObject *args) -{ - char extPort[6]; - unsigned short ePort; - char inPort[6]; - unsigned short iPort; - char reservedPort[6]; - const char * proto; - const char * host; - const char * desc; - const char * remoteHost; - const char * leaseDuration = "0"; - int r; - if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPort, "%hu", ePort); - sprintf(inPort, "%hu", iPort); - r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype, - extPort, inPort, host, desc, proto, - remoteHost, leaseDuration, reservedPort); -Py_END_ALLOW_THREADS - if(r==UPNPCOMMAND_SUCCESS) { - return Py_BuildValue("i", atoi(reservedPort)); - } else { - /* 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; - } -} - -/* DeletePortMappingRange(extPort, proto, removeHost='') - * proto = 'UDP', 'TCP' */ -static PyObject * -UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args) -{ - char extPortStart[6]; - unsigned short ePortStart; - char extPortEnd[6]; - unsigned short ePortEnd; - const char * proto; - unsigned char manage; - char manageStr[1]; - int r; - if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage)) - return NULL; -Py_BEGIN_ALLOW_THREADS - sprintf(extPortStart, "%hu", ePortStart); - sprintf(extPortEnd, "%hu", ePortEnd); - sprintf(manageStr, "%hhu", manage); - r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype, - extPortStart, extPortEnd, proto, manageStr); -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) { -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("I", n); -#else - return Py_BuildValue("i", (int)n); -#endif - } 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); -#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3) - return Py_BuildValue("(H,s,(s,H),s,s,s,I)", - ePort, protocol, intClient, iPort, - desc, enabled, rHost, dur); -#else - return Py_BuildValue("(i,s,(s,i),s,s,s,i)", - (int)ePort, protocol, intClient, (int)iPort, - desc, enabled, rHost, (int)dur); -#endif - } - 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" - }, - {"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS, - "add a port mapping, IGD to select alternative if necessary" - }, - {"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS, - "delete a port mapping" - }, - {"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS, - "delete a range of port mappings" - }, - {"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 */ - (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 - /* initialize Winsock. */ - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - - UPnPType.tp_new = PyType_GenericNew; -#endif - if (PyType_Ready(&UPnPType) < 0) -#if PY_MAJOR_VERSION >= 3 - return 0; -#else - return; -#endif - -#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/ext/miniupnpc/miniupnpcstrings.h.in b/ext/miniupnpc/miniupnpcstrings.h.in deleted file mode 100644 index 68bf4293..00000000 --- a/ext/miniupnpc/miniupnpcstrings.h.in +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: miniupnpcstrings.h.in,v 1.6 2014/11/04 22:31:55 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2014 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" - -#if 0 -/* according to "UPnP Device Architecture 1.0" */ -#define UPNP_VERSION_STRING "UPnP/1.0" -#else -/* according to "UPnP Device Architecture 1.1" */ -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#endif - diff --git a/ext/miniupnpc/miniupnpctypes.h b/ext/miniupnpc/miniupnpctypes.h deleted file mode 100644 index 591c32fb..00000000 --- a/ext/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/ext/miniupnpc/miniwget.c b/ext/miniupnpc/miniwget.c deleted file mode 100644 index e23f11e3..00000000 --- a/ext/miniupnpc/miniwget.c +++ /dev/null @@ -1,673 +0,0 @@ -/* $Id: miniwget.c,v 1.77 2017/05/09 10:04:57 nanard Exp $ */ -/* Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2017 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 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 -#include -#include -#include -#include -#define closesocket close -#include -#endif /* #else _WIN32 */ -#ifdef __GNU__ -#define MAXHOSTNAMELEN 64 -#endif /* __GNU__ */ - -#ifndef MIN -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif /* MIN */ - -#ifdef _WIN32 -#define OS_STRING "Win32" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#ifdef __ANDROID__ -#define OS_STRING "Android" -#define MINIUPNPC_VERSION_STRING "2.0" -#define UPNP_VERSION_STRING "UPnP/1.1" -#endif - -#include "miniwget.h" -#include "connecthostport.h" -#include "receivedata.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -/* - * Read a HTTP response from a socket. - * Process Content-Length and Transfer-encoding headers. - * return a pointer to the content buffer, which length is saved - * to the length parameter. - */ -void * -getHTTPResponse(int s, int * size, int * status_code) -{ - char buf[2048]; - int n; - int endofheaders = 0; - int chunked = 0; - int content_length = -1; - unsigned int chunksize = 0; - unsigned int bytestocopy = 0; - /* buffers : */ - char * header_buf; - unsigned int header_buf_len = 2048; - unsigned int header_buf_used = 0; - char * content_buf; - unsigned int content_buf_len = 2048; - unsigned int content_buf_used = 0; - char chunksize_buf[32]; - unsigned int chunksize_buf_index; -#ifdef DEBUG - char * reason_phrase = NULL; - int reason_phrase_len = 0; -#endif - - if(status_code) *status_code = -1; - header_buf = malloc(header_buf_len); - if(header_buf == NULL) - { -#ifdef DEBUG - fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); -#endif /* DEBUG */ - *size = -1; - return NULL; - } - content_buf = malloc(content_buf_len); - if(content_buf == NULL) - { - free(header_buf); -#ifdef DEBUG - fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); -#endif /* DEBUG */ - *size = -1; - return NULL; - } - chunksize_buf[0] = '\0'; - chunksize_buf_index = 0; - - while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0) - { - if(endofheaders == 0) - { - int i; - int linestart=0; - int colon=0; - int valuestart=0; - if(header_buf_used + n > header_buf_len) { - char * tmp = realloc(header_buf, header_buf_used + n); - if(tmp == NULL) { - /* memory allocation error */ - free(header_buf); - free(content_buf); - *size = -1; - return NULL; - } - header_buf = tmp; - header_buf_len = header_buf_used + n; - } - memcpy(header_buf + header_buf_used, buf, n); - header_buf_used += n; - /* search for CR LF CR LF (end of headers) - * recognize also LF LF */ - i = 0; - while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { - if(header_buf[i] == '\r') { - i++; - if(header_buf[i] == '\n') { - i++; - if(i < (int)header_buf_used && header_buf[i] == '\r') { - i++; - if(i < (int)header_buf_used && header_buf[i] == '\n') { - endofheaders = i+1; - } - } - } - } else if(header_buf[i] == '\n') { - i++; - if(header_buf[i] == '\n') { - endofheaders = i+1; - } - } - i++; - } - if(endofheaders == 0) - continue; - /* parse header lines */ - for(i = 0; i < endofheaders - 1; i++) { - if(linestart > 0 && colon <= linestart && header_buf[i]==':') - { - colon = i; - while(i < (endofheaders-1) - && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t')) - i++; - valuestart = i + 1; - } - /* detecting end of line */ - else if(header_buf[i]=='\r' || header_buf[i]=='\n') - { - if(linestart == 0 && status_code) - { - /* Status line - * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ - int sp; - for(sp = 0; sp < i; sp++) - if(header_buf[sp] == ' ') - { - if(*status_code < 0) - *status_code = atoi(header_buf + sp + 1); - else - { -#ifdef DEBUG - reason_phrase = header_buf + sp + 1; - reason_phrase_len = i - sp - 1; -#endif - break; - } - } -#ifdef DEBUG - printf("HTTP status code = %d, Reason phrase = %.*s\n", - *status_code, reason_phrase_len, reason_phrase); -#endif - } - else if(colon > linestart && valuestart > colon) - { -#ifdef DEBUG - printf("header='%.*s', value='%.*s'\n", - colon-linestart, header_buf+linestart, - i-valuestart, header_buf+valuestart); -#endif - if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart)) - { - content_length = atoi(header_buf+valuestart); -#ifdef DEBUG - printf("Content-Length: %d\n", content_length); -#endif - } - else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart) - && 0==strncasecmp(header_buf+valuestart, "chunked", 7)) - { -#ifdef DEBUG - printf("chunked transfer-encoding!\n"); -#endif - chunked = 1; - } - } - while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n')) - i++; - linestart = i; - colon = linestart; - valuestart = 0; - } - } - /* copy the remaining of the received data back to buf */ - n = header_buf_used - endofheaders; - memcpy(buf, header_buf + endofheaders, n); - /* if(headers) */ - } - if(endofheaders) - { - /* content */ - if(chunked) - { - int i = 0; - while(i < n) - { - if(chunksize == 0) - { - /* reading chunk size */ - if(chunksize_buf_index == 0) { - /* skipping any leading CR LF */ - if(i= '0' - && chunksize_buf[j] <= '9') - chunksize = (chunksize << 4) + (chunksize_buf[j] - '0'); - else - chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10); - } - chunksize_buf[0] = '\0'; - chunksize_buf_index = 0; - i++; - } else { - /* not finished to get chunksize */ - continue; - } -#ifdef DEBUG - printf("chunksize = %u (%x)\n", chunksize, chunksize); -#endif - if(chunksize == 0) - { -#ifdef DEBUG - printf("end of HTTP content - %d %d\n", i, n); - /*printf("'%.*s'\n", n-i, buf+i);*/ -#endif - goto end_of_stream; - } - } - /* it is guaranteed that (n >= i) */ - bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i); - if((content_buf_used + bytestocopy) > content_buf_len) - { - char * tmp; - if((content_length >= 0) && ((unsigned int)content_length >= (content_buf_used + bytestocopy))) { - content_buf_len = content_length; - } else { - content_buf_len = content_buf_used + bytestocopy; - } - tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { - /* memory allocation error */ - free(content_buf); - free(header_buf); - *size = -1; - return NULL; - } - content_buf = tmp; - } - memcpy(content_buf + content_buf_used, buf + i, bytestocopy); - content_buf_used += bytestocopy; - i += bytestocopy; - chunksize -= bytestocopy; - } - } - else - { - /* not chunked */ - if(content_length > 0 - && (content_buf_used + n) > (unsigned int)content_length) { - /* skipping additional bytes */ - n = content_length - content_buf_used; - } - if(content_buf_used + n > content_buf_len) - { - char * tmp; - if(content_length >= 0 - && (unsigned int)content_length >= (content_buf_used + n)) { - content_buf_len = content_length; - } else { - content_buf_len = content_buf_used + n; - } - tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { - /* memory allocation error */ - free(content_buf); - free(header_buf); - *size = -1; - return NULL; - } - content_buf = tmp; - } - memcpy(content_buf + content_buf_used, buf, n); - content_buf_used += n; - } - } - /* use the Content-Length header value if available */ - if(content_length > 0 && content_buf_used >= (unsigned int)content_length) - { -#ifdef DEBUG - printf("End of HTTP content\n"); -#endif - break; - } - } -end_of_stream: - free(header_buf); header_buf = NULL; - *size = content_buf_used; - if(content_buf_used == 0) - { - free(content_buf); - content_buf = NULL; - } - return content_buf; -} - -/* miniwget3() : - * do all the work. - * Return NULL if something failed. */ -static void * -miniwget3(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - const char * httpversion, unsigned int scope_id, - int * status_code) -{ - char buf[2048]; - int s; - int n; - int len; - int sent; - void * content; - - *size = 0; - s = connecthostport(host, port, scope_id); - if(s < 0) - return NULL; - - /* get address for caller ! */ - if(addr_str) - { - struct sockaddr_storage saddr; - socklen_t saddrlen; - - saddrlen = sizeof(saddr); - if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0) - { - perror("getsockname"); - } - else - { -#if defined(__amigaos__) && !defined(__amigaos4__) - /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD); - * But his function make a string with the port : nn.nn.nn.nn:port */ -/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr), - NULL, addr_str, (DWORD *)&addr_str_len)) - { - printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); - }*/ - /* the following code is only compatible with ip v4 addresses */ - strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len); -#else -#if 0 - if(saddr.sa_family == AF_INET6) { - inet_ntop(AF_INET6, - &(((struct sockaddr_in6 *)&saddr)->sin6_addr), - addr_str, addr_str_len); - } else { - inet_ntop(AF_INET, - &(((struct sockaddr_in *)&saddr)->sin_addr), - addr_str, addr_str_len); - } -#endif - /* getnameinfo return ip v6 address with the scope identifier - * such as : 2a01:e35:8b2b:7330::%4281128194 */ - n = getnameinfo((const struct sockaddr *)&saddr, saddrlen, - addr_str, addr_str_len, - NULL, 0, - NI_NUMERICHOST | NI_NUMERICSERV); - if(n != 0) { -#ifdef _WIN32 - fprintf(stderr, "getnameinfo() failed : %d\n", n); -#else - fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); -#endif - } -#endif - } -#ifdef DEBUG - printf("address miniwget : %s\n", addr_str); -#endif - } - - len = snprintf(buf, sizeof(buf), - "GET %s HTTP/%s\r\n" - "Host: %s:%d\r\n" - "Connection: Close\r\n" - "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - - "\r\n", - path, httpversion, host, port); - if ((unsigned int)len >= sizeof(buf)) - { - closesocket(s); - return NULL; - } - sent = 0; - /* sending the HTTP request */ - while(sent < len) - { - n = send(s, buf+sent, len-sent, 0); - if(n < 0) - { - perror("send"); - closesocket(s); - return NULL; - } - else - { - sent += n; - } - } - content = getHTTPResponse(s, size, status_code); - closesocket(s); - return content; -} - -/* miniwget2() : - * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ -static void * -miniwget2(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - unsigned int scope_id, int * status_code) -{ - char * respbuffer; - -#if 1 - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); -#else - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.0", - scope_id, status_code); - if (*size == 0) - { -#ifdef DEBUG - printf("Retrying with HTTP/1.1\n"); -#endif - free(respbuffer); - respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", - scope_id, status_code); - } -#endif - return respbuffer; -} - - - - -/* parseURL() - * arguments : - * url : source string not modified - * hostname : hostname destination string (size of MAXHOSTNAMELEN+1) - * port : port (destination) - * path : pointer to the path part of the URL - * - * Return values : - * 0 - Failure - * 1 - Success */ -int -parseURL(const char * url, - char * hostname, unsigned short * port, - char * * path, unsigned int * scope_id) -{ - char * p1, *p2, *p3; - if(!url) - return 0; - p1 = strstr(url, "://"); - if(!p1) - return 0; - p1 += 3; - if( (url[0]!='h') || (url[1]!='t') - ||(url[2]!='t') || (url[3]!='p')) - return 0; - memset(hostname, 0, MAXHOSTNAMELEN + 1); - if(*p1 == '[') - { - /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ - char * scope; - scope = strchr(p1, '%'); - p2 = strchr(p1, ']'); - if(p2 && scope && scope < p2 && scope_id) { - /* parse scope */ -#ifdef IF_NAMESIZE - char tmp[IF_NAMESIZE]; - int l; - scope++; - /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') - scope += 2; /* skip "25" */ - l = p2 - scope; - if(l >= IF_NAMESIZE) - l = IF_NAMESIZE - 1; - memcpy(tmp, scope, l); - tmp[l] = '\0'; - *scope_id = if_nametoindex(tmp); - if(*scope_id == 0) { - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); - } -#else - /* under windows, scope is numerical */ - char tmp[8]; - int l; - scope++; - /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') - scope += 2; /* skip "25" */ - l = p2 - scope; - if(l >= sizeof(tmp)) - l = sizeof(tmp) - 1; - memcpy(tmp, scope, l); - tmp[l] = '\0'; - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); -#endif - } - p3 = strchr(p1, '/'); - if(p2 && p3) - { - p2++; - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); - if(*p2 == ':') - { - *port = 0; - p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { - *port *= 10; - *port += (unsigned short)(*p2 - '0'); - p2++; - } - } - else - { - *port = 80; - } - *path = p3; - return 1; - } - } - p2 = strchr(p1, ':'); - p3 = strchr(p1, '/'); - if(!p3) - return 0; - if(!p2 || (p2>p3)) - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1))); - *port = 80; - } - else - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); - *port = 0; - p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { - *port *= 10; - *port += (unsigned short)(*p2 - '0'); - p2++; - } - } - *path = p3; - return 1; -} - -void * -miniwget(const char * url, int * size, - unsigned int scope_id, int * status_code) -{ - unsigned short port; - char * path; - /* protocol://host:port/chemin */ - char hostname[MAXHOSTNAMELEN+1]; - *size = 0; - if(!parseURL(url, hostname, &port, &path, &scope_id)) - return NULL; -#ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); -#endif - return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code); -} - -void * -miniwget_getaddr(const char * url, int * size, - char * addr, int addrlen, unsigned int scope_id, - int * status_code) -{ - unsigned short port; - char * path; - /* protocol://host:port/path */ - char hostname[MAXHOSTNAMELEN+1]; - *size = 0; - if(addr) - addr[0] = '\0'; - if(!parseURL(url, hostname, &port, &path, &scope_id)) - return NULL; -#ifdef DEBUG - printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); -#endif - return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code); -} - diff --git a/ext/miniupnpc/miniwget.h b/ext/miniupnpc/miniwget.h deleted file mode 100644 index 0701494d..00000000 --- a/ext/miniupnpc/miniwget.h +++ /dev/null @@ -1,30 +0,0 @@ -/* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. - * */ -#ifndef MINIWGET_H_INCLUDED -#define MINIWGET_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size, int * status_code); - -MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *); - -MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *); - -int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/ext/miniupnpc/minixml.c b/ext/miniupnpc/minixml.c deleted file mode 100644 index 935ec443..00000000 --- a/ext/miniupnpc/minixml.c +++ /dev/null @@ -1,231 +0,0 @@ -/* $Id: minixml.c,v 1.12 2017/12/12 11:17:40 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * minixml.c : the minimum size a xml parser can be ! */ -/* Project : miniupnp - * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author : Thomas Bernard - -Copyright (c) 2005-2017, 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. -*/ -#include -#include "minixml.h" - -/* parseatt : used to parse the argument list - * return 0 (false) in case of success and -1 (true) if the end - * of the xmlbuffer is reached. */ -static int parseatt(struct xmlparser * p) -{ - const char * attname; - int attnamelen; - const char * attvalue; - int attvaluelen; - while(p->xml < p->xmlend) - { - if(*p->xml=='/' || *p->xml=='>') - return 0; - if( !IS_WHITE_SPACE(*p->xml) ) - { - char sep; - attname = p->xml; - attnamelen = 0; - while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) - { - attnamelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - while(*(p->xml++) != '=') - { - if(p->xml >= p->xmlend) - return -1; - } - while(IS_WHITE_SPACE(*p->xml)) - { - p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - sep = *p->xml; - if(sep=='\'' || sep=='\"') - { - p->xml++; - if(p->xml >= p->xmlend) - return -1; - attvalue = p->xml; - attvaluelen = 0; - while(*p->xml != sep) - { - attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - } - else - { - attvalue = p->xml; - attvaluelen = 0; - while( !IS_WHITE_SPACE(*p->xml) - && *p->xml != '>' && *p->xml != '/') - { - attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) - return -1; - } - } - /*printf("%.*s='%.*s'\n", - attnamelen, attname, attvaluelen, attvalue);*/ - if(p->attfunc) - p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen); - } - p->xml++; - } - return -1; -} - -/* parseelt parse the xml stream and - * call the callback functions when needed... */ -static void parseelt(struct xmlparser * p) -{ - int i; - const char * elementname; - while(p->xml < (p->xmlend - 1)) - { - if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "", 3) != 0); - p->xml += 3; - } - else if((p->xml)[0]=='<' && (p->xml)[1]!='?') - { - i = 0; elementname = ++p->xml; - while( !IS_WHITE_SPACE(*p->xml) - && (*p->xml!='>') && (*p->xml!='/') - ) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - /* to ignore namespace : */ - if(*p->xml==':') - { - i = 0; - elementname = ++p->xml; - } - } - if(i>0) - { - if(p->starteltfunc) - p->starteltfunc(p->data, elementname, i); - if(parseatt(p)) - return; - if(*p->xml!='/') - { - const char * data; - i = 0; data = ++p->xml; - if (p->xml >= p->xmlend) - return; - while( IS_WHITE_SPACE(*p->xml) ) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - } - /* CDATA are at least 9 + 3 characters long : */ - if((p->xmlend >= (p->xml + (9 + 3))) && (memcmp(p->xml, "xml += 9; - data = p->xml; - i = 0; - while(memcmp(p->xml, "]]>", 3) != 0) - { - i++; p->xml++; - if ((p->xml + 3) >= p->xmlend) - return; - } - if(i>0 && p->datafunc) - p->datafunc(p->data, data, i); - while(*p->xml!='<') - { - p->xml++; - if (p->xml >= p->xmlend) - return; - } - } - else - { - while(*p->xml!='<') - { - i++; p->xml++; - if ((p->xml + 1) >= p->xmlend) - return; - } - if(i>0 && p->datafunc && *(p->xml + 1) == '/') - p->datafunc(p->data, data, i); - } - } - } - else if(*p->xml == '/') - { - i = 0; elementname = ++p->xml; - if (p->xml >= p->xmlend) - return; - while((*p->xml != '>')) - { - i++; p->xml++; - if (p->xml >= p->xmlend) - return; - } - if(p->endeltfunc) - p->endeltfunc(p->data, elementname, i); - p->xml++; - } - } - else - { - p->xml++; - } - } -} - -/* the parser must be initialized before calling this function */ -void parsexml(struct xmlparser * parser) -{ - parser->xml = parser->xmlstart; - parser->xmlend = parser->xmlstart + parser->xmlsize; - parseelt(parser); -} - - diff --git a/ext/miniupnpc/minixml.h b/ext/miniupnpc/minixml.h deleted file mode 100644 index 9f43aa48..00000000 --- a/ext/miniupnpc/minixml.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id: minixml.h,v 1.7 2012/09/27 15:42:10 nanard Exp $ */ -/* minimal xml parser - * - * Project : miniupnp - * Website : http://miniupnp.free.fr/ - * 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 MINIXML_H_INCLUDED -#define MINIXML_H_INCLUDED -#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n')) - -/* if a callback function pointer is set to NULL, - * the function is not called */ -struct xmlparser { - const char *xmlstart; - const char *xmlend; - const char *xml; /* pointer to current character */ - int xmlsize; - void * data; - void (*starteltfunc) (void *, const char *, int); - void (*endeltfunc) (void *, const char *, int); - void (*datafunc) (void *, const char *, int); - void (*attfunc) (void *, const char *, int, const char *, int); -}; - -/* parsexml() - * the xmlparser structure must be initialized before the call - * the following structure members have to be initialized : - * xmlstart, xmlsize, data, *func - * xml is for internal usage, xmlend is computed automatically */ -void parsexml(struct xmlparser *); - -#endif - diff --git a/ext/miniupnpc/minixmlvalid.c b/ext/miniupnpc/minixmlvalid.c deleted file mode 100644 index dad14881..00000000 --- a/ext/miniupnpc/minixmlvalid.c +++ /dev/null @@ -1,163 +0,0 @@ -/* $Id: minixmlvalid.c,v 1.7 2015/07/15 12:41:15 nanard Exp $ */ -/* MiniUPnP Project - * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ - * minixmlvalid.c : - * validation program for the minixml parser - * - * (c) 2006-2011 Thomas Bernard */ - -#include -#include -#include -#include "minixml.h" - -/* xml event structure */ -struct event { - enum { ELTSTART, ELTEND, ATT, CHARDATA } type; - const char * data; - int len; -}; - -struct eventlist { - int n; - struct event * events; -}; - -/* compare 2 xml event lists - * return 0 if the two lists are equals */ -int evtlistcmp(struct eventlist * a, struct eventlist * b) -{ - int i; - struct event * ae, * be; - if(a->n != b->n) - { - printf("event number not matching : %d != %d\n", a->n, b->n); - /*return 1;*/ - } - for(i=0; in; i++) - { - ae = a->events + i; - be = b->events + i; - if( (ae->type != be->type) - ||(ae->len != be->len) - ||memcmp(ae->data, be->data, ae->len)) - { - printf("Found a difference : %d '%.*s' != %d '%.*s'\n", - ae->type, ae->len, ae->data, - be->type, be->len, be->data); - return 1; - } - } - return 0; -} - -/* Test data */ -static const char xmldata[] = -"\n" -" " -"character data" -" \n \t" -"" -"\nstuff !\n ]]> \n\n" -" \tchardata1 chardata2 " -""; - -static const struct event evtref[] = -{ - {ELTSTART, "xmlroot", 7}, - {ELTSTART, "elt1", 4}, - /* attributes */ - {CHARDATA, "character data", 14}, - {ELTEND, "elt1", 4}, - {ELTSTART, "elt1b", 5}, - {ELTSTART, "elt1", 4}, - {CHARDATA, " stuff !\n ", 16}, - {ELTEND, "elt1", 4}, - {ELTSTART, "elt2a", 5}, - {ELTSTART, "elt2b", 5}, - {CHARDATA, "chardata1", 9}, - {ELTEND, "elt2b", 5}, - {ELTSTART, "elt2b", 5}, - {CHARDATA, " chardata2 ", 11}, - {ELTEND, "elt2b", 5}, - {ELTEND, "elt2a", 5}, - {ELTEND, "xmlroot", 7} -}; - -void startelt(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("startelt : %.*s\n", l, p);*/ - evt->type = ELTSTART; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -void endelt(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("endelt : %.*s\n", l, p);*/ - evt->type = ELTEND; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -void chardata(void * data, const char * p, int l) -{ - struct eventlist * evtlist = data; - struct event * evt; - evt = evtlist->events + evtlist->n; - /*printf("chardata : '%.*s'\n", l, p);*/ - evt->type = CHARDATA; - evt->data = p; - evt->len = l; - evtlist->n++; -} - -int testxmlparser(const char * xml, int size) -{ - int r; - struct eventlist evtlist; - struct eventlist evtlistref; - struct xmlparser parser; - evtlist.n = 0; - evtlist.events = malloc(sizeof(struct event)*100); - if(evtlist.events == NULL) - { - fprintf(stderr, "Memory allocation error.\n"); - return -1; - } - memset(&parser, 0, sizeof(parser)); - parser.xmlstart = xml; - parser.xmlsize = size; - parser.data = &evtlist; - parser.starteltfunc = startelt; - parser.endeltfunc = endelt; - parser.datafunc = chardata; - parsexml(&parser); - printf("%d events\n", evtlist.n); - /* compare */ - evtlistref.n = sizeof(evtref)/sizeof(struct event); - evtlistref.events = (struct event *)evtref; - r = evtlistcmp(&evtlistref, &evtlist); - free(evtlist.events); - return r; -} - -int main(int argc, char * * argv) -{ - int r; - (void)argc; (void)argv; - - r = testxmlparser(xmldata, sizeof(xmldata)-1); - if(r) - printf("minixml validation test failed\n"); - return r; -} - diff --git a/ext/miniupnpc/portlistingparse.c b/ext/miniupnpc/portlistingparse.c deleted file mode 100644 index d1954f59..00000000 --- a/ext/miniupnpc/portlistingparse.c +++ /dev/null @@ -1,172 +0,0 @@ -/* $Id: portlistingparse.c,v 1.10 2016/12/16 08:53:21 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011-2016 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ -#include -#include -#ifdef DEBUG -#include -#endif /* DEBUG */ -#include "portlistingparse.h" -#include "minixml.h" - -/* list of the elements */ -static const struct { - const portMappingElt code; - const char * const str; -} elements[] = { - { PortMappingEntry, "PortMappingEntry"}, - { NewRemoteHost, "NewRemoteHost"}, - { NewExternalPort, "NewExternalPort"}, - { NewProtocol, "NewProtocol"}, - { NewInternalPort, "NewInternalPort"}, - { NewInternalClient, "NewInternalClient"}, - { NewEnabled, "NewEnabled"}, - { NewDescription, "NewDescription"}, - { NewLeaseTime, "NewLeaseTime"}, - { PortMappingEltNone, NULL} -}; - -/* Helper function */ -static UNSIGNED_INTEGER -atoui(const char * p, int l) -{ - UNSIGNED_INTEGER r = 0; - while(l > 0 && *p) - { - if(*p >= '0' && *p <= '9') - r = r*10 + (*p - '0'); - else - break; - p++; - l--; - } - return r; -} - -/* Start element handler */ -static void -startelt(void * d, const char * name, int l) -{ - int i; - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - pdata->curelt = PortMappingEltNone; - for(i = 0; elements[i].str; i++) - { - if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0) - { - pdata->curelt = elements[i].code; - break; - } - } - if(pdata->curelt == PortMappingEntry) - { - struct PortMapping * pm; - pm = calloc(1, sizeof(struct PortMapping)); - if(pm == NULL) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "startelt"); -#endif /* DEBUG */ - return; - } - pm->l_next = pdata->l_head; /* insert in list */ - pdata->l_head = pm; - } -} - -/* End element handler */ -static void -endelt(void * d, const char * name, int l) -{ - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - (void)name; - (void)l; - pdata->curelt = PortMappingEltNone; -} - -/* Data handler */ -static void -data(void * d, const char * data, int l) -{ - struct PortMapping * pm; - struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - pm = pdata->l_head; - if(!pm) - return; - if(l > 63) - l = 63; - switch(pdata->curelt) - { - case NewRemoteHost: - memcpy(pm->remoteHost, data, l); - pm->remoteHost[l] = '\0'; - break; - case NewExternalPort: - pm->externalPort = (unsigned short)atoui(data, l); - break; - case NewProtocol: - if(l > 3) - l = 3; - memcpy(pm->protocol, data, l); - pm->protocol[l] = '\0'; - break; - case NewInternalPort: - pm->internalPort = (unsigned short)atoui(data, l); - break; - case NewInternalClient: - memcpy(pm->internalClient, data, l); - pm->internalClient[l] = '\0'; - break; - case NewEnabled: - pm->enabled = (unsigned char)atoui(data, l); - break; - case NewDescription: - memcpy(pm->description, data, l); - pm->description[l] = '\0'; - break; - case NewLeaseTime: - pm->leaseTime = atoui(data, l); - break; - default: - break; - } -} - - -/* Parse the PortMappingList XML document for IGD version 2 - */ -void -ParsePortListing(const char * buffer, int bufsize, - struct PortMappingParserData * pdata) -{ - struct xmlparser parser; - - memset(pdata, 0, sizeof(struct PortMappingParserData)); - /* init xmlparser */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = pdata; - parser.starteltfunc = startelt; - parser.endeltfunc = endelt; - parser.datafunc = data; - parser.attfunc = 0; - parsexml(&parser); -} - -void -FreePortListing(struct PortMappingParserData * pdata) -{ - struct PortMapping * pm; - while((pm = pdata->l_head) != NULL) - { - /* remove from list */ - pdata->l_head = pm->l_next; - free(pm); - } -} - diff --git a/ext/miniupnpc/portlistingparse.h b/ext/miniupnpc/portlistingparse.h deleted file mode 100644 index 661ad1fa..00000000 --- a/ext/miniupnpc/portlistingparse.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $Id: portlistingparse.h,v 1.11 2015/07/21 13:16:55 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011-2015 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ -#ifndef PORTLISTINGPARSE_H_INCLUDED -#define PORTLISTINGPARSE_H_INCLUDED - -#include "miniupnpc_declspec.h" -/* for the definition of UNSIGNED_INTEGER */ -#include "miniupnpctypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* sample of PortMappingEntry : - - 202.233.2.1 - 2345 - TCP - 2345 - 192.168.1.137 - 1 - dooom - 345 - - */ -typedef enum { PortMappingEltNone, - PortMappingEntry, NewRemoteHost, - NewExternalPort, NewProtocol, - NewInternalPort, NewInternalClient, - NewEnabled, NewDescription, - NewLeaseTime } portMappingElt; - -struct PortMapping { - struct PortMapping * l_next; /* list next element */ - UNSIGNED_INTEGER leaseTime; - unsigned short externalPort; - unsigned short internalPort; - char remoteHost[64]; - char internalClient[64]; - char description[64]; - char protocol[4]; - unsigned char enabled; -}; - -struct PortMappingParserData { - struct PortMapping * l_head; /* list head */ - portMappingElt curelt; -}; - -MINIUPNP_LIBSPEC void -ParsePortListing(const char * buffer, int bufsize, - struct PortMappingParserData * pdata); - -MINIUPNP_LIBSPEC void -FreePortListing(struct PortMappingParserData * pdata); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ext/miniupnpc/receivedata.c b/ext/miniupnpc/receivedata.c deleted file mode 100644 index 5dbd227b..00000000 --- a/ext/miniupnpc/receivedata.c +++ /dev/null @@ -1,105 +0,0 @@ -/* $Id: receivedata.c,v 1.8 2017/04/21 10:16:45 nanard Exp $ */ -/* Project : miniupnp - * Website : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2011-2014 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided in this distribution. */ - -#include -#include -#ifdef _WIN32 -#include -#include -#else /* _WIN32 */ -#include -#if defined(__amigaos__) && !defined(__amigaos4__) -#define socklen_t int -#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#include -#if !defined(__amigaos__) && !defined(__amigaos4__) -#include -#endif /* !defined(__amigaos__) && !defined(__amigaos4__) */ -#include -#define MINIUPNPC_IGNORE_EINTR -#endif /* _WIN32 */ - -#ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); -#else -#define PRINT_SOCKET_ERROR(x) perror(x) -#endif - -#include "receivedata.h" - -int -receivedata(int socket, - char * data, int length, - int timeout, unsigned int * scope_id) -{ -#ifdef MINIUPNPC_GET_SRC_ADDR - struct sockaddr_storage src_addr; - socklen_t src_addr_len = sizeof(src_addr); -#endif /* MINIUPNPC_GET_SRC_ADDR */ - int n; -#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) - /* using poll */ - struct pollfd fds[1]; /* for the poll */ -#ifdef MINIUPNPC_IGNORE_EINTR - do { -#endif /* MINIUPNPC_IGNORE_EINTR */ - fds[0].fd = socket; - fds[0].events = POLLIN; - n = poll(fds, 1, timeout); -#ifdef MINIUPNPC_IGNORE_EINTR - } while(n < 0 && errno == EINTR); -#endif /* MINIUPNPC_IGNORE_EINTR */ - if(n < 0) { - PRINT_SOCKET_ERROR("poll"); - return -1; - } else if(n == 0) { - /* timeout */ - return 0; - } -#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - /* using select under _WIN32 and amigaos */ - fd_set socketSet; - TIMEVAL timeval; - FD_ZERO(&socketSet); - FD_SET(socket, &socketSet); - timeval.tv_sec = timeout / 1000; - timeval.tv_usec = (timeout % 1000) * 1000; - n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval); - if(n < 0) { - PRINT_SOCKET_ERROR("select"); - return -1; - } else if(n == 0) { - return 0; - } -#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ -#ifdef MINIUPNPC_GET_SRC_ADDR - memset(&src_addr, 0, sizeof(src_addr)); - n = recvfrom(socket, data, length, 0, - (struct sockaddr *)&src_addr, &src_addr_len); -#else /* MINIUPNPC_GET_SRC_ADDR */ - n = recv(socket, data, length, 0); -#endif /* MINIUPNPC_GET_SRC_ADDR */ - if(n<0) { - PRINT_SOCKET_ERROR("recv"); - } -#ifdef MINIUPNPC_GET_SRC_ADDR - if (src_addr.ss_family == AF_INET6) { - const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr; -#ifdef DEBUG - printf("scope_id=%u\n", src_addr6->sin6_scope_id); -#endif /* DEBUG */ - if(scope_id) - *scope_id = src_addr6->sin6_scope_id; - } -#endif /* MINIUPNPC_GET_SRC_ADDR */ - return n; -} - diff --git a/ext/miniupnpc/receivedata.h b/ext/miniupnpc/receivedata.h deleted file mode 100644 index 0520a11d..00000000 --- a/ext/miniupnpc/receivedata.h +++ /dev/null @@ -1,19 +0,0 @@ -/* $Id: receivedata.h,v 1.4 2012/09/27 15:42:10 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2011-2012 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef RECEIVEDATA_H_INCLUDED -#define RECEIVEDATA_H_INCLUDED - -/* Reads data from the specified socket. - * Returns the number of bytes read if successful, zero if no bytes were - * read or if we timed out. Returns negative if there was an error. */ -int receivedata(int socket, - char * data, int length, - int timeout, unsigned int * scope_id); - -#endif - diff --git a/ext/miniupnpc/updateminiupnpcstrings.sh b/ext/miniupnpc/updateminiupnpcstrings.sh deleted file mode 100755 index dde4354a..00000000 --- a/ext/miniupnpc/updateminiupnpcstrings.sh +++ /dev/null @@ -1,53 +0,0 @@ -#! /bin/sh -# $Id: updateminiupnpcstrings.sh,v 1.7 2011/01/04 11:41:53 nanard Exp $ -# project miniupnp : http://miniupnp.free.fr/ -# (c) 2009 Thomas Bernard - -FILE=miniupnpcstrings.h -TMPFILE=miniupnpcstrings.h.tmp -TEMPLATE_FILE=${FILE}.in - -# detecting the OS name and version -OS_NAME=`uname -s` -OS_VERSION=`uname -r` -if [ -f /etc/debian_version ]; then - OS_NAME=Debian - OS_VERSION=`cat /etc/debian_version` -fi -# use lsb_release (Linux Standard Base) when available -LSB_RELEASE=`which lsb_release` -if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then - OS_NAME=`${LSB_RELEASE} -i -s` - OS_VERSION=`${LSB_RELEASE} -r -s` - case $OS_NAME in - Debian) - #OS_VERSION=`${LSB_RELEASE} -c -s` - ;; - Ubuntu) - #OS_VERSION=`${LSB_RELEASE} -c -s` - ;; - esac -fi - -# on AmigaOS 3, uname -r returns "unknown", so we use uname -v -if [ "$OS_NAME" = "AmigaOS" ]; then - if [ "$OS_VERSION" = "unknown" ]; then - OS_VERSION=`uname -v` - fi -fi - -echo "Detected OS [$OS_NAME] version [$OS_VERSION]" -MINIUPNPC_VERSION=`cat VERSION` -echo "MiniUPnPc version [${MINIUPNPC_VERSION}]" - -EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|" -#echo $EXPR -test -f ${FILE}.in -echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE." -sed -e "$EXPR" < $TEMPLATE_FILE > $TMPFILE - -EXPR="s|MINIUPNPC_VERSION_STRING \".*\"|MINIUPNPC_VERSION_STRING \"${MINIUPNPC_VERSION}\"|" -echo "setting MINIUPNPC_VERSION_STRING macro value to ${MINIUPNPC_VERSION} in $FILE." -sed -e "$EXPR" < $TMPFILE > $FILE -rm $TMPFILE - diff --git a/ext/miniupnpc/upnpc.c b/ext/miniupnpc/upnpc.c deleted file mode 100644 index e719ecec..00000000 --- a/ext/miniupnpc/upnpc.c +++ /dev/null @@ -1,857 +0,0 @@ -/* $Id: upnpc.c,v 1.117 2017/05/26 15:26:55 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas Bernard - * Copyright (c) 2005-2017 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 -#define snprintf _snprintf -#else -/* for IPPROTO_TCP / IPPROTO_UDP */ -#include -#endif -#include -#include "miniwget.h" -#include "miniupnpc.h" -#include "upnpcommands.h" -#include "upnperrors.h" -#include "miniupnpcstrings.h" - -/* protofix() checks if protocol is "UDP" or "TCP" - * returns NULL if not */ -const char * protofix(const char * proto) -{ - static const char proto_tcp[4] = { 'T', 'C', 'P', 0}; - static const char proto_udp[4] = { 'U', 'D', 'P', 0}; - int i, b; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_tcp[i]) - || (proto[i] == (proto_tcp[i] | 32)) ); - if(b) - return proto_tcp; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_udp[i]) - || (proto[i] == (proto_udp[i] | 32)) ); - if(b) - return proto_udp; - return 0; -} - -/* is_int() checks if parameter is an integer or not - * 1 for integer - * 0 for not an integer */ -int is_int(char const* s) -{ - if(s == NULL) - return 0; - while(*s) { - /* #define isdigit(c) ((c) >= '0' && (c) <= '9') */ - if(!isdigit(*s)) - return 0; - s++; - } - return 1; -} - -static void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - char externalIPAddress[40]; - char connectionType[64]; - char status[64]; - char lastconnerr[64]; - unsigned int uptime = 0; - unsigned int brUp, brDown; - time_t timenow, timestarted; - int r; - if(UPNP_GetConnectionTypeInfo(urls->controlURL, - data->first.servicetype, - connectionType) != UPNPCOMMAND_SUCCESS) - printf("GetConnectionTypeInfo failed.\n"); - else - printf("Connection Type : %s\n", connectionType); - if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) - printf("GetStatusInfo failed.\n"); - else - printf("Status : %s, uptime=%us, LastConnectionError : %s\n", - status, uptime, lastconnerr); - if(uptime > 0) { - timenow = time(NULL); - timestarted = timenow - uptime; - printf(" Time started : %s", ctime(×tarted)); - } - if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, - &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { - printf("GetLinkLayerMaxBitRates failed.\n"); - } else { - printf("MaxBitRateDown : %u bps", brDown); - if(brDown >= 1000000) { - printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); - } else if(brDown >= 1000) { - printf(" (%u Kbps)", brDown / 1000); - } - printf(" MaxBitRateUp %u bps", brUp); - if(brUp >= 1000000) { - printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10); - } else if(brUp >= 1000) { - printf(" (%u Kbps)", brUp / 1000); - } - printf("\n"); - } - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) { - printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); - } else { - printf("ExternalIPAddress = %s\n", externalIPAddress); - } -} - -static void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - DisplayInfos(urls, data); - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -static void ListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - char index[6]; - char intClient[40]; - char intPort[6]; - char extPort[6]; - char protocol[4]; - char desc[80]; - char enabled[6]; - char rHost[64]; - char duration[16]; - /*unsigned int num=0; - UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num); - printf("PortMappingNumberOfEntries : %u\n", num);*/ - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - do { - snprintf(index, 6, "%d", i); - rHost[0] = '\0'; enabled[0] = '\0'; - duration[0] = '\0'; desc[0] = '\0'; - extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; - r = UPNP_GetGenericPortMappingEntry(urls->controlURL, - data->first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); - if(r==0) - /* - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" - " desc='%s' rHost='%s'\n", - i, protocol, extPort, intClient, intPort, - enabled, duration, - desc, rHost); - */ - printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n", - i, protocol, extPort, intClient, intPort, - desc, rHost, duration); - else - printf("GetGenericPortMappingEntry() returned %d (%s)\n", - r, strupnperror(r)); - i++; - } while(r==0); -} - -static void NewListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - struct PortMappingParserData pdata; - struct PortMapping * pm; - - memset(&pdata, 0, sizeof(struct PortMappingParserData)); - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "TCP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } - r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "UDP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); - i++; - } - FreePortListing(&pdata); - } - else - { - printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); - } -} - -/* Test function - * 1 - get connection type - * 2 - get extenal ip address - * 3 - Add port mapping - * 4 - get this port mapping from the IGD */ -static int SetRedirectAndTest(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto, - const char * leaseDuration, - const char * description, - int addAny) -{ - char externalIPAddress[40]; - char intClient[40]; - char intPort[6]; - char reservedPort[6]; - char duration[16]; - int r; - - if(!iaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "invalid protocol\n"); - return -1; - } - - r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetExternalIPAddress failed.\n"); - else - printf("ExternalIPAddress = %s\n", externalIPAddress); - - if (addAny) { - r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration, reservedPort); - if(r==UPNPCOMMAND_SUCCESS) - eport = reservedPort; - else - printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - } else { - r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); - return -2; - } - } - - r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->first.servicetype, - eport, proto, NULL/*remoteHost*/, - intClient, intPort, NULL/*desc*/, - NULL/*enabled*/, duration); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", - r, strupnperror(r)); - return -2; - } else { - printf("InternalIP:Port = %s:%s\n", intClient, intPort); - printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", - externalIPAddress, eport, proto, intClient, intPort, duration); - } - return 0; -} - -static int -RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto, - const char * remoteHost) -{ - int r; - if(!proto || !eport) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, remoteHost); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMapping() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMapping() returned : %d\n", r); - } - return 0; -} - -static int -RemoveRedirectRange(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * ePortStart, char const * ePortEnd, - const char * proto, const char * manage) -{ - int r; - - if (!manage) - manage = "0"; - - if(!proto || !ePortStart || !ePortEnd) - { - fprintf(stderr, "invalid arguments\n"); - return -1; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return -1; - } - r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage); - if(r!=UPNPCOMMAND_SUCCESS) { - printf("UPNP_DeletePortMappingRange() failed with code : %d\n", r); - return -2; - }else { - printf("UPNP_DeletePortMappingRange() returned : %d\n", r); - } - return 0; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) -{ - unsigned int bytessent, bytesreceived, packetsreceived, packetssent; - int firewallEnabled = 0, inboundPinholeAllowed = 0; - - UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed); - printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed); - printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No"); - - bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); - bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); - packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype); - packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype); - printf("Bytes: Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived); - printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived); -} - -/* Test function - * 1 - Add pinhole - * 2 - Check if pinhole is working from the IGD side */ -static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto, const char * lease_time) -{ - char uniqueID[8]; - /*int isWorking = 0;*/ - int r; - char proto_tmp[8]; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - if(atoi(proto) == 0) - { - const char * protocol; - protocol = protofix(proto); - if(protocol && (strcmp("TCP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP); - proto = proto_tmp; - } - else if(protocol && (strcmp("UDP", protocol) == 0)) - { - snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP); - proto = proto_tmp; - } - else - { - fprintf(stderr, "invalid protocol\n"); - return; - } - } - r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID); - if(r!=UPNPCOMMAND_SUCCESS) - printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - remoteaddr, eport, intaddr, iport, r, strupnperror(r)); - else - { - printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", - remoteaddr, eport, intaddr, iport, uniqueID); - /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/ - } -} - -/* Test function - * 1 - Check if pinhole is working from the IGD side - * 2 - Update pinhole */ -static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, - const char * uniqueID, const char * lease_time) -{ - int isWorking = 0; - int r; - - if(!uniqueID || !lease_time) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - if(isWorking || r==709) - { - r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time); - printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time); - if(r!=UPNPCOMMAND_SUCCESS) - printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r)); - } -} - -/* Test function - * Get pinhole timeout - */ -static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto) -{ - int timeout = 0; - int r; - - if(!intaddr || !remoteaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return; - } - - r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - intaddr, iport, remoteaddr, eport, r, strupnperror(r)); - else - printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout); -} - -static void -GetPinholePackets(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, pinholePackets = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets); - if(r!=UPNPCOMMAND_SUCCESS) - printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets); -} - -static void -CheckPinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r, isWorking = 0; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) - printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - else - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); -} - -static void -RemovePinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ - int r; - if(!uniqueID) - { - fprintf(stderr, "invalid arguments\n"); - return; - } - r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID); - printf("UPNP_DeletePinhole() returned : %d\n", r); -} - - -/* sample upnp client program */ -int main(int argc, char ** argv) -{ - char command = 0; - char ** commandargv = 0; - int commandargc = 0; - struct UPNPDev * devlist = 0; - char lanaddr[64] = "unset"; /* my ip address on the LAN */ - int i; - const char * rootdescurl = 0; - const char * multicastif = 0; - const char * minissdpdpath = 0; - int localport = UPNP_LOCAL_PORT_ANY; - int retcode = 0; - int error = 0; - int ipv6 = 0; - unsigned char ttl = 2; /* defaulting to 2 */ - const char * description = 0; - -#ifdef _WIN32 - WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { - fprintf(stderr, "WSAStartup() failed.\n"); - return -1; - } -#endif - printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); - printf(" (c) 2005-2017 Thomas Bernard.\n"); - printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n" - "for more information.\n"); - /* command line processing */ - for(i=1; i65535 || - (localport >1 && localport < 1024)) - { - fprintf(stderr, "Invalid localport '%s'\n", argv[i]); - localport = UPNP_LOCAL_PORT_ANY; - break; - } - } - else if(argv[i][1] == 'p') - minissdpdpath = argv[++i]; - else if(argv[i][1] == '6') - ipv6 = 1; - else if(argv[i][1] == 'e') - description = argv[++i]; - else if(argv[i][1] == 't') - ttl = (unsigned char)atoi(argv[++i]); - else - { - command = argv[i][1]; - i++; - commandargv = argv + i; - commandargc = argc - i; - break; - } - } - else - { - fprintf(stderr, "option '%s' invalid\n", argv[i]); - } - } - - if(!command - || (command == 'a' && commandargc<4) - || (command == 'd' && argc<2) - || (command == 'r' && argc<2) - || (command == 'A' && commandargc<6) - || (command == 'U' && commandargc<2) - || (command == 'D' && commandargc<1)) - { - fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -d external_port protocol \n\t\tDelete port redirection\n", argv[0]); - fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); - fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]); - fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]); - fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]); - fprintf(stderr, " \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]); - fprintf(stderr, "\nprotocol is UDP or TCP\n"); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -e description : set description for port mapping.\n"); - fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n"); - fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n"); - fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n"); - fprintf(stderr, " -z localport : SSDP packets local (source) port (1024-65535).\n"); - fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n"); - fprintf(stderr, " -t ttl : set multicast TTL. Default value is 2.\n"); - return 1; - } - - if( rootdescurl - || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, - localport, ipv6, ttl, &error))) - { - struct UPNPDev * device; - struct UPNPUrls urls; - struct IGDdatas data; - if(devlist) - { - printf("List of UPNP devices found on the network :\n"); - for(device = devlist; device; device = device->pNext) - { - printf(" desc: %s\n st: %s\n\n", - device->descURL, device->st); - } - } - else if(!rootdescurl) - { - printf("upnpDiscover() error code=%d\n", error); - } - i = 1; - if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) - || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) - { - switch(i) { - case 1: - printf("Found valid IGD : %s\n", urls.controlURL); - break; - case 2: - printf("Found a (not connected?) IGD : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - case 3: - printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - default: - printf("Found device (igd ?) : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - } - printf("Local LAN ip address : %s\n", lanaddr); - #if 0 - printf("getting \"%s\"\n", urls.ipcondescURL); - descXML = miniwget(urls.ipcondescURL, &descXMLsize); - if(descXML) - { - /*fwrite(descXML, 1, descXMLsize, stdout);*/ - free(descXML); descXML = NULL; - } - #endif - - switch(command) - { - case 'l': - DisplayInfos(&urls, &data); - ListRedirections(&urls, &data); - break; - case 'L': - NewListRedirections(&urls, &data); - break; - case 'a': - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 0) < 0) - retcode = 2; - break; - case 'd': - if (RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], - commandargc > 2 ? commandargv[2] : NULL) < 0) - retcode = 2; - break; - case 'n': /* aNy */ - if (SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 1) < 0) - retcode = 2; - break; - case 'N': - if (commandargc < 3) - fprintf(stderr, "too few arguments\n"); - - if (RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], - commandargc > 3 ? commandargv[3] : NULL) < 0) - retcode = 2; - break; - case 's': - GetConnectionStatus(&urls, &data); - break; - case 'r': - i = 0; - while(i */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i+1], commandargv[i+2], "0", - description, 0) < 0) - retcode = 2; - i+=3; /* 3 parameters parsed */ - } else { - /* 2nd parameter not an integer : */ - if (SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i], commandargv[i+1], "0", - description, 0) < 0) - retcode = 2; - i+=2; /* 2 parameters parsed */ - } - } - break; - case 'A': - SetPinholeAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4], commandargv[5]); - break; - case 'U': - GetPinholeAndUpdate(&urls, &data, - commandargv[0], commandargv[1]); - break; - case 'C': - for(i=0; i -#include -#include -#include "upnpcommands.h" -#include "miniupnpc.h" -#include "portlistingparse.h" - -static UNSIGNED_INTEGER -my_atoui(const char * s) -{ - return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesSent(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalBytesSent", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesReceived(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalBytesReceived", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsSent(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalPacketsSent", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* - * */ -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsReceived(const char * controlURL, - const char * servicetype) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - unsigned int r = 0; - char * p; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetTotalPacketsReceived", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived"); - r = my_atoui(p); - ClearNameValueList(&pdata); - return r; -} - -/* UPNP_GetStatusInfo() call the corresponding UPNP method - * returns the current status and uptime */ -MINIUPNP_LIBSPEC int -UPNP_GetStatusInfo(const char * controlURL, - const char * servicetype, - char * status, - unsigned int * uptime, - char * lastconnerror) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - char * up; - char * err; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!status && !uptime) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetStatusInfo", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - /*DisplayNameValueList(buffer, bufsize);*/ - free(buffer); buffer = NULL; - up = GetValueFromNameValueList(&pdata, "NewUptime"); - p = GetValueFromNameValueList(&pdata, "NewConnectionStatus"); - err = GetValueFromNameValueList(&pdata, "NewLastConnectionError"); - if(p && up) - ret = UPNPCOMMAND_SUCCESS; - - if(status) { - if(p){ - strncpy(status, p, 64 ); - status[63] = '\0'; - }else - status[0]= '\0'; - } - - if(uptime) { - if(up) - sscanf(up,"%u",uptime); - else - *uptime = 0; - } - - if(lastconnerror) { - if(err) { - strncpy(lastconnerror, err, 64 ); - lastconnerror[63] = '\0'; - } else - lastconnerror[0] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method - * returns the connection type */ -MINIUPNP_LIBSPEC int -UPNP_GetConnectionTypeInfo(const char * controlURL, - const char * servicetype, - char * connectionType) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!connectionType) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetConnectionTypeInfo", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "NewConnectionType"); - /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/ - /* PossibleConnectionTypes will have several values.... */ - if(p) { - strncpy(connectionType, p, 64 ); - connectionType[63] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - connectionType[0] = '\0'; - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method. - * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth. - * One of the values can be null - * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only - * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetLinkLayerMaxBitRates(const char * controlURL, - const char * servicetype, - unsigned int * bitrateDown, - unsigned int * bitrateUp) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - char * down; - char * up; - char * p; - - if(!bitrateDown && !bitrateUp) - return UPNPCOMMAND_INVALID_ARGS; - - /* shouldn't we use GetCommonLinkProperties ? */ - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetCommonLinkProperties", 0, &bufsize))) { - /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/ - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/ - /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/ - down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate"); - up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate"); - /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/ - /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/ - if(down && up) - ret = UPNPCOMMAND_SUCCESS; - - if(bitrateDown) { - if(down) - sscanf(down,"%u",bitrateDown); - else - *bitrateDown = 0; - } - - if(bitrateUp) { - if(up) - sscanf(up,"%u",bitrateUp); - else - *bitrateUp = 0; - } - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - - -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 16 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - */ -MINIUPNP_LIBSPEC int -UPNP_GetExternalIPAddress(const char * controlURL, - const char * servicetype, - char * extIpAdd) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!extIpAdd || !controlURL || !servicetype) - return UPNPCOMMAND_INVALID_ARGS; - - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetExternalIPAddress", 0, &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/ - p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress"); - if(p) { - strncpy(extIpAdd, p, 16 ); - extIpAdd[15] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - extIpAdd[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration) -{ - struct UPNParg * AddPortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!inPort || !inClient || !proto || !extPort) - return UPNPCOMMAND_INVALID_ARGS; - - AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); - if(AddPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - AddPortMappingArgs[0].elt = "NewRemoteHost"; - AddPortMappingArgs[0].val = remoteHost; - AddPortMappingArgs[1].elt = "NewExternalPort"; - AddPortMappingArgs[1].val = extPort; - AddPortMappingArgs[2].elt = "NewProtocol"; - AddPortMappingArgs[2].val = proto; - AddPortMappingArgs[3].elt = "NewInternalPort"; - AddPortMappingArgs[3].val = inPort; - AddPortMappingArgs[4].elt = "NewInternalClient"; - AddPortMappingArgs[4].val = inClient; - AddPortMappingArgs[5].elt = "NewEnabled"; - AddPortMappingArgs[5].val = "1"; - AddPortMappingArgs[6].elt = "NewPortMappingDescription"; - AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; - AddPortMappingArgs[7].elt = "NewLeaseDuration"; - AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPortMapping", AddPortMappingArgs, - &bufsize); - free(AddPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - /*buffer[bufsize] = '\0';*/ - /*puts(buffer);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration, - char * reservedPort) -{ - struct UPNParg * AddPortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!inPort || !inClient || !proto || !extPort) - return UPNPCOMMAND_INVALID_ARGS; - - AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); - if(AddPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - AddPortMappingArgs[0].elt = "NewRemoteHost"; - AddPortMappingArgs[0].val = remoteHost; - AddPortMappingArgs[1].elt = "NewExternalPort"; - AddPortMappingArgs[1].val = extPort; - AddPortMappingArgs[2].elt = "NewProtocol"; - AddPortMappingArgs[2].val = proto; - AddPortMappingArgs[3].elt = "NewInternalPort"; - AddPortMappingArgs[3].val = inPort; - AddPortMappingArgs[4].elt = "NewInternalClient"; - AddPortMappingArgs[4].val = inClient; - AddPortMappingArgs[5].elt = "NewEnabled"; - AddPortMappingArgs[5].val = "1"; - AddPortMappingArgs[6].elt = "NewPortMappingDescription"; - AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; - AddPortMappingArgs[7].elt = "NewLeaseDuration"; - AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddAnyPortMapping", AddPortMappingArgs, - &bufsize); - free(AddPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - char *p; - - p = GetValueFromNameValueList(&pdata, "NewReservedPort"); - if(p) { - strncpy(reservedPort, p, 6); - reservedPort[5] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else { - ret = UPNPCOMMAND_INVALID_RESPONSE; - } - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, - const char * extPort, const char * proto, - const char * remoteHost) -{ - /*struct NameValueParserData pdata;*/ - struct UPNParg * DeletePortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg)); - if(DeletePortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePortMappingArgs[0].elt = "NewRemoteHost"; - DeletePortMappingArgs[0].val = remoteHost; - DeletePortMappingArgs[1].elt = "NewExternalPort"; - DeletePortMappingArgs[1].val = extPort; - DeletePortMappingArgs[2].elt = "NewProtocol"; - DeletePortMappingArgs[2].val = proto; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMapping", - DeletePortMappingArgs, &bufsize); - free(DeletePortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, - const char * extPortStart, const char * extPortEnd, - const char * proto, - const char * manage) -{ - struct UPNParg * DeletePortMappingArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!extPortStart || !extPortEnd || !proto || !manage) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg)); - if(DeletePortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePortMappingArgs[0].elt = "NewStartPort"; - DeletePortMappingArgs[0].val = extPortStart; - DeletePortMappingArgs[1].elt = "NewEndPort"; - DeletePortMappingArgs[1].val = extPortEnd; - DeletePortMappingArgs[2].elt = "NewProtocol"; - DeletePortMappingArgs[2].val = proto; - DeletePortMappingArgs[3].elt = "NewManage"; - DeletePortMappingArgs[3].val = manage; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMappingRange", - DeletePortMappingArgs, &bufsize); - free(DeletePortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } else { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetGenericPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * index, - char * extPort, - char * intClient, - char * intPort, - char * protocol, - char * desc, - char * enabled, - char * rHost, - char * duration) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPortMappingArgs; - char * buffer; - int bufsize; - char * p; - int r = UPNPCOMMAND_UNKNOWN_ERROR; - if(!index) - return UPNPCOMMAND_INVALID_ARGS; - intClient[0] = '\0'; - intPort[0] = '\0'; - GetPortMappingArgs = calloc(2, sizeof(struct UPNParg)); - if(GetPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPortMappingArgs[0].elt = "NewPortMappingIndex"; - GetPortMappingArgs[0].val = index; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetGenericPortMappingEntry", - GetPortMappingArgs, &bufsize); - free(GetPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewRemoteHost"); - if(p && rHost) - { - strncpy(rHost, p, 64); - rHost[63] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewExternalPort"); - if(p && extPort) - { - strncpy(extPort, p, 6); - extPort[5] = '\0'; - r = UPNPCOMMAND_SUCCESS; - } - p = GetValueFromNameValueList(&pdata, "NewProtocol"); - if(p && protocol) - { - strncpy(protocol, p, 4); - protocol[3] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewInternalClient"); - if(p) - { - strncpy(intClient, p, 16); - intClient[15] = '\0'; - r = 0; - } - p = GetValueFromNameValueList(&pdata, "NewInternalPort"); - if(p) - { - strncpy(intPort, p, 6); - intPort[5] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewEnabled"); - if(p && enabled) - { - strncpy(enabled, p, 4); - enabled[3] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); - if(p && desc) - { - strncpy(desc, p, 80); - desc[79] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); - if(p && duration) - { - strncpy(duration, p, 16); - duration[15] = '\0'; - } - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - r = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &r); - } - ClearNameValueList(&pdata); - return r; -} - -MINIUPNP_LIBSPEC int -UPNP_GetPortMappingNumberOfEntries(const char * controlURL, - const char * servicetype, - unsigned int * numEntries) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char* p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetPortMappingNumberOfEntries", 0, - &bufsize))) { - return UPNPCOMMAND_HTTP_ERROR; - } -#ifdef DEBUG - DisplayNameValueList(buffer, bufsize); -#endif - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries"); - if(numEntries && p) { - *numEntries = 0; - sscanf(p, "%u", numEntries); - ret = UPNPCOMMAND_SUCCESS; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping - * the result is returned in the intClient and intPort strings - * please provide 16 and 6 bytes of data */ -MINIUPNP_LIBSPEC int -UPNP_GetSpecificPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * extPort, - const char * proto, - const char * remoteHost, - char * intClient, - char * intPort, - char * desc, - char * enabled, - char * leaseDuration) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPortMappingArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!intPort || !intClient || !extPort || !proto) - return UPNPCOMMAND_INVALID_ARGS; - - GetPortMappingArgs = calloc(4, sizeof(struct UPNParg)); - if(GetPortMappingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPortMappingArgs[0].elt = "NewRemoteHost"; - GetPortMappingArgs[0].val = remoteHost; - GetPortMappingArgs[1].elt = "NewExternalPort"; - GetPortMappingArgs[1].val = extPort; - GetPortMappingArgs[2].elt = "NewProtocol"; - GetPortMappingArgs[2].val = proto; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetSpecificPortMappingEntry", - GetPortMappingArgs, &bufsize); - free(GetPortMappingArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "NewInternalClient"); - if(p) { - strncpy(intClient, p, 16); - intClient[15] = '\0'; - ret = UPNPCOMMAND_SUCCESS; - } else - intClient[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "NewInternalPort"); - if(p) { - strncpy(intPort, p, 6); - intPort[5] = '\0'; - } else - intPort[0] = '\0'; - - p = GetValueFromNameValueList(&pdata, "NewEnabled"); - if(p && enabled) { - strncpy(enabled, p, 4); - enabled[3] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); - if(p && desc) { - strncpy(desc, p, 80); - desc[79] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); - if(p && leaseDuration) - { - strncpy(leaseDuration, p, 16); - leaseDuration[15] = '\0'; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -/* UPNP_GetListOfPortMappings() - * - * Possible UPNP Error codes : - * 606 Action not Authorized - * 730 PortMappingNotFound - no port mapping is found in the specified range. - * 733 InconsistantParameters - NewStartPort and NewEndPort values are not - * consistent. - */ -MINIUPNP_LIBSPEC int -UPNP_GetListOfPortMappings(const char * controlURL, - const char * servicetype, - const char * startPort, - const char * endPort, - const char * protocol, - const char * numberOfPorts, - struct PortMappingParserData * data) -{ - struct NameValueParserData pdata; - struct UPNParg * GetListOfPortMappingsArgs; - const char * p; - char * buffer; - int bufsize; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!startPort || !endPort || !protocol) - return UPNPCOMMAND_INVALID_ARGS; - - GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg)); - if(GetListOfPortMappingsArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetListOfPortMappingsArgs[0].elt = "NewStartPort"; - GetListOfPortMappingsArgs[0].val = startPort; - GetListOfPortMappingsArgs[1].elt = "NewEndPort"; - GetListOfPortMappingsArgs[1].val = endPort; - GetListOfPortMappingsArgs[2].elt = "NewProtocol"; - GetListOfPortMappingsArgs[2].val = protocol; - GetListOfPortMappingsArgs[3].elt = "NewManage"; - GetListOfPortMappingsArgs[3].val = "1"; - GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts"; - GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000"; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetListOfPortMappings", - GetListOfPortMappingsArgs, &bufsize); - free(GetListOfPortMappingsArgs); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/ - /*if(p) { - printf("NewPortListing : %s\n", p); - }*/ - /*printf("NewPortListing(%d chars) : %s\n", - pdata.portListingLength, pdata.portListing);*/ - if(pdata.portListing) - { - /*struct PortMapping * pm; - int i = 0;*/ - ParsePortListing(pdata.portListing, pdata.portListingLength, - data); - ret = UPNPCOMMAND_SUCCESS; - /* - for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next) - { - printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost); - i++; - } - */ - /*FreePortListing(&data);*/ - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - - /*printf("%.*s", bufsize, buffer);*/ - - return ret; -} - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetFirewallStatus(const char * controlURL, - const char * servicetype, - int * firewallEnabled, - int * inboundPinholeAllowed) -{ - struct NameValueParserData pdata; - char * buffer; - int bufsize; - char * fe, *ipa, *p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!firewallEnabled || !inboundPinholeAllowed) - return UPNPCOMMAND_INVALID_ARGS; - - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetFirewallStatus", 0, &bufsize); - if(!buffer) { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - fe = GetValueFromNameValueList(&pdata, "FirewallEnabled"); - ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed"); - if(ipa && fe) - ret = UPNPCOMMAND_SUCCESS; - if(fe) - *firewallEnabled = my_atoui(fe); - /*else - *firewallEnabled = 0;*/ - if(ipa) - *inboundPinholeAllowed = my_atoui(ipa); - /*else - *inboundPinholeAllowed = 0;*/ - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - int * opTimeout) -{ - struct UPNParg * GetOutboundPinholeTimeoutArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - char * p; - int ret; - - if(!intPort || !intClient || !proto || !remotePort || !remoteHost) - return UPNPCOMMAND_INVALID_ARGS; - - GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg)); - if(GetOutboundPinholeTimeoutArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost"; - GetOutboundPinholeTimeoutArgs[0].val = remoteHost; - GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort"; - GetOutboundPinholeTimeoutArgs[1].val = remotePort; - GetOutboundPinholeTimeoutArgs[2].elt = "Protocol"; - GetOutboundPinholeTimeoutArgs[2].val = proto; - GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort"; - GetOutboundPinholeTimeoutArgs[3].val = intPort; - GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient"; - GetOutboundPinholeTimeoutArgs[4].val = intClient; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize); - free(GetOutboundPinholeTimeoutArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout"); - if(p) - *opTimeout = my_atoui(p); - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_AddPinhole(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - const char * leaseTime, - char * uniqueID) -{ - struct UPNParg * AddPinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - char * p; - int ret; - - if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime) - return UPNPCOMMAND_INVALID_ARGS; - - AddPinholeArgs = calloc(7, sizeof(struct UPNParg)); - if(AddPinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - /* RemoteHost can be wilcarded */ - if(strncmp(remoteHost, "empty", 5)==0) - { - AddPinholeArgs[0].elt = "RemoteHost"; - AddPinholeArgs[0].val = ""; - } - else - { - AddPinholeArgs[0].elt = "RemoteHost"; - AddPinholeArgs[0].val = remoteHost; - } - AddPinholeArgs[1].elt = "RemotePort"; - AddPinholeArgs[1].val = remotePort; - AddPinholeArgs[2].elt = "Protocol"; - AddPinholeArgs[2].val = proto; - AddPinholeArgs[3].elt = "InternalPort"; - AddPinholeArgs[3].val = intPort; - if(strncmp(intClient, "empty", 5)==0) - { - AddPinholeArgs[4].elt = "InternalClient"; - AddPinholeArgs[4].val = ""; - } - else - { - AddPinholeArgs[4].elt = "InternalClient"; - AddPinholeArgs[4].val = intClient; - } - AddPinholeArgs[5].elt = "LeaseTime"; - AddPinholeArgs[5].val = leaseTime; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPinhole", AddPinholeArgs, &bufsize); - free(AddPinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - p = GetValueFromNameValueList(&pdata, "UniqueID"); - if(p) - { - strncpy(uniqueID, p, 8); - uniqueID[7] = '\0'; - } - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, - const char * uniqueID, - const char * leaseTime) -{ - struct UPNParg * UpdatePinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!uniqueID || !leaseTime) - return UPNPCOMMAND_INVALID_ARGS; - - UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg)); - if(UpdatePinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - UpdatePinholeArgs[0].elt = "UniqueID"; - UpdatePinholeArgs[0].val = uniqueID; - UpdatePinholeArgs[1].elt = "NewLeaseTime"; - UpdatePinholeArgs[1].val = leaseTime; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "UpdatePinhole", UpdatePinholeArgs, &bufsize); - free(UpdatePinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID) -{ - /*struct NameValueParserData pdata;*/ - struct UPNParg * DeletePinholeArgs; - char * buffer; - int bufsize; - struct NameValueParserData pdata; - const char * resVal; - int ret; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - DeletePinholeArgs = calloc(2, sizeof(struct UPNParg)); - if(DeletePinholeArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - DeletePinholeArgs[0].elt = "UniqueID"; - DeletePinholeArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePinhole", DeletePinholeArgs, &bufsize); - free(DeletePinholeArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - /*DisplayNameValueList(buffer, bufsize);*/ - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(resVal, "%d", &ret); - } - else - { - ret = UPNPCOMMAND_SUCCESS; - } - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, - const char * uniqueID, int * isWorking) -{ - struct NameValueParserData pdata; - struct UPNParg * CheckPinholeWorkingArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg)); - if(CheckPinholeWorkingArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - CheckPinholeWorkingArgs[0].elt = "UniqueID"; - CheckPinholeWorkingArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize); - free(CheckPinholeWorkingArgs); - if(!buffer) - { - return UPNPCOMMAND_HTTP_ERROR; - } - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "IsWorking"); - if(p) - { - *isWorking=my_atoui(p); - ret = UPNPCOMMAND_SUCCESS; - } - else - *isWorking = 0; - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - -MINIUPNP_LIBSPEC int -UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, - const char * uniqueID, int * packets) -{ - struct NameValueParserData pdata; - struct UPNParg * GetPinholePacketsArgs; - char * buffer; - int bufsize; - char * p; - int ret = UPNPCOMMAND_UNKNOWN_ERROR; - - if(!uniqueID) - return UPNPCOMMAND_INVALID_ARGS; - - GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg)); - if(GetPinholePacketsArgs == NULL) - return UPNPCOMMAND_MEM_ALLOC_ERROR; - GetPinholePacketsArgs[0].elt = "UniqueID"; - GetPinholePacketsArgs[0].val = uniqueID; - buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetPinholePackets", GetPinholePacketsArgs, &bufsize); - free(GetPinholePacketsArgs); - if(!buffer) - return UPNPCOMMAND_HTTP_ERROR; - ParseNameValue(buffer, bufsize, &pdata); - free(buffer); buffer = NULL; - - p = GetValueFromNameValueList(&pdata, "PinholePackets"); - if(p) - { - *packets=my_atoui(p); - ret = UPNPCOMMAND_SUCCESS; - } - - p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { - ret = UPNPCOMMAND_UNKNOWN_ERROR; - sscanf(p, "%d", &ret); - } - - ClearNameValueList(&pdata); - return ret; -} - - diff --git a/ext/miniupnpc/upnpcommands.h b/ext/miniupnpc/upnpcommands.h deleted file mode 100644 index 22eda5e3..00000000 --- a/ext/miniupnpc/upnpcommands.h +++ /dev/null @@ -1,348 +0,0 @@ -/* $Id: upnpcommands.h,v 1.31 2015/07/21 13:16:55 nanard Exp $ */ -/* Miniupnp project : http://miniupnp.free.fr/ - * Author : Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file provided within this distribution */ -#ifndef UPNPCOMMANDS_H_INCLUDED -#define UPNPCOMMANDS_H_INCLUDED - -#include "upnpreplyparse.h" -#include "portlistingparse.h" -#include "miniupnpc_declspec.h" -#include "miniupnpctypes.h" - -/* MiniUPnPc return codes : */ -#define UPNPCOMMAND_SUCCESS (0) -#define UPNPCOMMAND_UNKNOWN_ERROR (-1) -#define UPNPCOMMAND_INVALID_ARGS (-2) -#define UPNPCOMMAND_HTTP_ERROR (-3) -#define UPNPCOMMAND_INVALID_RESPONSE (-4) -#define UPNPCOMMAND_MEM_ALLOC_ERROR (-5) - -#ifdef __cplusplus -extern "C" { -#endif - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesSent(const char * controlURL, - const char * servicetype); - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesReceived(const char * controlURL, - const char * servicetype); - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsSent(const char * controlURL, - const char * servicetype); - -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsReceived(const char * controlURL, - const char * servicetype); - -/* UPNP_GetStatusInfo() - * status and lastconnerror are 64 byte buffers - * Return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ -MINIUPNP_LIBSPEC int -UPNP_GetStatusInfo(const char * controlURL, - const char * servicetype, - char * status, - unsigned int * uptime, - char * lastconnerror); - -/* UPNP_GetConnectionTypeInfo() - * argument connectionType is a 64 character buffer - * Return Values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ -MINIUPNP_LIBSPEC int -UPNP_GetConnectionTypeInfo(const char * controlURL, - const char * servicetype, - char * connectionType); - -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 16 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * possible UPnP Errors : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. */ -MINIUPNP_LIBSPEC int -UPNP_GetExternalIPAddress(const char * controlURL, - const char * servicetype, - char * extIpAdd); - -/* UPNP_GetLinkLayerMaxBitRates() - * call WANCommonInterfaceConfig:1#GetCommonLinkProperties - * - * return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. */ -MINIUPNP_LIBSPEC int -UPNP_GetLinkLayerMaxBitRates(const char* controlURL, - const char* servicetype, - unsigned int * bitrateDown, - unsigned int * bitrateUp); - -/* UPNP_AddPortMapping() - * if desc is NULL, it will be defaulted to "libminiupnpc" - * remoteHost is usually NULL because IGD don't support it. - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR. Either an UPnP error code or an unknown error. - * - * List of possible UPnP errors for AddPortMapping : - * errorCode errorDescription (short) - Description (long) - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization and - * the sender was not authorized. - * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be - * wild-carded - * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded - * 718 ConflictInMappingEntry - The port mapping entry specified conflicts - * with a mapping assigned previously to another client - * 724 SamePortValuesRequired - Internal and External port values - * must be the same - * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports - * permanent lease times on port mappings - * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard - * and cannot be a specific IP address or DNS name - * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and - * cannot be a specific port value - * 728 NoPortMapsAvailable - There are not enough free ports available to - * complete port mapping. - * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed - * due to conflict with other mechanisms. - * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded - */ -MINIUPNP_LIBSPEC int -UPNP_AddPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration); - -/* UPNP_AddAnyPortMapping() - * if desc is NULL, it will be defaulted to "libminiupnpc" - * remoteHost is usually NULL because IGD don't support it. - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR. Either an UPnP error code or an unknown error. - * - * List of possible UPnP errors for AddPortMapping : - * errorCode errorDescription (short) - Description (long) - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization and - * the sender was not authorized. - * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be - * wild-carded - * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded - * 728 NoPortMapsAvailable - There are not enough free ports available to - * complete port mapping. - * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed - * due to conflict with other mechanisms. - * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded - */ -MINIUPNP_LIBSPEC int -UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration, - char * reservedPort); - -/* UPNP_DeletePortMapping() - * Use same argument values as what was used for AddPortMapping(). - * remoteHost is usually NULL because IGD don't support it. - * Return Values : - * 0 : SUCCESS - * NON ZERO : error. Either an UPnP error code or an undefined error. - * - * List of possible UPnP errors for DeletePortMapping : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 714 NoSuchEntryInArray - The specified value does not exist in the array */ -MINIUPNP_LIBSPEC int -UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, - const char * extPort, const char * proto, - const char * remoteHost); - -/* UPNP_DeletePortRangeMapping() - * Use same argument values as what was used for AddPortMapping(). - * remoteHost is usually NULL because IGD don't support it. - * Return Values : - * 0 : SUCCESS - * NON ZERO : error. Either an UPnP error code or an undefined error. - * - * List of possible UPnP errors for DeletePortMapping : - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 730 PortMappingNotFound - This error message is returned if no port - * mapping is found in the specified range. - * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */ -MINIUPNP_LIBSPEC int -UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, - const char * extPortStart, const char * extPortEnd, - const char * proto, - const char * manage); - -/* UPNP_GetPortMappingNumberOfEntries() - * not supported by all routers */ -MINIUPNP_LIBSPEC int -UPNP_GetPortMappingNumberOfEntries(const char* controlURL, - const char* servicetype, - unsigned int * num); - -/* UPNP_GetSpecificPortMappingEntry() - * retrieves an existing port mapping - * params : - * in extPort - * in proto - * in remoteHost - * out intClient (16 bytes) - * out intPort (6 bytes) - * out desc (80 bytes) - * out enabled (4 bytes) - * out leaseDuration (16 bytes) - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. - * - * List of possible UPnP errors for _GetSpecificPortMappingEntry : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 714 NoSuchEntryInArray - The specified value does not exist in the array. - */ -MINIUPNP_LIBSPEC int -UPNP_GetSpecificPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * extPort, - const char * proto, - const char * remoteHost, - char * intClient, - char * intPort, - char * desc, - char * enabled, - char * leaseDuration); - -/* UPNP_GetGenericPortMappingEntry() - * params : - * in index - * out extPort (6 bytes) - * out intClient (16 bytes) - * out intPort (6 bytes) - * out protocol (4 bytes) - * out desc (80 bytes) - * out enabled (4 bytes) - * out rHost (64 bytes) - * out duration (16 bytes) - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. - * - * Possible UPNP Error codes : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds - */ -MINIUPNP_LIBSPEC int -UPNP_GetGenericPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * index, - char * extPort, - char * intClient, - char * intPort, - char * protocol, - char * desc, - char * enabled, - char * rHost, - char * duration); - -/* UPNP_GetListOfPortMappings() Available in IGD v2 - * - * - * Possible UPNP Error codes : - * 606 Action not Authorized - * 730 PortMappingNotFound - no port mapping is found in the specified range. - * 733 InconsistantParameters - NewStartPort and NewEndPort values are not - * consistent. - */ -MINIUPNP_LIBSPEC int -UPNP_GetListOfPortMappings(const char * controlURL, - const char * servicetype, - const char * startPort, - const char * endPort, - const char * protocol, - const char * numberOfPorts, - struct PortMappingParserData * data); - -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetFirewallStatus(const char * controlURL, - const char * servicetype, - int * firewallEnabled, - int * inboundPinholeAllowed); - -MINIUPNP_LIBSPEC int -UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - int * opTimeout); - -MINIUPNP_LIBSPEC int -UPNP_AddPinhole(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - const char * leaseTime, - char * uniqueID); - -MINIUPNP_LIBSPEC int -UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, - const char * uniqueID, - const char * leaseTime); - -MINIUPNP_LIBSPEC int -UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID); - -MINIUPNP_LIBSPEC int -UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, - const char * uniqueID, int * isWorking); - -MINIUPNP_LIBSPEC int -UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, - const char * uniqueID, int * packets); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/ext/miniupnpc/upnpdev.c b/ext/miniupnpc/upnpdev.c deleted file mode 100644 index d89a9934..00000000 --- a/ext/miniupnpc/upnpdev.c +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: upnpdev.c,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ -/* Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#include -#include "upnpdev.h" - -/* freeUPNPDevlist() should be used to - * free the chained list returned by upnpDiscover() */ -void freeUPNPDevlist(struct UPNPDev * devlist) -{ - struct UPNPDev * next; - while(devlist) - { - next = devlist->pNext; - free(devlist); - devlist = next; - } -} - diff --git a/ext/miniupnpc/upnpdev.h b/ext/miniupnpc/upnpdev.h deleted file mode 100644 index f49fbe17..00000000 --- a/ext/miniupnpc/upnpdev.h +++ /dev/null @@ -1,36 +0,0 @@ -/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ -/* Project : miniupnp - * Web : http://miniupnp.free.fr/ - * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard - * This software is subjet to the conditions detailed in the - * provided LICENSE file. */ -#ifndef UPNPDEV_H_INCLUDED -#define UPNPDEV_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct UPNPDev { - struct UPNPDev * pNext; - char * descURL; - char * st; - unsigned int scope_id; - char * usn; - char buffer[3]; -}; - -/* freeUPNPDevlist() - * free list returned by upnpDiscover() */ -MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); - - -#ifdef __cplusplus -} -#endif - - -#endif /* UPNPDEV_H_INCLUDED */ diff --git a/ext/miniupnpc/upnperrors.c b/ext/miniupnpc/upnperrors.c deleted file mode 100644 index 7ab8ee96..00000000 --- a/ext/miniupnpc/upnperrors.c +++ /dev/null @@ -1,107 +0,0 @@ -/* $Id: upnperrors.c,v 1.8 2014/06/10 09:41:48 nanard Exp $ */ -/* Project : miniupnp - * Author : Thomas BERNARD - * copyright (c) 2007 Thomas Bernard - * All Right reserved. - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#include -#include "upnperrors.h" -#include "upnpcommands.h" -#include "miniupnpc.h" - -const char * strupnperror(int err) -{ - const char * s = NULL; - switch(err) { - case UPNPCOMMAND_SUCCESS: - s = "Success"; - break; - case UPNPCOMMAND_UNKNOWN_ERROR: - s = "Miniupnpc Unknown Error"; - break; - case UPNPCOMMAND_INVALID_ARGS: - s = "Miniupnpc Invalid Arguments"; - break; - case UPNPCOMMAND_INVALID_RESPONSE: - s = "Miniupnpc Invalid response"; - break; - case UPNPDISCOVER_SOCKET_ERROR: - s = "Miniupnpc Socket error"; - break; - case UPNPDISCOVER_MEMORY_ERROR: - s = "Miniupnpc Memory allocation error"; - break; - case 401: - s = "Invalid Action"; - break; - case 402: - s = "Invalid Args"; - break; - case 501: - s = "Action Failed"; - break; - case 606: - s = "Action not authorized"; - break; - case 701: - s = "PinholeSpaceExhausted"; - break; - case 702: - s = "FirewallDisabled"; - break; - case 703: - s = "InboundPinholeNotAllowed"; - break; - case 704: - s = "NoSuchEntry"; - break; - case 705: - s = "ProtocolNotSupported"; - break; - case 706: - s = "InternalPortWildcardingNotAllowed"; - break; - case 707: - s = "ProtocolWildcardingNotAllowed"; - break; - case 708: - s = "WildcardNotPermittedInSrcIP"; - break; - case 709: - s = "NoPacketSent"; - break; - case 713: - s = "SpecifiedArrayIndexInvalid"; - break; - case 714: - s = "NoSuchEntryInArray"; - break; - case 715: - s = "WildCardNotPermittedInSrcIP"; - break; - case 716: - s = "WildCardNotPermittedInExtPort"; - break; - case 718: - s = "ConflictInMappingEntry"; - break; - case 724: - s = "SamePortValuesRequired"; - break; - case 725: - s = "OnlyPermanentLeasesSupported"; - break; - case 726: - s = "RemoteHostOnlySupportsWildcard"; - break; - case 727: - s = "ExternalPortOnlySupportsWildcard"; - break; - default: - s = "UnknownError"; - break; - } - return s; -} diff --git a/ext/miniupnpc/upnperrors.h b/ext/miniupnpc/upnperrors.h deleted file mode 100644 index 3115aee5..00000000 --- a/ext/miniupnpc/upnperrors.h +++ /dev/null @@ -1,26 +0,0 @@ -/* $Id: upnperrors.h,v 1.6 2015/07/21 13:16:55 nanard Exp $ */ -/* (c) 2007-2015 Thomas Bernard - * All rights reserved. - * MiniUPnP Project. - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * This software is subjet to the conditions detailed in the - * provided LICENCE file. */ -#ifndef UPNPERRORS_H_INCLUDED -#define UPNPERRORS_H_INCLUDED - -#include "miniupnpc_declspec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* strupnperror() - * Return a string description of the UPnP error code - * or NULL for undefinded errors */ -MINIUPNP_LIBSPEC const char * strupnperror(int err); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ext/miniupnpc/upnpreplyparse.c b/ext/miniupnpc/upnpreplyparse.c deleted file mode 100644 index 5921349d..00000000 --- a/ext/miniupnpc/upnpreplyparse.c +++ /dev/null @@ -1,196 +0,0 @@ -/* $Id: upnpreplyparse.c,v 1.20 2017/12/12 11:26:25 nanard Exp $ */ -/* vim: tabstop=4 shiftwidth=4 noexpandtab - * MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2017 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - -#include -#include -#include - -#include "upnpreplyparse.h" -#include "minixml.h" - -static void -NameValueParserStartElt(void * d, const char * name, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - data->topelt = 1; - if(l>63) - l = 63; - memcpy(data->curelt, name, l); - data->curelt[l] = '\0'; - data->cdata = NULL; - data->cdatalen = 0; -} - -static void -NameValueParserEndElt(void * d, const char * name, int namelen) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - struct NameValue * nv; - (void)name; - (void)namelen; - if(!data->topelt) - return; - if(strcmp(data->curelt, "NewPortListing") != 0) - { - int l; - /* standard case. Limited to n chars strings */ - l = data->cdatalen; - nv = malloc(sizeof(struct NameValue)); - if(nv == NULL) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "NameValueParserEndElt"); -#endif /* DEBUG */ - return; - } - if(l>=(int)sizeof(nv->value)) - l = sizeof(nv->value) - 1; - strncpy(nv->name, data->curelt, 64); - nv->name[63] = '\0'; - if(data->cdata != NULL) - { - memcpy(nv->value, data->cdata, l); - nv->value[l] = '\0'; - } - else - { - nv->value[0] = '\0'; - } - nv->l_next = data->l_head; /* insert in list */ - data->l_head = nv; - } - data->cdata = NULL; - data->cdatalen = 0; - data->topelt = 0; -} - -static void -NameValueParserGetData(void * d, const char * datas, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - if(strcmp(data->curelt, "NewPortListing") == 0) - { - /* specific case for NewPortListing which is a XML Document */ - data->portListing = malloc(l + 1); - if(!data->portListing) - { - /* malloc error */ -#ifdef DEBUG - fprintf(stderr, "%s: error allocating memory", - "NameValueParserGetData"); -#endif /* DEBUG */ - return; - } - memcpy(data->portListing, datas, l); - data->portListing[l] = '\0'; - data->portListingLength = l; - } - else - { - /* standard case. */ - data->cdata = datas; - data->cdatalen = l; - } -} - -void -ParseNameValue(const char * buffer, int bufsize, - struct NameValueParserData * data) -{ - struct xmlparser parser; - memset(data, 0, sizeof(struct NameValueParserData)); - /* init xmlparser object */ - parser.xmlstart = buffer; - parser.xmlsize = bufsize; - parser.data = data; - parser.starteltfunc = NameValueParserStartElt; - parser.endeltfunc = NameValueParserEndElt; - parser.datafunc = NameValueParserGetData; - parser.attfunc = 0; - parsexml(&parser); -} - -void -ClearNameValueList(struct NameValueParserData * pdata) -{ - struct NameValue * nv; - if(pdata->portListing) - { - free(pdata->portListing); - pdata->portListing = NULL; - pdata->portListingLength = 0; - } - while((nv = pdata->l_head) != NULL) - { - pdata->l_head = nv->l_next; - free(nv); - } -} - -char * -GetValueFromNameValueList(struct NameValueParserData * pdata, - const char * Name) -{ - struct NameValue * nv; - char * p = NULL; - for(nv = pdata->l_head; - (nv != NULL) && (p == NULL); - nv = nv->l_next) - { - if(strcmp(nv->name, Name) == 0) - p = nv->value; - } - return p; -} - -#if 0 -/* useless now that minixml ignores namespaces by itself */ -char * -GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, - const char * Name) -{ - struct NameValue * nv; - char * p = NULL; - char * pname; - for(nv = pdata->head.lh_first; - (nv != NULL) && (p == NULL); - nv = nv->entries.le_next) - { - pname = strrchr(nv->name, ':'); - if(pname) - pname++; - else - pname = nv->name; - if(strcmp(pname, Name)==0) - p = nv->value; - } - return p; -} -#endif - -/* debug all-in-one function - * do parsing then display to stdout */ -#ifdef DEBUG -void -DisplayNameValueList(char * buffer, int bufsize) -{ - struct NameValueParserData pdata; - struct NameValue * nv; - ParseNameValue(buffer, bufsize, &pdata); - for(nv = pdata.l_head; - nv != NULL; - nv = nv->l_next) - { - printf("%s = %s\n", nv->name, nv->value); - } - ClearNameValueList(&pdata); -} -#endif /* DEBUG */ - diff --git a/ext/miniupnpc/upnpreplyparse.h b/ext/miniupnpc/upnpreplyparse.h deleted file mode 100644 index 6badd15b..00000000 --- a/ext/miniupnpc/upnpreplyparse.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2013 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - -#ifndef UPNPREPLYPARSE_H_INCLUDED -#define UPNPREPLYPARSE_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -struct NameValue { - struct NameValue * l_next; - char name[64]; - char value[128]; -}; - -struct NameValueParserData { - struct NameValue * l_head; - char curelt[64]; - char * portListing; - int portListingLength; - int topelt; - const char * cdata; - int cdatalen; -}; - -/* ParseNameValue() */ -void -ParseNameValue(const char * buffer, int bufsize, - struct NameValueParserData * data); - -/* ClearNameValueList() */ -void -ClearNameValueList(struct NameValueParserData * pdata); - -/* GetValueFromNameValueList() */ -char * -GetValueFromNameValueList(struct NameValueParserData * pdata, - const char * Name); - -#if 0 -/* GetValueFromNameValueListIgnoreNS() */ -char * -GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, - const char * Name); -#endif - -/* DisplayNameValueList() */ -#ifdef DEBUG -void -DisplayNameValueList(char * buffer, int bufsize); -#endif - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/ext/miniupnpc/wingenminiupnpcstrings.c b/ext/miniupnpc/wingenminiupnpcstrings.c deleted file mode 100644 index 50df06a7..00000000 --- a/ext/miniupnpc/wingenminiupnpcstrings.c +++ /dev/null @@ -1,83 +0,0 @@ -/* $Id: wingenminiupnpcstrings.c,v 1.4 2015/02/08 08:46:06 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENSE file provided within this distribution */ -#include -#include - -/* This program display the Windows version and is used to - * generate the miniupnpcstrings.h - * wingenminiupnpcstrings miniupnpcstrings.h.in miniupnpcstrings.h - */ -int main(int argc, char * * argv) { - char buffer[256]; - OSVERSIONINFO osvi; - FILE * fin; - FILE * fout; - int n; - char miniupnpcVersion[32]; - /* dwMajorVersion : - The major version number of the operating system. For more information, see Remarks. - dwMinorVersion : - The minor version number of the operating system. For more information, see Remarks. - dwBuildNumber : - The build number of the operating system. - dwPlatformId - The operating system platform. This member can be the following value. - szCSDVersion - A null-terminated string, such as "Service Pack 3", that indicates the - latest Service Pack installed on the system. If no Service Pack has - been installed, the string is empty. - */ - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - GetVersionEx(&osvi); - - printf("Windows %lu.%lu Build %lu %s\n", - osvi.dwMajorVersion, osvi.dwMinorVersion, - osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion)); - - fin = fopen("VERSION", "r"); - fgets(miniupnpcVersion, sizeof(miniupnpcVersion), fin); - fclose(fin); - for(n = 0; n < sizeof(miniupnpcVersion); n++) { - if(miniupnpcVersion[n] < ' ') - miniupnpcVersion[n] = '\0'; - } - printf("MiniUPnPc version %s\n", miniupnpcVersion); - - if(argc >= 3) { - fin = fopen(argv[1], "r"); - if(!fin) { - fprintf(stderr, "Cannot open %s for reading.\n", argv[1]); - return 1; - } - fout = fopen(argv[2], "w"); - if(!fout) { - fprintf(stderr, "Cannot open %s for writing.\n", argv[2]); - fclose(fin); - return 1; - } - n = 0; - while(fgets(buffer, sizeof(buffer), fin)) { - if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) { - sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n", - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); - } else if(0 == memcmp(buffer, "#define MINIUPNPC_VERSION_STRING \"version\"", 42)) { - sprintf(buffer, "#define MINIUPNPC_VERSION_STRING \"%s\"\n", - miniupnpcVersion); - } - /*fputs(buffer, stdout);*/ - fputs(buffer, fout); - n++; - } - fclose(fin); - fclose(fout); - printf("%d lines written to %s.\n", n, argv[2]); - } - return 0; -} diff --git a/ext/x64-salsa2012-asm/README.md b/ext/x64-salsa2012-asm/README.md deleted file mode 100644 index a69a1a67..00000000 --- a/ext/x64-salsa2012-asm/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Blazingly fast X64 ASM implementation of Salsa20/12 -====== - -This is ripped from the [cnacl](https://github.com/cjdelisle/cnacl) source. The actual code is by Danial J. Bernstein and is in the public domain. - -This is included on Linux and Mac 64-bit builds and is significantly faster than the SSE intrinsics or C versions. It's used for packet encode/decode only since its use differs a bit from the regular Salsa20 C++ class. Specifically it lacks the ability to be called on multiple blocks, preferring instead to take a key and a single stream to encrypt and that's it. diff --git a/ext/x64-salsa2012-asm/salsa2012.h b/ext/x64-salsa2012-asm/salsa2012.h deleted file mode 100644 index 73e375eb..00000000 --- a/ext/x64-salsa2012-asm/salsa2012.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef ZT_X64_SALSA2012_ASM -#define ZT_X64_SALSA2012_ASM - -#ifdef __cplusplus -extern "C" { -#endif - -// Generates Salsa20/12 key stream -// output, outlen, nonce, key (256-bit / 32-byte) -extern int zt_salsa2012_amd64_xmm6(unsigned char *, unsigned long long, const unsigned char *, const unsigned char *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ext/x64-salsa2012-asm/salsa2012.s b/ext/x64-salsa2012-asm/salsa2012.s deleted file mode 100644 index 699c89ac..00000000 --- a/ext/x64-salsa2012-asm/salsa2012.s +++ /dev/null @@ -1,4488 +0,0 @@ -# qhasm: enter zt_salsa2012_amd64_xmm6 -.text -.p2align 5 -.globl _zt_salsa2012_amd64_xmm6 -.globl zt_salsa2012_amd64_xmm6 -_zt_salsa2012_amd64_xmm6: -zt_salsa2012_amd64_xmm6: -mov %rsp,%r11 -and $31,%r11 -add $480,%r11 -sub %r11,%rsp - -# qhasm: r11_stack = r11_caller -# asm 1: movq r11_stack=stack64#1 -# asm 2: movq r11_stack=352(%rsp) -movq %r11,352(%rsp) - -# qhasm: r12_stack = r12_caller -# asm 1: movq r12_stack=stack64#2 -# asm 2: movq r12_stack=360(%rsp) -movq %r12,360(%rsp) - -# qhasm: r13_stack = r13_caller -# asm 1: movq r13_stack=stack64#3 -# asm 2: movq r13_stack=368(%rsp) -movq %r13,368(%rsp) - -# qhasm: r14_stack = r14_caller -# asm 1: movq r14_stack=stack64#4 -# asm 2: movq r14_stack=376(%rsp) -movq %r14,376(%rsp) - -# qhasm: r15_stack = r15_caller -# asm 1: movq r15_stack=stack64#5 -# asm 2: movq r15_stack=384(%rsp) -movq %r15,384(%rsp) - -# qhasm: rbx_stack = rbx_caller -# asm 1: movq rbx_stack=stack64#6 -# asm 2: movq rbx_stack=392(%rsp) -movq %rbx,392(%rsp) - -# qhasm: rbp_stack = rbp_caller -# asm 1: movq rbp_stack=stack64#7 -# asm 2: movq rbp_stack=400(%rsp) -movq %rbp,400(%rsp) - -# qhasm: bytes = arg2 -# asm 1: mov bytes=int64#6 -# asm 2: mov bytes=%r9 -mov %rsi,%r9 - -# qhasm: out = arg1 -# asm 1: mov out=int64#1 -# asm 2: mov out=%rdi -mov %rdi,%rdi - -# qhasm: m = out -# asm 1: mov m=int64#2 -# asm 2: mov m=%rsi -mov %rdi,%rsi - -# qhasm: iv = arg3 -# asm 1: mov iv=int64#3 -# asm 2: mov iv=%rdx -mov %rdx,%rdx - -# qhasm: k = arg4 -# asm 1: mov k=int64#8 -# asm 2: mov k=%r10 -mov %rcx,%r10 - -# qhasm: unsigned>? bytes - 0 -# asm 1: cmp $0, -jbe ._done - -# qhasm: a = 0 -# asm 1: mov $0,>a=int64#7 -# asm 2: mov $0,>a=%rax -mov $0,%rax - -# qhasm: i = bytes -# asm 1: mov i=int64#4 -# asm 2: mov i=%rcx -mov %r9,%rcx - -# qhasm: while (i) { *out++ = a; --i } -rep stosb - -# qhasm: out -= bytes -# asm 1: sub r11_stack=stack64#1 -# asm 2: movq r11_stack=352(%rsp) -movq %r11,352(%rsp) - -# qhasm: r12_stack = r12_caller -# asm 1: movq r12_stack=stack64#2 -# asm 2: movq r12_stack=360(%rsp) -movq %r12,360(%rsp) - -# qhasm: r13_stack = r13_caller -# asm 1: movq r13_stack=stack64#3 -# asm 2: movq r13_stack=368(%rsp) -movq %r13,368(%rsp) - -# qhasm: r14_stack = r14_caller -# asm 1: movq r14_stack=stack64#4 -# asm 2: movq r14_stack=376(%rsp) -movq %r14,376(%rsp) - -# qhasm: r15_stack = r15_caller -# asm 1: movq r15_stack=stack64#5 -# asm 2: movq r15_stack=384(%rsp) -movq %r15,384(%rsp) - -# qhasm: rbx_stack = rbx_caller -# asm 1: movq rbx_stack=stack64#6 -# asm 2: movq rbx_stack=392(%rsp) -movq %rbx,392(%rsp) - -# qhasm: rbp_stack = rbp_caller -# asm 1: movq rbp_stack=stack64#7 -# asm 2: movq rbp_stack=400(%rsp) -movq %rbp,400(%rsp) - -# qhasm: out = arg1 -# asm 1: mov out=int64#1 -# asm 2: mov out=%rdi -mov %rdi,%rdi - -# qhasm: m = arg2 -# asm 1: mov m=int64#2 -# asm 2: mov m=%rsi -mov %rsi,%rsi - -# qhasm: bytes = arg3 -# asm 1: mov bytes=int64#6 -# asm 2: mov bytes=%r9 -mov %rdx,%r9 - -# qhasm: iv = arg4 -# asm 1: mov iv=int64#3 -# asm 2: mov iv=%rdx -mov %rcx,%rdx - -# qhasm: k = arg5 -# asm 1: mov k=int64#8 -# asm 2: mov k=%r10 -mov %r8,%r10 - -# qhasm: unsigned>? bytes - 0 -# asm 1: cmp $0, -jbe ._done -# comment:fp stack unchanged by fallthrough - -# qhasm: start: -._start: - -# qhasm: in12 = *(uint32 *) (k + 20) -# asm 1: movl 20(in12=int64#4d -# asm 2: movl 20(in12=%ecx -movl 20(%r10),%ecx - -# qhasm: in1 = *(uint32 *) (k + 0) -# asm 1: movl 0(in1=int64#5d -# asm 2: movl 0(in1=%r8d -movl 0(%r10),%r8d - -# qhasm: in6 = *(uint32 *) (iv + 0) -# asm 1: movl 0(in6=int64#7d -# asm 2: movl 0(in6=%eax -movl 0(%rdx),%eax - -# qhasm: in11 = *(uint32 *) (k + 16) -# asm 1: movl 16(in11=int64#9d -# asm 2: movl 16(in11=%r11d -movl 16(%r10),%r11d - -# qhasm: ((uint32 *)&x1)[0] = in12 -# asm 1: movl x1=stack128#1 -# asm 2: movl x1=0(%rsp) -movl %ecx,0(%rsp) - -# qhasm: ((uint32 *)&x1)[1] = in1 -# asm 1: movl in8=int64#4 -# asm 2: mov $0,>in8=%rcx -mov $0,%rcx - -# qhasm: in13 = *(uint32 *) (k + 24) -# asm 1: movl 24(in13=int64#5d -# asm 2: movl 24(in13=%r8d -movl 24(%r10),%r8d - -# qhasm: in2 = *(uint32 *) (k + 4) -# asm 1: movl 4(in2=int64#7d -# asm 2: movl 4(in2=%eax -movl 4(%r10),%eax - -# qhasm: in7 = *(uint32 *) (iv + 4) -# asm 1: movl 4(in7=int64#3d -# asm 2: movl 4(in7=%edx -movl 4(%rdx),%edx - -# qhasm: ((uint32 *)&x2)[0] = in8 -# asm 1: movl x2=stack128#2 -# asm 2: movl x2=16(%rsp) -movl %ecx,16(%rsp) - -# qhasm: ((uint32 *)&x2)[1] = in13 -# asm 1: movl in4=int64#3d -# asm 2: movl 12(in4=%edx -movl 12(%r10),%edx - -# qhasm: in9 = 0 -# asm 1: mov $0,>in9=int64#4 -# asm 2: mov $0,>in9=%rcx -mov $0,%rcx - -# qhasm: in14 = *(uint32 *) (k + 28) -# asm 1: movl 28(in14=int64#5d -# asm 2: movl 28(in14=%r8d -movl 28(%r10),%r8d - -# qhasm: in3 = *(uint32 *) (k + 8) -# asm 1: movl 8(in3=int64#7d -# asm 2: movl 8(in3=%eax -movl 8(%r10),%eax - -# qhasm: ((uint32 *)&x3)[0] = in4 -# asm 1: movl x3=stack128#3 -# asm 2: movl x3=32(%rsp) -movl %edx,32(%rsp) - -# qhasm: ((uint32 *)&x3)[1] = in9 -# asm 1: movl in0=int64#3 -# asm 2: mov $1634760805,>in0=%rdx -mov $1634760805,%rdx - -# qhasm: in5 = 857760878 -# asm 1: mov $857760878,>in5=int64#4 -# asm 2: mov $857760878,>in5=%rcx -mov $857760878,%rcx - -# qhasm: in10 = 2036477234 -# asm 1: mov $2036477234,>in10=int64#5 -# asm 2: mov $2036477234,>in10=%r8 -mov $2036477234,%r8 - -# qhasm: in15 = 1797285236 -# asm 1: mov $1797285236,>in15=int64#7 -# asm 2: mov $1797285236,>in15=%rax -mov $1797285236,%rax - -# qhasm: ((uint32 *)&x0)[0] = in0 -# asm 1: movl x0=stack128#4 -# asm 2: movl x0=48(%rsp) -movl %edx,48(%rsp) - -# qhasm: ((uint32 *)&x0)[1] = in5 -# asm 1: movl z0=int6464#1 -# asm 2: movdqa z0=%xmm0 -movdqa 48(%rsp),%xmm0 - -# qhasm: z5 = z0[1,1,1,1] -# asm 1: pshufd $0x55,z5=int6464#2 -# asm 2: pshufd $0x55,z5=%xmm1 -pshufd $0x55,%xmm0,%xmm1 - -# qhasm: z10 = z0[2,2,2,2] -# asm 1: pshufd $0xaa,z10=int6464#3 -# asm 2: pshufd $0xaa,z10=%xmm2 -pshufd $0xaa,%xmm0,%xmm2 - -# qhasm: z15 = z0[3,3,3,3] -# asm 1: pshufd $0xff,z15=int6464#4 -# asm 2: pshufd $0xff,z15=%xmm3 -pshufd $0xff,%xmm0,%xmm3 - -# qhasm: z0 = z0[0,0,0,0] -# asm 1: pshufd $0x00,z0=int6464#1 -# asm 2: pshufd $0x00,z0=%xmm0 -pshufd $0x00,%xmm0,%xmm0 - -# qhasm: orig5 = z5 -# asm 1: movdqa orig5=stack128#5 -# asm 2: movdqa orig5=64(%rsp) -movdqa %xmm1,64(%rsp) - -# qhasm: orig10 = z10 -# asm 1: movdqa orig10=stack128#6 -# asm 2: movdqa orig10=80(%rsp) -movdqa %xmm2,80(%rsp) - -# qhasm: orig15 = z15 -# asm 1: movdqa orig15=stack128#7 -# asm 2: movdqa orig15=96(%rsp) -movdqa %xmm3,96(%rsp) - -# qhasm: orig0 = z0 -# asm 1: movdqa orig0=stack128#8 -# asm 2: movdqa orig0=112(%rsp) -movdqa %xmm0,112(%rsp) - -# qhasm: z1 = x1 -# asm 1: movdqa z1=int6464#1 -# asm 2: movdqa z1=%xmm0 -movdqa 0(%rsp),%xmm0 - -# qhasm: z6 = z1[2,2,2,2] -# asm 1: pshufd $0xaa,z6=int6464#2 -# asm 2: pshufd $0xaa,z6=%xmm1 -pshufd $0xaa,%xmm0,%xmm1 - -# qhasm: z11 = z1[3,3,3,3] -# asm 1: pshufd $0xff,z11=int6464#3 -# asm 2: pshufd $0xff,z11=%xmm2 -pshufd $0xff,%xmm0,%xmm2 - -# qhasm: z12 = z1[0,0,0,0] -# asm 1: pshufd $0x00,z12=int6464#4 -# asm 2: pshufd $0x00,z12=%xmm3 -pshufd $0x00,%xmm0,%xmm3 - -# qhasm: z1 = z1[1,1,1,1] -# asm 1: pshufd $0x55,z1=int6464#1 -# asm 2: pshufd $0x55,z1=%xmm0 -pshufd $0x55,%xmm0,%xmm0 - -# qhasm: orig6 = z6 -# asm 1: movdqa orig6=stack128#9 -# asm 2: movdqa orig6=128(%rsp) -movdqa %xmm1,128(%rsp) - -# qhasm: orig11 = z11 -# asm 1: movdqa orig11=stack128#10 -# asm 2: movdqa orig11=144(%rsp) -movdqa %xmm2,144(%rsp) - -# qhasm: orig12 = z12 -# asm 1: movdqa orig12=stack128#11 -# asm 2: movdqa orig12=160(%rsp) -movdqa %xmm3,160(%rsp) - -# qhasm: orig1 = z1 -# asm 1: movdqa orig1=stack128#12 -# asm 2: movdqa orig1=176(%rsp) -movdqa %xmm0,176(%rsp) - -# qhasm: z2 = x2 -# asm 1: movdqa z2=int6464#1 -# asm 2: movdqa z2=%xmm0 -movdqa 16(%rsp),%xmm0 - -# qhasm: z7 = z2[3,3,3,3] -# asm 1: pshufd $0xff,z7=int6464#2 -# asm 2: pshufd $0xff,z7=%xmm1 -pshufd $0xff,%xmm0,%xmm1 - -# qhasm: z13 = z2[1,1,1,1] -# asm 1: pshufd $0x55,z13=int6464#3 -# asm 2: pshufd $0x55,z13=%xmm2 -pshufd $0x55,%xmm0,%xmm2 - -# qhasm: z2 = z2[2,2,2,2] -# asm 1: pshufd $0xaa,z2=int6464#1 -# asm 2: pshufd $0xaa,z2=%xmm0 -pshufd $0xaa,%xmm0,%xmm0 - -# qhasm: orig7 = z7 -# asm 1: movdqa orig7=stack128#13 -# asm 2: movdqa orig7=192(%rsp) -movdqa %xmm1,192(%rsp) - -# qhasm: orig13 = z13 -# asm 1: movdqa orig13=stack128#14 -# asm 2: movdqa orig13=208(%rsp) -movdqa %xmm2,208(%rsp) - -# qhasm: orig2 = z2 -# asm 1: movdqa orig2=stack128#15 -# asm 2: movdqa orig2=224(%rsp) -movdqa %xmm0,224(%rsp) - -# qhasm: z3 = x3 -# asm 1: movdqa z3=int6464#1 -# asm 2: movdqa z3=%xmm0 -movdqa 32(%rsp),%xmm0 - -# qhasm: z4 = z3[0,0,0,0] -# asm 1: pshufd $0x00,z4=int6464#2 -# asm 2: pshufd $0x00,z4=%xmm1 -pshufd $0x00,%xmm0,%xmm1 - -# qhasm: z14 = z3[2,2,2,2] -# asm 1: pshufd $0xaa,z14=int6464#3 -# asm 2: pshufd $0xaa,z14=%xmm2 -pshufd $0xaa,%xmm0,%xmm2 - -# qhasm: z3 = z3[3,3,3,3] -# asm 1: pshufd $0xff,z3=int6464#1 -# asm 2: pshufd $0xff,z3=%xmm0 -pshufd $0xff,%xmm0,%xmm0 - -# qhasm: orig4 = z4 -# asm 1: movdqa orig4=stack128#16 -# asm 2: movdqa orig4=240(%rsp) -movdqa %xmm1,240(%rsp) - -# qhasm: orig14 = z14 -# asm 1: movdqa orig14=stack128#17 -# asm 2: movdqa orig14=256(%rsp) -movdqa %xmm2,256(%rsp) - -# qhasm: orig3 = z3 -# asm 1: movdqa orig3=stack128#18 -# asm 2: movdqa orig3=272(%rsp) -movdqa %xmm0,272(%rsp) - -# qhasm: bytesatleast256: -._bytesatleast256: - -# qhasm: in8 = ((uint32 *)&x2)[0] -# asm 1: movl in8=int64#3d -# asm 2: movl in8=%edx -movl 16(%rsp),%edx - -# qhasm: in9 = ((uint32 *)&x3)[1] -# asm 1: movl 4+in9=int64#4d -# asm 2: movl 4+in9=%ecx -movl 4+32(%rsp),%ecx - -# qhasm: ((uint32 *) &orig8)[0] = in8 -# asm 1: movl orig8=stack128#19 -# asm 2: movl orig8=288(%rsp) -movl %edx,288(%rsp) - -# qhasm: ((uint32 *) &orig9)[0] = in9 -# asm 1: movl orig9=stack128#20 -# asm 2: movl orig9=304(%rsp) -movl %ecx,304(%rsp) - -# qhasm: in8 += 1 -# asm 1: add $1,in9=int64#4 -# asm 2: mov in9=%rcx -mov %rdx,%rcx - -# qhasm: (uint64) in9 >>= 32 -# asm 1: shr $32,in9=int64#4 -# asm 2: mov in9=%rcx -mov %rdx,%rcx - -# qhasm: (uint64) in9 >>= 32 -# asm 1: shr $32,in9=int64#4 -# asm 2: mov in9=%rcx -mov %rdx,%rcx - -# qhasm: (uint64) in9 >>= 32 -# asm 1: shr $32,in9=int64#4 -# asm 2: mov in9=%rcx -mov %rdx,%rcx - -# qhasm: (uint64) in9 >>= 32 -# asm 1: shr $32,x2=stack128#2 -# asm 2: movl x2=16(%rsp) -movl %edx,16(%rsp) - -# qhasm: ((uint32 *)&x3)[1] = in9 -# asm 1: movl bytes_backup=stack64#8 -# asm 2: movq bytes_backup=408(%rsp) -movq %r9,408(%rsp) - -# qhasm: i = 12 -# asm 1: mov $12,>i=int64#3 -# asm 2: mov $12,>i=%rdx -mov $12,%rdx - -# qhasm: z5 = orig5 -# asm 1: movdqa z5=int6464#1 -# asm 2: movdqa z5=%xmm0 -movdqa 64(%rsp),%xmm0 - -# qhasm: z10 = orig10 -# asm 1: movdqa z10=int6464#2 -# asm 2: movdqa z10=%xmm1 -movdqa 80(%rsp),%xmm1 - -# qhasm: z15 = orig15 -# asm 1: movdqa z15=int6464#3 -# asm 2: movdqa z15=%xmm2 -movdqa 96(%rsp),%xmm2 - -# qhasm: z14 = orig14 -# asm 1: movdqa z14=int6464#4 -# asm 2: movdqa z14=%xmm3 -movdqa 256(%rsp),%xmm3 - -# qhasm: z3 = orig3 -# asm 1: movdqa z3=int6464#5 -# asm 2: movdqa z3=%xmm4 -movdqa 272(%rsp),%xmm4 - -# qhasm: z6 = orig6 -# asm 1: movdqa z6=int6464#6 -# asm 2: movdqa z6=%xmm5 -movdqa 128(%rsp),%xmm5 - -# qhasm: z11 = orig11 -# asm 1: movdqa z11=int6464#7 -# asm 2: movdqa z11=%xmm6 -movdqa 144(%rsp),%xmm6 - -# qhasm: z1 = orig1 -# asm 1: movdqa z1=int6464#8 -# asm 2: movdqa z1=%xmm7 -movdqa 176(%rsp),%xmm7 - -# qhasm: z7 = orig7 -# asm 1: movdqa z7=int6464#9 -# asm 2: movdqa z7=%xmm8 -movdqa 192(%rsp),%xmm8 - -# qhasm: z13 = orig13 -# asm 1: movdqa z13=int6464#10 -# asm 2: movdqa z13=%xmm9 -movdqa 208(%rsp),%xmm9 - -# qhasm: z2 = orig2 -# asm 1: movdqa z2=int6464#11 -# asm 2: movdqa z2=%xmm10 -movdqa 224(%rsp),%xmm10 - -# qhasm: z9 = orig9 -# asm 1: movdqa z9=int6464#12 -# asm 2: movdqa z9=%xmm11 -movdqa 304(%rsp),%xmm11 - -# qhasm: z0 = orig0 -# asm 1: movdqa z0=int6464#13 -# asm 2: movdqa z0=%xmm12 -movdqa 112(%rsp),%xmm12 - -# qhasm: z12 = orig12 -# asm 1: movdqa z12=int6464#14 -# asm 2: movdqa z12=%xmm13 -movdqa 160(%rsp),%xmm13 - -# qhasm: z4 = orig4 -# asm 1: movdqa z4=int6464#15 -# asm 2: movdqa z4=%xmm14 -movdqa 240(%rsp),%xmm14 - -# qhasm: z8 = orig8 -# asm 1: movdqa z8=int6464#16 -# asm 2: movdqa z8=%xmm15 -movdqa 288(%rsp),%xmm15 - -# qhasm: mainloop1: -._mainloop1: - -# qhasm: z10_stack = z10 -# asm 1: movdqa z10_stack=stack128#21 -# asm 2: movdqa z10_stack=320(%rsp) -movdqa %xmm1,320(%rsp) - -# qhasm: z15_stack = z15 -# asm 1: movdqa z15_stack=stack128#22 -# asm 2: movdqa z15_stack=336(%rsp) -movdqa %xmm2,336(%rsp) - -# qhasm: y4 = z12 -# asm 1: movdqa y4=int6464#2 -# asm 2: movdqa y4=%xmm1 -movdqa %xmm13,%xmm1 - -# qhasm: uint32323232 y4 += z0 -# asm 1: paddd r4=int6464#3 -# asm 2: movdqa r4=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y4 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,y9=int6464#2 -# asm 2: movdqa y9=%xmm1 -movdqa %xmm7,%xmm1 - -# qhasm: uint32323232 y9 += z5 -# asm 1: paddd r9=int6464#3 -# asm 2: movdqa r9=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y9 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,y8=int6464#2 -# asm 2: movdqa y8=%xmm1 -movdqa %xmm12,%xmm1 - -# qhasm: uint32323232 y8 += z4 -# asm 1: paddd r8=int6464#3 -# asm 2: movdqa r8=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y8 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y13=int6464#2 -# asm 2: movdqa y13=%xmm1 -movdqa %xmm0,%xmm1 - -# qhasm: uint32323232 y13 += z9 -# asm 1: paddd r13=int6464#3 -# asm 2: movdqa r13=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y13 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y12=int6464#2 -# asm 2: movdqa y12=%xmm1 -movdqa %xmm14,%xmm1 - -# qhasm: uint32323232 y12 += z8 -# asm 1: paddd r12=int6464#3 -# asm 2: movdqa r12=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y12 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y1=int6464#2 -# asm 2: movdqa y1=%xmm1 -movdqa %xmm11,%xmm1 - -# qhasm: uint32323232 y1 += z13 -# asm 1: paddd r1=int6464#3 -# asm 2: movdqa r1=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y1 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y0=int6464#2 -# asm 2: movdqa y0=%xmm1 -movdqa %xmm15,%xmm1 - -# qhasm: uint32323232 y0 += z12 -# asm 1: paddd r0=int6464#3 -# asm 2: movdqa r0=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y0 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,z10=int6464#2 -# asm 2: movdqa z10=%xmm1 -movdqa 320(%rsp),%xmm1 - -# qhasm: z0_stack = z0 -# asm 1: movdqa z0_stack=stack128#21 -# asm 2: movdqa z0_stack=320(%rsp) -movdqa %xmm12,320(%rsp) - -# qhasm: y5 = z13 -# asm 1: movdqa y5=int6464#3 -# asm 2: movdqa y5=%xmm2 -movdqa %xmm9,%xmm2 - -# qhasm: uint32323232 y5 += z1 -# asm 1: paddd r5=int6464#13 -# asm 2: movdqa r5=%xmm12 -movdqa %xmm2,%xmm12 - -# qhasm: uint32323232 y5 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,y14=int6464#3 -# asm 2: movdqa y14=%xmm2 -movdqa %xmm5,%xmm2 - -# qhasm: uint32323232 y14 += z10 -# asm 1: paddd r14=int6464#13 -# asm 2: movdqa r14=%xmm12 -movdqa %xmm2,%xmm12 - -# qhasm: uint32323232 y14 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,z15=int6464#3 -# asm 2: movdqa z15=%xmm2 -movdqa 336(%rsp),%xmm2 - -# qhasm: z5_stack = z5 -# asm 1: movdqa z5_stack=stack128#22 -# asm 2: movdqa z5_stack=336(%rsp) -movdqa %xmm0,336(%rsp) - -# qhasm: y3 = z11 -# asm 1: movdqa y3=int6464#1 -# asm 2: movdqa y3=%xmm0 -movdqa %xmm6,%xmm0 - -# qhasm: uint32323232 y3 += z15 -# asm 1: paddd r3=int6464#13 -# asm 2: movdqa r3=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y3 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,y2=int6464#1 -# asm 2: movdqa y2=%xmm0 -movdqa %xmm1,%xmm0 - -# qhasm: uint32323232 y2 += z14 -# asm 1: paddd r2=int6464#13 -# asm 2: movdqa r2=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y2 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y7=int6464#1 -# asm 2: movdqa y7=%xmm0 -movdqa %xmm2,%xmm0 - -# qhasm: uint32323232 y7 += z3 -# asm 1: paddd r7=int6464#13 -# asm 2: movdqa r7=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y7 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y6=int6464#1 -# asm 2: movdqa y6=%xmm0 -movdqa %xmm3,%xmm0 - -# qhasm: uint32323232 y6 += z2 -# asm 1: paddd r6=int6464#13 -# asm 2: movdqa r6=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y6 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y11=int6464#1 -# asm 2: movdqa y11=%xmm0 -movdqa %xmm4,%xmm0 - -# qhasm: uint32323232 y11 += z7 -# asm 1: paddd r11=int6464#13 -# asm 2: movdqa r11=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y11 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y10=int6464#1 -# asm 2: movdqa y10=%xmm0 -movdqa %xmm10,%xmm0 - -# qhasm: uint32323232 y10 += z6 -# asm 1: paddd r10=int6464#13 -# asm 2: movdqa r10=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y10 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,z0=int6464#1 -# asm 2: movdqa z0=%xmm0 -movdqa 320(%rsp),%xmm0 - -# qhasm: z10_stack = z10 -# asm 1: movdqa z10_stack=stack128#21 -# asm 2: movdqa z10_stack=320(%rsp) -movdqa %xmm1,320(%rsp) - -# qhasm: y1 = z3 -# asm 1: movdqa y1=int6464#2 -# asm 2: movdqa y1=%xmm1 -movdqa %xmm4,%xmm1 - -# qhasm: uint32323232 y1 += z0 -# asm 1: paddd r1=int6464#13 -# asm 2: movdqa r1=%xmm12 -movdqa %xmm1,%xmm12 - -# qhasm: uint32323232 y1 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,y15=int6464#2 -# asm 2: movdqa y15=%xmm1 -movdqa %xmm8,%xmm1 - -# qhasm: uint32323232 y15 += z11 -# asm 1: paddd r15=int6464#13 -# asm 2: movdqa r15=%xmm12 -movdqa %xmm1,%xmm12 - -# qhasm: uint32323232 y15 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,z5=int6464#13 -# asm 2: movdqa z5=%xmm12 -movdqa 336(%rsp),%xmm12 - -# qhasm: z15_stack = z15 -# asm 1: movdqa z15_stack=stack128#22 -# asm 2: movdqa z15_stack=336(%rsp) -movdqa %xmm2,336(%rsp) - -# qhasm: y6 = z4 -# asm 1: movdqa y6=int6464#2 -# asm 2: movdqa y6=%xmm1 -movdqa %xmm14,%xmm1 - -# qhasm: uint32323232 y6 += z5 -# asm 1: paddd r6=int6464#3 -# asm 2: movdqa r6=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y6 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,y2=int6464#2 -# asm 2: movdqa y2=%xmm1 -movdqa %xmm0,%xmm1 - -# qhasm: uint32323232 y2 += z1 -# asm 1: paddd r2=int6464#3 -# asm 2: movdqa r2=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y2 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y7=int6464#2 -# asm 2: movdqa y7=%xmm1 -movdqa %xmm12,%xmm1 - -# qhasm: uint32323232 y7 += z6 -# asm 1: paddd r7=int6464#3 -# asm 2: movdqa r7=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y7 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y3=int6464#2 -# asm 2: movdqa y3=%xmm1 -movdqa %xmm7,%xmm1 - -# qhasm: uint32323232 y3 += z2 -# asm 1: paddd r3=int6464#3 -# asm 2: movdqa r3=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y3 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y4=int6464#2 -# asm 2: movdqa y4=%xmm1 -movdqa %xmm5,%xmm1 - -# qhasm: uint32323232 y4 += z7 -# asm 1: paddd r4=int6464#3 -# asm 2: movdqa r4=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y4 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y0=int6464#2 -# asm 2: movdqa y0=%xmm1 -movdqa %xmm10,%xmm1 - -# qhasm: uint32323232 y0 += z3 -# asm 1: paddd r0=int6464#3 -# asm 2: movdqa r0=%xmm2 -movdqa %xmm1,%xmm2 - -# qhasm: uint32323232 y0 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,z10=int6464#2 -# asm 2: movdqa z10=%xmm1 -movdqa 320(%rsp),%xmm1 - -# qhasm: z0_stack = z0 -# asm 1: movdqa z0_stack=stack128#21 -# asm 2: movdqa z0_stack=320(%rsp) -movdqa %xmm0,320(%rsp) - -# qhasm: y5 = z7 -# asm 1: movdqa y5=int6464#1 -# asm 2: movdqa y5=%xmm0 -movdqa %xmm8,%xmm0 - -# qhasm: uint32323232 y5 += z4 -# asm 1: paddd r5=int6464#3 -# asm 2: movdqa r5=%xmm2 -movdqa %xmm0,%xmm2 - -# qhasm: uint32323232 y5 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,y11=int6464#1 -# asm 2: movdqa y11=%xmm0 -movdqa %xmm11,%xmm0 - -# qhasm: uint32323232 y11 += z10 -# asm 1: paddd r11=int6464#3 -# asm 2: movdqa r11=%xmm2 -movdqa %xmm0,%xmm2 - -# qhasm: uint32323232 y11 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,z15=int6464#3 -# asm 2: movdqa z15=%xmm2 -movdqa 336(%rsp),%xmm2 - -# qhasm: z5_stack = z5 -# asm 1: movdqa z5_stack=stack128#22 -# asm 2: movdqa z5_stack=336(%rsp) -movdqa %xmm12,336(%rsp) - -# qhasm: y12 = z14 -# asm 1: movdqa y12=int6464#1 -# asm 2: movdqa y12=%xmm0 -movdqa %xmm3,%xmm0 - -# qhasm: uint32323232 y12 += z15 -# asm 1: paddd r12=int6464#13 -# asm 2: movdqa r12=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y12 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,y8=int6464#1 -# asm 2: movdqa y8=%xmm0 -movdqa %xmm1,%xmm0 - -# qhasm: uint32323232 y8 += z11 -# asm 1: paddd r8=int6464#13 -# asm 2: movdqa r8=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y8 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y13=int6464#1 -# asm 2: movdqa y13=%xmm0 -movdqa %xmm2,%xmm0 - -# qhasm: uint32323232 y13 += z12 -# asm 1: paddd r13=int6464#13 -# asm 2: movdqa r13=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y13 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,y9=int6464#1 -# asm 2: movdqa y9=%xmm0 -movdqa %xmm6,%xmm0 - -# qhasm: uint32323232 y9 += z8 -# asm 1: paddd r9=int6464#13 -# asm 2: movdqa r9=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y9 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y14=int6464#1 -# asm 2: movdqa y14=%xmm0 -movdqa %xmm13,%xmm0 - -# qhasm: uint32323232 y14 += z13 -# asm 1: paddd r14=int6464#13 -# asm 2: movdqa r14=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y14 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,y10=int6464#1 -# asm 2: movdqa y10=%xmm0 -movdqa %xmm15,%xmm0 - -# qhasm: uint32323232 y10 += z9 -# asm 1: paddd r10=int6464#13 -# asm 2: movdqa r10=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y10 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,y15=int6464#1 -# asm 2: movdqa y15=%xmm0 -movdqa %xmm9,%xmm0 - -# qhasm: uint32323232 y15 += z14 -# asm 1: paddd r15=int6464#13 -# asm 2: movdqa r15=%xmm12 -movdqa %xmm0,%xmm12 - -# qhasm: uint32323232 y15 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,z0=int6464#13 -# asm 2: movdqa z0=%xmm12 -movdqa 320(%rsp),%xmm12 - -# qhasm: z5 = z5_stack -# asm 1: movdqa z5=int6464#1 -# asm 2: movdqa z5=%xmm0 -movdqa 336(%rsp),%xmm0 - -# qhasm: unsigned>? i -= 2 -# asm 1: sub $2, -ja ._mainloop1 - -# qhasm: uint32323232 z0 += orig0 -# asm 1: paddd in0=int64#3 -# asm 2: movd in0=%rdx -movd %xmm12,%rdx - -# qhasm: in1 = z1 -# asm 1: movd in1=int64#4 -# asm 2: movd in1=%rcx -movd %xmm7,%rcx - -# qhasm: in2 = z2 -# asm 1: movd in2=int64#5 -# asm 2: movd in2=%r8 -movd %xmm10,%r8 - -# qhasm: in3 = z3 -# asm 1: movd in3=int64#6 -# asm 2: movd in3=%r9 -movd %xmm4,%r9 - -# qhasm: z0 <<<= 96 -# asm 1: pshufd $0x39,in0=int64#3 -# asm 2: movd in0=%rdx -movd %xmm12,%rdx - -# qhasm: in1 = z1 -# asm 1: movd in1=int64#4 -# asm 2: movd in1=%rcx -movd %xmm7,%rcx - -# qhasm: in2 = z2 -# asm 1: movd in2=int64#5 -# asm 2: movd in2=%r8 -movd %xmm10,%r8 - -# qhasm: in3 = z3 -# asm 1: movd in3=int64#6 -# asm 2: movd in3=%r9 -movd %xmm4,%r9 - -# qhasm: z0 <<<= 96 -# asm 1: pshufd $0x39,in0=int64#3 -# asm 2: movd in0=%rdx -movd %xmm12,%rdx - -# qhasm: in1 = z1 -# asm 1: movd in1=int64#4 -# asm 2: movd in1=%rcx -movd %xmm7,%rcx - -# qhasm: in2 = z2 -# asm 1: movd in2=int64#5 -# asm 2: movd in2=%r8 -movd %xmm10,%r8 - -# qhasm: in3 = z3 -# asm 1: movd in3=int64#6 -# asm 2: movd in3=%r9 -movd %xmm4,%r9 - -# qhasm: z0 <<<= 96 -# asm 1: pshufd $0x39,in0=int64#3 -# asm 2: movd in0=%rdx -movd %xmm12,%rdx - -# qhasm: in1 = z1 -# asm 1: movd in1=int64#4 -# asm 2: movd in1=%rcx -movd %xmm7,%rcx - -# qhasm: in2 = z2 -# asm 1: movd in2=int64#5 -# asm 2: movd in2=%r8 -movd %xmm10,%r8 - -# qhasm: in3 = z3 -# asm 1: movd in3=int64#6 -# asm 2: movd in3=%r9 -movd %xmm4,%r9 - -# qhasm: (uint32) in0 ^= *(uint32 *) (m + 192) -# asm 1: xorl 192(in4=int64#3 -# asm 2: movd in4=%rdx -movd %xmm14,%rdx - -# qhasm: in5 = z5 -# asm 1: movd in5=int64#4 -# asm 2: movd in5=%rcx -movd %xmm0,%rcx - -# qhasm: in6 = z6 -# asm 1: movd in6=int64#5 -# asm 2: movd in6=%r8 -movd %xmm5,%r8 - -# qhasm: in7 = z7 -# asm 1: movd in7=int64#6 -# asm 2: movd in7=%r9 -movd %xmm8,%r9 - -# qhasm: z4 <<<= 96 -# asm 1: pshufd $0x39,in4=int64#3 -# asm 2: movd in4=%rdx -movd %xmm14,%rdx - -# qhasm: in5 = z5 -# asm 1: movd in5=int64#4 -# asm 2: movd in5=%rcx -movd %xmm0,%rcx - -# qhasm: in6 = z6 -# asm 1: movd in6=int64#5 -# asm 2: movd in6=%r8 -movd %xmm5,%r8 - -# qhasm: in7 = z7 -# asm 1: movd in7=int64#6 -# asm 2: movd in7=%r9 -movd %xmm8,%r9 - -# qhasm: z4 <<<= 96 -# asm 1: pshufd $0x39,in4=int64#3 -# asm 2: movd in4=%rdx -movd %xmm14,%rdx - -# qhasm: in5 = z5 -# asm 1: movd in5=int64#4 -# asm 2: movd in5=%rcx -movd %xmm0,%rcx - -# qhasm: in6 = z6 -# asm 1: movd in6=int64#5 -# asm 2: movd in6=%r8 -movd %xmm5,%r8 - -# qhasm: in7 = z7 -# asm 1: movd in7=int64#6 -# asm 2: movd in7=%r9 -movd %xmm8,%r9 - -# qhasm: z4 <<<= 96 -# asm 1: pshufd $0x39,in4=int64#3 -# asm 2: movd in4=%rdx -movd %xmm14,%rdx - -# qhasm: in5 = z5 -# asm 1: movd in5=int64#4 -# asm 2: movd in5=%rcx -movd %xmm0,%rcx - -# qhasm: in6 = z6 -# asm 1: movd in6=int64#5 -# asm 2: movd in6=%r8 -movd %xmm5,%r8 - -# qhasm: in7 = z7 -# asm 1: movd in7=int64#6 -# asm 2: movd in7=%r9 -movd %xmm8,%r9 - -# qhasm: (uint32) in4 ^= *(uint32 *) (m + 208) -# asm 1: xorl 208(in8=int64#3 -# asm 2: movd in8=%rdx -movd %xmm15,%rdx - -# qhasm: in9 = z9 -# asm 1: movd in9=int64#4 -# asm 2: movd in9=%rcx -movd %xmm11,%rcx - -# qhasm: in10 = z10 -# asm 1: movd in10=int64#5 -# asm 2: movd in10=%r8 -movd %xmm1,%r8 - -# qhasm: in11 = z11 -# asm 1: movd in11=int64#6 -# asm 2: movd in11=%r9 -movd %xmm6,%r9 - -# qhasm: z8 <<<= 96 -# asm 1: pshufd $0x39,in8=int64#3 -# asm 2: movd in8=%rdx -movd %xmm15,%rdx - -# qhasm: in9 = z9 -# asm 1: movd in9=int64#4 -# asm 2: movd in9=%rcx -movd %xmm11,%rcx - -# qhasm: in10 = z10 -# asm 1: movd in10=int64#5 -# asm 2: movd in10=%r8 -movd %xmm1,%r8 - -# qhasm: in11 = z11 -# asm 1: movd in11=int64#6 -# asm 2: movd in11=%r9 -movd %xmm6,%r9 - -# qhasm: z8 <<<= 96 -# asm 1: pshufd $0x39,in8=int64#3 -# asm 2: movd in8=%rdx -movd %xmm15,%rdx - -# qhasm: in9 = z9 -# asm 1: movd in9=int64#4 -# asm 2: movd in9=%rcx -movd %xmm11,%rcx - -# qhasm: in10 = z10 -# asm 1: movd in10=int64#5 -# asm 2: movd in10=%r8 -movd %xmm1,%r8 - -# qhasm: in11 = z11 -# asm 1: movd in11=int64#6 -# asm 2: movd in11=%r9 -movd %xmm6,%r9 - -# qhasm: z8 <<<= 96 -# asm 1: pshufd $0x39,in8=int64#3 -# asm 2: movd in8=%rdx -movd %xmm15,%rdx - -# qhasm: in9 = z9 -# asm 1: movd in9=int64#4 -# asm 2: movd in9=%rcx -movd %xmm11,%rcx - -# qhasm: in10 = z10 -# asm 1: movd in10=int64#5 -# asm 2: movd in10=%r8 -movd %xmm1,%r8 - -# qhasm: in11 = z11 -# asm 1: movd in11=int64#6 -# asm 2: movd in11=%r9 -movd %xmm6,%r9 - -# qhasm: (uint32) in8 ^= *(uint32 *) (m + 224) -# asm 1: xorl 224(in12=int64#3 -# asm 2: movd in12=%rdx -movd %xmm13,%rdx - -# qhasm: in13 = z13 -# asm 1: movd in13=int64#4 -# asm 2: movd in13=%rcx -movd %xmm9,%rcx - -# qhasm: in14 = z14 -# asm 1: movd in14=int64#5 -# asm 2: movd in14=%r8 -movd %xmm3,%r8 - -# qhasm: in15 = z15 -# asm 1: movd in15=int64#6 -# asm 2: movd in15=%r9 -movd %xmm2,%r9 - -# qhasm: z12 <<<= 96 -# asm 1: pshufd $0x39,in12=int64#3 -# asm 2: movd in12=%rdx -movd %xmm13,%rdx - -# qhasm: in13 = z13 -# asm 1: movd in13=int64#4 -# asm 2: movd in13=%rcx -movd %xmm9,%rcx - -# qhasm: in14 = z14 -# asm 1: movd in14=int64#5 -# asm 2: movd in14=%r8 -movd %xmm3,%r8 - -# qhasm: in15 = z15 -# asm 1: movd in15=int64#6 -# asm 2: movd in15=%r9 -movd %xmm2,%r9 - -# qhasm: z12 <<<= 96 -# asm 1: pshufd $0x39,in12=int64#3 -# asm 2: movd in12=%rdx -movd %xmm13,%rdx - -# qhasm: in13 = z13 -# asm 1: movd in13=int64#4 -# asm 2: movd in13=%rcx -movd %xmm9,%rcx - -# qhasm: in14 = z14 -# asm 1: movd in14=int64#5 -# asm 2: movd in14=%r8 -movd %xmm3,%r8 - -# qhasm: in15 = z15 -# asm 1: movd in15=int64#6 -# asm 2: movd in15=%r9 -movd %xmm2,%r9 - -# qhasm: z12 <<<= 96 -# asm 1: pshufd $0x39,in12=int64#3 -# asm 2: movd in12=%rdx -movd %xmm13,%rdx - -# qhasm: in13 = z13 -# asm 1: movd in13=int64#4 -# asm 2: movd in13=%rcx -movd %xmm9,%rcx - -# qhasm: in14 = z14 -# asm 1: movd in14=int64#5 -# asm 2: movd in14=%r8 -movd %xmm3,%r8 - -# qhasm: in15 = z15 -# asm 1: movd in15=int64#6 -# asm 2: movd in15=%r9 -movd %xmm2,%r9 - -# qhasm: (uint32) in12 ^= *(uint32 *) (m + 240) -# asm 1: xorl 240(bytes=int64#6 -# asm 2: movq bytes=%r9 -movq 408(%rsp),%r9 - -# qhasm: bytes -= 256 -# asm 1: sub $256,? bytes - 0 -# asm 1: cmp $0, -jbe ._done -# comment:fp stack unchanged by fallthrough - -# qhasm: bytesbetween1and255: -._bytesbetween1and255: - -# qhasm: unsignedctarget=int64#3 -# asm 2: mov ctarget=%rdx -mov %rdi,%rdx - -# qhasm: out = &tmp -# asm 1: leaq out=int64#1 -# asm 2: leaq out=%rdi -leaq 416(%rsp),%rdi - -# qhasm: i = bytes -# asm 1: mov i=int64#4 -# asm 2: mov i=%rcx -mov %r9,%rcx - -# qhasm: while (i) { *out++ = *m++; --i } -rep movsb - -# qhasm: out = &tmp -# asm 1: leaq out=int64#1 -# asm 2: leaq out=%rdi -leaq 416(%rsp),%rdi - -# qhasm: m = &tmp -# asm 1: leaq m=int64#2 -# asm 2: leaq m=%rsi -leaq 416(%rsp),%rsi -# comment:fp stack unchanged by fallthrough - -# qhasm: nocopy: -._nocopy: - -# qhasm: bytes_backup = bytes -# asm 1: movq bytes_backup=stack64#8 -# asm 2: movq bytes_backup=408(%rsp) -movq %r9,408(%rsp) - -# qhasm: diag0 = x0 -# asm 1: movdqa diag0=int6464#1 -# asm 2: movdqa diag0=%xmm0 -movdqa 48(%rsp),%xmm0 - -# qhasm: diag1 = x1 -# asm 1: movdqa diag1=int6464#2 -# asm 2: movdqa diag1=%xmm1 -movdqa 0(%rsp),%xmm1 - -# qhasm: diag2 = x2 -# asm 1: movdqa diag2=int6464#3 -# asm 2: movdqa diag2=%xmm2 -movdqa 16(%rsp),%xmm2 - -# qhasm: diag3 = x3 -# asm 1: movdqa diag3=int6464#4 -# asm 2: movdqa diag3=%xmm3 -movdqa 32(%rsp),%xmm3 - -# qhasm: a0 = diag1 -# asm 1: movdqa a0=int6464#5 -# asm 2: movdqa a0=%xmm4 -movdqa %xmm1,%xmm4 - -# qhasm: i = 12 -# asm 1: mov $12,>i=int64#4 -# asm 2: mov $12,>i=%rcx -mov $12,%rcx - -# qhasm: mainloop2: -._mainloop2: - -# qhasm: uint32323232 a0 += diag0 -# asm 1: paddd a1=int6464#6 -# asm 2: movdqa a1=%xmm5 -movdqa %xmm0,%xmm5 - -# qhasm: b0 = a0 -# asm 1: movdqa b0=int6464#7 -# asm 2: movdqa b0=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a0 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,a2=int6464#5 -# asm 2: movdqa a2=%xmm4 -movdqa %xmm3,%xmm4 - -# qhasm: b1 = a1 -# asm 1: movdqa b1=int6464#7 -# asm 2: movdqa b1=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a1 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,a3=int6464#6 -# asm 2: movdqa a3=%xmm5 -movdqa %xmm2,%xmm5 - -# qhasm: b2 = a2 -# asm 1: movdqa b2=int6464#7 -# asm 2: movdqa b2=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a2 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,a4=int6464#5 -# asm 2: movdqa a4=%xmm4 -movdqa %xmm3,%xmm4 - -# qhasm: b3 = a3 -# asm 1: movdqa b3=int6464#7 -# asm 2: movdqa b3=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a3 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,a5=int6464#6 -# asm 2: movdqa a5=%xmm5 -movdqa %xmm0,%xmm5 - -# qhasm: b4 = a4 -# asm 1: movdqa b4=int6464#7 -# asm 2: movdqa b4=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a4 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,a6=int6464#5 -# asm 2: movdqa a6=%xmm4 -movdqa %xmm1,%xmm4 - -# qhasm: b5 = a5 -# asm 1: movdqa b5=int6464#7 -# asm 2: movdqa b5=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a5 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,a7=int6464#6 -# asm 2: movdqa a7=%xmm5 -movdqa %xmm2,%xmm5 - -# qhasm: b6 = a6 -# asm 1: movdqa b6=int6464#7 -# asm 2: movdqa b6=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a6 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,a0=int6464#5 -# asm 2: movdqa a0=%xmm4 -movdqa %xmm1,%xmm4 - -# qhasm: b7 = a7 -# asm 1: movdqa b7=int6464#7 -# asm 2: movdqa b7=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a7 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,a1=int6464#6 -# asm 2: movdqa a1=%xmm5 -movdqa %xmm0,%xmm5 - -# qhasm: b0 = a0 -# asm 1: movdqa b0=int6464#7 -# asm 2: movdqa b0=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a0 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,a2=int6464#5 -# asm 2: movdqa a2=%xmm4 -movdqa %xmm3,%xmm4 - -# qhasm: b1 = a1 -# asm 1: movdqa b1=int6464#7 -# asm 2: movdqa b1=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a1 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,a3=int6464#6 -# asm 2: movdqa a3=%xmm5 -movdqa %xmm2,%xmm5 - -# qhasm: b2 = a2 -# asm 1: movdqa b2=int6464#7 -# asm 2: movdqa b2=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a2 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,a4=int6464#5 -# asm 2: movdqa a4=%xmm4 -movdqa %xmm3,%xmm4 - -# qhasm: b3 = a3 -# asm 1: movdqa b3=int6464#7 -# asm 2: movdqa b3=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a3 <<= 18 -# asm 1: pslld $18,>= 14 -# asm 1: psrld $14,a5=int6464#6 -# asm 2: movdqa a5=%xmm5 -movdqa %xmm0,%xmm5 - -# qhasm: b4 = a4 -# asm 1: movdqa b4=int6464#7 -# asm 2: movdqa b4=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a4 <<= 7 -# asm 1: pslld $7,>= 25 -# asm 1: psrld $25,a6=int6464#5 -# asm 2: movdqa a6=%xmm4 -movdqa %xmm1,%xmm4 - -# qhasm: b5 = a5 -# asm 1: movdqa b5=int6464#7 -# asm 2: movdqa b5=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a5 <<= 9 -# asm 1: pslld $9,>= 23 -# asm 1: psrld $23,a7=int6464#6 -# asm 2: movdqa a7=%xmm5 -movdqa %xmm2,%xmm5 - -# qhasm: b6 = a6 -# asm 1: movdqa b6=int6464#7 -# asm 2: movdqa b6=%xmm6 -movdqa %xmm4,%xmm6 - -# qhasm: uint32323232 a6 <<= 13 -# asm 1: pslld $13,>= 19 -# asm 1: psrld $19,? i -= 4 -# asm 1: sub $4,a0=int6464#5 -# asm 2: movdqa a0=%xmm4 -movdqa %xmm1,%xmm4 - -# qhasm: b7 = a7 -# asm 1: movdqa b7=int6464#7 -# asm 2: movdqa b7=%xmm6 -movdqa %xmm5,%xmm6 - -# qhasm: uint32323232 a7 <<= 18 -# asm 1: pslld $18,b0=int6464#8,>b0=int6464#8 -# asm 2: pxor >b0=%xmm7,>b0=%xmm7 -pxor %xmm7,%xmm7 - -# qhasm: uint32323232 b7 >>= 14 -# asm 1: psrld $14, -ja ._mainloop2 - -# qhasm: uint32323232 diag0 += x0 -# asm 1: paddd in0=int64#4 -# asm 2: movd in0=%rcx -movd %xmm0,%rcx - -# qhasm: in12 = diag1 -# asm 1: movd in12=int64#5 -# asm 2: movd in12=%r8 -movd %xmm1,%r8 - -# qhasm: in8 = diag2 -# asm 1: movd in8=int64#6 -# asm 2: movd in8=%r9 -movd %xmm2,%r9 - -# qhasm: in4 = diag3 -# asm 1: movd in4=int64#7 -# asm 2: movd in4=%rax -movd %xmm3,%rax - -# qhasm: diag0 <<<= 96 -# asm 1: pshufd $0x39,in5=int64#4 -# asm 2: movd in5=%rcx -movd %xmm0,%rcx - -# qhasm: in1 = diag1 -# asm 1: movd in1=int64#5 -# asm 2: movd in1=%r8 -movd %xmm1,%r8 - -# qhasm: in13 = diag2 -# asm 1: movd in13=int64#6 -# asm 2: movd in13=%r9 -movd %xmm2,%r9 - -# qhasm: in9 = diag3 -# asm 1: movd in9=int64#7 -# asm 2: movd in9=%rax -movd %xmm3,%rax - -# qhasm: diag0 <<<= 96 -# asm 1: pshufd $0x39,in10=int64#4 -# asm 2: movd in10=%rcx -movd %xmm0,%rcx - -# qhasm: in6 = diag1 -# asm 1: movd in6=int64#5 -# asm 2: movd in6=%r8 -movd %xmm1,%r8 - -# qhasm: in2 = diag2 -# asm 1: movd in2=int64#6 -# asm 2: movd in2=%r9 -movd %xmm2,%r9 - -# qhasm: in14 = diag3 -# asm 1: movd in14=int64#7 -# asm 2: movd in14=%rax -movd %xmm3,%rax - -# qhasm: diag0 <<<= 96 -# asm 1: pshufd $0x39,in15=int64#4 -# asm 2: movd in15=%rcx -movd %xmm0,%rcx - -# qhasm: in11 = diag1 -# asm 1: movd in11=int64#5 -# asm 2: movd in11=%r8 -movd %xmm1,%r8 - -# qhasm: in7 = diag2 -# asm 1: movd in7=int64#6 -# asm 2: movd in7=%r9 -movd %xmm2,%r9 - -# qhasm: in3 = diag3 -# asm 1: movd in3=int64#7 -# asm 2: movd in3=%rax -movd %xmm3,%rax - -# qhasm: (uint32) in15 ^= *(uint32 *) (m + 60) -# asm 1: xorl 60(bytes=int64#6 -# asm 2: movq bytes=%r9 -movq 408(%rsp),%r9 - -# qhasm: in8 = ((uint32 *)&x2)[0] -# asm 1: movl in8=int64#4d -# asm 2: movl in8=%ecx -movl 16(%rsp),%ecx - -# qhasm: in9 = ((uint32 *)&x3)[1] -# asm 1: movl 4+in9=int64#5d -# asm 2: movl 4+in9=%r8d -movl 4+32(%rsp),%r8d - -# qhasm: in8 += 1 -# asm 1: add $1,in9=int64#5 -# asm 2: mov in9=%r8 -mov %rcx,%r8 - -# qhasm: (uint64) in9 >>= 32 -# asm 1: shr $32,x2=stack128#2 -# asm 2: movl x2=16(%rsp) -movl %ecx,16(%rsp) - -# qhasm: ((uint32 *)&x3)[1] = in9 -# asm 1: movl ? unsigned -ja ._bytesatleast65 -# comment:fp stack unchanged by jump - -# qhasm: goto bytesatleast64 if !unsigned< -jae ._bytesatleast64 - -# qhasm: m = out -# asm 1: mov m=int64#2 -# asm 2: mov m=%rsi -mov %rdi,%rsi - -# qhasm: out = ctarget -# asm 1: mov out=int64#1 -# asm 2: mov out=%rdi -mov %rdx,%rdi - -# qhasm: i = bytes -# asm 1: mov i=int64#4 -# asm 2: mov i=%rcx -mov %r9,%rcx - -# qhasm: while (i) { *out++ = *m++; --i } -rep movsb -# comment:fp stack unchanged by fallthrough - -# qhasm: bytesatleast64: -._bytesatleast64: -# comment:fp stack unchanged by fallthrough - -# qhasm: done: -._done: - -# qhasm: r11_caller = r11_stack -# asm 1: movq r11_caller=int64#9 -# asm 2: movq r11_caller=%r11 -movq 352(%rsp),%r11 - -# qhasm: r12_caller = r12_stack -# asm 1: movq r12_caller=int64#10 -# asm 2: movq r12_caller=%r12 -movq 360(%rsp),%r12 - -# qhasm: r13_caller = r13_stack -# asm 1: movq r13_caller=int64#11 -# asm 2: movq r13_caller=%r13 -movq 368(%rsp),%r13 - -# qhasm: r14_caller = r14_stack -# asm 1: movq r14_caller=int64#12 -# asm 2: movq r14_caller=%r14 -movq 376(%rsp),%r14 - -# qhasm: r15_caller = r15_stack -# asm 1: movq r15_caller=int64#13 -# asm 2: movq r15_caller=%r15 -movq 384(%rsp),%r15 - -# qhasm: rbx_caller = rbx_stack -# asm 1: movq rbx_caller=int64#14 -# asm 2: movq rbx_caller=%rbx -movq 392(%rsp),%rbx - -# qhasm: rbp_caller = rbp_stack -# asm 1: movq rbp_caller=int64#15 -# asm 2: movq rbp_caller=%rbp -movq 400(%rsp),%rbp - -# qhasm: leave -add %r11,%rsp -xor %rax,%rax -xor %rdx,%rdx -ret - -# qhasm: bytesatleast65: -._bytesatleast65: - -# qhasm: bytes -= 64 -# asm 1: sub $64, 1 { + if len(args) > 2 { + Help() + os.Exit(1) + } + name = strings.TrimSpace(args[1]) + } + + var result zerotier.Root + apiPost(basePath, authToken, "/root/"+url.PathEscape(name), &zerotier.Root{ + Name: name, + Locator: loc, + }, &result) + + fmt.Println(jsonDump(&result)) + os.Exit(0) +} diff --git a/go/cmd/zerotier/cli/help.go b/go/cmd/zerotier/cli/help.go new file mode 100644 index 00000000..f9197d21 --- /dev/null +++ b/go/cmd/zerotier/cli/help.go @@ -0,0 +1,83 @@ +/* + * Copyright (c)2019 ZeroTier, Inc. + * + * Use of this software is governed by the Business Source License included + * in the LICENSE.TXT file in the project's root directory. + * + * Change Date: 2023-01-01 + * + * On the date above, in accordance with the Business Source License, use + * of this software will be governed by version 2.0 of the Apache License. + */ +/****/ + +package cli + +import ( + "fmt" + + "zerotier/pkg/zerotier" +) + +var copyrightText = fmt.Sprintf(`ZeroTier Network Virtualization Service Version %d.%d.%d +(c)2019 ZeroTier, Inc. +Licensed under the ZeroTier BSL (see LICENSE.txt)`, zerotier.CoreVersionMajor, zerotier.CoreVersionMinor, zerotier.CoreVersionRevision) + +// Help dumps help to stdout +func Help() { + fmt.Println(copyrightText) + fmt.Println(` +Usage: zerotier [-options] [command args] + +Global Options: + -j Output raw JSON where applicable + -p Use alternate base path + -t Use secret auth token from this file + +Commands: + help Show this help + version Print version + service Start in system service mode + status Show ZeroTier service status and config + peers Show VL1 peers + roots Show configured VL1 root servers + addroot [name] Add a VL1 root + removeroot Remove a VL1 root + locator [args] Locator management commands + new
[...] Create and sign locator for identity + newdnskey Create a secure DNS name and secret + getdns Create secure DNS TXT records + identity [args] Identity management commands + new [c25519|p384] Create new identity (including secret) + getpublic Extract only public part of identity + validate Locally validate an identity + sign Sign a file with an identity's key + verify Verify a signature + networks List joined VL2 virtual networks + network Show verbose network info + join Join a virtual network + leave Leave a virtual network + set