Forráskód Böngészése

Merge pull request #107161 from akien-mga/miniupnpc-2.3.3

miniupnpc: Update to 2.3.3
Rémi Verschelde 1 hónapja
szülő
commit
69b9c06fc4

+ 1 - 1
COPYRIGHT.txt

@@ -416,7 +416,7 @@ License: CC0-1.0
 
 Files: thirdparty/miniupnpc/*
 Comment: MiniUPnP Project
-Copyright: 2005-2024, Thomas Bernard
+Copyright: 2005-2025, Thomas Bernard
 License: BSD-3-clause
 
 Files: thirdparty/minizip/*

+ 1 - 1
thirdparty/README.md

@@ -717,7 +717,7 @@ Patches:
 ## miniupnpc
 
 - Upstream: https://github.com/miniupnp/miniupnp
-- Version: 2.2.8 (b55145ec095652289a59c33603f3abafee898273, 2024)
+- Version: 2.3.3 (bf4215a7574f88aa55859db9db00e3ae58cf42d6, 2025)
 - License: BSD-3-Clause
 
 Files extracted from upstream source:

+ 1 - 1
thirdparty/miniupnpc/LICENSE

@@ -1,6 +1,6 @@
 BSD 3-Clause License
 
-Copyright (c) 2005-2024, Thomas BERNARD
+Copyright (c) 2005-2025, Thomas BERNARD
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without

+ 38 - 12
thirdparty/miniupnpc/include/miniupnpc/igd_desc_parse.h

@@ -1,46 +1,72 @@
-/* $Id: igd_desc_parse.h,v 1.12 2014/11/17 17:19:13 nanard Exp $ */
+/* $Id: igd_desc_parse.h,v 1.14 2025/02/08 23:15:16 nanard Exp $ */
 /* Project : miniupnp
- * http://miniupnp.free.fr/
+ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author : Thomas Bernard
- * Copyright (c) 2005-2014 Thomas Bernard
+ * Copyright (c) 2005-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  * */
 #ifndef IGD_DESC_PARSE_H_INCLUDED
 #define IGD_DESC_PARSE_H_INCLUDED
 
-/* Structure to store the result of the parsing of UPnP
- * descriptions of Internet Gateway Devices */
+/*! \file igd_desc_parse.h
+ * \brief API to parse UPNP device description XML
+ * \todo should not be exposed in the public API
+ */
+
+/*! \brief maximum lenght of URLs */
 #define MINIUPNPC_URL_MAXSIZE (128)
+
+/*! \brief Structure to store the result of the parsing of UPnP
+ * descriptions of Internet Gateway Devices services */
 struct IGDdatas_service {
+	/*! \brief controlURL for the service */
 	char controlurl[MINIUPNPC_URL_MAXSIZE];
+	/*! \brief eventSubURL for the service */
 	char eventsuburl[MINIUPNPC_URL_MAXSIZE];
+	/*! \brief SCPDURL for the service */
 	char scpdurl[MINIUPNPC_URL_MAXSIZE];
+	/*! \brief serviceType */
 	char servicetype[MINIUPNPC_URL_MAXSIZE];
 	/*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
 };
 
+/*! \brief Structure to store the result of the parsing of UPnP
+ * descriptions of Internet Gateway Devices */
 struct IGDdatas {
+	/*! \brief current element name */
 	char cureltname[MINIUPNPC_URL_MAXSIZE];
+	/*! \brief URLBase */
 	char urlbase[MINIUPNPC_URL_MAXSIZE];
+	/*! \brief presentationURL */
 	char presentationurl[MINIUPNPC_URL_MAXSIZE];
+	/*! \brief depth into the XML tree */
 	int level;
-	/*int state;*/
-	/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
+	/*! \brief "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
 	struct IGDdatas_service CIF;
-	/* "urn:schemas-upnp-org:service:WANIPConnection:1"
-	 * "urn:schemas-upnp-org:service:WANPPPConnection:1" */
+	/*! \brief first of "urn:schemas-upnp-org:service:WANIPConnection:1"
+	 * or "urn:schemas-upnp-org:service:WANPPPConnection:1" */
 	struct IGDdatas_service first;
-	/* if both WANIPConnection and WANPPPConnection are present */
+	/*! \brief second of "urn:schemas-upnp-org:service:WANIPConnection:1"
+	 * or "urn:schemas-upnp-org:service:WANPPPConnection:1" */
 	struct IGDdatas_service second;
-	/* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
+	/*! \brief "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
 	struct IGDdatas_service IPv6FC;
-	/* tmp */
+	/*! \brief currently parsed service */
 	struct IGDdatas_service tmp;
 };
 
+/*!
+ * \brief XML start element handler
+ */
 void IGDstartelt(void *, const char *, int);
+/*!
+ * \brief XML end element handler
+ */
 void IGDendelt(void *, const char *, int);
+/*!
+ * \brief XML characted data handler
+ */
 void IGDdata(void *, const char *, int);
 #ifdef DEBUG
 void printIGD(struct IGDdatas *);

+ 204 - 55
thirdparty/miniupnpc/include/miniupnpc/miniupnpc.h

@@ -1,32 +1,54 @@
-/* $Id: miniupnpc.h,v 1.66 2024/06/08 22:13:14 nanard Exp $ */
+/* $Id: miniupnpc.h,v 1.80 2025/05/26 22:56:40 nanard Exp $ */
 /* vim: tabstop=4 shiftwidth=4 noexpandtab
  * Project: miniupnp
  * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author: Thomas Bernard
- * Copyright (c) 2005-2024 Thomas Bernard
+ * Copyright (c) 2005-2025 Thomas Bernard
  * This software is subjects to the conditions detailed
  * in the LICENCE file provided within this distribution */
 #ifndef MINIUPNPC_H_INCLUDED
 #define MINIUPNPC_H_INCLUDED
 
+/*! \file miniupnpc.h
+ * \brief Main C API for MiniUPnPc
+ *
+ * Contains functions to discover devices and check for device validity
+ * or connectivity.
+ *
+ * \mainpage MiniUPnPc API documentation
+ * MiniUPnPc (MiniUPnP client) is a library implementing a UPnP
+ * Internet Gateway Device (IGD) control point.
+ *
+ * It should be used by applications that need to listen to incoming
+ * traffic from the internet which are running on a LAN where a
+ * UPnP IGD is running on the router (or gateway).
+ *
+ * See more documentation on the website http://miniupnp.free.fr
+ * or https://miniupnp.tuxfamily.org/ or GitHub :
+ * https://github.com/miniupnp/miniupnp/tree/master/miniupnpc
+ */
 #include "miniupnpc_declspec.h"
 #include "igd_desc_parse.h"
 #include "upnpdev.h"
 
 /* error codes : */
+/*! \brief value for success */
 #define UPNPDISCOVER_SUCCESS (0)
+/*! \brief value for unknown error */
 #define UPNPDISCOVER_UNKNOWN_ERROR (-1)
+/*! \brief value for a socket error */
 #define UPNPDISCOVER_SOCKET_ERROR (-101)
+/*! \brief value for a memory allocation error */
 #define UPNPDISCOVER_MEMORY_ERROR (-102)
 
-/* versions : */
-#define MINIUPNPC_VERSION	"2.2.8"
-#define MINIUPNPC_API_VERSION	18
+/*! \brief software version */
+#define MINIUPNPC_VERSION	"2.3.3"
+/*! \brief C API version */
+#define MINIUPNPC_API_VERSION	21
 
-/* Source port:
-   Using "1" as an alias for 1900 for backwards compatibility
-   (presuming one would have used that for the "sameport" parameter) */
+/*! \brief any (ie system chosen) port */
 #define UPNP_LOCAL_PORT_ANY     0
+/*! \brief Use as an alias for 1900 for backwards compatibility */
 #define UPNP_LOCAL_PORT_SAME    1
 
 #ifdef __cplusplus
@@ -34,49 +56,126 @@ extern "C" {
 #endif
 
 /* Structures definitions : */
-struct UPNParg { const char * elt; const char * val; };
 
+/*!
+ * \brief UPnP method argument
+ */
+struct UPNParg {
+	const char * elt;	/*!< \brief UPnP argument name */
+	const char * val;	/*!< \brief UPnP argument value */
+};
+
+/*!
+ * \brief execute a UPnP method (SOAP action)
+ *
+ * \todo error reporting should be improved
+ *
+ * \param[in] url Control URL for the service
+ * \param[in] service service to use
+ * \param[in] action action to call
+ * \param[in] args action arguments
+ * \param[out] bufsize the size of the returned buffer
+ * \return NULL in case of error or the raw XML response
+ */
 char *
-simpleUPnPcommand(int, const char *, const char *,
-                  const char *, struct UPNParg *,
-                  int *);
+simpleUPnPcommand(const char * url, const char * service,
+                  const char * action, const struct UPNParg * args,
+                  int * bufsize);
 
-/* upnpDiscover()
- * discover UPnP devices on the network.
+/*!
+ * \brief Discover UPnP IGD on the network.
+ *
  * The discovered devices are returned as a chained list.
  * It is up to the caller to free the list with freeUPNPDevlist().
- * delay (in millisecond) is the maximum time for waiting any device
- * response.
  * If available, device list will be obtained from MiniSSDPd.
- * Default path for minissdpd socket will be used if minissdpdsock argument
- * is NULL.
- * If multicastif is not NULL, it will be used instead of the default
- * multicast interface for sending SSDP discover packets.
- * If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent
- * from the source port 1900 (same as destination port), if set to
- * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will
- * be attempted as the source port.
- * "searchalltypes" parameter is useful when searching several types,
- * if 0, the discovery will stop with the first type returning results.
- * TTL should default to 2. */
+ *
+ * \param[in] delay (in millisecond) maximum time for waiting any device
+ *            response
+ * \param[in] multicastif If not NULL, used instead of the default
+ *            multicast interface for sending SSDP discover packets
+ * \param[in] minissdpdsock Path to minissdpd socket, default is used if
+ *            NULL
+ * \param[in] localport Source port to send SSDP packets.
+ *            #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
+ *            #UPNP_LOCAL_PORT_ANY to let system assign a source port
+ * \param[in] ipv6 0 for IPv4, 1 of IPv6
+ * \param[in] ttl should default to 2 as advised by UDA 1.1
+ * \param[out] error error code when NULL is returned
+ * \return NULL or a linked list
+ */
 MINIUPNP_LIBSPEC struct UPNPDev *
 upnpDiscover(int delay, const char * multicastif,
              const char * minissdpdsock, int localport,
              int ipv6, unsigned char ttl,
              int * error);
 
+/*!
+ * \brief Discover all UPnP devices on the network
+ *
+ * search for "ssdp:all"
+ * \param[in] delay (in millisecond) maximum time for waiting any device
+ *            response
+ * \param[in] multicastif If not NULL, used instead of the default
+ *            multicast interface for sending SSDP discover packets
+ * \param[in] minissdpdsock Path to minissdpd socket, default is used if
+ *            NULL
+ * \param[in] localport Source port to send SSDP packets.
+ *            #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
+ *            #UPNP_LOCAL_PORT_ANY to let system assign a source port
+ * \param[in] ipv6 0 for IPv4, 1 of IPv6
+ * \param[in] ttl should default to 2 as advised by UDA 1.1
+ * \param[out] error error code when NULL is returned
+ * \return NULL or a linked list
+ */
 MINIUPNP_LIBSPEC struct UPNPDev *
 upnpDiscoverAll(int delay, const char * multicastif,
                 const char * minissdpdsock, int localport,
                 int ipv6, unsigned char ttl,
                 int * error);
 
+/*!
+ * \brief Discover one type of UPnP devices
+ *
+ * \param[in] device device type to search
+ * \param[in] delay (in millisecond) maximum time for waiting any device
+ *            response
+ * \param[in] multicastif If not NULL, used instead of the default
+ *            multicast interface for sending SSDP discover packets
+ * \param[in] minissdpdsock Path to minissdpd socket, default is used if
+ *            NULL
+ * \param[in] localport Source port to send SSDP packets.
+ *            #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
+ *            #UPNP_LOCAL_PORT_ANY to let system assign a source port
+ * \param[in] ipv6 0 for IPv4, 1 of IPv6
+ * \param[in] ttl should default to 2 as advised by UDA 1.1
+ * \param[out] error error code when NULL is returned
+ * \return NULL or a linked list
+ */
 MINIUPNP_LIBSPEC struct UPNPDev *
 upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
                 const char * minissdpdsock, int localport,
                 int ipv6, unsigned char ttl,
                 int * error);
 
+/*!
+ * \brief Discover one or several type of UPnP devices
+ *
+ * \param[in] deviceTypes array of device types to search (ending with NULL)
+ * \param[in] delay (in millisecond) maximum time for waiting any device
+ *            response
+ * \param[in] multicastif If not NULL, used instead of the default
+ *            multicast interface for sending SSDP discover packets
+ * \param[in] minissdpdsock Path to minissdpd socket, default is used if
+ *            NULL
+ * \param[in] localport Source port to send SSDP packets.
+ *            #UPNP_LOCAL_PORT_SAME for 1900 (same as destination port)
+ *            #UPNP_LOCAL_PORT_ANY to let system assign a source port
+ * \param[in] ipv6 0 for IPv4, 1 of IPv6
+ * \param[in] ttl should default to 2 as advised by UDA 1.1
+ * \param[out] error error code when NULL is returned
+ * \param[in] searchalltypes 0 to stop with the first type returning results
+ * \return NULL or a linked list
+ */
 MINIUPNP_LIBSPEC struct UPNPDev *
 upnpDiscoverDevices(const char * const deviceTypes[],
                     int delay, const char * multicastif,
@@ -85,38 +184,60 @@ upnpDiscoverDevices(const char * const deviceTypes[],
                     int * error,
                     int searchalltypes);
 
-/* parserootdesc() :
- * parse root XML description of a UPnP device and fill the IGDdatas
- * structure. */
-MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
+/*!
+ * \brief parse root XML description of a UPnP device
+ *
+ * fill the IGDdatas structure.
+ * \param[in] buffer character buffer containing the XML description
+ * \param[in] bufsize size in bytes of the buffer
+ * \param[out] data IGDdatas structure to fill
+ */
+MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data);
 
-/* structure used to get fast access to urls
- * controlURL: controlURL of the WANIPConnection
- * ipcondescURL: url of the description of the WANIPConnection
- * controlURL_CIF: controlURL of the WANCommonInterfaceConfig
- * controlURL_6FC: controlURL of the WANIPv6FirewallControl
+/*!
+ * \brief structure used to get fast access to urls
  */
 struct UPNPUrls {
+	/*! \brief controlURL of the WANIPConnection */
 	char * controlURL;
+	/*! \brief url of the description of the WANIPConnection */
 	char * ipcondescURL;
+	/*! \brief controlURL of the WANCommonInterfaceConfig */
 	char * controlURL_CIF;
+	/*! \brief controlURL of the WANIPv6FirewallControl */
 	char * controlURL_6FC;
+	/*! \brief url of the root description */
 	char * rootdescURL;
 };
 
-/* UPNP_GetValidIGD() :
- * return values :
- *     0 = NO IGD found
- *     1 = A valid connected IGD has been found
- *     2 = A valid connected IGD has been found but its
- *         IP address is reserved (non routable)
- *     3 = A valid IGD has been found but it reported as
- *         not connected
- *     4 = an UPnP device has been found but was not recognized as an IGD
+/*! \brief NO IGD found */
+#define UPNP_NO_IGD (0)
+/*! \brief valid and connected IGD */
+#define UPNP_CONNECTED_IGD (1)
+/*! \brief valid and connected IGD but with a reserved address
+ * (non routable) */
+#define UPNP_PRIVATEIP_IGD (2)
+/*! \brief valid but not connected IGD */
+#define UPNP_DISCONNECTED_IGD (3)
+/*! \brief UPnP device not recognized as an IGD */
+#define UPNP_UNKNOWN_DEVICE (4)
+
+/*!
+ * \brief look for a valid and possibly connected IGD in the list
  *
  * In any non zero return case, the urls and data structures
  * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
  * free allocated memory.
+ * \param[in] devlist A device list obtained with upnpDiscover() /
+ *            upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices()
+ * \param[out] urls Urls for the IGD found
+ * \param[out] data datas for the IGD found
+ * \param[out] lanaddr buffer to copy the local address of the host to reach the IGD
+ * \param[in] lanaddrlen size of the lanaddr buffer
+ * \param[out] wanaddr buffer to copy the public address of the IGD
+ * \param[in] wanaddrlen size of the wanaddr buffer
+ * \return #UPNP_NO_IGD / #UPNP_CONNECTED_IGD / #UPNP_PRIVATEIP_IGD /
+ *         #UPNP_DISCONNECTED_IGD / #UPNP_UNKNOWN_DEVICE
  */
 MINIUPNP_LIBSPEC int
 UPNP_GetValidIGD(struct UPNPDev * devlist,
@@ -125,27 +246,55 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
                  char * lanaddr, int lanaddrlen,
                  char * wanaddr, int wanaddrlen);
 
-/* UPNP_GetIGDFromUrl()
+/*!
+ * \brief Get IGD URLs and data for URL
+ *
  * Used when skipping the discovery process.
- * When succeding, urls, data, and lanaddr arguments are set.
- * return value :
- *   0 - Not ok
- *   1 - OK */
+ * \param[in] rootdescurl Root description URL of the device
+ * \param[out] urls Urls for the IGD found
+ * \param[out] data datas for the IGD found
+ * \param[out] lanaddr buffer to copy the local address of the host to reach the IGD
+ * \param[in] lanaddrlen size of the lanaddr buffer
+ * \return 0 Not ok / 1 OK
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetIGDFromUrl(const char * rootdescurl,
                    struct UPNPUrls * urls,
                    struct IGDdatas * data,
                    char * lanaddr, int lanaddrlen);
 
+/*!
+ * \brief Prepare the URLs for usage
+ *
+ * build absolute URLs from the root description
+ * \param[out] urls URL structure to initialize
+ * \param[in] data datas for the IGD
+ * \param[in] descURL root description URL for the IGD
+ * \param[in] scope_id if not 0, add the scope to the linklocal IPv6
+ *            addresses in URLs
+ */
 MINIUPNP_LIBSPEC void
-GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
-            const char *, unsigned int);
+GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
+            const char * descURL, unsigned int scope_id);
 
+/*!
+ * \brief free the members of a UPNPUrls struct
+ *
+ * All URLs buffers are freed and zeroed
+ * \param[out] urls URL structure to free
+ */
 MINIUPNP_LIBSPEC void
-FreeUPNPUrls(struct UPNPUrls *);
+FreeUPNPUrls(struct UPNPUrls * urls);
 
-/* return 0 or 1 */
-MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
+/*!
+ * \brief check the current connection status of an IGD
+ *
+ * it uses UPNP_GetStatusInfo()
+ * \param[in] urls IGD URLs
+ * \param[in] data IGD data
+ * \return 1 Connected / 0 Disconnected
+ */
+MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data);
 
 
 #ifdef __cplusplus

+ 2 - 1
thirdparty/miniupnpc/include/miniupnpc/miniupnpc_declspec.h

@@ -1,6 +1,8 @@
 #ifndef MINIUPNPC_DECLSPEC_H_INCLUDED
 #define MINIUPNPC_DECLSPEC_H_INCLUDED
 
+/*! \file miniupnpc_declspec.h
+ * \brief define #MINIUPNP_LIBSPEC for dll exports and imports */
 #if defined(_WIN32) && !defined(MINIUPNP_STATICLIB)
 	/* for windows dll */
 	#ifdef MINIUPNP_EXPORTS
@@ -18,4 +20,3 @@
 #endif
 
 #endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */
-

+ 15 - 9
thirdparty/miniupnpc/include/miniupnpc/miniupnpctypes.h

@@ -1,21 +1,27 @@
-/* $Id: miniupnpctypes.h,v 1.1 2011/02/15 11:10:40 nanard Exp $ */
-/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org
- * Author : Thomas Bernard
- * Copyright (c) 2021 Thomas Bernard
+/* $Id: miniupnpctypes.h,v 1.4 2025/02/08 23:15:16 nanard Exp $ */
+/* Project: miniupnp
+ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org
+ * Author: Thomas Bernard
+ * Copyright (c) 2021-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided within this distribution */
 #ifndef MINIUPNPCTYPES_H_INCLUDED
 #define MINIUPNPCTYPES_H_INCLUDED
 
-/* Use unsigned long long when available :
- * strtoull is C99 */
+/*! \file miniupnpctypes.h
+ * \brief type definitions
+ *
+ * Use unsigned long long when available :
+ * strtoull is C99
+ *
+ * \def UNSIGNED_INTEGER
+ * \brief `unsigned long long` or `unsigned int`
+ * \todo int can be 16 bits, so it should be `unsigned long`
+ */
 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 #define UNSIGNED_INTEGER unsigned long long
-#define STRTOUI	strtoull
 #else
 #define UNSIGNED_INTEGER unsigned int
-#define STRTOUI	strtoul
 #endif
 
 #endif
-

+ 33 - 6
thirdparty/miniupnpc/include/miniupnpc/miniwget.h

@@ -1,24 +1,51 @@
-/* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */
+/* $Id: miniwget.h,v 1.14 2025/02/08 23:15:17 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas Bernard
- * Copyright (c) 2005-2016 Thomas Bernard
+ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
+ * Copyright (c) 2005-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  * */
 #ifndef MINIWGET_H_INCLUDED
 #define MINIWGET_H_INCLUDED
 
+/*! \file miniwget.h
+ * \brief Lightweight HTTP client API
+ */
 #include "miniupnpc_declspec.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *);
+/*! \brief perform HTTP GET on an URL
+ *
+ * \param[in] url HTTP URL to GET
+ * \param[out] size length of the returned buffer. -1 in case of memory
+ *             allocation error
+ * \param[in] scope_id interface id for IPv6 to use if not specified in the URL
+ * \param[out] status_code HTTP response status code (200, 404, etc.)
+ * \return the body of the HTTP response
+ */
+MINIUPNP_LIBSPEC void * miniwget(const char * url, int * size,
+                                 unsigned int scope_id, int * status_code);
 
-MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *);
-
-int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);
+/*! \brief perform HTTP GET on an URL
+ *
+ * Also get the local address used to reach the HTTP server
+ *
+ * \param[in] url HTTP URL to GET
+ * \param[out] size length of the returned buffer. -1 in case of memory
+ *             allocation error
+ * \param[out] addr local address used to connect to the server
+ * \param[in] addrlen size of the addr buffer
+ * \param[in] scope_id interface id for IPv6 to use if not specified in the URL
+ * \param[out] status_code HTTP response status code (200, 404, etc.)
+ * \return the body of the HTTP response
+ */
+MINIUPNP_LIBSPEC void * miniwget_getaddr(const char * url, int * size,
+                                         char * addr, int addrlen,
+                                         unsigned int scope_id, int * status_code);
 
 #ifdef __cplusplus
 }

+ 50 - 24
thirdparty/miniupnpc/include/miniupnpc/portlistingparse.h

@@ -1,12 +1,29 @@
-/* $Id: portlistingparse.h,v 1.10 2014/11/01 10:37:32 nanard Exp $ */
+/* $Id: portlistingparse.h,v 1.12 2025/02/08 23:15:17 nanard Exp $ */
 /* MiniUPnP project
  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2011-2015 Thomas Bernard
+ * (c) 2011-2025 Thomas Bernard
  * This software is subject to the conditions detailed
  * in the LICENCE file provided within the distribution */
 #ifndef PORTLISTINGPARSE_H_INCLUDED
 #define PORTLISTINGPARSE_H_INCLUDED
 
+/*! \file portlistingparse.h
+ * \brief Parsing of the list of port mappings
+ *
+ * As returned by GetListOfPortMappings.
+ * Sample of PortMappingEntry :
+ *
+ *     <p:PortMappingEntry>
+ *       <p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>
+ *       <p:NewExternalPort>2345</p:NewExternalPort>
+ *       <p:NewProtocol>TCP</p:NewProtocol>
+ *       <p:NewInternalPort>2345</p:NewInternalPort>
+ *       <p:NewInternalClient>192.168.1.137</p:NewInternalClient>
+ *       <p:NewEnabled>1</p:NewEnabled>
+ *       <p:NewDescription>dooom</p:NewDescription>
+ *       <p:NewLeaseTime>345</p:NewLeaseTime>
+ *     </p:PortMappingEntry>
+ */
 #include "miniupnpc_declspec.h"
 /* for the definition of UNSIGNED_INTEGER */
 #include "miniupnpctypes.h"
@@ -15,17 +32,8 @@
 extern "C" {
 #endif
 
-/* sample of PortMappingEntry :
-  <p:PortMappingEntry>
-    <p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>
-    <p:NewExternalPort>2345</p:NewExternalPort>
-    <p:NewProtocol>TCP</p:NewProtocol>
-    <p:NewInternalPort>2345</p:NewInternalPort>
-    <p:NewInternalClient>192.168.1.137</p:NewInternalClient>
-    <p:NewEnabled>1</p:NewEnabled>
-    <p:NewDescription>dooom</p:NewDescription>
-    <p:NewLeaseTime>345</p:NewLeaseTime>
-  </p:PortMappingEntry>
+/*!
+ * \brief enum of all XML elements
  */
 typedef enum { PortMappingEltNone,
        PortMappingEntry, NewRemoteHost,
@@ -34,27 +42,45 @@ typedef enum { PortMappingEltNone,
        NewEnabled, NewDescription,
        NewLeaseTime } portMappingElt;
 
+/*!
+ * \brief linked list of port mappings
+ */
 struct PortMapping {
-	struct PortMapping * l_next;	/* list next element */
-	UNSIGNED_INTEGER leaseTime;
-	unsigned short externalPort;
-	unsigned short internalPort;
-	char remoteHost[64];
-	char internalClient[64];
-	char description[64];
-	char protocol[4];
-	unsigned char enabled;
+	struct PortMapping * l_next;	/*!< \brief next list element */
+	UNSIGNED_INTEGER leaseTime;	/*!< \brief in seconds */
+	unsigned short externalPort;	/*!< \brief external port */
+	unsigned short internalPort;	/*!< \brief internal port */
+	char remoteHost[64];	/*!< \brief empty for wildcard */
+	char internalClient[64];	/*!< \brief internal IP address */
+	char description[64];	/*!< \brief description */
+	char protocol[4];		/*!< \brief `TCP` or `UDP` */
+	unsigned char enabled;	/*!< \brief 0 (false) or 1 (true) */
 };
 
+/*!
+ * \brief structure for ParsePortListing()
+ */
 struct PortMappingParserData {
-	struct PortMapping * l_head;	/* list head */
-	portMappingElt curelt;
+	struct PortMapping * l_head;	/*!< \brief list head */
+	portMappingElt curelt;			/*!< \brief currently parsed element */
 };
 
+/*!
+ * \brief parse the NewPortListing part of GetListOfPortMappings response
+ *
+ * \param[in] buffer XML data
+ * \param[in] bufsize length of XML data
+ * \param[out] pdata Parsed data
+ */
 MINIUPNP_LIBSPEC void
 ParsePortListing(const char * buffer, int bufsize,
                  struct PortMappingParserData * pdata);
 
+/*!
+ * \brief free parsed data structure
+ *
+ * \param[in] pdata Parsed data to free
+ */
 MINIUPNP_LIBSPEC void
 FreePortListing(struct PortMappingParserData * pdata);
 

+ 445 - 148
thirdparty/miniupnpc/include/miniupnpc/upnpcommands.h

@@ -1,21 +1,41 @@
-/* $Id: upnpcommands.h,v 1.32 2018/03/13 23:34:47 nanard Exp $ */
-/* Miniupnp project : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2018 Thomas Bernard
+/* $Id: upnpcommands.h,v 1.36 2025/03/18 23:40:15 nanard Exp $ */
+/* vim: tabstop=4 shiftwidth=4 noexpandtab
+ * Project: miniupnp
+ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
+ * Author: Thomas Bernard
+ * Copyright (c) 2005-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided within this distribution */
 #ifndef UPNPCOMMANDS_H_INCLUDED
 #define UPNPCOMMANDS_H_INCLUDED
 
+/*! \file upnpcommands.h
+ * \brief Internet Gateway Device methods
+ *
+ * See the documentation for both IGD v1 and IGD v2 :
+ * - https://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf
+ * - https://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf
+ *
+ * The methods are from WANIPConnection:1 or 2, WANCommonInterfaceConfig:1,
+ * and WANIPv6FirewallControl:1
+ *
+ */
+
 #include "miniupnpc_declspec.h"
 #include "miniupnpctypes.h"
 
 /* MiniUPnPc return codes : */
+/*! \brief value for success */
 #define UPNPCOMMAND_SUCCESS (0)
+/*! \brief value for unknown error */
 #define UPNPCOMMAND_UNKNOWN_ERROR (-1)
+/*! \brief error while checking the arguments */
 #define UPNPCOMMAND_INVALID_ARGS (-2)
+/*! \brief HTTP communication error */
 #define UPNPCOMMAND_HTTP_ERROR (-3)
+/*! \brief The response contains invalid values */
 #define UPNPCOMMAND_INVALID_RESPONSE (-4)
+/*! \brief Memory allocation error */
 #define UPNPCOMMAND_MEM_ALLOC_ERROR (-5)
 
 #ifdef __cplusplus
@@ -24,27 +44,70 @@ extern "C" {
 
 struct PortMappingParserData;
 
+/*! \brief WANCommonInterfaceConfig:GetTotalBytesSent
+ *
+ * Note: this is a 32bits unsigned value and rolls over to 0 after reaching
+ * the maximum value
+ *
+ * \param[in] controlURL controlURL of the WANCommonInterfaceConfig of
+ *            a WANDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
+ */
 MINIUPNP_LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalBytesSent(const char * controlURL,
 					const char * servicetype);
 
+/*! \brief WANCommonInterfaceConfig:GetTotalBytesReceived
+ *
+ * Note: this is a 32bits unsigned value and rolls over to 0 after reaching
+ * the maximum value
+ *
+ * \param[in] controlURL controlURL of the WANCommonInterfaceConfig of a WANDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
+ */
 MINIUPNP_LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalBytesReceived(const char * controlURL,
 						const char * servicetype);
 
+/*! \brief WANCommonInterfaceConfig:GetTotalPacketsSent
+ *
+ * Note: this is a 32bits unsigned value and rolls over to 0 after reaching
+ * the maximum value
+ *
+ * \param[in] controlURL controlURL of the WANCommonInterfaceConfig of a WANDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
+ */
 MINIUPNP_LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalPacketsSent(const char * controlURL,
 					const char * servicetype);
 
+/*! \brief WANCommonInterfaceConfig:GetTotalBytesReceived
+ *
+ * Note: this is a 32bits unsigned value and rolls over to 0 after reaching
+ * the maximum value
+ *
+ * \param[in] controlURL controlURL of the WANCommonInterfaceConfig of a WANDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
+ */
 MINIUPNP_LIBSPEC UNSIGNED_INTEGER
 UPNP_GetTotalPacketsReceived(const char * controlURL,
 					const char * servicetype);
 
-/* UPNP_GetStatusInfo()
- * status and lastconnerror are 64 byte buffers
- * Return values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error code */
+/*! \brief WANIPConnection:GetStatusInfo()
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[out] status 64 bytes buffer : `Unconfigured`, `Connecting`,
+ *             `Connected`, `PendingDisconnect`, `Disconnecting`, `Disconnected`
+ * \param[out] uptime time in seconds
+ * \param[out] lastconnerror 64 bytes buffer : `ERROR_NONE`,
+ *             `ERROR_COMMAND_ABORTED`, `ERROR_NOT_ENABLED_FOR_INTERNET`,
+ *             `ERROR_USER_DISCONNECT`, `ERROR_ISP_DISCONNECT`,
+ *             `ERROR_IDLE_DISCONNECT`, `ERROR_FORCED_DISCONNECT`,
+ *             `ERROR_NO_CARRIER`, `ERROR_IP_CONFIGURATION`, `ERROR_UNKNOWN`
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP Error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetStatusInfo(const char * controlURL,
 			       const char * servicetype,
@@ -52,76 +115,87 @@ UPNP_GetStatusInfo(const char * controlURL,
 				   unsigned int * uptime,
                    char * lastconnerror);
 
-/* UPNP_GetConnectionTypeInfo()
- * argument connectionType is a 64 character buffer
- * Return Values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error code */
+/*! \brief WANIPConnection:GetConnectionTypeInfo()
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[out] connectionType 64 characters buffer : `Unconfigured`,
+ *             `IP_Routed`, `IP_Bridged`
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP Error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetConnectionTypeInfo(const char * controlURL,
                            const char * servicetype,
 						   char * connectionType);
 
-/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
- * if the third arg is not null the value is copied to it.
- * at least 16 bytes must be available
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR Either an UPnP error code or an unknown error.
+/*! \brief WANIPConnection:GetExternalIPAddress()
  *
  * possible UPnP Errors :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control. */
+ * - 402 Invalid Args - See UPnP Device Architecture section on Control.
+ * - 501 Action Failed - See UPnP Device Architecture section on Control.
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[out] extIpAdd 16 bytes buffer
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_UNKNOWN_ERROR,
+ *         #UPNPCOMMAND_INVALID_ARGS, #UPNPCOMMAND_HTTP_ERROR or an
+ *         UPnP error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetExternalIPAddress(const char * controlURL,
                           const char * servicetype,
                           char * extIpAdd);
 
-/* UPNP_GetLinkLayerMaxBitRates()
- * call WANCommonInterfaceConfig:1#GetCommonLinkProperties
+/*! \brief UPNP_GetLinkLayerMaxBitRates()
+ * call `WANCommonInterfaceConfig:GetCommonLinkProperties`
  *
- * return values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code. */
+ * \param[in] controlURL controlURL of the WANCommonInterfaceConfig of a WANDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
+ * \param[out] bitrateDown bits per second
+ * \param[out] bitrateUp bits per second
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP Error Code.
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
 							const char* servicetype,
 							unsigned int * bitrateDown,
 							unsigned int * bitrateUp);
 
-/* UPNP_AddPortMapping()
- * if desc is NULL, it will be defaulted to "libminiupnpc"
- * remoteHost is usually NULL because IGD don't support it.
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR. Either an UPnP error code or an unknown error.
+/*! \brief WANIPConnection:AddPortMapping()
  *
  * List of possible UPnP errors for AddPortMapping :
- * errorCode errorDescription (short) - Description (long)
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization and
- *                             the sender was not authorized.
- * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
- *                                   wild-carded
- * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
- * 718 ConflictInMappingEntry - The port mapping entry specified conflicts
- *                     with a mapping assigned previously to another client
- * 724 SamePortValuesRequired - Internal and External port values
- *                              must be the same
- * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
- *                  permanent lease times on port mappings
- * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
- *                             and cannot be a specific IP address or DNS name
- * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and
- *                                        cannot be a specific port value
- * 728 NoPortMapsAvailable - There are not enough free ports available to
- *                           complete port mapping.
- * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
- *                                   due to conflict with other mechanisms.
- * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | -----------------
+ * 402 Invalid Args | See UPnP Device Architecture section on Control.
+ * 501 Action Failed | See UPnP Device Architecture section on Control.
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 715 WildCardNotPermittedInSrcIP | The source IP address cannot be wild-carded
+ * 716 WildCardNotPermittedInExtPort | The external port cannot be wild-carded
+ * 718 ConflictInMappingEntry | The port mapping entry specified conflicts with a mapping assigned previously to another client
+ * 724 SamePortValuesRequired | Internal and External port values must be the same
+ * 725 OnlyPermanentLeasesSupported | The NAT implementation only supports permanent lease times on port mappings
+ * 726 RemoteHostOnlySupportsWildcard | RemoteHost must be a wildcard and cannot be a specific IP address or DNS name
+ * 727 ExternalPortOnlySupportsWildcard | ExternalPort must be a wildcard and cannot be a specific port value
+ * 728 NoPortMapsAvailable | There are not enough free ports available to complete port mapping.
+ * 729 ConflictWithOtherMechanisms | Attempted port mapping is not allowed due to conflict with other mechanisms.
+ * 732 WildCardNotPermittedInIntPort | The internal port cannot be wild-carded
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[in] extPort External port
+ * \param[in] inPort Internal port
+ * \param[in] inClient IP of Internal client.
+ * \param[in] desc Port Mapping description. if NULL, defaults to
+ *            "libminiupnpc"
+ * \param[in] proto `TCP` or `UDP`
+ * \param[in] remoteHost IP or empty string for wildcard. Most IGD don't
+ *            support it
+ * \param[in] leaseDuration between 0 and 604800
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_MEM_ALLOC_ERROR, #UPNPCOMMAND_HTTP_ERROR,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP error code.
  */
 MINIUPNP_LIBSPEC int
 UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
@@ -133,28 +207,38 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
 		    const char * remoteHost,
 		    const char * leaseDuration);
 
-/* UPNP_AddAnyPortMapping()
- * if desc is NULL, it will be defaulted to "libminiupnpc"
- * remoteHost is usually NULL because IGD don't support it.
+/*! \brief WANIPConnection:AddAnyPortMapping()
  *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR. Either an UPnP error code or an unknown error.
+ * Only in WANIPConnection:2
  *
  * List of possible UPnP errors for AddPortMapping :
- * errorCode errorDescription (short) - Description (long)
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization and
- *                             the sender was not authorized.
- * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
- *                                   wild-carded
- * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
- * 728 NoPortMapsAvailable - There are not enough free ports available to
- *                           complete port mapping.
- * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
- *                                   due to conflict with other mechanisms.
- * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 402 Invalid Args | See UPnP Device Architecture section on Control.
+ * 501 Action Failed | See UPnP Device Architecture section on Control.
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 715 WildCardNotPermittedInSrcIP | The source IP address cannot be wild-carded
+ * 716 WildCardNotPermittedInExtPort | The external port cannot be wild-carded
+ * 728 NoPortMapsAvailable | There are not enough free ports available to complete port mapping.
+ * 729 ConflictWithOtherMechanisms | Attempted port mapping is not allowed due to conflict with other mechanisms.
+ * 732 WildCardNotPermittedInIntPort | The internal port cannot be wild-carded
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:2
+ * \param[in] extPort External port
+ * \param[in] inPort Internal port
+ * \param[in] inClient IP of Internal client.
+ * \param[in] desc Port Mapping description. if NULL, defaults to
+ *            "libminiupnpc"
+ * \param[in] proto `TCP` or `UDP`
+ * \param[in] remoteHost IP or empty string for wildcard. Most IGD don't
+ *            support it
+ * \param[in] leaseDuration between 0 and 604800
+ * \param[out] reservedPort 6 bytes buffer
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_MEM_ALLOC_ERROR, #UPNPCOMMAND_HTTP_ERROR,
+ *         #UPNPCOMMAND_INVALID_RESPONSE, #UPNPCOMMAND_UNKNOWN_ERROR
+ *         or a UPnP error code.
  */
 MINIUPNP_LIBSPEC int
 UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
@@ -167,24 +251,35 @@ UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
 		       const char * leaseDuration,
 		       char * reservedPort);
 
-/* UPNP_DeletePortMapping()
- * Use same argument values as what was used for AddPortMapping().
- * remoteHost is usually NULL because IGD don't support it.
- * Return Values :
- * 0 : SUCCESS
- * NON ZERO : error. Either an UPnP error code or an undefined error.
+/*! \brief WANIPConnection:DeletePortMapping()
  *
- * List of possible UPnP errors for DeletePortMapping :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 714 NoSuchEntryInArray - The specified value does not exist in the array */
+ * Use same argument values as what was used for UPNP_AddPortMapping()
+ *
+ * List of possible UPnP errors for UPNP_DeletePortMapping() :
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 402 Invalid Args | See UPnP Device Architecture section on Control.
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 714 NoSuchEntryInArray | The specified value does not exist in the array
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[in] extPort External port
+ * \param[in] proto `TCP` or `UDP`
+ * \param[in] remoteHost IP or empty string for wildcard. Most IGD don't
+ *            support it
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_MEM_ALLOC_ERROR, #UPNPCOMMAND_HTTP_ERROR,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP error code.
+ */
 MINIUPNP_LIBSPEC int
 UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
 		       const char * extPort, const char * proto,
 		       const char * remoteHost);
 
-/* UPNP_DeletePortRangeMapping()
+/*! \brief WANIPConnection:DeletePortRangeMapping()
+ *
+ * Only in WANIPConnection:2
  * Use same argument values as what was used for AddPortMapping().
  * remoteHost is usually NULL because IGD don't support it.
  * Return Values :
@@ -192,46 +287,66 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
  * NON ZERO : error. Either an UPnP error code or an undefined error.
  *
  * List of possible UPnP errors for DeletePortMapping :
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 730 PortMappingNotFound - This error message is returned if no port
- *			     mapping is found in the specified range.
- * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 730 PortMappingNotFound | This error message is returned if no port mapping is found in the specified range.
+ * 733 InconsistentParameters | NewStartPort and NewEndPort values are not consistent.
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:2
+ * \param[in] extPortStart External port range start
+ * \param[in] extPortEnd External port range end
+ * \param[in] proto `TCP` or `UDP`
+ * \param[in] manage `0` to remove only the port mappings of this IGD,
+ *            `1` to remove port mappings also for other clients
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_MEM_ALLOC_ERROR, #UPNPCOMMAND_HTTP_ERROR,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP error code.
+ */
 MINIUPNP_LIBSPEC int
 UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
         		    const char * extPortStart, const char * extPortEnd,
         		    const char * proto,
         		    const char * manage);
 
-/* UPNP_GetPortMappingNumberOfEntries()
- * not supported by all routers */
+/*! \brief WANIPConnection:GetPortMappingNumberOfEntries()
+ *
+ * not supported by all routers
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[out] numEntries Port mappings count
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_HTTP_ERROR,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP error code.
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
                                    const char * servicetype,
                                    unsigned int * numEntries);
 
-/* UPNP_GetSpecificPortMappingEntry()
- *    retrieves an existing port mapping
- * params :
- *  in   extPort
- *  in   proto
- *  in   remoteHost
- *  out  intClient (16 bytes)
- *  out  intPort (6 bytes)
- *  out  desc (80 bytes)
- *  out  enabled (4 bytes)
- *  out  leaseDuration (16 bytes)
- *
- * return value :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code.
- *
- * List of possible UPnP errors for _GetSpecificPortMappingEntry :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 714 NoSuchEntryInArray - The specified value does not exist in the array.
+/*! \brief retrieves an existing port mapping for a port:protocol
+ *
+ * List of possible UPnP errors for UPNP_GetSpecificPortMappingEntry() :
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 402 Invalid Args | See UPnP Device Architecture section on Control.
+ * 501 Action Failed | See UPnP Device Architecture section on Control.
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 714 NoSuchEntryInArray | The specified value does not exist in the array.
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[in] extPort External port
+ * \param[in] proto `TCP` or `UDP`
+ * \param[in] remoteHost IP or empty string for wildcard. Most IGD don't
+ *            support it
+ * \param[out] intClient 16 bytes buffer
+ * \param[out] intPort 6 bytes buffer
+ * \param[out] desc 80 bytes buffer
+ * \param[out] enabled 4 bytes buffer
+ * \param[out] leaseDuration 16 bytes
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP Error Code.
  */
 MINIUPNP_LIBSPEC int
 UPNP_GetSpecificPortMappingEntry(const char * controlURL,
@@ -245,27 +360,65 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
                                  char * enabled,
                                  char * leaseDuration);
 
-/* UPNP_GetGenericPortMappingEntry()
- * params :
- *  in   index
- *  out  extPort (6 bytes)
- *  out  intClient (16 bytes)
- *  out  intPort (6 bytes)
- *  out  protocol (4 bytes)
- *  out  desc (80 bytes)
- *  out  enabled (4 bytes)
- *  out  rHost (64 bytes)
- *  out  duration (16 bytes)
- *
- * return value :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code.
- *
- * Possible UPNP Error codes :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds
+/*! \brief retrieves an existing port mapping for a port:protocol
+ *
+ * List of possible UPnP errors for UPNP_GetSpecificPortMappingEntry() :
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 402 Invalid Args | See UPnP Device Architecture section on Control.
+ * 501 Action Failed | See UPnP Device Architecture section on Control.
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 714 NoSuchEntryInArray | The specified value does not exist in the array.
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[in] extPort External port
+ * \param[in] proto `TCP` or `UDP`
+ * \param[in] remoteHost IP or empty string for wildcard. Most IGD don't
+ *            support it
+ * \param[out] intClient 16 bytes buffer
+ * \param[out] intPort 6 bytes buffer
+ * \param[out] desc desclen bytes buffer
+ * \param[in] desclen desc buffer length
+ * \param[out] enabled 4 bytes buffer
+ * \param[out] leaseDuration 16 bytes
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP Error Code.
+ */
+MINIUPNP_LIBSPEC int
+UPNP_GetSpecificPortMappingEntryExt(const char * controlURL,
+                                    const char * servicetype,
+                                    const char * extPort,
+                                    const char * proto,
+                                    const char * remoteHost,
+                                    char * intClient,
+                                    char * intPort,
+                                    char * desc,
+                                    size_t desclen,
+                                    char * enabled,
+                                    char * leaseDuration);
+
+/*! \brief WANIPConnection:GetGenericPortMappingEntry()
+ *
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 402 Invalid Args | See UPnP Device Architecture section on Control.
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 713 SpecifiedArrayIndexInvalid | The specified array index is out of bounds
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[in] index
+ * \param[out] extPort 6 bytes buffer
+ * \param[out] intClient 16 bytes buffer
+ * \param[out] intPort 6 bytes buffer
+ * \param[out] protocol 4 bytes buffer
+ * \param[out] desc 80 bytes buffer
+ * \param[out] enabled 4 bytes buffer
+ * \param[out] rHost 64 bytes buffer
+ * \param[out] duration 16 bytes buffer
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP Error Code.
  */
 MINIUPNP_LIBSPEC int
 UPNP_GetGenericPortMappingEntry(const char * controlURL,
@@ -280,14 +433,64 @@ UPNP_GetGenericPortMappingEntry(const char * controlURL,
 								char * rHost,
 								char * duration);
 
-/* UPNP_GetListOfPortMappings()      Available in IGD v2
+/*! \brief WANIPConnection:GetGenericPortMappingEntry()
  *
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 402 Invalid Args | See UPnP Device Architecture section on Control.
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 713 SpecifiedArrayIndexInvalid | The specified array index is out of bounds
  *
- * Possible UPNP Error codes :
- * 606 Action not Authorized
- * 730 PortMappingNotFound - no port mapping is found in the specified range.
- * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
- *                              consistent.
+ * \param[in] controlURL controlURL of the WANIPConnection of a WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:1
+ * \param[in] index
+ * \param[out] extPort 6 bytes buffer
+ * \param[out] intClient 16 bytes buffer
+ * \param[out] intPort 6 bytes buffer
+ * \param[out] protocol 4 bytes buffer
+ * \param[out] desc desclen bytes buffer
+ * \param[in] desclen desc buffer length
+ * \param[out] enabled 4 bytes buffer
+ * \param[out] rHost desclen bytes buffer
+ * \param[in] rHostlen rHost buffer length
+ * \param[out] duration 16 bytes buffer
+ * \return #UPNPCOMMAND_SUCCESS, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_UNKNOWN_ERROR or a UPnP Error Code.
+ */
+MINIUPNP_LIBSPEC int
+UPNP_GetGenericPortMappingEntryExt(const char * controlURL,
+                                   const char * servicetype,
+                                   const char * index,
+                                   char * extPort,
+                                   char * intClient,
+                                   char * intPort,
+                                   char * protocol,
+                                   char * desc,
+                                   size_t desclen,
+                                   char * enabled,
+                                   char * rHost,
+                                   size_t rHostlen,
+                                   char * duration);
+
+/*! \brief  retrieval of a list of existing port mappings
+ *
+ * Available in IGD v2 : WANIPConnection:GetListOfPortMappings()
+ *
+ * errorCode errorDescription (short) | Description (long)
+ * ---------------------------------- | ------------------
+ * 606 Action not authorized | The action requested REQUIRES authorization and the sender was not authorized.
+ * 730 PortMappingNotFound | no port mapping is found in the specified range.
+ * 733 InconsistantParameters | NewStartPort and NewEndPort values are not consistent.
+ *
+ * \param[in] controlURL controlURL of the WANIPConnection of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPConnection:2
+ * \param[in] startPort port interval start
+ * \param[in] endPort port interval end
+ * \param[in] protocol `TCP` or `UDP`
+ * \param[in] numberOfPorts size limit of the list returned. `0` to request
+ *            all port mappings
+ * \param[out] data port mappings list
  */
 MINIUPNP_LIBSPEC int
 UPNP_GetListOfPortMappings(const char * controlURL,
@@ -298,15 +501,48 @@ UPNP_GetListOfPortMappings(const char * controlURL,
                            const char * numberOfPorts,
                            struct PortMappingParserData * data);
 
-/* IGD:2, functions for service WANIPv6FirewallControl:1 */
+/*! \brief GetFirewallStatus() retrieves whether the firewall is enabled
+ * and pinhole can be created through UPnP
+ *
+ * IGD:2, functions for service WANIPv6FirewallControl:1
+ *
+ * \param[in] controlURL controlURL of the WANIPv6FirewallControl of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
+ * \param[out] firewallEnabled false (0) or true (1)
+ * \param[out] inboundPinholeAllowed false (0) or true (1)
+ * \return #UPNPCOMMAND_UNKNOWN_ERROR, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_HTTP_ERROR, #UPNPCOMMAND_SUCCESS or an UPnP error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetFirewallStatus(const char * controlURL,
 				const char * servicetype,
 				int * firewallEnabled,
 				int * inboundPinholeAllowed);
 
+/*! \brief retrieve default value after which automatically created pinholes
+ * expire
+ *
+ * The returned value may be specific to the \p proto, \p remoteHost,
+ * \p remotePort, \p intClient and \p intPort, but this behavior depends
+ * on the implementation of the firewall.
+ *
+ * \param[in] controlURL controlURL of the WANIPv6FirewallControl of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
+ * \param[in] remoteHost
+ * \param[in] remotePort
+ * \param[in] intClient
+ * \param[in] intPort
+ * \param[in] proto `TCP` or `UDP`
+ * \param[out] opTimeout lifetime in seconds of an inbound "automatic"
+ *             firewall pinhole created by an outbound traffic initiation.
+ * \return #UPNPCOMMAND_UNKNOWN_ERROR, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_HTTP_ERROR, #UPNPCOMMAND_SUCCESS or an UPnP error code
+ */
 MINIUPNP_LIBSPEC int
-UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
+UPNP_GetOutboundPinholeTimeout(const char * controlURL,
+                    const char * servicetype,
                     const char * remoteHost,
                     const char * remotePort,
                     const char * intClient,
@@ -314,6 +550,24 @@ UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype
                     const char * proto,
                     int * opTimeout);
 
+/*! \brief create a new pinhole that allows incoming traffic to pass
+ * through the firewall
+ *
+ * \param[in] controlURL controlURL of the WANIPv6FirewallControl of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
+ * \param[in] remoteHost literal presentation of IPv6 address or domain name.
+ *            empty string for wildcard
+ * \param[in] remotePort remote host port. Likely 0 (for wildcard)
+ * \param[in] intClient IP address of internal client. cannot be wildcarded
+ * \param[in] intPort client port. 0 for wildcard
+ * \param[in] proto IP protocol integer (6 for TCP, 17 for UDP, etc.)
+ *            65535 for wildcard.
+ * \param[in] leaseTime in seconds
+ * \param[out] uniqueID 8 bytes buffer
+ * \return #UPNPCOMMAND_UNKNOWN_ERROR, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_HTTP_ERROR, #UPNPCOMMAND_SUCCESS or an UPnP error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_AddPinhole(const char * controlURL, const char * servicetype,
                     const char * remoteHost,
@@ -324,18 +578,61 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype,
                     const char * leaseTime,
                     char * uniqueID);
 
+/*! \brief update a pinhole’s lease time
+ *
+ * \param[in] controlURL controlURL of the WANIPv6FirewallControl of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
+ * \param[in] uniqueID value obtained through UPNP_AddPinhole()
+ * \param[in] leaseTime in seconds
+ * \return #UPNPCOMMAND_UNKNOWN_ERROR, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_HTTP_ERROR, #UPNPCOMMAND_SUCCESS or an UPnP error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
                     const char * uniqueID,
                     const char * leaseTime);
 
+/*! \brief remove a pinhole
+ *
+ * \param[in] controlURL controlURL of the WANIPv6FirewallControl of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
+ * \param[in] uniqueID value obtained through UPNP_AddPinhole()
+ * \return #UPNPCOMMAND_UNKNOWN_ERROR, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_HTTP_ERROR, #UPNPCOMMAND_SUCCESS or an UPnP error code
+ */
 MINIUPNP_LIBSPEC int
-UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID);
+UPNP_DeletePinhole(const char * controlURL,
+                   const char * servicetype,
+                   const char * uniqueID);
 
+/*! \brief checking if a certain pinhole allows traffic to pass through the firewall
+ *
+ * \param[in] controlURL controlURL of the WANIPv6FirewallControl of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
+ * \param[in] uniqueID value obtained through UPNP_AddPinhole()
+ * \param[out] isWorking `0` for false, `1` for true
+ * \return #UPNPCOMMAND_UNKNOWN_ERROR, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_HTTP_ERROR, #UPNPCOMMAND_SUCCESS or an UPnP error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
                                  const char * uniqueID, int * isWorking);
 
+/*! \brief get the total number of IP packets which have been going through
+ * the specified pinhole
+ * \todo \p packets should be #UNSIGNED_INTEGER
+ * \param[in] controlURL controlURL of the WANIPv6FirewallControl of a
+ *            WANConnectionDevice
+ * \param[in] servicetype urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
+ * \param[in] uniqueID value obtained through UPNP_AddPinhole()
+ * \param[out] packets how many IP packets have been going through the
+ *             specified pinhole
+ * \return #UPNPCOMMAND_UNKNOWN_ERROR, #UPNPCOMMAND_INVALID_ARGS,
+ *         #UPNPCOMMAND_HTTP_ERROR, #UPNPCOMMAND_SUCCESS or an UPnP error code
+ */
 MINIUPNP_LIBSPEC int
 UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
                                  const char * uniqueID, int * packets);

+ 18 - 4
thirdparty/miniupnpc/include/miniupnpc/upnpdev.h

@@ -1,27 +1,40 @@
-/* $Id: upnpdev.h,v 1.4 2021/08/21 09:45:01 nanard Exp $ */
+/* $Id: upnpdev.h,v 1.6 2025/02/08 23:15:17 nanard Exp $ */
 /* Project : miniupnp
  * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author : Thomas BERNARD
- * copyright (c) 2005-2021 Thomas Bernard
+ * copyright (c) 2005-2025 Thomas Bernard
  * This software is subjet to the conditions detailed in the
  * provided LICENSE file. */
 #ifndef UPNPDEV_H_INCLUDED
 #define UPNPDEV_H_INCLUDED
 
+/*! \file upnpdev.h
+ * \brief UPNPDev device linked-list structure
+ * \todo could be merged into miniupnpc.h
+ */
 #include "miniupnpc_declspec.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/*!
+ * \brief UPnP device linked-list
+ */
 struct UPNPDev {
+	/*! \brief pointer to the next element */
 	struct UPNPDev * pNext;
+	/*! \brief root description URL */
 	char * descURL;
+	/*! \brief ST: as advertised */
 	char * st;
+	/*! \brief USN: as advertised */
 	char * usn;
+	/*! \brief IPv6 scope id of the network interface */
 	unsigned int scope_id;
 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 	/* C99 flexible array member */
+	/*! \brief buffer for descURL, st and usn */
 	char buffer[];
 #elif defined(__GNUC__)
 	char buffer[0];
@@ -31,8 +44,9 @@ struct UPNPDev {
 #endif
 };
 
-/* freeUPNPDevlist()
- * free list returned by upnpDiscover() */
+/*! \brief free list returned by upnpDiscover()
+ * \param[in] devlist linked list to free
+ */
 MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
 
 

+ 39 - 20
thirdparty/miniupnpc/include/miniupnpc/upnpreplyparse.h

@@ -1,53 +1,73 @@
-/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */
+/* $Id: upnpreplyparse.h,v 1.22 2025/03/29 17:58:12 nanard Exp $ */
 /* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2006-2013 Thomas Bernard
+ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
+ * (c) 2006-2025 Thomas Bernard
  * This software is subject to the conditions detailed
  * in the LICENCE file provided within the distribution */
 
 #ifndef UPNPREPLYPARSE_H_INCLUDED
 #define UPNPREPLYPARSE_H_INCLUDED
 
+/*! \file upnpreplyparse.h
+ * \brief Parsing of UPnP SOAP responses
+ */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-struct NameValue {
-	struct NameValue * l_next;
-	char name[64];
-	char value[128];
-};
+/*! \brief Name/Value linked list
+ * not exposed in the public API
+ */
+struct NameValue;
 
+/*! \brief data structure for parsing */
 struct NameValueParserData {
+	/*! \brief name/value linked list */
 	struct NameValue * l_head;
+	/*! \brief current element name */
 	char curelt[64];
+	/*! \brief port listing array */
 	char * portListing;
+	/*! \brief port listing array length */
 	int portListingLength;
+	/*! \brief flag indicating the current element is  */
 	int topelt;
+	/*! \brief top element character data */
 	const char * cdata;
+	/*! \brief top element character data length */
 	int cdatalen;
 };
 
-/* ParseNameValue() */
+/*!
+ * \brief Parse XML and fill the structure
+ *
+ * \param[in] buffer XML data
+ * \param[in] bufsize buffer length
+ * \param[out] data structure to fill
+ */
 void
 ParseNameValue(const char * buffer, int bufsize,
                struct NameValueParserData * data);
 
-/* ClearNameValueList() */
+/*!
+ * \brief free memory
+ *
+ * \param[in,out] pdata data structure
+ */
 void
 ClearNameValueList(struct NameValueParserData * pdata);
 
-/* GetValueFromNameValueList() */
+/*!
+ * \brief get a value from the parsed data
+ *
+ * \param[in] pdata data structure
+ * \param[in] name name
+ * \return the value or NULL if not found
+ */
 char *
 GetValueFromNameValueList(struct NameValueParserData * pdata,
-                          const char * Name);
-
-#if 0
-/* GetValueFromNameValueListIgnoreNS() */
-char *
-GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
-                                  const char * Name);
-#endif
+                          const char * name);
 
 /* DisplayNameValueList() */
 #ifdef DEBUG
@@ -60,4 +80,3 @@ DisplayNameValueList(char * buffer, int bufsize);
 #endif
 
 #endif
-

+ 7 - 3
thirdparty/miniupnpc/src/addr_is_reserved.c

@@ -1,13 +1,14 @@
-/* $Id: addr_is_reserved.c,v 1.4 2021/03/02 23:40:32 nanard Exp $ */
+/* $Id: addr_is_reserved.c,v 1.7 2025/01/12 15:47:17 nanard Exp $ */
 /* vim: tabstop=4 shiftwidth=4 noexpandtab
  * Project : miniupnp
  * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author : Thomas BERNARD
- * copyright (c) 2005-2024 Thomas Bernard
+ * copyright (c) 2005-2025 Thomas Bernard
  * This software is subjet to the conditions detailed in the
  * provided LICENSE file. */
 #ifdef _WIN32
 /* Win32 Specific includes and defines */
+#define WIN32_LEAN_AND_MEAN
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #if !defined(_MSC_VER)
@@ -15,6 +16,9 @@
 #else /* !defined(_MSC_VER) */
 typedef unsigned long uint32_t;
 #endif /* !defined(_MSC_VER) */
+#if !defined(_WIN32_WINNT_VISTA)
+#define _WIN32_WINNT_VISTA 0x0600
+#endif
 #else /* _WIN32 */
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -59,7 +63,7 @@ int addr_is_reserved(const char * addr_str)
 	uint32_t addr_n, address;
 	size_t i;
 
-#if defined(_WIN32) && _WIN32_WINNT < 0x0600 // _WIN32_WINNT_VISTA
+#if defined(_WIN32) && (_WIN32_WINNT < _WIN32_WINNT_VISTA)
 	addr_n = inet_addr(addr_str);
 	if (addr_n == INADDR_NONE)
 		return 1;

+ 16 - 10
thirdparty/miniupnpc/src/connecthostport.c

@@ -1,8 +1,9 @@
-/* $Id: connecthostport.c,v 1.24 2020/11/09 19:26:53 nanard Exp $ */
+/* $Id: connecthostport.c,v 1.25 2025/05/24 15:59:08 nanard Exp $ */
 /* vim: tabstop=4 shiftwidth=4 noexpandtab
  * Project : miniupnp
+ * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author : Thomas Bernard
- * Copyright (c) 2010-2020 Thomas Bernard
+ * Copyright (c) 2010-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution. */
 
@@ -15,6 +16,7 @@
 #include <string.h>
 #include <stdio.h>
 #ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <io.h>
@@ -123,8 +125,12 @@ SOCKET connecthostport(const char * host, unsigned short port,
 #else
 		n = select(s + 1, NULL, &wset, NULL, NULL);
 #endif
-		if(n == -1 && errno == EINTR)
-			continue;
+		if(n < 0) {
+			if (errno == EINTR)
+				continue;	/* try again */
+			else
+				break;	/* EBADF, EFAULT, EINVAL */
+		}
 #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
 		if(n == 0) {
 			errno = ETIMEDOUT;
@@ -132,8 +138,6 @@ SOCKET connecthostport(const char * host, unsigned short port,
 			break;
 		}
 #endif
-		/*len = 0;*/
-		/*n = getpeername(s, NULL, &len);*/
 		len = sizeof(err);
 		if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
 			PRINT_SOCKET_ERROR("getsockopt");
@@ -240,8 +244,12 @@ SOCKET connecthostport(const char * host, unsigned short port,
 #else
 			n = select(s + 1, NULL, &wset, NULL, NULL);
 #endif
-			if(n == -1 && errno == EINTR)
-				continue;
+			if(n < 0) {
+				if (errno == EINTR)
+					continue;	/* try again */
+				else
+					break; /* EBADF, EFAULT, EINVAL */
+			}
 #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
 			if(n == 0) {
 				errno = ETIMEDOUT;
@@ -249,8 +257,6 @@ SOCKET connecthostport(const char * host, unsigned short port,
 				break;
 			}
 #endif
-			/*len = 0;*/
-			/*n = getpeername(s, NULL, &len);*/
 			len = sizeof(err);
 			if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
 				PRINT_SOCKET_ERROR("getsockopt");

+ 3 - 3
thirdparty/miniupnpc/src/minisoap.c

@@ -1,8 +1,8 @@
-/* $Id: minisoap.c,v 1.32 2023/07/05 22:43:50 nanard Exp $ */
+/* $Id: minisoap.c,v 1.35 2025/04/27 21:13:45 nanard Exp $ */
 /* vim: tabstop=4 shiftwidth=4 noexpandtab
  * Project : miniupnp
  * Author : Thomas Bernard
- * Copyright (c) 2005-2024 Thomas Bernard
+ * Copyright (c) 2005-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  *
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <string.h>
 #ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
 #include <io.h>
 #include <winsock2.h>
 #include "win32_snprintf.h"
@@ -99,7 +100,6 @@ int soapPostSubmit(SOCKET fd,
 #endif
 					   "SOAPAction: \"%s\"\r\n"
 					   "Connection: close\r\n"
-					   "Cache-Control: no-cache\r\n"	/* ??? */
 					   "\r\n",
 					   url, httpversion, host, portstr, bodysize, action);
 	if ((unsigned int)headerssize >= sizeof(headerbuf))

+ 19 - 13
thirdparty/miniupnpc/src/minissdpc.c

@@ -1,9 +1,9 @@
-/* $Id: minissdpc.c,v 1.51 2024/05/16 00:12:05 nanard Exp $ */
+/* $Id: minissdpc.c,v 1.54 2025/03/29 17:59:01 nanard Exp $ */
 /* vim: tabstop=4 shiftwidth=4 noexpandtab
  * Project : miniupnp
  * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author : Thomas BERNARD
- * copyright (c) 2005-2024 Thomas Bernard
+ * copyright (c) 2005-2025 Thomas Bernard
  * This software is subjet to the conditions detailed in the
  * provided LICENCE file. */
 #include <stdio.h>
@@ -16,6 +16,7 @@
 #endif
 #if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
 #ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <io.h>
@@ -39,6 +40,9 @@ typedef unsigned short uint16_t;
 static const IN6_ADDR in6addr_any_init = {0};
 #endif
 #endif
+#if !defined(_WIN32_WINNT_VISTA)
+#define _WIN32_WINNT_VISTA 0x0600
+#endif
 #endif /* _WIN32 */
 #if defined(__amigaos__) || defined(__amigaos4__)
 #include <sys/socket.h>
@@ -387,7 +391,7 @@ free_tmp_and_return:
  * the last 4 arguments are filled during the parsing :
  *    - location/locationsize : "location:" field of the SSDP reply packet
  *    - st/stsize : "st:" field of the SSDP reply packet.
- *    - usn/usnsize : "usn:" filed of the SSDP reply packet
+ *    - usn/usnsize : "usn:" field of the SSDP reply packet
  * The strings are NOT null terminated */
 static void
 parseMSEARCHReply(const char * reply, int size,
@@ -460,7 +464,7 @@ parseMSEARCHReply(const char * reply, int size,
 static int upnp_gettimeofday(struct timeval * tv)
 {
 #if defined(_WIN32)
-#if _WIN32_WINNT >= 0x0600 // _WIN32_WINNT_VISTA
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
 	ULONGLONG ts = GetTickCount64();
 #else
 	DWORD ts = GetTickCount();
@@ -539,10 +543,10 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
 	int n;
 	struct sockaddr_storage sockudp_r;
 	unsigned int mx;
+	int rv;
 #ifdef NO_GETADDRINFO
 	struct sockaddr_storage sockudp_w;
 #else
-	int rv;
 	struct addrinfo hints, *servinfo;
 #endif
 #ifdef _WIN32
@@ -591,8 +595,8 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
  * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
 	if(!ipv6) {
 		DWORD ifbestidx;
-#if _WIN32_WINNT >= 0x0600 // _WIN32_WINNT_VISTA
-		// While we don't need IPv6 support, the IPv4 only funciton is not available in UWP apps.
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
+		// While we don't need IPv6 support, the IPv4 only function is not available in UWP apps.
 		SOCKADDR_IN destAddr;
 		memset(&destAddr, 0, sizeof(destAddr));
 		destAddr.sin_family = AF_INET;
@@ -747,7 +751,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
 		} else {
 			struct in_addr mc_if;
 #if defined(_WIN32)
-#if _WIN32_WINNT >= 0x0600 // _WIN32_WINNT_VISTA
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
 			InetPtonA(AF_INET, multicastif, &mc_if);
 #else
 			mc_if.s_addr = inet_addr(multicastif); /* old Windows SDK do not support InetPtoA() */
@@ -871,9 +875,9 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
 			p->sin_port = htons(SSDP_PORT);
 			p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
 		}
-		n = sendto(sudp, bufr, n, 0, &sockudp_w,
-		           ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
-		if (n < 0) {
+		rv = sendto(sudp, bufr, n, 0, (struct sockaddr *)&sockudp_w,
+		            ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
+		if (rv < 0) {
 			if(error)
 				*error = MINISSDPC_SOCKET_ERROR;
 			PRINT_SOCKET_ERROR("sendto");
@@ -899,9 +903,11 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
 			break;
 		} else {
 			struct addrinfo *p;
+			/* as getaddrinfo() returns a linked list, we are iterating it
+			 * even thought it should only return one result here */
 			for(p = servinfo; p; p = p->ai_next) {
-				n = sendto(sudp, bufr, n, 0, p->ai_addr, MSC_CAST_INT p->ai_addrlen);
-				if (n < 0) {
+				rv = sendto(sudp, bufr, n, 0, p->ai_addr, MSC_CAST_INT p->ai_addrlen);
+				if (rv < 0) {
 #ifdef DEBUG
 					char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
 					if (getnameinfo(p->ai_addr, (socklen_t)p->ai_addrlen, hbuf, sizeof(hbuf), sbuf,

+ 15 - 14
thirdparty/miniupnpc/src/miniupnpc.c

@@ -1,9 +1,9 @@
-/* $Id: miniupnpc.c,v 1.159 2021/03/02 23:36:32 nanard Exp $ */
+/* $Id: miniupnpc.c,v 1.165 2025/01/10 22:57:21 nanard Exp $ */
 /* vim: tabstop=4 shiftwidth=4 noexpandtab
  * Project : miniupnp
  * Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author : Thomas BERNARD
- * copyright (c) 2005-2024 Thomas Bernard
+ * copyright (c) 2005-2025 Thomas Bernard
  * This software is subjet to the conditions detailed in the
  * provided LICENSE file. */
 #include <stdlib.h>
@@ -11,6 +11,7 @@
 #include <string.h>
 #ifdef _WIN32
 /* Win32 Specific includes and defines */
+#define WIN32_LEAN_AND_MEAN
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <io.h>
@@ -98,8 +99,8 @@ MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGD
  *   pointer - OK
  *   NULL - error */
 char *
-simpleUPnPcommand(int s, const char * url, const char * service,
-                  const char * action, struct UPNParg * args,
+simpleUPnPcommand(const char * url, const char * service,
+                  const char * action, const struct UPNParg * args,
                   int * bufsize)
 {
 	char hostname[MAXHOSTNAMELEN+1];
@@ -111,6 +112,7 @@ simpleUPnPcommand(int s, const char * url, const char * service,
 	char * buf;
 	int n;
 	int status_code;
+	SOCKET s;
 
 	*bufsize = 0;
 	snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
@@ -197,12 +199,10 @@ simpleUPnPcommand(int s, const char * url, const char * service,
 			return NULL;
 	}
 	if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
-	if(ISINVALID((SOCKET)s)) {
-		s = connecthostport(hostname, port, 0);
-		if(ISINVALID((SOCKET)s)) {
-			/* failed to connect */
-			return NULL;
-		}
+	s = connecthostport(hostname, port, 0);
+	if(ISINVALID(s)) {
+		/* failed to connect */
+		return NULL;
 	}
 
 	n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, "1.1");
@@ -505,13 +505,14 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
 /* UPNP_GetValidIGD() :
  * return values :
  *    -1 = Internal error
- *     0 = NO IGD found
- *     1 = A valid connected IGD has been found
+ *     0 = NO IGD found (UPNP_NO_IGD)
+ *     1 = A valid connected IGD has been found (UPNP_CONNECTED_IGD)
  *     2 = A valid connected IGD has been found but its
- *         IP address is reserved (non routable)
+ *         IP address is reserved (non routable) (UPNP_PRIVATEIP_IGD)
  *     3 = A valid IGD has been found but it reported as
- *         not connected
+ *         not connected (UPNP_DISCONNECTED_IGD)
  *     4 = an UPnP device has been found but was not recognized as an IGD
+ *         (UPNP_UNKNOWN_DEVICE)
  *
  * In any positive non zero return case, the urls and data structures
  * passed as parameters are set. Don't forget to call FreeUPNPUrls(urls) to

+ 1 - 1
thirdparty/miniupnpc/src/miniupnpcstrings.h

@@ -2,7 +2,7 @@
 #define MINIUPNPCSTRINGS_H_INCLUDED
 
 #define OS_STRING "Godot Engine/1.0"
-#define MINIUPNPC_VERSION_STRING "2.2.8"
+#define MINIUPNPC_VERSION_STRING "2.3.3"
 
 #if 0
 /* according to "UPnP Device Architecture 1.0" */

+ 3 - 2
thirdparty/miniupnpc/src/miniwget.c

@@ -1,8 +1,8 @@
-/* $Id: miniwget.c,v 1.85 2023/06/15 21:47:50 nanard Exp $ */
+/* $Id: miniwget.c,v 1.88 2025/05/25 21:56:49 nanard Exp $ */
 /* Project : miniupnp
  * Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
  * Author : Thomas Bernard
- * Copyright (c) 2005-2024 Thomas Bernard
+ * Copyright (c) 2005-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution. */
 
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <ctype.h>
 #ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <io.h>

+ 40 - 1
thirdparty/miniupnpc/src/miniwget_private.h

@@ -1,15 +1,54 @@
 /* $Id: miniwget_private.h,v 1.1 2018/04/06 10:17:58 nanard Exp $ */
 /* Project : miniupnp
  * Author : Thomas Bernard
- * Copyright (c) 2018 Thomas Bernard
+ * Copyright (c) 2018-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution.
  * */
 #ifndef MINIWGET_INTERNAL_H_INCLUDED
 #define MINIWGET_INTERNAL_H_INCLUDED
 
+/*! \file miniwget_private.h
+ * \brief Lightweight HTTP client private API
+ */
 #include "miniupnpc_socketdef.h"
 
+/*! \brief Read a HTTP response from a socket
+ *
+ * Processed HTTP headers :
+ * - `Content-Length`
+ * - `Transfer-encoding`
+ * return a pointer to the content buffer, which length is saved
+ * to the length parameter.
+ * \param[in] s socket
+ * \param[out] size returned content buffer size
+ * \param[out] status_code HTTP Status code
+ * \return malloc'ed content buffer
+ */
 void * getHTTPResponse(SOCKET s, int * size, int * status_code);
 
+/*! \brief parse a HTTP URL
+ *
+ * URL formats supported :
+ * - `http://192.168.1.1/path/xxx`
+ * - `http://192.168.1.1:8080/path/xxx`
+ * - `http://[2a00:1234:5678:90ab::123]/path/xxx`
+ * - `http://[2a00:1234:5678:90ab::123]:8080/path/xxx`
+ * - `http://[fe80::1234:5678:90ab%%eth0]/path/xxx`
+ * - `http://[fe80::1234:5678:90ab%%eth0]:8080/path/xxx`
+ *
+ * `%` may be encoded as `%25`
+ *
+ * \param[in] url URL to parse
+ * \param[out] hostname hostname part of the URL (size of MAXHOSTNAMELEN+1)
+ * \param[out] port set to the port specified in the URL or 80
+ * \param[out] path set to the begining of the path part of the URL
+ * \param[out] scope_id set to the interface id if specified in the
+ *             link-local IPv6 address
+ * \return 0 for failure, 1 for success
+ */
+int parseURL(const char * url,
+             char * hostname, unsigned short * port, char * * path,
+             unsigned int * scope_id);
+
 #endif

+ 4 - 4
thirdparty/miniupnpc/src/portlistingparse.c

@@ -1,7 +1,7 @@
-/* $Id: portlistingparse.c,v 1.9 2015/07/15 12:41:13 nanard Exp $ */
+/* $Id: portlistingparse.c,v 1.12 2025/03/29 17:58:33 nanard Exp $ */
 /* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2011-2020 Thomas Bernard
+ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
+ * (c) 2011-2025 Thomas Bernard
  * This software is subject to the conditions detailed
  * in the LICENCE file provided within the distribution */
 #include <string.h>
@@ -15,7 +15,7 @@
 #if defined(__HAIKU__)
 /* rename our private function because Haiku already defines a atoui() function */
 #define atoui atoui2
-#endif 
+#endif
 
 /* list of the elements */
 static const struct {

+ 3 - 2
thirdparty/miniupnpc/src/receivedata.c

@@ -1,14 +1,15 @@
-/* $Id: receivedata.c,v 1.10 2021/03/02 23:33:07 nanard Exp $ */
+/* $Id: receivedata.c,v 1.11 2025/05/25 21:56:49 nanard Exp $ */
 /* Project : miniupnp
  * Website : http://miniupnp.free.fr/
  * Author : Thomas Bernard
- * Copyright (c) 2011-2021 Thomas Bernard
+ * Copyright (c) 2011-2025 Thomas Bernard
  * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution. */
 
 #include <stdio.h>
 #include <string.h>
 #ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #else /* _WIN32 */

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 257 - 281
thirdparty/miniupnpc/src/upnpcommands.c


+ 23 - 33
thirdparty/miniupnpc/src/upnpreplyparse.c

@@ -1,8 +1,8 @@
-/* $Id: upnpreplyparse.c,v 1.20 2017/12/12 11:26:25 nanard Exp $ */
+/* $Id: upnpreplyparse.c,v 1.22 2025/02/08 23:12:26 nanard Exp $ */
 /* vim: tabstop=4 shiftwidth=4 noexpandtab
  * MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2006-2019 Thomas Bernard
+ * http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
+ * (c) 2006-2025 Thomas Bernard
  * This software is subject to the conditions detailed
  * in the LICENCE file provided within the distribution */
 
@@ -13,6 +13,23 @@
 #include "upnpreplyparse.h"
 #include "minixml.h"
 
+struct NameValue {
+	/*! \brief pointer to the next element */
+	struct NameValue * l_next;
+	/*! \brief name */
+	char name[64];
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+	/* C99 flexible array member */
+	/*! \brief character value */
+	char value[];
+#elif defined(__GNUC__)
+	char value[0];
+#else
+	/* Fallback to a hack */
+	char value[1];
+#endif
+};
+
 static void
 NameValueParserStartElt(void * d, const char * name, int l)
 {
@@ -40,7 +57,7 @@ NameValueParserEndElt(void * d, const char * name, int namelen)
 		int l;
 		/* standard case. Limited to n chars strings */
 		l = data->cdatalen;
-	    nv = malloc(sizeof(struct NameValue));
+	    nv = malloc(sizeof(struct NameValue) + l + 1);
 		if(nv == NULL)
 		{
 			/* malloc error */
@@ -50,8 +67,6 @@ NameValueParserEndElt(void * d, const char * name, int namelen)
 #endif /* DEBUG */
 			return;
 		}
-	    if(l>=(int)sizeof(nv->value))
-	        l = sizeof(nv->value) - 1;
 	    strncpy(nv->name, data->curelt, 64);
 		nv->name[63] = '\0';
 		if(data->cdata != NULL)
@@ -137,7 +152,7 @@ ClearNameValueList(struct NameValueParserData * pdata)
 
 char *
 GetValueFromNameValueList(struct NameValueParserData * pdata,
-                          const char * Name)
+                          const char * name)
 {
     struct NameValue * nv;
     char * p = NULL;
@@ -145,37 +160,12 @@ GetValueFromNameValueList(struct NameValueParserData * pdata,
         (nv != NULL) && (p == NULL);
         nv = nv->l_next)
     {
-        if(strcmp(nv->name, Name) == 0)
+        if(strcmp(nv->name, name) == 0)
             p = nv->value;
     }
     return p;
 }
 
-#if 0
-/* useless now that minixml ignores namespaces by itself */
-char *
-GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
-                                  const char * Name)
-{
-	struct NameValue * nv;
-	char * p = NULL;
-	char * pname;
-	for(nv = pdata->head.lh_first;
-	    (nv != NULL) && (p == NULL);
-		nv = nv->entries.le_next)
-	{
-		pname = strrchr(nv->name, ':');
-		if(pname)
-			pname++;
-		else
-			pname = nv->name;
-		if(strcmp(pname, Name)==0)
-			p = nv->value;
-	}
-	return p;
-}
-#endif
-
 /* debug all-in-one function
  * do parsing then display to stdout */
 #ifdef DEBUG

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott