diff options
58 files changed, 1063 insertions, 306 deletions
diff --git a/external/boost/archive/portable_binary_oarchive.hpp b/external/boost/archive/portable_binary_oarchive.hpp index 9ed30d064..e2dcb9456 100644 --- a/external/boost/archive/portable_binary_oarchive.hpp +++ b/external/boost/archive/portable_binary_oarchive.hpp @@ -41,19 +41,24 @@ class portable_binary_oarchive_exception : public boost::archive::archive_exception
{
public:
- typedef enum {
+ enum exception_code {
invalid_flags
- } exception_code;
- portable_binary_oarchive_exception(exception_code c = invalid_flags )
+ } m_exception_code ;
+ portable_binary_oarchive_exception(exception_code c = invalid_flags ) :
+ boost::archive::archive_exception(boost::archive::archive_exception::other_exception),
+ m_exception_code(c)
{}
virtual const char *what( ) const throw( )
{
const char *msg = "programmer error";
- switch(code){
+ switch(m_exception_code){
case invalid_flags:
msg = "cannot be both big and little endian";
+ break;
default:
- boost::archive::archive_exception::what();
+ msg = boost::archive::archive_exception::what();
+ assert(false);
+ break;
}
return msg;
}
diff --git a/external/db_drivers/liblmdb/mdb.c b/external/db_drivers/liblmdb/mdb.c index 377512ebe..b3de9702f 100644 --- a/external/db_drivers/liblmdb/mdb.c +++ b/external/db_drivers/liblmdb/mdb.c @@ -6288,6 +6288,10 @@ release: if (rc) return rc; } +#ifdef MDB_VL32 + if (mc->mc_ovpg == mp) + mc->mc_ovpg = NULL; +#endif mc->mc_db->md_overflow_pages -= ovpages; return 0; } diff --git a/external/miniupnpc/.gitignore b/external/miniupnpc/.gitignore index b1209ccd8..6bc38af20 100644 --- a/external/miniupnpc/.gitignore +++ b/external/miniupnpc/.gitignore @@ -4,6 +4,9 @@ build/ *.a *.so *.dll +*.dll.def +*.exe +*.lib *.dylib Makefile.bak miniupnpcstrings.h @@ -30,3 +33,4 @@ testigddescparse validateigddescparse dist/ miniupnpc.egg-info/ +init diff --git a/external/miniupnpc/Changelog.txt b/external/miniupnpc/Changelog.txt index 078bebce3..a3ef51809 100644 --- a/external/miniupnpc/Changelog.txt +++ b/external/miniupnpc/Changelog.txt @@ -1,6 +1,16 @@ -$Id: Changelog.txt,v 1.223 2016/04/19 21:06:20 nanard Exp $ +$Id: Changelog.txt,v 1.226 2016/12/16 08:57:19 nanard Exp $ miniUPnP client Changelog. +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: diff --git a/external/miniupnpc/LICENSE b/external/miniupnpc/LICENSE index cb5a06044..081673370 100644 --- a/external/miniupnpc/LICENSE +++ b/external/miniupnpc/LICENSE @@ -1,5 +1,5 @@ MiniUPnPc -Copyright (c) 2005-2015, Thomas BERNARD +Copyright (c) 2005-2016, Thomas BERNARD All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/external/miniupnpc/MANIFEST.in b/external/miniupnpc/MANIFEST.in index 54b86f95e..543ffd6ac 100644 --- a/external/miniupnpc/MANIFEST.in +++ b/external/miniupnpc/MANIFEST.in @@ -1,4 +1,6 @@ include README +include VERSION +include LICENSE include miniupnpcmodule.c include setup.py include *.h diff --git a/external/miniupnpc/Makefile b/external/miniupnpc/Makefile index b7826caa1..178fbf5d3 100644 --- a/external/miniupnpc/Makefile +++ b/external/miniupnpc/Makefile @@ -1,9 +1,9 @@ -# $Id: Makefile,v 1.133 2016/01/24 17:24:35 nanard Exp $ +# $Id: Makefile,v 1.134 2016/10/07 09:04:36 nanard Exp $ # MiniUPnP Project # http://miniupnp.free.fr/ # http://miniupnp.tuxfamily.org/ # https://github.com/miniupnp/miniupnp -# (c) 2005-2015 Thomas Bernard +# (c) 2005-2017 Thomas Bernard # to install use : # $ make DESTDIR=/tmp/dummylocation install # or @@ -48,7 +48,7 @@ CFLAGS += -D_XOPEN_SOURCE=600 endif endif #CFLAGS += -ansi -# -DNO_GETADDRINFO +#CFLAGS += -DNO_GETADDRINFO INSTALL = install SH = /bin/sh JAVA = java @@ -65,7 +65,9 @@ JNAERATORARGS = -mode StandaloneJar -runtime JNAerator -library miniupnpc JNAERATORBASEURL = https://repo1.maven.org/maven2/com/nativelibs4java/jnaerator/0.12 ifeq (SunOS, $(OS)) - LDFLAGS=-lsocket -lnsl -lresolv + LDLIBS=-lsocket -lnsl -lresolv + CFLAGS += -D__EXTENSIONS__ + CFLAGS += -std=c99 endif # APIVERSION is used to build SONAME @@ -85,7 +87,9 @@ LIBOBJS = miniwget.o minixml.o igd_desc_parse.o minisoap.o \ connecthostport.o portlistingparse.o receivedata.o upnpdev.o ifneq ($(OS), AmigaOS) +ifeq (,$(findstring CYGWIN,$(OS))) CFLAGS := -fPIC $(CFLAGS) +endif LIBOBJS := $(LIBOBJS) minissdpc.o endif @@ -169,18 +173,18 @@ check: validateminixml validateminiwget validateupnpreplyparse \ everything: all $(EXECUTABLES_ADDTESTS) pythonmodule: $(LIBRARY) miniupnpcmodule.c setup.py - python setup.py build + MAKE=$(MAKE) python setup.py build touch $@ installpythonmodule: pythonmodule - python setup.py install + MAKE=$(MAKE) python setup.py install pythonmodule3: $(LIBRARY) miniupnpcmodule.c setup.py - python3 setup.py build + MAKE=$(MAKE) python3 setup.py build touch $@ installpythonmodule3: pythonmodule3 - python3 setup.py install + MAKE=$(MAKE) python3 setup.py install validateminixml: minixmlvalid @echo "minixml validation test" diff --git a/external/miniupnpc/README b/external/miniupnpc/README index 91535dbc8..0d3b8054c 100644 --- a/external/miniupnpc/README +++ b/external/miniupnpc/README @@ -1,9 +1,8 @@ Project: miniupnp -Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ +Project web page: http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/ github: https://github.com/miniupnp/miniupnp -freecode: http://freecode.com/projects/miniupnp Author: Thomas Bernard -Copyright (c) 2005-2016 Thomas Bernard +Copyright (c) 2005-2017 Thomas Bernard This software is subject to the conditions detailed in the LICENSE file provided within this distribution. @@ -58,7 +57,7 @@ If you are using libminiupnpc in your application, please send me an email ! For any question, you can use the web forum : -http://miniupnp.tuxfamily.org/forum/ +https://miniupnp.tuxfamily.org/forum/ Bugs should be reported on github : https://github.com/miniupnp/miniupnp/issues diff --git a/external/miniupnpc/connecthostport.c b/external/miniupnpc/connecthostport.c index 1f2a032ee..d28aaf5e0 100644 --- a/external/miniupnpc/connecthostport.c +++ b/external/miniupnpc/connecthostport.c @@ -1,7 +1,7 @@ /* $Id: connecthostport.c,v 1.15 2015/10/09 16:26:19 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2010-2015 Thomas Bernard + * Copyright (c) 2010-2017 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -36,15 +36,13 @@ /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions * during the connect() call */ #define MINIUPNPC_IGNORE_EINTR -#ifndef USE_GETHOSTBYNAME #include <sys/socket.h> #include <sys/select.h> -#endif /* #ifndef USE_GETHOSTBYNAME */ #endif /* #else _WIN32 */ /* definition of PRINT_SOCKET_ERROR */ #ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) #endif @@ -100,13 +98,13 @@ int connecthostport(const char * host, unsigned short port, timeout.tv_usec = 0; if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) { - PRINT_SOCKET_ERROR("setsockopt"); + 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"); + PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO"); } #endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ dest.sin_family = AF_INET; diff --git a/external/miniupnpc/minihttptestserver.c b/external/miniupnpc/minihttptestserver.c index 1848bde26..e4cdc203c 100644 --- a/external/miniupnpc/minihttptestserver.c +++ b/external/miniupnpc/minihttptestserver.c @@ -1,7 +1,7 @@ /* $Id: minihttptestserver.c,v 1.19 2015/11/17 09:07:17 nanard Exp $ */ /* Project : miniUPnP * Author : Thomas Bernard - * Copyright (c) 2011-2015 Thomas Bernard + * Copyright (c) 2011-2016 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ @@ -611,7 +611,7 @@ int main(int argc, char * * argv) { if(pid < 0) { perror("wait"); } else { - printf("child(%d) terminated with status %d\n", pid, status); + printf("child(%d) terminated with status %d\n", (int)pid, status); } --child_to_wait_for; } @@ -648,7 +648,7 @@ int main(int argc, char * * argv) { if(pid < 0) { perror("wait"); } else { - printf("child(%d) terminated with status %d\n", pid, status); + printf("child(%d) terminated with status %d\n", (int)pid, status); } --child_to_wait_for; } diff --git a/external/miniupnpc/minisoap.c b/external/miniupnpc/minisoap.c index 5c9a11438..76225f4b6 100644 --- a/external/miniupnpc/minisoap.c +++ b/external/miniupnpc/minisoap.c @@ -25,7 +25,7 @@ #include <stdlib.h> #ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) #endif diff --git a/external/miniupnpc/minissdpc.c b/external/miniupnpc/minissdpc.c index dc4f94702..8eee2e927 100644 --- a/external/miniupnpc/minissdpc.c +++ b/external/miniupnpc/minissdpc.c @@ -1,9 +1,9 @@ -/* $Id: minissdpc.c,v 1.28 2015/09/18 13:05:39 nanard Exp $ */ +/* $Id: minissdpc.c,v 1.32 2016/10/07 09:04:36 nanard Exp $ */ /* vim: tabstop=4 shiftwidth=4 noexpandtab * Project : miniupnp * Web : http://miniupnp.free.fr/ * Author : Thomas BERNARD - * copyright (c) 2005-2015 Thomas Bernard + * copyright (c) 2005-2017 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ /*#include <syslog.h>*/ @@ -62,7 +62,7 @@ struct sockaddr_un { #endif #ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) #endif @@ -73,6 +73,9 @@ struct sockaddr_un { #if !defined(HAS_IP_MREQN) && !defined(_WIN32) #include <sys/ioctl.h> +#if defined(__sun) +#include <sys/sockio.h> +#endif #endif #if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) @@ -169,7 +172,7 @@ connectToMiniSSDPD(const char * socketpath) { int s; struct sockaddr_un addr; -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT +#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) struct timeval timeout; #endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ @@ -180,23 +183,25 @@ connectToMiniSSDPD(const char * socketpath) perror("socket(unix)"); return MINISSDPC_SOCKET_ERROR; } -#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT +#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"); + 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"); + 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 */ @@ -498,6 +503,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], unsigned long _ttl = (unsigned long)ttl; #endif int linklocal = 1; + int sentok; if(error) *error = MINISSDPC_UNKNOWN_ERROR; @@ -608,14 +614,22 @@ ssdpDiscoverDevices(const char * const deviceTypes[], return NULL; } + if(ipv6) { + int mcastHops = ttl; + if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastHops, sizeof(mcastHops)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt(IPV6_MULTICAST_HOPS,...)"); + } + } else { #ifdef _WIN32 - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0) + 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) + 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,...)"); + { + /* not a fatal error */ + PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)"); + } } if(multicastif) @@ -628,7 +642,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */ if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) { - PRINT_SOCKET_ERROR("setsockopt"); + PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF"); } #else #ifdef DEBUG @@ -643,7 +657,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], ((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"); + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); } } else { #ifdef HAS_IP_MREQN @@ -653,7 +667,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], reqn.imr_ifindex = if_nametoindex(multicastif); if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) { - PRINT_SOCKET_ERROR("setsockopt"); + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); } #elif !defined(_WIN32) struct ifreq ifr; @@ -667,7 +681,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], 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"); + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); } #else /* _WIN32 */ #ifdef DEBUG @@ -700,6 +714,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], } /* receiving SSDP response packet */ for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { + sentok = 0; /* sending the SSDP M-SEARCH packet */ n = snprintf(bufr, sizeof(bufr), MSearchMsgFmt, @@ -743,7 +758,8 @@ ssdpDiscoverDevices(const char * const deviceTypes[], if(error) *error = MINISSDPC_SOCKET_ERROR; PRINT_SOCKET_ERROR("sendto"); - break; + } else { + sentok = 1; } #else /* #ifdef NO_GETADDRINFO */ memset(&hints, 0, sizeof(hints)); @@ -775,19 +791,20 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #endif PRINT_SOCKET_ERROR("sendto"); continue; + } else { + sentok = 1; } } freeaddrinfo(servinfo); - if(n < 0) { + if(!sentok) { if(error) *error = MINISSDPC_SOCKET_ERROR; - break; } #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(!searchalltypes || !deviceTypes[deviceIndex + 1]) do { + if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do { n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); if (n < 0) { /* error */ diff --git a/external/miniupnpc/miniupnpcmodule.c b/external/miniupnpc/miniupnpcmodule.c index fd970476c..8ffbf51a1 100644 --- a/external/miniupnpc/miniupnpcmodule.c +++ b/external/miniupnpc/miniupnpcmodule.c @@ -2,7 +2,7 @@ /* Project : miniupnp * Author : Thomas BERNARD * website : http://miniupnp.tuxfamily.org/ - * copyright (c) 2007-2014 Thomas Bernard + * copyright (c) 2007-2016 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ #include <Python.h> @@ -12,6 +12,10 @@ #include "upnpcommands.h" #include "upnperrors.h" +#ifdef _WIN32 +#include <winsock2.h> +#endif + /* for compatibility with Python < 2.4 */ #ifndef Py_RETURN_NONE #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None @@ -303,7 +307,7 @@ UPnP_addportmapping(UPnPObject *self, PyObject *args) const char * remoteHost; const char * leaseDuration = "0"; int r; - if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto, + if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -345,7 +349,7 @@ UPnP_addanyportmapping(UPnPObject *self, PyObject *args) const char * remoteHost; const char * leaseDuration = "0"; int r; - if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) + if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost)) return NULL; Py_BEGIN_ALLOW_THREADS sprintf(extPort, "%hu", ePort); @@ -669,6 +673,10 @@ initminiupnpc(void) 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) diff --git a/external/miniupnpc/miniwget.c b/external/miniupnpc/miniwget.c index ca88a1e9d..1eda57c5e 100644 --- a/external/miniupnpc/miniwget.c +++ b/external/miniupnpc/miniwget.c @@ -2,7 +2,7 @@ /* Project : miniupnp * Website : http://miniupnp.free.fr/ * Author : Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard + * Copyright (c) 2005-2017 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -83,8 +83,10 @@ getHTTPResponse(int s, int * size, int * status_code) 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); @@ -109,7 +111,7 @@ getHTTPResponse(int s, int * size, int * status_code) chunksize_buf[0] = '\0'; chunksize_buf_index = 0; - while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0) + while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0) { if(endofheaders == 0) { @@ -181,8 +183,10 @@ getHTTPResponse(int s, int * size, int * status_code) *status_code = atoi(header_buf + sp + 1); else { +#ifdef DEBUG reason_phrase = header_buf + sp + 1; reason_phrase_len = i - sp - 1; +#endif break; } } @@ -280,11 +284,12 @@ getHTTPResponse(int s, int * size, int * status_code) goto end_of_stream; } } - bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i); + /* 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 >= (int)(content_buf_used + bytestocopy)) { + 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; @@ -309,14 +314,15 @@ getHTTPResponse(int s, int * size, int * status_code) { /* not chunked */ if(content_length > 0 - && (int)(content_buf_used + n) > content_length) { + && (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 >= (int)(content_buf_used + n)) { + 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; @@ -336,7 +342,7 @@ getHTTPResponse(int s, int * size, int * status_code) } } /* use the Content-Length header value if available */ - if(content_length > 0 && (int)content_buf_used >= content_length) + if(content_length > 0 && content_buf_used >= (unsigned int)content_length) { #ifdef DEBUG printf("End of HTTP content\n"); diff --git a/external/miniupnpc/msvc/.gitignore b/external/miniupnpc/msvc/.gitignore new file mode 100644 index 000000000..6d88bf128 --- /dev/null +++ b/external/miniupnpc/msvc/.gitignore @@ -0,0 +1,4 @@ +*.db +.vs +Debug/ +Release/ diff --git a/external/miniupnpc/msvc/miniupnpc.vcxproj b/external/miniupnpc/msvc/miniupnpc.vcxproj new file mode 100644 index 000000000..2725136e3 --- /dev/null +++ b/external/miniupnpc/msvc/miniupnpc.vcxproj @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D28CE435-CB33-4BAE-8A52-C6EF915956F5}</ProjectGuid> + <RootNamespace>miniupnpc</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\connecthostport.c" /> + <ClCompile Include="..\igd_desc_parse.c" /> + <ClCompile Include="..\minisoap.c" /> + <ClCompile Include="..\minissdpc.c" /> + <ClCompile Include="..\miniupnpc.c" /> + <ClCompile Include="..\miniwget.c" /> + <ClCompile Include="..\minixml.c" /> + <ClCompile Include="..\portlistingparse.c" /> + <ClCompile Include="..\receivedata.c" /> + <ClCompile Include="..\upnpcommands.c" /> + <ClCompile Include="..\upnpdev.c" /> + <ClCompile Include="..\upnperrors.c" /> + <ClCompile Include="..\upnpreplyparse.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\connecthostport.h" /> + <ClInclude Include="..\declspec.h" /> + <ClInclude Include="..\igd_desc_parse.h" /> + <ClInclude Include="..\minisoap.h" /> + <ClInclude Include="..\minissdpc.h" /> + <ClInclude Include="..\miniupnpc.h" /> + <ClInclude Include="..\miniupnpcstrings.h" /> + <ClInclude Include="..\miniupnpctypes.h" /> + <ClInclude Include="..\miniwget.h" /> + <ClInclude Include="..\minixml.h" /> + <ClInclude Include="..\portlistingparse.h" /> + <ClInclude Include="..\receivedata.h" /> + <ClInclude Include="..\upnpcommands.h" /> + <ClInclude Include="..\upnpdev.h" /> + <ClInclude Include="..\upnperrors.h" /> + <ClInclude Include="..\upnpreplyparse.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/external/miniupnpc/msvc/miniupnpc.vcxproj.filters b/external/miniupnpc/msvc/miniupnpc.vcxproj.filters new file mode 100644 index 000000000..01a4dbeb2 --- /dev/null +++ b/external/miniupnpc/msvc/miniupnpc.vcxproj.filters @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Fichiers sources"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Fichiers d%27en-tête"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Fichiers de ressources"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\connecthostport.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\igd_desc_parse.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\minisoap.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\minissdpc.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\miniupnpc.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\miniwget.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\minixml.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\portlistingparse.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\receivedata.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\upnpcommands.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\upnpdev.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\upnperrors.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + <ClCompile Include="..\upnpreplyparse.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\connecthostport.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\declspec.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\igd_desc_parse.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\minisoap.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\minissdpc.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\miniupnpc.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\miniupnpcstrings.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\miniupnpctypes.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\miniwget.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\minixml.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\portlistingparse.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\receivedata.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\upnpcommands.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\upnpdev.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\upnperrors.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + <ClInclude Include="..\upnpreplyparse.h"> + <Filter>Fichiers d%27en-tête</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/external/miniupnpc/msvc/miniupnpc_vs2015.sln b/external/miniupnpc/msvc/miniupnpc_vs2015.sln new file mode 100644 index 000000000..27a43f6c3 --- /dev/null +++ b/external/miniupnpc/msvc/miniupnpc_vs2015.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "miniupnpc.vcxproj", "{D28CE435-CB33-4BAE-8A52-C6EF915956F5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "upnpc-static", "upnpc-static.vcxproj", "{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.ActiveCfg = Debug|Win32 + {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Debug|Win32.Build.0 = Debug|Win32 + {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.ActiveCfg = Release|Win32 + {D28CE435-CB33-4BAE-8A52-C6EF915956F5}.Release|Win32.Build.0 = Release|Win32 + {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.ActiveCfg = Debug|Win32 + {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Debug|Win32.Build.0 = Debug|Win32 + {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.ActiveCfg = Release|Win32 + {469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/miniupnpc/msvc/upnpc-static.vcxproj b/external/miniupnpc/msvc/upnpc-static.vcxproj new file mode 100644 index 000000000..44dea81e8 --- /dev/null +++ b/external/miniupnpc/msvc/upnpc-static.vcxproj @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{469E1CF6-08A2-4B7B-A2AA-5BDB089857C1}</ProjectGuid> + <RootNamespace>upnpcstatic</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> + <IntDir>$(Configuration)\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;_CONSOLE;MINIUPNP_STATICLIB;DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>ws2_32.lib;IPHlpApi.Lib;Debug\miniupnpc.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;MINIUPNP_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeader /> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <Link> + <AdditionalDependencies>ws2_32.lib;IPHlpApi.Lib;Release\miniupnpc.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Console</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <TargetMachine>MachineX86</TargetMachine> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\upnpc.c" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="miniupnpc.vcxproj"> + <Project>{d28ce435-cb33-4bae-8a52-c6ef915956f5}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/external/miniupnpc/msvc/upnpc-static.vcxproj.filters b/external/miniupnpc/msvc/upnpc-static.vcxproj.filters new file mode 100644 index 000000000..2e75de02f --- /dev/null +++ b/external/miniupnpc/msvc/upnpc-static.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Fichiers sources"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Fichiers d%27en-tête"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Fichiers de ressources"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\upnpc.c"> + <Filter>Fichiers sources</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/external/miniupnpc/portlistingparse.c b/external/miniupnpc/portlistingparse.c index 0e0927803..55859f271 100644 --- a/external/miniupnpc/portlistingparse.c +++ b/external/miniupnpc/portlistingparse.c @@ -1,7 +1,7 @@ /* $Id: portlistingparse.c,v 1.9 2015/07/15 12:41:13 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2011-2015 Thomas Bernard + * (c) 2011-2016 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ #include <string.h> @@ -55,7 +55,7 @@ startelt(void * d, const char * name, int l) pdata->curelt = PortMappingEltNone; for(i = 0; elements[i].str; i++) { - if(memcmp(name, elements[i].str, l) == 0) + if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0) { pdata->curelt = elements[i].code; break; diff --git a/external/miniupnpc/receivedata.c b/external/miniupnpc/receivedata.c index ef85a3db4..d003eb69d 100644 --- a/external/miniupnpc/receivedata.c +++ b/external/miniupnpc/receivedata.c @@ -28,7 +28,7 @@ #endif /* _WIN32 */ #ifdef _WIN32 -#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#define PRINT_SOCKET_ERROR(x) fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError()); #else #define PRINT_SOCKET_ERROR(x) perror(x) #endif diff --git a/external/miniupnpc/setup.py b/external/miniupnpc/setup.py index aa632db82..24a676d85 100755 --- a/external/miniupnpc/setup.py +++ b/external/miniupnpc/setup.py @@ -1,19 +1,25 @@ #! /usr/bin/python # vim: tabstop=8 shiftwidth=8 expandtab # $Id: setup.py,v 1.9 2012/05/23 08:50:10 nanard Exp $ -# the MiniUPnP Project (c) 2007-2014 Thomas Bernard +# the MiniUPnP Project (c) 2007-2017 Thomas Bernard # http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/ # # python script to build the miniupnpc module under unix # -# replace libminiupnpc.a by libminiupnpc.so for shared library usage -try: - from setuptools import setup, Extension -except ImportError: - from distutils.core import setup, Extension -from distutils import sysconfig -sysconfig.get_config_vars()["OPT"] = '' -sysconfig.get_config_vars()["CFLAGS"] = '' +# Uses MAKE environment variable (defaulting to 'make') + +from setuptools import setup, Extension +from setuptools.command import build_ext +import subprocess +import os + +EXT = ['libminiupnpc.a'] + +class make_then_build_ext(build_ext.build_ext): + def run(self): + subprocess.check_call([os.environ.get('MAKE', 'make')] + EXT) + build_ext.build_ext.run(self) + setup(name="miniupnpc", version=open('VERSION').read().strip(), author='Thomas BERNARD', @@ -21,8 +27,9 @@ setup(name="miniupnpc", license=open('LICENSE').read(), url='http://miniupnp.free.fr/', description='miniUPnP client', + cmdclass={'build_ext': make_then_build_ext}, ext_modules=[ Extension(name="miniupnpc", sources=["miniupnpcmodule.c"], - extra_objects=["libminiupnpc.a"]) + extra_objects=EXT) ]) diff --git a/external/miniupnpc/testdesc/new_LiveBox_desc.xml b/external/miniupnpc/testdesc/new_LiveBox_desc.xml index 9d5160bb8..620eb55af 100644 --- a/external/miniupnpc/testdesc/new_LiveBox_desc.xml +++ b/external/miniupnpc/testdesc/new_LiveBox_desc.xml @@ -87,4 +87,4 @@ </device>
</deviceList>
</device>
-</root> +</root>
\ No newline at end of file diff --git a/external/miniupnpc/testupnpigd.py b/external/miniupnpc/testupnpigd.py index 6d167a4ce..33019bd99 100755 --- a/external/miniupnpc/testupnpigd.py +++ b/external/miniupnpc/testupnpigd.py @@ -8,7 +8,11 @@ # import the python miniupnpc module import miniupnpc import socket -import BaseHTTPServer + +try: + from http.server import BaseHTTPRequestHandler, HTTPServer +except ImportError: + from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer # function definition def list_redirections(): @@ -17,11 +21,11 @@ def list_redirections(): p = u.getgenericportmapping(i) if p==None: break - print i, p + print(i, p) i = i + 1 #define the handler class for HTTP connections -class handler_class(BaseHTTPServer.BaseHTTPRequestHandler): +class handler_class(BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.end_headers() @@ -37,20 +41,20 @@ u = miniupnpc.UPnP() u.discoverdelay = 200; try: - print 'Discovering... delay=%ums' % u.discoverdelay + print('Discovering... delay=%ums' % u.discoverdelay) ndevices = u.discover() - print ndevices, 'device(s) detected' + print(ndevices, 'device(s) detected') # select an igd u.selectigd() # display information about the IGD and the internet connection - print 'local ip address :', u.lanaddr + print('local ip address :', u.lanaddr) externalipaddress = u.externalipaddress() - print 'external ip address :', externalipaddress - print u.statusinfo(), u.connectiontype() + print('external ip address :', externalipaddress) + print(u.statusinfo(), u.connectiontype()) #instanciate a HTTPd object. The port is assigned by the system. - httpd = BaseHTTPServer.HTTPServer((u.lanaddr, 0), handler_class) + httpd = HTTPServer((u.lanaddr, 0), handler_class) eport = httpd.server_port # find a free port for the redirection @@ -59,26 +63,26 @@ try: eport = eport + 1 r = u.getspecificportmapping(eport, 'TCP') - print 'trying to redirect %s port %u TCP => %s port %u TCP' % (externalipaddress, eport, u.lanaddr, httpd.server_port) + print('trying to redirect %s port %u TCP => %s port %u TCP' % (externalipaddress, eport, u.lanaddr, httpd.server_port)) b = u.addportmapping(eport, 'TCP', u.lanaddr, httpd.server_port, 'UPnP IGD Tester port %u' % eport, '') if b: - print 'Success. Now waiting for some HTTP request on http://%s:%u' % (externalipaddress ,eport) + print('Success. Now waiting for some HTTP request on http://%s:%u' % (externalipaddress ,eport)) try: httpd.handle_request() httpd.server_close() - except KeyboardInterrupt, details: - print "CTRL-C exception!", details + except KeyboardInterrupt as details: + print("CTRL-C exception!", details) b = u.deleteportmapping(eport, 'TCP') if b: - print 'Successfully deleted port mapping' + print('Successfully deleted port mapping') else: - print 'Failed to remove port mapping' + print('Failed to remove port mapping') else: - print 'Failed' + print('Failed') httpd.server_close() -except Exception, e: - print 'Exception :', e +except Exception as e: + print('Exception :', e) diff --git a/external/miniupnpc/upnpc.c b/external/miniupnpc/upnpc.c index 94f131c87..e719ecec5 100644 --- a/external/miniupnpc/upnpc.c +++ b/external/miniupnpc/upnpc.c @@ -1,7 +1,7 @@ -/* $Id: upnpc.c,v 1.114 2016/01/22 15:04:23 nanard Exp $ */ +/* $Id: upnpc.c,v 1.117 2017/05/26 15:26:55 nanard Exp $ */ /* Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2016 Thomas Bernard + * Copyright (c) 2005-2017 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ @@ -242,7 +242,7 @@ static void NewListRedirections(struct UPNPUrls * urls, * 2 - get extenal ip address * 3 - Add port mapping * 4 - get this port mapping from the IGD */ -static void SetRedirectAndTest(struct UPNPUrls * urls, +static int SetRedirectAndTest(struct UPNPUrls * urls, struct IGDdatas * data, const char * iaddr, const char * iport, @@ -262,13 +262,13 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, if(!iaddr || !iport || !eport || !proto) { fprintf(stderr, "Wrong arguments\n"); - return; + return -1; } proto = protofix(proto); if(!proto) { fprintf(stderr, "invalid protocol\n"); - return; + return -1; } r = UPNP_GetExternalIPAddress(urls->controlURL, @@ -292,9 +292,11 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, eport, iport, iaddr, description, proto, 0, leaseDuration); - if(r!=UPNPCOMMAND_SUCCESS) + 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, @@ -302,17 +304,19 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, eport, proto, NULL/*remoteHost*/, intClient, intPort, NULL/*desc*/, NULL/*enabled*/, duration); - if(r!=UPNPCOMMAND_SUCCESS) + if(r!=UPNPCOMMAND_SUCCESS) { printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", r, strupnperror(r)); - else { + 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 void +static int RemoveRedirect(struct UPNPUrls * urls, struct IGDdatas * data, const char * eport, @@ -323,19 +327,25 @@ RemoveRedirect(struct UPNPUrls * urls, if(!proto || !eport) { fprintf(stderr, "invalid arguments\n"); - return; + return -1; } proto = protofix(proto); if(!proto) { fprintf(stderr, "protocol invalid\n"); - return; + return -1; } r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, remoteHost); - printf("UPNP_DeletePortMapping() returned : %d\n", r); + 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 void +static int RemoveRedirectRange(struct UPNPUrls * urls, struct IGDdatas * data, const char * ePortStart, char const * ePortEnd, @@ -349,16 +359,22 @@ RemoveRedirectRange(struct UPNPUrls * urls, if(!proto || !ePortStart || !ePortEnd) { fprintf(stderr, "invalid arguments\n"); - return; + return -1; } proto = protofix(proto); if(!proto) { fprintf(stderr, "protocol invalid\n"); - return; + return -1; } r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage); - printf("UPNP_DeletePortMappingRange() returned : %d\n", r); + 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 */ @@ -562,8 +578,8 @@ int main(int argc, char ** argv) } #endif printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); - printf(" (c) 2005-2016 Thomas Bernard.\n"); - printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n" + 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; i<argc; i++) @@ -711,29 +727,33 @@ int main(int argc, char ** argv) NewListRedirections(&urls, &data); break; case 'a': - SetRedirectAndTest(&urls, &data, + if (SetRedirectAndTest(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargv[3], (commandargc > 4)?commandargv[4]:"0", - description, 0); + description, 0) < 0) + retcode = 2; break; case 'd': - RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], - commandargc > 2 ? commandargv[2] : NULL); + if (RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], + commandargc > 2 ? commandargv[2] : NULL) < 0) + retcode = 2; break; case 'n': /* aNy */ - SetRedirectAndTest(&urls, &data, + if (SetRedirectAndTest(&urls, &data, commandargv[0], commandargv[1], commandargv[2], commandargv[3], (commandargc > 4)?commandargv[4]:"0", - description, 1); + description, 1) < 0) + retcode = 2; break; case 'N': if (commandargc < 3) fprintf(stderr, "too few arguments\n"); - RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], - commandargc > 3 ? commandargv[3] : NULL); + if (RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], + commandargc > 3 ? commandargv[3] : NULL) < 0) + retcode = 2; break; case 's': GetConnectionStatus(&urls, &data); @@ -749,17 +769,19 @@ int main(int argc, char ** argv) break; } else if(is_int(commandargv[i+1])){ /* 2nd parameter is an integer : <port> <external_port> <protocol> */ - SetRedirectAndTest(&urls, &data, + if (SetRedirectAndTest(&urls, &data, lanaddr, commandargv[i], commandargv[i+1], commandargv[i+2], "0", - description, 0); + description, 0) < 0) + retcode = 2; i+=3; /* 3 parameters parsed */ } else { /* 2nd parameter not an integer : <port> <protocol> */ - SetRedirectAndTest(&urls, &data, + if (SetRedirectAndTest(&urls, &data, lanaddr, commandargv[i], commandargv[i], commandargv[i+1], "0", - description, 0); + description, 0) < 0) + retcode = 2; i+=2; /* 2 parameters parsed */ } } diff --git a/external/miniupnpc/upnpcommands.c b/external/miniupnpc/upnpcommands.c index 76cf9e391..9f704496f 100644 --- a/external/miniupnpc/upnpcommands.c +++ b/external/miniupnpc/upnpcommands.c @@ -1,7 +1,8 @@ /* $Id: upnpcommands.c,v 1.46 2015/07/15 12:19:00 nanard Exp $ */ -/* Project : miniupnp +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project : miniupnp * Author : Thomas Bernard - * Copyright (c) 2005-2015 Thomas Bernard + * Copyright (c) 2005-2017 Thomas Bernard * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. * */ @@ -372,10 +373,11 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype, AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; AddPortMappingArgs[7].elt = "NewLeaseDuration"; AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPortMapping", AddPortMappingArgs, - &bufsize))) { - free(AddPortMappingArgs); + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "AddPortMapping", AddPortMappingArgs, + &bufsize); + free(AddPortMappingArgs); + if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } /*DisplayNameValueList(buffer, bufsize);*/ @@ -392,7 +394,6 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype, ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); - free(AddPortMappingArgs); return ret; } @@ -436,10 +437,11 @@ UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; AddPortMappingArgs[7].elt = "NewLeaseDuration"; AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddAnyPortMapping", AddPortMappingArgs, - &bufsize))) { - free(AddPortMappingArgs); + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "AddAnyPortMapping", AddPortMappingArgs, + &bufsize); + free(AddPortMappingArgs); + if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } ParseNameValue(buffer, bufsize, &pdata); @@ -461,7 +463,6 @@ UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, } } ClearNameValueList(&pdata); - free(AddPortMappingArgs); return ret; } @@ -490,10 +491,11 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, DeletePortMappingArgs[1].val = extPort; DeletePortMappingArgs[2].elt = "NewProtocol"; DeletePortMappingArgs[2].val = proto; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMapping", - DeletePortMappingArgs, &bufsize))) { - free(DeletePortMappingArgs); + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "DeletePortMapping", + DeletePortMappingArgs, &bufsize); + free(DeletePortMappingArgs); + if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } /*DisplayNameValueList(buffer, bufsize);*/ @@ -507,7 +509,6 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); - free(DeletePortMappingArgs); return ret; } @@ -539,10 +540,11 @@ UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, DeletePortMappingArgs[3].elt = "NewManage"; DeletePortMappingArgs[3].val = manage; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePortMappingRange", - DeletePortMappingArgs, &bufsize))) { - free(DeletePortMappingArgs); + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "DeletePortMappingRange", + DeletePortMappingArgs, &bufsize); + free(DeletePortMappingArgs); + if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } ParseNameValue(buffer, bufsize, &pdata); @@ -555,7 +557,6 @@ UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); - free(DeletePortMappingArgs); return ret; } @@ -587,10 +588,11 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL, return UPNPCOMMAND_MEM_ALLOC_ERROR; GetPortMappingArgs[0].elt = "NewPortMappingIndex"; GetPortMappingArgs[0].val = index; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetGenericPortMappingEntry", - GetPortMappingArgs, &bufsize))) { - free(GetPortMappingArgs); + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetGenericPortMappingEntry", + GetPortMappingArgs, &bufsize); + free(GetPortMappingArgs); + if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } ParseNameValue(buffer, bufsize, &pdata); @@ -652,7 +654,6 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL, sscanf(p, "%d", &r); } ClearNameValueList(&pdata); - free(GetPortMappingArgs); return r; } @@ -728,10 +729,11 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL, GetPortMappingArgs[1].val = extPort; GetPortMappingArgs[2].elt = "NewProtocol"; GetPortMappingArgs[2].val = proto; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetSpecificPortMappingEntry", - GetPortMappingArgs, &bufsize))) { - free(GetPortMappingArgs); + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetSpecificPortMappingEntry", + GetPortMappingArgs, &bufsize); + free(GetPortMappingArgs); + if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } /*DisplayNameValueList(buffer, bufsize);*/ @@ -779,7 +781,6 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL, } ClearNameValueList(&pdata); - free(GetPortMappingArgs); return ret; } @@ -824,13 +825,13 @@ UPNP_GetListOfPortMappings(const char * controlURL, GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts"; GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000"; - if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetListOfPortMappings", - GetListOfPortMappingsArgs, &bufsize))) { - free(GetListOfPortMappingsArgs); + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetListOfPortMappings", + GetListOfPortMappingsArgs, &bufsize); + free(GetListOfPortMappingsArgs); + if(!buffer) { return UPNPCOMMAND_HTTP_ERROR; } - free(GetListOfPortMappingsArgs); /*DisplayNameValueList(buffer, bufsize);*/ ParseNameValue(buffer, bufsize, &pdata); @@ -954,6 +955,7 @@ UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype GetOutboundPinholeTimeoutArgs[4].val = intClient; buffer = simpleUPnPcommand(-1, controlURL, servicetype, "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize); + free(GetOutboundPinholeTimeoutArgs); if(!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); @@ -972,7 +974,6 @@ UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype *opTimeout = my_atoui(p); } ClearNameValueList(&pdata); - free(GetOutboundPinholeTimeoutArgs); return ret; } @@ -1031,6 +1032,7 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype, AddPinholeArgs[5].val = leaseTime; buffer = simpleUPnPcommand(-1, controlURL, servicetype, "AddPinhole", AddPinholeArgs, &bufsize); + free(AddPinholeArgs); if(!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); @@ -1053,7 +1055,6 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype, ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); - free(AddPinholeArgs); return ret; } @@ -1081,6 +1082,7 @@ UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, UpdatePinholeArgs[1].val = leaseTime; buffer = simpleUPnPcommand(-1, controlURL, servicetype, "UpdatePinhole", UpdatePinholeArgs, &bufsize); + free(UpdatePinholeArgs); if(!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); @@ -1097,7 +1099,6 @@ UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); - free(UpdatePinholeArgs); return ret; } @@ -1122,6 +1123,7 @@ UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char DeletePinholeArgs[0].val = uniqueID; buffer = simpleUPnPcommand(-1, controlURL, servicetype, "DeletePinhole", DeletePinholeArgs, &bufsize); + free(DeletePinholeArgs); if(!buffer) return UPNPCOMMAND_HTTP_ERROR; /*DisplayNameValueList(buffer, bufsize);*/ @@ -1138,7 +1140,6 @@ UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); - free(DeletePinholeArgs); return ret; } @@ -1163,8 +1164,11 @@ UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, 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; @@ -1185,7 +1189,6 @@ UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, } ClearNameValueList(&pdata); - free(CheckPinholeWorkingArgs); return ret; } @@ -1210,6 +1213,7 @@ UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, GetPinholePacketsArgs[0].val = uniqueID; buffer = simpleUPnPcommand(-1, controlURL, servicetype, "GetPinholePackets", GetPinholePacketsArgs, &bufsize); + free(GetPinholePacketsArgs); if(!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); @@ -1230,7 +1234,6 @@ UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, } ClearNameValueList(&pdata); - free(GetPinholePacketsArgs); return ret; } diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 01a59e079..d62a250ff 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -78,6 +78,23 @@ std::string blockchain_db_types(const std::string& sep) return ret; } +std::string arg_db_type_description = "Specify database type, available: " + cryptonote::blockchain_db_types(", "); +const command_line::arg_descriptor<std::string> arg_db_type = { + "db-type" +, arg_db_type_description.c_str() +, DEFAULT_DB_TYPE +}; +const command_line::arg_descriptor<std::string> arg_db_sync_mode = { + "db-sync-mode" +, "Specify sync option, using format [safe|fast|fastest]:[sync|async]:[nblocks_per_sync]." +, "fast:async:1000" +}; +const command_line::arg_descriptor<bool> arg_db_salvage = { + "db-salvage" +, "Try to salvage a blockchain database if it seems corrupted" +, false +}; + BlockchainDB *new_db(const std::string& db_type) { if (db_type == "lmdb") @@ -89,6 +106,13 @@ BlockchainDB *new_db(const std::string& db_type) return NULL; } +void BlockchainDB::init_options(boost::program_options::options_description& desc) +{ + command_line::add_arg(desc, arg_db_type); + command_line::add_arg(desc, arg_db_sync_mode); + command_line::add_arg(desc, arg_db_salvage); +} + void BlockchainDB::pop_block() { block blk; diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index ad246d85e..85a494ce7 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -33,6 +33,8 @@ #include <list> #include <string> #include <exception> +#include <boost/program_options.hpp> +#include "common/command_line.h" #include "crypto/hash.h" #include "cryptonote_protocol/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" @@ -101,6 +103,10 @@ namespace cryptonote /** a pair of <transaction hash, output index>, typedef for convenience */ typedef std::pair<crypto::hash, uint64_t> tx_out_index; +extern const command_line::arg_descriptor<std::string> arg_db_type; +extern const command_line::arg_descriptor<std::string> arg_db_sync_mode; +extern const command_line::arg_descriptor<bool, false> arg_db_salvage; + #pragma pack(push, 1) /** @@ -536,6 +542,11 @@ public: virtual ~BlockchainDB() { }; /** + * @brief init command line options + */ + static void init_options(boost::program_options::options_description& desc); + + /** * @brief reset profiling stats */ void reset_stats(); diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 4100d9cca..b6978bdc4 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -2604,6 +2604,16 @@ void BlockchainLMDB::batch_commit() memset(&m_wcursors, 0, sizeof(m_wcursors)); } +void BlockchainLMDB::cleanup_batch() +{ + // for destruction of batch transaction + m_write_txn = nullptr; + delete m_write_batch_txn; + m_write_batch_txn = nullptr; + m_batch_active = false; + memset(&m_wcursors, 0, sizeof(m_wcursors)); +} + void BlockchainLMDB::batch_stop() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -2618,15 +2628,18 @@ void BlockchainLMDB::batch_stop() check_open(); LOG_PRINT_L3("batch transaction: committing..."); TIME_MEASURE_START(time1); - m_write_txn->commit(); - TIME_MEASURE_FINISH(time1); - time_commit1 += time1; - // for destruction of batch transaction - m_write_txn = nullptr; - delete m_write_batch_txn; - m_write_batch_txn = nullptr; - m_batch_active = false; - memset(&m_wcursors, 0, sizeof(m_wcursors)); + try + { + m_write_txn->commit(); + TIME_MEASURE_FINISH(time1); + time_commit1 += time1; + cleanup_batch(); + } + catch (const std::exception &e) + { + cleanup_batch(); + throw; + } LOG_PRINT_L3("batch transaction: end"); } diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 3a11ddf0d..90274b904 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -368,6 +368,9 @@ private: // migrate from DB version 0 to 1 void migrate_0_1(); + void cleanup_batch(); + +private: MDB_env* m_env; MDB_dbi m_blocks; diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index ded854ca4..635a70b10 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -208,7 +208,8 @@ int check_flush(cryptonote::core &core, std::list<block_complete_entry> &blocks, } } // each download block - core.cleanup_handle_incoming_blocks(); + if (!core.cleanup_handle_incoming_blocks()) + return 1; blocks.clear(); return 0; @@ -316,9 +317,9 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path MWARNING("WARNING: chunk_size " << chunk_size << " > BUFFER_SIZE " << BUFFER_SIZE); throw std::runtime_error("Aborting: chunk size exceeds buffer size"); } - if (chunk_size > 100000) + if (chunk_size > CHUNK_SIZE_WARNING_THRESHOLD) { - MINFO("NOTE: chunk_size " << chunk_size << " > 100000"); + MINFO("NOTE: chunk_size " << chunk_size << " > " << CHUNK_SIZE_WARNING_THRESHOLD); } else if (chunk_size == 0) { MFATAL("ERROR: chunk_size == 0"); @@ -326,9 +327,19 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path } import_file.read(buffer_block, chunk_size); if (! import_file) { - MFATAL("ERROR: unexpected end of file: bytes read before error: " - << import_file.gcount() << " of chunk_size " << chunk_size); - return 2; + if (import_file.eof()) + { + std::cout << refresh_string; + MINFO("End of file reached - file was truncated"); + quit = 1; + break; + } + else + { + MFATAL("ERROR: unexpected end of file: bytes read before error: " + << import_file.gcount() << " of chunk_size " << chunk_size); + return 2; + } } bytes_read += chunk_size; MDEBUG("Total bytes read: " << bytes_read); @@ -394,7 +405,10 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path blocks.push_back({block, txs}); int ret = check_flush(core, blocks, false); if (ret) + { + quit = 2; // make sure we don't commit partial block data break; + } } else { @@ -682,18 +696,12 @@ int main(int argc, char* argv[]) MINFO("bootstrap file path: " << import_file_path); MINFO("database path: " << m_config_folder); + cryptonote::cryptonote_protocol_stub pr; //TODO: stub only for this kind of test, make real validation of relayed objects + cryptonote::core core(&pr); + try { - // fake_core needed for verification to work when enabled. - // - // NOTE: don't need fake_core method of doing things when we're going to call - // BlockchainDB add_block() directly and have available the 3 block - // properties to do so. Both ways work, but fake core isn't necessary in that - // circumstance. - - cryptonote::cryptonote_protocol_stub pr; //TODO: stub only for this kind of test, make real validation of relayed objects - cryptonote::core core(&pr); core.disable_dns_checkpoints(true); if (!core.init(vm, NULL)) { @@ -721,23 +729,19 @@ int main(int argc, char* argv[]) import_from_file(core, import_file_path, block_stop); + // ensure db closed + // - transactions properly checked and handled + // - disk sync if needed + // + core.deinit(); } catch (const DB_ERROR& e) { std::cout << std::string("Error loading blockchain db: ") + e.what() + " -- shutting down now" << ENDL; + core.deinit(); return 1; } - // destructors called at exit: - // - // ensure db closed - // - transactions properly checked and handled - // - disk sync if needed - // - // fake_core object's destructor is called when it goes out of scope. For an - // LMDB fake_core, it calls Blockchain::deinit() on its object, which in turn - // calls delete on its BlockchainDB derived class' object, which closes its - // files. return 0; CATCH_ENTRY("Import error", 1); diff --git a/src/blockchain_utilities/blockchain_utilities.h b/src/blockchain_utilities/blockchain_utilities.h index af934bf29..6fb5e1131 100644 --- a/src/blockchain_utilities/blockchain_utilities.h +++ b/src/blockchain_utilities/blockchain_utilities.h @@ -34,6 +34,7 @@ // bounds checking is done before writing to buffer, but buffer size // should be a sensible maximum #define BUFFER_SIZE 1000000 +#define CHUNK_SIZE_WARNING_THRESHOLD 500000 #define NUM_BLOCKS_PER_CHUNK 1 #define BLOCKCHAIN_RAW "blockchain.raw" diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp index d5bb37d93..2b1a5d6c7 100644 --- a/src/blockchain_utilities/bootstrap_file.cpp +++ b/src/blockchain_utilities/bootstrap_file.cpp @@ -436,10 +436,10 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) << " height: " << h-1); throw std::runtime_error("Aborting: chunk size exceeds buffer size"); } - if (chunk_size > 100000) + if (chunk_size > CHUNK_SIZE_WARNING_THRESHOLD) { std::cout << refresh_string; - MDEBUG("NOTE: chunk_size " << chunk_size << " > 100000" << " height: " + MDEBUG("NOTE: chunk_size " << chunk_size << " > " << CHUNK_SIZE_WARNING_THRESHOLD << " << height: " << h-1); } else if (chunk_size <= 0) { diff --git a/src/blocks/checkpoints.dat b/src/blocks/checkpoints.dat Binary files differindex a15f53e67..15fa042cf 100644 --- a/src/blocks/checkpoints.dat +++ b/src/blocks/checkpoints.dat diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index ad66b2009..666b3267f 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -32,7 +32,6 @@ #include <boost/algorithm/string/compare.hpp> #include <boost/algorithm/string/predicate.hpp> #include <unordered_set> -#include "blockchain_db/db_types.h" #include "common/i18n.h" #include "cryptonote_config.h" #include "string_tools.h" @@ -96,22 +95,6 @@ namespace command_line , "checkpoints from DNS server will be enforced" , false }; - std::string arg_db_type_description = "Specify database type, available: " + cryptonote::blockchain_db_types(", "); - const command_line::arg_descriptor<std::string> arg_db_type = { - "db-type" - , arg_db_type_description.c_str() - , DEFAULT_DB_TYPE - }; - const command_line::arg_descriptor<std::string> arg_db_sync_mode = { - "db-sync-mode" - , "Specify sync option, using format [safe|fast|fastest]:[sync|async]:[nblocks_per_sync]." - , "fast:async:1000" - }; - const arg_descriptor<bool> arg_db_salvage = { - "db-salvage" - , "Try to salvage a blockchain database if it seems corrupted" - , false - }; const command_line::arg_descriptor<uint64_t> arg_fast_block_sync = { "fast-block-sync" , "Sync up most of the way by using embedded, known block hashes." @@ -137,4 +120,9 @@ namespace command_line , "Check for new versions of monero: [disabled|notify|download|update]" , "notify" }; + const arg_descriptor<bool> arg_fluffy_blocks = { + "fluffy-blocks" + , "Relay blocks as fluffy blocks where possible (automatic on testnet)" + , false + }; } diff --git a/src/common/command_line.h b/src/common/command_line.h index 03ba35a5b..d4231acd0 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -212,12 +212,10 @@ namespace command_line extern const arg_descriptor<int> arg_test_dbg_lock_sleep; extern const arg_descriptor<bool, false> arg_testnet_on; extern const arg_descriptor<bool> arg_dns_checkpoints; - extern const arg_descriptor<std::string> arg_db_type; - extern const arg_descriptor<std::string> arg_db_sync_mode; - extern const arg_descriptor<bool, false> arg_db_salvage; extern const arg_descriptor<uint64_t> arg_fast_block_sync; extern const arg_descriptor<uint64_t> arg_prep_blocks_threads; extern const arg_descriptor<uint64_t> arg_show_time_stats; extern const arg_descriptor<size_t> arg_block_sync_size; extern const arg_descriptor<std::string> arg_check_updates; + extern const arg_descriptor<bool> arg_fluffy_blocks; } diff --git a/src/cryptonote_basic/checkpoints.cpp b/src/cryptonote_basic/checkpoints.cpp index 103a4a33e..98e509561 100644 --- a/src/cryptonote_basic/checkpoints.cpp +++ b/src/cryptonote_basic/checkpoints.cpp @@ -167,6 +167,8 @@ namespace cryptonote ADD_CHECKPOINT(1100000, "3fd720c5c8b3072fc1ccda922dec1ef25f9ed88a1e6ad4103d0fe00b180a5903"); ADD_CHECKPOINT(1150000, "1dd16f626d18e1e988490dfd06de5920e22629c972c58b4d8daddea0038627b2"); ADD_CHECKPOINT(1200000, "fa7d13a90850882060479d100141ff84286599ae39c3277c8ea784393f882d1f"); + ADD_CHECKPOINT(1300000, "31b34272343a44a9f4ac7de7a8fcf3b7d8a3124d7d6870affd510d2f37e74cd0"); + ADD_CHECKPOINT(1390000, "a8f5649dd4ded60eedab475f2bec8c934681c07e3cf640e9be0617554f13ff6c"); return true; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 35d42a394..2330b6c42 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -3632,12 +3632,23 @@ void Blockchain::block_longhash_worker(uint64_t height, const std::vector<block> //------------------------------------------------------------------ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync) { + bool success = false; + MTRACE("Blockchain::" << __func__); CRITICAL_REGION_BEGIN(m_blockchain_lock); TIME_MEASURE_START(t1); - m_db->batch_stop(); - if (m_sync_counter > 0) + try + { + m_db->batch_stop(); + success = true; + } + catch (const std::exception &e) + { + MERROR("Exception in cleanup_handle_incoming_blocks: " << e.what()); + } + + if (success && m_sync_counter > 0) { if (force_sync) { @@ -3672,7 +3683,7 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync) CRITICAL_REGION_END(); m_tx_pool.unlock(); - return true; + return success; } //------------------------------------------------------------------ @@ -4173,7 +4184,7 @@ void Blockchain::cancel() } #if defined(PER_BLOCK_CHECKPOINT) -static const char expected_block_hashes_hash[] = "23d8a8c73de7b2383c72a016d9a6034e69d62dd48077d1c414e064ceab6daa94"; +static const char expected_block_hashes_hash[] = "d3ca80d50661684cde0e715d46d7c19704d2e216b21ed088af9fd4ef37ed4d65"; void Blockchain::load_compiled_in_block_hashes() { if (m_fast_sync && get_blocks_dat_start(m_testnet) != nullptr && get_blocks_dat_size(m_testnet) > 0) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index cda54c65d..01ee64b78 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -156,20 +156,19 @@ namespace cryptonote command_line::add_arg(desc, command_line::arg_testnet_on); command_line::add_arg(desc, command_line::arg_dns_checkpoints); - command_line::add_arg(desc, command_line::arg_db_type); command_line::add_arg(desc, command_line::arg_prep_blocks_threads); command_line::add_arg(desc, command_line::arg_fast_block_sync); - command_line::add_arg(desc, command_line::arg_db_sync_mode); - command_line::add_arg(desc, command_line::arg_db_salvage); command_line::add_arg(desc, command_line::arg_show_time_stats); command_line::add_arg(desc, command_line::arg_block_sync_size); command_line::add_arg(desc, command_line::arg_check_updates); + command_line::add_arg(desc, command_line::arg_fluffy_blocks); // we now also need some of net_node's options (p2p bind arg, for separate data dir) command_line::add_arg(desc, nodetool::arg_testnet_p2p_bind_port, false); command_line::add_arg(desc, nodetool::arg_p2p_bind_port, false); miner::init_options(desc); + BlockchainDB::init_options(desc); } //----------------------------------------------------------------------------------------------- bool core::handle_command_line(const boost::program_options::variables_map& vm) @@ -199,6 +198,7 @@ namespace cryptonote set_enforce_dns_checkpoints(command_line::get_arg(vm, command_line::arg_dns_checkpoints)); test_drop_download_height(command_line::get_arg(vm, command_line::arg_test_drop_download_height)); + m_fluffy_blocks_enabled = m_testnet || get_arg(vm, command_line::arg_fluffy_blocks); if (command_line::get_arg(vm, command_line::arg_test_drop_download) == true) test_drop_download(); @@ -279,9 +279,9 @@ namespace cryptonote m_config_folder_mempool = m_config_folder_mempool + "/" + m_port; } - std::string db_type = command_line::get_arg(vm, command_line::arg_db_type); - std::string db_sync_mode = command_line::get_arg(vm, command_line::arg_db_sync_mode); - bool db_salvage = command_line::get_arg(vm, command_line::arg_db_salvage) != 0; + std::string db_type = command_line::get_arg(vm, cryptonote::arg_db_type); + std::string db_sync_mode = command_line::get_arg(vm, cryptonote::arg_db_sync_mode); + bool db_salvage = command_line::get_arg(vm, cryptonote::arg_db_salvage) != 0; bool fast_sync = command_line::get_arg(vm, command_line::arg_fast_block_sync) != 0; uint64_t blocks_threads = command_line::get_arg(vm, command_line::arg_prep_blocks_threads); std::string check_updates_string = command_line::get_arg(vm, command_line::arg_check_updates); @@ -585,6 +585,8 @@ namespace cryptonote //----------------------------------------------------------------------------------------------- bool core::handle_incoming_txs(const std::list<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { + TRY_ENTRY(); + struct result { bool res; cryptonote::transaction tx; crypto::hash hash; crypto::hash prefix_hash; bool in_txpool; bool in_blockchain; }; std::vector<result> results(tx_blobs.size()); @@ -593,7 +595,15 @@ namespace cryptonote std::list<blobdata>::const_iterator it = tx_blobs.begin(); for (size_t i = 0; i < tx_blobs.size(); i++, ++it) { region.run([&, i, it] { - results[i].res = handle_incoming_tx_pre(*it, tvc[i], results[i].tx, results[i].hash, results[i].prefix_hash, keeped_by_block, relayed, do_not_relay); + try + { + results[i].res = handle_incoming_tx_pre(*it, tvc[i], results[i].tx, results[i].hash, results[i].prefix_hash, keeped_by_block, relayed, do_not_relay); + } + catch (const std::exception &e) + { + MERROR_VER("Exception in handle_incoming_tx_pre: " << e.what()); + results[i].res = false; + } }); } }); @@ -613,7 +623,15 @@ namespace cryptonote else { region.run([&, i, it] { - results[i].res = handle_incoming_tx_post(*it, tvc[i], results[i].tx, results[i].hash, results[i].prefix_hash, keeped_by_block, relayed, do_not_relay); + try + { + results[i].res = handle_incoming_tx_post(*it, tvc[i], results[i].tx, results[i].hash, results[i].prefix_hash, keeped_by_block, relayed, do_not_relay); + } + catch (const std::exception &e) + { + MERROR_VER("Exception in handle_incoming_tx_post: " << e.what()); + results[i].res = false; + } }); } } @@ -638,6 +656,8 @@ namespace cryptonote MDEBUG("tx added: " << results[i].hash); } return ok; + + CATCH_ENTRY_L0("core::handle_incoming_txs()", false); } //----------------------------------------------------------------------------------------------- bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) @@ -1071,17 +1091,20 @@ namespace cryptonote //----------------------------------------------------------------------------------------------- bool core::cleanup_handle_incoming_blocks(bool force_sync) { + bool success = false; try { - m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync); + success = m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync); } catch (...) {} m_incoming_tx_lock.unlock(); - return true; + return success; } //----------------------------------------------------------------------------------------------- bool core::handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate) { + TRY_ENTRY(); + // load json & DNS checkpoints every 10min/hour respectively, // and verify them with respect to what blocks we already have CHECK_AND_ASSERT_MES(update_checkpoints(), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints."); @@ -1105,6 +1128,8 @@ namespace cryptonote if(update_miner_blocktemplate && bvc.m_added_to_main_chain) update_miner_block_template(); return true; + + CATCH_ENTRY_L0("core::handle_incoming_block()", false); } //----------------------------------------------------------------------------------------------- // Used by the RPC server to check the size of an incoming diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index d94d1ad86..a9ee9e9d0 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -745,6 +745,13 @@ namespace cryptonote */ bool get_testnet() const { return m_testnet; }; + /** + * @brief get whether fluffy blocks are enabled + * + * @return whether fluffy blocks are enabled + */ + bool fluffy_blocks_enabled() const { return m_fluffy_blocks_enabled; } + private: /** @@ -962,6 +969,8 @@ namespace cryptonote tools::download_async_handle m_update_download; size_t m_last_update_length; boost::mutex m_update_mutex; + + bool m_fluffy_blocks_enabled; }; } diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index e1f640a97..54d3ec0da 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -92,7 +92,7 @@ namespace cryptonote LockedTXN(Blockchain &b): m_blockchain(b), m_batch(false) { m_batch = m_blockchain.get_db().batch_start(); } - ~LockedTXN() { if (m_batch) { m_blockchain.get_db().batch_stop(); } } + ~LockedTXN() { try { if (m_batch) { m_blockchain.get_db().batch_stop(); } } catch (const std::exception &e) { MWARNING("LockedTXN dtor filtering exception: " << e.what()); } } private: Blockchain &m_blockchain; bool m_batch; @@ -922,6 +922,9 @@ namespace cryptonote std::unordered_set<crypto::key_image> k_images; LOG_PRINT_L2("Filling block template, median size " << median_size << ", " << m_txs_by_fee_and_receive_time.size() << " txes in the pool"); + + LockedTXN lock(m_blockchain); + auto sorted_it = m_txs_by_fee_and_receive_time.begin(); while (sorted_it != m_txs_by_fee_and_receive_time.end()) { diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index e762cf9c8..803d948cc 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -364,7 +364,12 @@ namespace cryptonote block_verification_context bvc = boost::value_initialized<block_verification_context>(); m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block - m_core.cleanup_handle_incoming_blocks(true); + if (!m_core.cleanup_handle_incoming_blocks(true)) + { + LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks"); + m_core.resume_mine(); + return 1; + } m_core.resume_mine(); if(bvc.m_verifivation_failed) { @@ -623,7 +628,12 @@ namespace cryptonote block_verification_context bvc = boost::value_initialized<block_verification_context>(); m_core.handle_incoming_block(arg.b.block, bvc); // got block from handle_notify_new_block - m_core.cleanup_handle_incoming_blocks(true); + if (!m_core.cleanup_handle_incoming_blocks(true)) + { + LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks"); + m_core.resume_mine(); + return 1; + } m_core.resume_mine(); if( bvc.m_verifivation_failed ) @@ -930,6 +940,7 @@ namespace cryptonote { const uint64_t subchain_height = start_height + arg.blocks.size(); LOG_DEBUG_CC(context, "These are old blocks, ignoring: blocks " << start_height << " - " << (subchain_height-1) << ", blockchain height " << m_core.get_current_blockchain_height()); + m_block_queue.remove_spans(context.m_connection_id, start_height); goto skip; } @@ -1055,7 +1066,11 @@ skip: })) LOG_ERROR_CCONTEXT("span connection id not found"); - m_core.cleanup_handle_incoming_blocks(); + if (!m_core.cleanup_handle_incoming_blocks()) + { + LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks"); + return 1; + } // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it m_block_queue.remove_spans(span_connection_id, start_height); return 1; @@ -1080,7 +1095,12 @@ skip: })) LOG_ERROR_CCONTEXT("span connection id not found"); - m_core.cleanup_handle_incoming_blocks(); + if (!m_core.cleanup_handle_incoming_blocks()) + { + LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks"); + return 1; + } + // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it m_block_queue.remove_spans(span_connection_id, start_height); return 1; @@ -1094,7 +1114,12 @@ skip: })) LOG_ERROR_CCONTEXT("span connection id not found"); - m_core.cleanup_handle_incoming_blocks(); + if (!m_core.cleanup_handle_incoming_blocks()) + { + LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks"); + return 1; + } + // in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it m_block_queue.remove_spans(span_connection_id, start_height); return 1; @@ -1107,7 +1132,11 @@ skip: MCINFO("sync-info", "Block process time (" << blocks.size() << " blocks, " << num_txs << " txs): " << block_process_time_full + transactions_process_time_full << " (" << transactions_process_time_full << "/" << block_process_time_full << ") ms"); - m_core.cleanup_handle_incoming_blocks(); + if (!m_core.cleanup_handle_incoming_blocks()) + { + LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks"); + return 1; + } m_block_queue.remove_spans(span_connection_id, start_height); @@ -1593,7 +1622,7 @@ skip: { if (peer_id && exclude_context.m_connection_id != context.m_connection_id) { - if(m_core.get_testnet() && (support_flags & P2P_SUPPORT_FLAG_FLUFFY_BLOCKS)) + if(m_core.fluffy_blocks_enabled() && (support_flags & P2P_SUPPORT_FLAG_FLUFFY_BLOCKS)) { LOG_DEBUG_CC(context, "PEER SUPPORTS FLUFFY BLOCKS - RELAYING THIN/COMPACT WHATEVER BLOCK"); fluffyConnections.push_back(context.m_connection_id); diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 12f7c5fa4..9df698547 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -231,7 +231,7 @@ t_command_server::t_command_server( m_command_lookup.set_handler( "print_coinbase_tx_sum" , std::bind(&t_command_parser_executor::print_coinbase_tx_sum, &m_parser, p::_1) - , "Print sum of coinbase transactions (start height, block count)" + , "Print sum of coinbase transactions <start height> [block count]" ); m_command_lookup.set_handler( "alt_chain_info" diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index b35a864e9..8f6d542b6 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -145,7 +145,7 @@ int main(int argc, char const * argv[]) epee::debug::g_test_dbg_lock_sleep() = command_line::get_arg(vm, command_line::arg_test_dbg_lock_sleep); - std::string db_type = command_line::get_arg(vm, command_line::arg_db_type); + std::string db_type = command_line::get_arg(vm, cryptonote::arg_db_type); // verify that blockchaindb type is valid if(!cryptonote::blockchain_valid_db_type(db_type)) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 3d6a01cd1..cda6f3f95 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -420,16 +420,17 @@ bool t_rpc_command_executor::show_status() { } std::time_t uptime = std::time(nullptr) - ires.start_time; + uint64_t net_height = ires.target_height > ires.height ? ires.target_height : ires.height; tools::success_msg_writer() << boost::format("Height: %llu/%llu (%.1f%%) on %s, %s, net hash %s, v%u%s, %s, %u(out)+%u(in) connections, uptime %ud %uh %um %us") % (unsigned long long)ires.height - % (unsigned long long)(ires.target_height >= ires.height ? ires.target_height : ires.height) + % (unsigned long long)net_height % get_sync_percentage(ires) % (ires.testnet ? "testnet" : "mainnet") % (!has_mining_info ? "mining info unavailable" : mining_busy ? "syncing" : mres.active ? ( ( mres.is_background_mining_enabled ? "smart " : "" ) + std::string("mining at ") + get_mining_speed(mres.speed) ) : "not mining") % get_mining_speed(ires.difficulty / ires.target) % (unsigned)hfres.version - % get_fork_extra_info(hfres.earliest_height, ires.height, ires.target) + % get_fork_extra_info(hfres.earliest_height, net_height, ires.target) % (hfres.state == cryptonote::HardFork::Ready ? "up to date" : hfres.state == cryptonote::HardFork::UpdateNeeded ? "update needed" : "out of date, likely forked") % (unsigned)ires.outgoing_connections_count % (unsigned)ires.incoming_connections_count diff --git a/src/debug_utilities/CMakeLists.txt b/src/debug_utilities/CMakeLists.txt index e6d49fd61..99198dc57 100644 --- a/src/debug_utilities/CMakeLists.txt +++ b/src/debug_utilities/CMakeLists.txt @@ -37,7 +37,6 @@ monero_add_executable(cn_deserialize target_link_libraries(cn_deserialize LINK_PRIVATE cryptonote_core - common blockchain_db p2p epee diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h index 43c5ea5f0..6ea2d48fd 100644 --- a/src/p2p/net_peerlist_boost_serialization.h +++ b/src/p2p/net_peerlist_boost_serialization.h @@ -59,6 +59,8 @@ namespace boost { a & na.m_ip; a & na.m_port; + if (!typename Archive::is_saving()) + na.init_ids(); } diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index b526277a8..dbbe07972 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -125,7 +125,7 @@ namespace cryptonote MAP_JON_RPC_WE_IF("get_alternate_chains",on_get_alternate_chains, COMMAND_RPC_GET_ALTERNATE_CHAINS, !m_restricted) MAP_JON_RPC_WE_IF("relay_tx", on_relay_tx, COMMAND_RPC_RELAY_TX, !m_restricted) MAP_JON_RPC_WE_IF("sync_info", on_sync_info, COMMAND_RPC_SYNC_INFO, !m_restricted) - MAP_JON_RPC_WE_IF("get_txpool_backlog", on_get_txpool_backlog, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG, !m_restricted) + MAP_JON_RPC_WE("get_txpool_backlog", on_get_txpool_backlog, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG) END_JSON_RPC_MAP() END_URI_MAP2() diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 479adcafc..857e2af6e 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -391,6 +391,61 @@ bool simple_wallet::payment_id(const std::vector<std::string> &args/* = std::vec return true; } +bool simple_wallet::print_fee_info(const std::vector<std::string> &args/* = std::vector<std::string>()*/) +{ + if (!try_connect_to_daemon()) + { + fail_msg_writer() << tr("Cannot connect to daemon"); + return true; + } + const uint64_t per_kb_fee = m_wallet->get_per_kb_fee(); + const uint64_t typical_size_kb = 13; + message_writer() << (boost::format(tr("Current fee is %s monero per kB")) % print_money(per_kb_fee)).str(); + + std::vector<uint64_t> fees; + for (uint32_t priority = 1; priority <= 4; ++priority) + { + uint64_t mult = m_wallet->get_fee_multiplier(priority); + fees.push_back(per_kb_fee * typical_size_kb * mult); + } + std::vector<std::pair<uint64_t, uint64_t>> blocks; + try + { + uint64_t base_size = typical_size_kb * 1024; + blocks = m_wallet->estimate_backlog(base_size, base_size + 1023, fees); + } + catch (const std::exception &e) + { + fail_msg_writer() << tr("Error: failed to estimate backlog array size: ") << e.what(); + return true; + } + if (blocks.size() != 4) + { + fail_msg_writer() << tr("Error: bad estimated backlog array size"); + return true; + } + + for (uint32_t priority = 1; priority <= 4; ++priority) + { + uint64_t nblocks_low = blocks[priority - 1].first; + uint64_t nblocks_high = blocks[priority - 1].second; + if (nblocks_low > 0) + { + std::string msg; + if (priority == m_wallet->get_default_priority() || (m_wallet->get_default_priority() == 0 && priority == 2)) + msg = tr(" (current)"); + uint64_t minutes_low = nblocks_low * DIFFICULTY_TARGET_V2 / 60, minutes_high = nblocks_high * DIFFICULTY_TARGET_V2 / 60; + if (nblocks_high == nblocks_low) + message_writer() << (boost::format(tr("%u block (%u minutes) backlog at priority %u%s")) % nblocks_low % minutes_low % priority % msg).str(); + else + message_writer() << (boost::format(tr("%u to %u block (%u to %u minutes) backlog at priority %u")) % nblocks_low % nblocks_high % minutes_low % minutes_high % priority).str(); + } + else + message_writer() << tr("No backlog at priority ") << priority; + } + return true; +} + bool simple_wallet::set_always_confirm_transfers(const std::vector<std::string> &args/* = std::vector<std::string>()*/) { const auto pwd_container = get_and_verify_password(); @@ -722,6 +777,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("show_transfer", boost::bind(&simple_wallet::show_transfer, this, _1), tr("Show information about a transfer to/from this address")); m_cmd_binder.set_handler("password", boost::bind(&simple_wallet::change_password, this, _1), tr("Change wallet password")); m_cmd_binder.set_handler("payment_id", boost::bind(&simple_wallet::payment_id, this, _1), tr("Generate a new random full size payment id - these will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids")); + m_cmd_binder.set_handler("fee", boost::bind(&simple_wallet::print_fee_info, this, _1), tr("Print information about fee and current transaction backlog")); m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("Show this help")); } //---------------------------------------------------------------------------------------------------- @@ -2431,6 +2487,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri break; default: LOG_ERROR("Unknown transfer method, using original"); + /* FALLTHRU */ case TransferOriginal: ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, priority, extra, m_trusted_daemon); break; @@ -2461,9 +2518,16 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri } try { - uint64_t nblocks = m_wallet->estimate_backlog(size, fee); - if (nblocks > 0) - prompt << (boost::format(tr("There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No)")) % nblocks).str(); + std::vector<std::pair<uint64_t, uint64_t>> nblocks = m_wallet->estimate_backlog(size, size, {fee}); + if (nblocks.size() != 1) + { + prompt << "Internal error checking for backlog. " << tr("Is this okay anyway? (Y/Yes/N/No): "); + } + else + { + if (nblocks[0].first > 0) + prompt << (boost::format(tr("There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No)")) % nblocks[0].first).str(); + } } catch (const std::exception &e) { diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index eac4cbc99..079fae9f5 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -175,6 +175,7 @@ namespace cryptonote bool show_transfer(const std::vector<std::string> &args); bool change_password(const std::vector<std::string>& args); bool payment_id(const std::vector<std::string> &args); + bool print_fee_info(const std::vector<std::string> &args); uint64_t get_daemon_blockchain_height(std::string& err); bool try_connect_to_daemon(bool silent = false, uint32_t* version = nullptr); diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index c0974f880..7afc1f449 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -379,7 +379,32 @@ bool WalletImpl::createWatchOnly(const std::string &path, const std::string &pas const cryptonote::account_public_address address = m_wallet->get_account().get_keys().m_account_address; try { + // Generate view only wallet view_wallet->generate(path, password, address, viewkey); + + // Export/Import outputs + auto outputs = m_wallet->export_outputs(); + view_wallet->import_outputs(outputs); + + // Copy scanned blockchain + auto bc = m_wallet->export_blockchain(); + view_wallet->import_blockchain(bc); + + // copy payments + auto payments = m_wallet->export_payments(); + view_wallet->import_payments(payments); + + // copy confirmed outgoing payments + std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> out_payments; + m_wallet->get_payments_out(out_payments, 0); + view_wallet->import_payments_out(out_payments); + + // Export/Import key images + // We already know the spent status from the outputs we exported, thus no need to check them again + auto key_images = m_wallet->export_key_images(); + uint64_t spent = 0; + uint64_t unspent = 0; + view_wallet->import_key_images(key_images,spent,unspent,false); m_status = Status_Ok; } catch (const std::exception &e) { LOG_ERROR("Error creating view only wallet: " << e.what()); @@ -387,6 +412,8 @@ bool WalletImpl::createWatchOnly(const std::string &path, const std::string &pas m_errorString = e.what(); return false; } + // Store wallet + view_wallet->store(); return true; } @@ -862,6 +889,11 @@ bool WalletImpl::exportKeyImages(const string &filename) bool WalletImpl::importKeyImages(const string &filename) { + if (!trustedDaemon()) { + m_status = Status_Error; + m_errorString = tr("Key images can only be imported with a trusted daemon"); + return false; + } try { uint64_t spent = 0, unspent = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 09ca8efe1..323a3a7fe 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3457,12 +3457,15 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal return true; } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::get_fee_multiplier(uint32_t priority, int fee_algorithm) const +uint64_t wallet2::get_fee_multiplier(uint32_t priority, int fee_algorithm) { static const uint64_t old_multipliers[3] = {1, 2, 3}; static const uint64_t new_multipliers[3] = {1, 20, 166}; static const uint64_t newer_multipliers[4] = {1, 4, 20, 166}; + if (fee_algorithm == -1) + fee_algorithm = get_fee_algorithm(); + // 0 -> default (here, x1 till fee algorithm 2, x4 from it) if (priority == 0) priority = m_default_priority; @@ -5098,6 +5101,9 @@ uint64_t wallet2::get_approximate_blockchain_height() const const int seconds_per_block = DIFFICULTY_TARGET_V2; // Calculated blockchain height uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block; + // testnet got some huge rollbacks, so the estimation is way off + if (m_testnet && approx_blockchain_height > 105000) + approx_blockchain_height -= 105000; LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height); return approx_blockchain_height; } @@ -5330,7 +5336,7 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent) +uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent, bool check_spent) { COMMAND_RPC_IS_KEY_IMAGE_SPENT::request req = AUTO_VAL_INIT(req); COMMAND_RPC_IS_KEY_IMAGE_SPENT::response daemon_resp = AUTO_VAL_INIT(daemon_resp); @@ -5379,34 +5385,88 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag m_transfers[n].m_key_image_known = true; } - m_daemon_rpc_mutex.lock(); - bool r = epee::net_utils::invoke_http_json("/is_key_image_spent", req, daemon_resp, m_http_client, rpc_timeout); - m_daemon_rpc_mutex.unlock(); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent"); - THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent"); - THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::is_key_image_spent_error, daemon_resp.status); - THROW_WALLET_EXCEPTION_IF(daemon_resp.spent_status.size() != signed_key_images.size(), error::wallet_internal_error, - "daemon returned wrong response for is_key_image_spent, wrong amounts count = " + - std::to_string(daemon_resp.spent_status.size()) + ", expected " + std::to_string(signed_key_images.size())); - + if(check_spent) + { + m_daemon_rpc_mutex.lock(); + bool r = epee::net_utils::invoke_http_json("/is_key_image_spent", req, daemon_resp, m_http_client, rpc_timeout); + m_daemon_rpc_mutex.unlock(); + THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent"); + THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "is_key_image_spent"); + THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::is_key_image_spent_error, daemon_resp.status); + THROW_WALLET_EXCEPTION_IF(daemon_resp.spent_status.size() != signed_key_images.size(), error::wallet_internal_error, + "daemon returned wrong response for is_key_image_spent, wrong amounts count = " + + std::to_string(daemon_resp.spent_status.size()) + ", expected " + std::to_string(signed_key_images.size())); + for (size_t n = 0; n < daemon_resp.spent_status.size(); ++n) + { + transfer_details &td = m_transfers[n]; + td.m_spent = daemon_resp.spent_status[n] != COMMAND_RPC_IS_KEY_IMAGE_SPENT::UNSPENT; + } + } spent = 0; unspent = 0; - for (size_t n = 0; n < daemon_resp.spent_status.size(); ++n) + for(size_t i = 0; i < m_transfers.size(); ++i) { - transfer_details &td = m_transfers[n]; + transfer_details &td = m_transfers[i]; uint64_t amount = td.amount(); - td.m_spent = daemon_resp.spent_status[n] != COMMAND_RPC_IS_KEY_IMAGE_SPENT::UNSPENT; if (td.m_spent) spent += amount; else unspent += amount; - LOG_PRINT_L2("Transfer " << n << ": " << print_money(amount) << " (" << td.m_global_output_index << "): " - << (td.m_spent ? "spent" : "unspent") << " (key image " << req.key_images[n] << ")"); + LOG_PRINT_L2("Transfer " << i << ": " << print_money(amount) << " (" << td.m_global_output_index << "): " + << (td.m_spent ? "spent" : "unspent") << " (key image " << req.key_images[i] << ")"); } - LOG_PRINT_L1("Total: " << print_money(spent) << " spent, " << print_money(unspent) << " unspent"); - + MDEBUG("Total: " << print_money(spent) << " spent, " << print_money(unspent) << " unspent"); return m_transfers[signed_key_images.size() - 1].m_block_height; } +wallet2::payment_container wallet2::export_payments() const +{ + payment_container payments; + for (auto const &p : m_payments) + { + payments.emplace(p); + } + return payments; +} +void wallet2::import_payments(const payment_container &payments) +{ + m_payments.clear(); + for (auto const &p : payments) + { + m_payments.emplace(p); + } +} +void wallet2::import_payments_out(const std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>> &confirmed_payments) +{ + m_confirmed_txs.clear(); + for (auto const &p : confirmed_payments) + { + m_confirmed_txs.emplace(p); + } +} + +std::vector<crypto::hash> wallet2::export_blockchain() const +{ + std::vector<crypto::hash> bc; + for (auto const &b : m_blockchain) + { + bc.push_back(b); + } + return bc; +} + +void wallet2::import_blockchain(const std::vector<crypto::hash> &bc) +{ + m_blockchain.clear(); + for (auto const &b : bc) + { + m_blockchain.push_back(b); + } + cryptonote::block genesis; + generate_genesis(genesis); + crypto::hash genesis_hash = get_block_hash(genesis); + check_genesis(genesis_hash); + m_local_bc_height = m_blockchain.size(); +} //---------------------------------------------------------------------------------------------------- std::vector<tools::wallet2::transfer_details> wallet2::export_outputs() const { @@ -5747,10 +5807,14 @@ bool wallet2::is_synced() const return get_blockchain_current_height() >= height; } //---------------------------------------------------------------------------------------------------- -uint64_t wallet2::estimate_backlog(uint64_t blob_size, uint64_t fee) +std::vector<std::pair<uint64_t, uint64_t>> wallet2::estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size, const std::vector<uint64_t> &fees) { - THROW_WALLET_EXCEPTION_IF(blob_size == 0, error::wallet_internal_error, "Invalid 0 fee"); - THROW_WALLET_EXCEPTION_IF(fee == 0, error::wallet_internal_error, "Invalid 0 fee"); + THROW_WALLET_EXCEPTION_IF(min_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee"); + THROW_WALLET_EXCEPTION_IF(max_blob_size == 0, error::wallet_internal_error, "Invalid 0 fee"); + for (uint64_t fee: fees) + { + THROW_WALLET_EXCEPTION_IF(fee == 0, error::wallet_internal_error, "Invalid 0 fee"); + } // get txpool backlog epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG::request> req = AUTO_VAL_INIT(req); @@ -5776,27 +5840,35 @@ uint64_t wallet2::estimate_backlog(uint64_t blob_size, uint64_t fee) THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_info"); THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_info"); THROW_WALLET_EXCEPTION_IF(resp_t.result.status != CORE_RPC_STATUS_OK, error::get_tx_pool_error); + uint64_t full_reward_zone = resp_t.result.block_size_limit / 2; - double our_fee_byte = fee / (double)blob_size; - uint64_t priority_size = 0; - for (const auto &i: res.result.backlog) + std::vector<std::pair<uint64_t, uint64_t>> blocks; + for (uint64_t fee: fees) { - if (i.blob_size == 0) + double our_fee_byte_min = fee / (double)min_blob_size, our_fee_byte_max = fee / (double)max_blob_size; + uint64_t priority_size_min = 0, priority_size_max = 0; + for (const auto &i: res.result.backlog) { - MWARNING("Got 0 sized blob from txpool, ignored"); - continue; + if (i.blob_size == 0) + { + MWARNING("Got 0 sized blob from txpool, ignored"); + continue; + } + double this_fee_byte = i.fee / (double)i.blob_size; + if (this_fee_byte >= our_fee_byte_min) + priority_size_min += i.blob_size; + if (this_fee_byte >= our_fee_byte_max) + priority_size_max += i.blob_size; } - double this_fee_byte = i.fee / (double)i.blob_size; - if (this_fee_byte < our_fee_byte) - continue; - priority_size += i.blob_size; - } - uint64_t full_reward_zone = resp_t.result.block_size_limit / 2; - uint64_t nblocks = (priority_size + full_reward_zone - 1) / full_reward_zone; - MDEBUG("estimate_backlog: priority_size " << priority_size << " for " << our_fee_byte << " (" << our_fee_byte << " piconero fee/byte), " - << nblocks << " blocks at block size " << full_reward_zone); - return nblocks; + uint64_t nblocks_min = (priority_size_min + full_reward_zone - 1) / full_reward_zone; + uint64_t nblocks_max = (priority_size_max + full_reward_zone - 1) / full_reward_zone; + MDEBUG("estimate_backlog: priority_size " << priority_size_min << " - " << priority_size_max << " for " << fee + << " (" << our_fee_byte_min << " - " << our_fee_byte_max << " piconero byte fee), " + << nblocks_min << " - " << nblocks_max << " blocks at block size " << full_reward_zone); + blocks.push_back(std::make_pair(nblocks_min, nblocks_max)); + } + return blocks; } //---------------------------------------------------------------------------------------------------- void wallet2::generate_genesis(cryptonote::block& b) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index f30c97635..adf03abcc 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -582,12 +582,17 @@ namespace tools std::string sign(const std::string &data) const; bool verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const; + // Import/Export wallet data std::vector<tools::wallet2::transfer_details> export_outputs() const; size_t import_outputs(const std::vector<tools::wallet2::transfer_details> &outputs); - + payment_container export_payments() const; + void import_payments(const payment_container &payments); + void import_payments_out(const std::list<std::pair<crypto::hash,wallet2::confirmed_transfer_details>> &confirmed_payments); + std::vector<crypto::hash> export_blockchain() const; + void import_blockchain(const std::vector<crypto::hash> &bc); bool export_key_images(const std::string filename); std::vector<std::pair<crypto::key_image, crypto::signature>> export_key_images() const; - uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent); + uint64_t import_key_images(const std::vector<std::pair<crypto::key_image, crypto::signature>> &signed_key_images, uint64_t &spent, uint64_t &unspent, bool check_spent = true); uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent); void update_pool_state(bool refreshed = false); @@ -604,7 +609,10 @@ namespace tools bool is_synced() const; - uint64_t estimate_backlog(uint64_t blob_size, uint64_t fee); + std::vector<std::pair<uint64_t, uint64_t>> estimate_backlog(uint64_t min_blob_size, uint64_t max_blob_size, const std::vector<uint64_t> &fees); + + uint64_t get_fee_multiplier(uint32_t priority, int fee_algorithm = -1); + uint64_t get_per_kb_fee(); private: /*! @@ -646,9 +654,7 @@ namespace tools void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const; uint64_t get_upper_transaction_size_limit(); std::vector<uint64_t> get_unspent_amounts_vector(); - uint64_t get_fee_multiplier(uint32_t priority, int fee_algorithm) const; uint64_t get_dynamic_per_kb_fee_estimate(); - uint64_t get_per_kb_fee(); float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const; std::vector<size_t> pick_preferred_rct_inputs(uint64_t needed_money) const; void set_spent(size_t idx, uint64_t height); diff --git a/tests/core_proxy/CMakeLists.txt b/tests/core_proxy/CMakeLists.txt index 680e34911..d22fecc9c 100644 --- a/tests/core_proxy/CMakeLists.txt +++ b/tests/core_proxy/CMakeLists.txt @@ -39,8 +39,6 @@ target_link_libraries(core_proxy PRIVATE cryptonote_core cryptonote_protocol - common - blockchain_db p2p epee ${CMAKE_THREAD_LIBS_INIT} diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h index c4fb462e3..85518612a 100644 --- a/tests/core_proxy/core_proxy.h +++ b/tests/core_proxy/core_proxy.h @@ -100,5 +100,6 @@ namespace tests uint8_t get_ideal_hard_fork_version(uint64_t height) const { return 0; } uint8_t get_hard_fork_version(uint64_t height) const { return 0; } cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; } + bool fluffy_blocks_enabled() const { return false; } }; } diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt index cb77f8f56..853d46a12 100644 --- a/tests/fuzz/CMakeLists.txt +++ b/tests/fuzz/CMakeLists.txt @@ -30,8 +30,6 @@ add_executable(block_fuzz_tests block.cpp fuzzer.cpp) target_link_libraries(block_fuzz_tests PRIVATE cryptonote_core - common - blockchain_db p2p epee ${CMAKE_THREAD_LIBS_INIT} @@ -44,8 +42,6 @@ add_executable(transaction_fuzz_tests transaction.cpp fuzzer.cpp) target_link_libraries(transaction_fuzz_tests PRIVATE cryptonote_core - common - blockchain_db p2p epee ${CMAKE_THREAD_LIBS_INIT} @@ -59,8 +55,6 @@ target_link_libraries(signature_fuzz_tests PRIVATE wallet cryptonote_core - common - blockchain_db p2p epee ${CMAKE_THREAD_LIBS_INIT} @@ -74,8 +68,6 @@ target_link_libraries(cold-outputs_fuzz_tests PRIVATE wallet cryptonote_core - common - blockchain_db p2p epee ${CMAKE_THREAD_LIBS_INIT} @@ -89,8 +81,6 @@ target_link_libraries(cold-transaction_fuzz_tests PRIVATE wallet cryptonote_core - common - blockchain_db p2p epee ${CMAKE_THREAD_LIBS_INIT} diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp index bcffc85c9..82ff058b1 100644 --- a/tests/unit_tests/ban.cpp +++ b/tests/unit_tests/ban.cpp @@ -77,6 +77,7 @@ public: uint8_t get_ideal_hard_fork_version(uint64_t height) const { return 0; } uint8_t get_hard_fork_version(uint64_t height) const { return 0; } cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; } + bool fluffy_blocks_enabled() const { return false; } }; typedef nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<test_core>> Server; |