]> granicus.if.org Git - transmission/commitdiff
Remove third-party code stored in the repo directly
authorMike Gelfand <mikedld@mikedld.com>
Sun, 1 Jan 2017 13:01:00 +0000 (16:01 +0300)
committerMike Gelfand <mikedld@mikedld.com>
Sun, 1 Jan 2017 13:01:00 +0000 (16:01 +0300)
74 files changed:
third-party/dht/CHANGES [deleted file]
third-party/dht/LICENCE [deleted file]
third-party/dht/Makefile.am [deleted file]
third-party/dht/README [deleted file]
third-party/dht/dht-example.c [deleted file]
third-party/dht/dht.c [deleted file]
third-party/dht/dht.h [deleted file]
third-party/libb64/AUTHORS [deleted file]
third-party/libb64/CHANGELOG [deleted file]
third-party/libb64/INSTALL [deleted file]
third-party/libb64/LICENSE [deleted file]
third-party/libb64/Makefile.am [deleted file]
third-party/libb64/README [deleted file]
third-party/libb64/b64/cdecode.h [deleted file]
third-party/libb64/b64/cencode.h [deleted file]
third-party/libb64/cdecode.c [deleted file]
third-party/libb64/cencode.c [deleted file]
third-party/libnatpmp/Changelog.txt [deleted file]
third-party/libnatpmp/LICENSE [deleted file]
third-party/libnatpmp/Makefile.am [deleted file]
third-party/libnatpmp/README [deleted file]
third-party/libnatpmp/declspec.h [deleted file]
third-party/libnatpmp/getgateway.c [deleted file]
third-party/libnatpmp/getgateway.h [deleted file]
third-party/libnatpmp/natpmp.c [deleted file]
third-party/libnatpmp/natpmp.h [deleted file]
third-party/libnatpmp/wingettimeofday.c [deleted file]
third-party/libnatpmp/wingettimeofday.h [deleted file]
third-party/libutp/LICENSE [deleted file]
third-party/libutp/Makefile.am [deleted file]
third-party/libutp/README.md [deleted file]
third-party/libutp/StdAfx.h [deleted file]
third-party/libutp/templates.h [deleted file]
third-party/libutp/utp.cpp [deleted file]
third-party/libutp/utp.h [deleted file]
third-party/libutp/utp_config.h [deleted file]
third-party/libutp/utp_config_example.h [deleted file]
third-party/libutp/utp_utils.cpp [deleted file]
third-party/libutp/utp_utils.h [deleted file]
third-party/libutp/utypes.h [deleted file]
third-party/miniupnp/Changelog.txt [deleted file]
third-party/miniupnp/LICENSE [deleted file]
third-party/miniupnp/Makefile.am [deleted file]
third-party/miniupnp/README [deleted file]
third-party/miniupnp/VERSION [deleted file]
third-party/miniupnp/apiversions.txt [deleted file]
third-party/miniupnp/bsdqueue.h [deleted file]
third-party/miniupnp/codelength.h [deleted file]
third-party/miniupnp/connecthostport.c [deleted file]
third-party/miniupnp/connecthostport.h [deleted file]
third-party/miniupnp/declspec.h [deleted file]
third-party/miniupnp/igd_desc_parse.c [deleted file]
third-party/miniupnp/igd_desc_parse.h [deleted file]
third-party/miniupnp/minisoap.c [deleted file]
third-party/miniupnp/minisoap.h [deleted file]
third-party/miniupnp/minissdpc.c [deleted file]
third-party/miniupnp/minissdpc.h [deleted file]
third-party/miniupnp/miniupnpc.c [deleted file]
third-party/miniupnp/miniupnpc.h [deleted file]
third-party/miniupnp/miniupnpcstrings.h.in [deleted file]
third-party/miniupnp/miniupnpctypes.h [deleted file]
third-party/miniupnp/miniwget.c [deleted file]
third-party/miniupnp/miniwget.h [deleted file]
third-party/miniupnp/minixml.c [deleted file]
third-party/miniupnp/minixml.h [deleted file]
third-party/miniupnp/portlistingparse.c [deleted file]
third-party/miniupnp/portlistingparse.h [deleted file]
third-party/miniupnp/receivedata.c [deleted file]
third-party/miniupnp/receivedata.h [deleted file]
third-party/miniupnp/updateminiupnpcstrings.sh [deleted file]
third-party/miniupnp/upnpcommands.c [deleted file]
third-party/miniupnp/upnpcommands.h [deleted file]
third-party/miniupnp/upnpreplyparse.c [deleted file]
third-party/miniupnp/upnpreplyparse.h [deleted file]

diff --git a/third-party/dht/CHANGES b/third-party/dht/CHANGES
deleted file mode 100644 (file)
index 6904abd..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-3 May 2014: dht-0.22
-
-  * INCOMPATIBLE CHANGE: the callback now takes const arguments.
-  * Consult the local storage when performing a search, which should
-    make bootstrapping of tiny DHTs easier.  Note that we're still not
-    performing local stores, since that would require knowing our IP
-    address.
-  * Don't attempt to flush the debug stream if debugging is disabled.
-    This appears to work around a bug in Transmission.
-
-25 July 2011: dht-0.21
-
-  * Blacklisting support.
-
-7 July 2011: dht-0.20
-
-  * Fix compilation on systems that have memmem but don't define HAVE_MEMMEM.
-
-30 April 2011: dht-0.19
-
-  * Fix incorrect parsing of announces.  Thanks to cjdelisle.
-  * Relax rate limiting slightly.
-
-20 January 2011: dht-0.18
-
-  * Fix a bug that could cause parse_message to enter an infinite loop
-    on overflow.  Thanks to Jordan Lee.
-
-9 January 2011: dht-0.17:
-
-  * Fix a bug that prevented calling dht_init after dht_uninit.
-  * Remove the "dofree" parameter to dht_uninit.
-
-23 December 2010: dht-0.16:
-
-  * Change the interface to allow sharing of the UDP socket e.g. with uTP.
-
-1 July 2010: dht-0.15
-
-  * Port to Windows, for the needs of Transmission.
-
-25 March 2010: dht-0.14
-
-  * Fixed ordering of entries in parameter dictionaries.
-
-15 December 2009: dht-0.13
-
-  * Implemented protection against incorrect addresses in the DHT.
-  * Tweaked neighborhood maintenance to wake up less often.
-
-11 December 2009: dht-0.12
-  * Fixed slightly incorrect formatting of DHT messages.
-  * Fixed incorrect debugging message.
-
-22 November 2009: dht-0.11
-
-  * Implemented IPv6 support (BEP-32).
-  * Fixed a bug which could cause us to never mark a search as finished.
-  * Fixed a bug that could cause us to send incomplete lists in response to
-    find_nodes.
-  * Limit the number of hashes that we're willing to track.
-  * Made bucket maintenance slightly more aggressive.
-  * Produce on-the-wire error messages to give a hint to the other side.
-  * Added a bunch of options to dht-example to make it useful as
-    a bootstrap node.
-  * Send version "JC\0\0" when using dht-example.
-
-18 October 2009: dht-0.10
-
-  * Send nodes even when sending values.  This is a violation of the
-    protocol, but I have been assured that it doesn't break any deployed
-    implementation.  This is also what both libtorrent and uTorrent do.
-  * Give up immediately on a search peer when no token was provided.  This
-    is a very reasonable extension to the protocol, and certainly doesn't
-    break anything.
-  * Parse heterogeneous values lists correctly.  This is mandated by BEP 32.
-
-20 September 2009: dht-0.9
-
-  * Fixed incorrect computation of number of nodes.
-  * Made the initial bucket split eagerly (speeds up bootstrapping).
-  * Fixed initial filling of search buckets (speeds up searches).
-
-28 July 2009: dht-0.8
-
-  * Fixed a crash when expiring the first search on the list.
-  * Fixed freeing of the search list when uniniting with dofree = 1.
-
-24 June 2009: dht-0.7
-
-  * Removed the fixed limit on the number of concurrent searches, we now
-    use a linked list.
-  * Fixed build on FreeBSD (thanks to Humihara and Charles Kerr).
-
-22 May 2009: dht-0.6
-
-  * Fixed a buffer overflow (when reading) in parse_message.
-  * Fixed slightly inacurrate metric computation when searching.
-  * Removed a slightly inaccurate shortcut when responding to find_nodes.
-  * Relaxed the rate-limiting parameters to 4 requests per second.
-
-19 May 2009: dht-0.5
-
-  * Made reading of /dev/urandom a function provided by the user.
-  * Implemented the ``v'' extension that identifies node implementations.
-
-18 May 2009: dht-0.4
-
-  * Fixed the handling of tokens in announce_peer messages.
-  * Implemented backtracking during search when nodes turn out to be dead.
-
-17 May 2009: dht-0.3
-
-  * Fixed a number of incorrectly formatted messages.
-  * Changed reply to find_peers to spread the load more uniformly.
-  * Fixed a bug that could cause premature splitting.
-  * Implemented rate limiting.
-  * Changed some time constants to be less chatty.
-  * When determining if a bucket is fresh enough, we now only take replies
-    into account.
-  * dht_get_nodes now returns nodes starting with our own bucket.
-  * Tweaked the memory allocation strategy for stored peers.
-
-17 May 2009: dht-0.2
-
-  * Fixed a crash in dht_uninit.
-  * Added support for saving the list of known-good nodes.
-  * Changed the interface of dht_nodes to provide the number of nodes that
-    recently sent incoming requests.
-
-13 May 2009: dht-0.1
-
-  * Initial public release.
diff --git a/third-party/dht/LICENCE b/third-party/dht/LICENCE
deleted file mode 100644 (file)
index cf2d390..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2009, 2010 by Juliusz Chroboczek
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/third-party/dht/Makefile.am b/third-party/dht/Makefile.am
deleted file mode 100644 (file)
index 869284c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-AM_CFLAGS = @PTHREAD_CFLAGS@ 
-
-noinst_LIBRARIES = libdht.a
-libdht_a_SOURCES = dht.c
-noinst_HEADERS = dht.h
-EXTRA_DIST = CHANGES dht-example.c LICENCE README
diff --git a/third-party/dht/README b/third-party/dht/README
deleted file mode 100644 (file)
index 5252a94..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-The files dht.c and dht.h implement the variant of the Kademlia Distributed
-Hash Table (DHT) used in the Bittorrent network (``mainline'' variant).
-
-The file dht-example.c is a stand-alone program that participates in the
-DHT.  Another example is a patch against Transmission, which you might or
-might not be able to find somewhere.
-
-The code is designed to work well in both event-driven and threaded code.
-The caller, which is either an event-loop or a dedicated thread, must
-periodically call the function dht_periodic.  In addition, it must call
-dht_periodic whenever any data has arrived from the network.
-
-All functions return -1 in case of failure, in which case errno is set, or
-a positive value in case of success.
-
-Initialisation
-**************
-
-* dht_init
-
-This must be called before using the library.  You pass it a bound IPv4
-datagram socket, a bound IPv6 datagram socket, and your node id, a 20-octet
-array that should be globally unique.
-
-If you're on a multi-homed host, you should bind the sockets to one of your
-addresses.
-
-Node ids must be well distributed, so you cannot just use your Bittorrent
-id; you should either generate a truly random value (using plenty of
-entropy), or at least take the SHA-1 of something.  However, it is a good
-idea to keep the id stable, so you may want to store it in stable storage
-at client shutdown.
-
-* dht_uninit
-
-This may be called at the end of the session.
-
-Bootstrapping
-*************
-
-The DHT needs to be taught a small number of contacts to begin functioning.
-You can hard-wire a small number of stable nodes in your application, but
-this obviously fails to scale.  You may save the list of known good nodes
-at shutdown, and restore it at restart.  You may also grab nodes from
-torrent files (the nodes field), and you may exchange contacts with other
-Bittorrent peers using the PORT extension.
-
-* dht_ping
-
-This is the main bootstrapping primitive.  You pass it an address at which
-you believe that a DHT node may be living, and a query will be sent.  If
-a node replies, and if there is space in the routing table, it will be
-inserted.
-
-* dht_insert_node
-
-This is a softer bootstrapping method, which doesn't actually send
-a query -- it only stores the node in the routing table for later use.  It
-is a good idea to use that when e.g. restoring your routing table from
-disk.
-
-Note that dht_insert_node requires that you supply a node id.  If the id
-turns out to be wrong, the DHT will eventually recover; still, inserting
-massive amounts of incorrect information into your routing table is
-certainly not a good idea.
-
-An additionaly difficulty with dht_insert_node is that, for various
-reasons, a Kademlia routing table cannot absorb nodes faster than a certain
-rate.  Dumping a large number of nodes into a table using dht_insert_node
-will probably cause most of these nodes to be discarded straight away.
-(The tolerable rate is difficult to estimate; it is probably on the order
-of one node every few seconds per node already in the table divided by 8,
-for some suitable value of 8.)
-
-Doing some work
-***************
-
-* dht_periodic
-
-This function should be called by your main loop periodically, and also
-whenever data is available on the socket.  The time after which
-dht_periodic should be called if no data is available is returned in the
-parameter tosleep.  (You do not need to be particularly accurate; actually,
-it is a good idea to be late by a random value.)
-
-The parameters buf, buflen, from and fromlen optionally carry a received
-message.  If buflen is 0, then no message was received.
-
-Dht_periodic also takes a callback, which will be called whenever something
-interesting happens (see below).
-
-* dht_search
-
-This schedules a search for information about the info-hash specified in
-id.  If port is not 0, it specifies the TCP port on which the current peer
-is listening; in that case, when the search is complete it will be announced
-to the network.  The port is in host order, beware if you got it from
-a struct sockaddr_in.
-
-In either case, data is passed to the callback function as soon as it is
-available, possibly in multiple pieces.  The callback function will
-additionally be called when the search is complete.
-
-Up to DHT_MAX_SEARCHES (1024) searches can be in progress at a given time;
-any more, and dht_search will return -1.  If you specify a new search for
-the same info hash as a search still in progress, the previous search is
-combined with the new one -- you will only receive a completion indication
-once.
-
-Information queries
-*******************
-
-* dht_nodes
-
-This returns the number of known good, dubious and cached nodes in our
-routing table.  This can be used to decide whether it's reasonable to start
-a search; a search is likely to be successful as long as we have a few good
-nodes; however, in order to avoid overloading your bootstrap nodes, you may
-want to wait until good is at least 4 and good + doubtful is at least 30 or
-so.
-
-It also includes the number of nodes that recently send us an unsolicited
-request; this can be used to determine if the UDP port used for the DHT is
-firewalled.
-
-If you want to display a single figure to the user, you should display
-good + doubtful, which is the total number of nodes in your routing table.
-Some clients try to estimate the total number of nodes, but this doesn't
-make much sense -- since the result is exponential in the number of nodes
-in the routing table, small variations in the latter cause huge jumps in
-the former.
-
-* dht_get_nodes
-
-This retrieves the list of known good nodes, starting with the nodes in our
-own bucket.  It is a good idea to save the list of known good nodes at
-shutdown, and ping them at startup.
-
-* dht_dump_tables
-* dht_debug
-
-These are debugging aids.
-
-Functions provided by you
-*************************
-
-* The callback function
-
-The callback function is called with 5 arguments.  Closure is simply the
-value that you passed to dht_periodic.  Event is one of DHT_EVENT_VALUES or
-DHT_EVENT_VALUES6, which indicates that we have new values, or
-DHT_EVENT_SEARCH_DONE or DHT_EVENT_SEARCH_DONE6, which indicates that
-a search has completed.  In either case, info_hash is set to the info-hash
-of the search.
-
-In the case of DHT_EVENT_VALUES, data is a list of nodes in ``compact''
-format -- 6 or 18 bytes per node.  Its length in bytes is in data_len.
-
-* dht_blacklisted
-
-This is a function that takes an IP address and returns true if this
-address should be silently ignored.  Do not use this feature unless you
-really must -- Kademlia supposes transitive reachability.
-
-* dht_hash
-
-This should compute a reasonably strong cryptographic hash of the passed
-values.  It should map cleanly to your favourite crypto toolkit's MD5 or
-SHA-1 function.
-
-* dht_random_bytes
-
-This should fill the supplied buffer with true random bytes.
-
-Final notes
-***********
-
-* NAT
-
-Nothing works well across NATs, but Kademlia is somewhat less impacted than
-many other protocols.  The implementation takes care to distinguish between
-unidirectional and bidirectional reachability, and NATed nodes will
-eventually fall out from other nodes' routing tables.
-
-While there is no periodic pinging in this implementation, maintaining
-a full routing table requires slightly more than one packet exchange per
-minute, even in a completely idle network; this should be sufficient to
-make most full cone NATs happy.
-
-* Missing functionality
-
-Some of the code has had very little testing.  If it breaks, you get to
-keep both pieces.
-
-
-                                        Juliusz Chroboczek
-                                        <jch@pps.jussieu.fr>
diff --git a/third-party/dht/dht-example.c b/third-party/dht/dht-example.c
deleted file mode 100644 (file)
index 7ab08b6..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-/* This example code was written by Juliusz Chroboczek.
-   You are free to cut'n'paste from it to your heart's content. */
-
-/* For crypt */
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <sys/signal.h>
-
-#include "dht.h"
-
-#define MAX_BOOTSTRAP_NODES 20
-static struct sockaddr_storage bootstrap_nodes[MAX_BOOTSTRAP_NODES];
-static int num_bootstrap_nodes = 0;
-
-static volatile sig_atomic_t dumping = 0, searching = 0, exiting = 0;
-
-static void
-sigdump(int signo)
-{
-    dumping = 1;
-}
-
-static void
-sigtest(int signo)
-{
-    searching = 1;
-}
-
-static void
-sigexit(int signo)
-{
-    exiting = 1;
-}
-
-static void
-init_signals(void)
-{
-    struct sigaction sa;
-    sigset_t ss;
-
-    sigemptyset(&ss);
-    sa.sa_handler = sigdump;
-    sa.sa_mask = ss;
-    sa.sa_flags = 0;
-    sigaction(SIGUSR1, &sa, NULL);
-
-    sigemptyset(&ss);
-    sa.sa_handler = sigtest;
-    sa.sa_mask = ss;
-    sa.sa_flags = 0;
-    sigaction(SIGUSR2, &sa, NULL);
-
-    sigemptyset(&ss);
-    sa.sa_handler = sigexit;
-    sa.sa_mask = ss;
-    sa.sa_flags = 0;
-    sigaction(SIGINT, &sa, NULL);
-}
-
-const unsigned char hash[20] = {
-    0x54, 0x57, 0x87, 0x89, 0xdf, 0xc4, 0x23, 0xee, 0xf6, 0x03,
-    0x1f, 0x81, 0x94, 0xa9, 0x3a, 0x16, 0x98, 0x8b, 0x72, 0x7b
-};
-
-/* The call-back function is called by the DHT whenever something
-   interesting happens.  Right now, it only happens when we get a new value or
-   when a search completes, but this may be extended in future versions. */
-static void
-callback(void *closure,
-         int event,
-         const unsigned char *info_hash,
-         const void *data, size_t data_len)
-{
-    if(event == DHT_EVENT_SEARCH_DONE)
-        printf("Search done.\n");
-    else if(event == DHT_EVENT_VALUES)
-        printf("Received %d values.\n", (int)(data_len / 6));
-}
-
-static unsigned char buf[4096];
-
-int
-main(int argc, char **argv)
-{
-    int i, rc, fd;
-    int s = -1, s6 = -1, port;
-    int have_id = 0;
-    unsigned char myid[20];
-    time_t tosleep = 0;
-    char *id_file = "dht-example.id";
-    int opt;
-    int quiet = 0, ipv4 = 1, ipv6 = 1;
-    struct sockaddr_in sin;
-    struct sockaddr_in6 sin6;
-    struct sockaddr_storage from;
-    socklen_t fromlen;
-
-    memset(&sin, 0, sizeof(sin));
-    sin.sin_family = AF_INET;
-
-    memset(&sin6, 0, sizeof(sin6));
-    sin6.sin6_family = AF_INET6;
-
-
-
-    while(1) {
-        opt = getopt(argc, argv, "q46b:i:");
-        if(opt < 0)
-            break;
-
-        switch(opt) {
-        case 'q': quiet = 1; break;
-        case '4': ipv6 = 0; break;
-        case '6': ipv4 = 0; break;
-        case 'b': {
-            char buf[16];
-            int rc;
-            rc = inet_pton(AF_INET, optarg, buf);
-            if(rc == 1) {
-                memcpy(&sin.sin_addr, buf, 4);
-                break;
-            }
-            rc = inet_pton(AF_INET6, optarg, buf);
-            if(rc == 1) {
-                memcpy(&sin6.sin6_addr, buf, 16);
-                break;
-            }
-            goto usage;
-        }
-            break;
-        case 'i':
-            id_file = optarg;
-            break;
-        default:
-            goto usage;
-        }
-    }
-
-    /* Ids need to be distributed evenly, so you cannot just use your
-       bittorrent id.  Either generate it randomly, or take the SHA-1 of
-       something. */
-    fd = open(id_file, O_RDONLY);
-    if(fd >= 0) {
-        rc = read(fd, myid, 20);
-        if(rc == 20)
-            have_id = 1;
-        close(fd);
-    }
-    
-    fd = open("/dev/urandom", O_RDONLY);
-    if(fd < 0) {
-        perror("open(random)");
-        exit(1);
-    }
-
-    if(!have_id) {
-        int ofd;
-
-        rc = read(fd, myid, 20);
-        if(rc < 0) {
-            perror("read(random)");
-            exit(1);
-        }
-        have_id = 1;
-        close(fd);
-
-        ofd = open(id_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-        if(ofd >= 0) {
-            rc = write(ofd, myid, 20);
-            if(rc < 20)
-                unlink(id_file);
-            close(ofd);
-        }
-    }
-
-    {
-        unsigned seed;
-        read(fd, &seed, sizeof(seed));
-        srandom(seed);
-    }
-
-    close(fd);
-
-    if(argc < 2)
-        goto usage;
-
-    i = optind;
-
-    if(argc < i + 1)
-        goto usage;
-
-    port = atoi(argv[i++]);
-    if(port <= 0 || port >= 0x10000)
-        goto usage;
-
-    while(i < argc) {
-        struct addrinfo hints, *info, *infop;
-        memset(&hints, 0, sizeof(hints));
-        hints.ai_socktype = SOCK_DGRAM;
-        if(!ipv6)
-            hints.ai_family = AF_INET;
-        else if(!ipv4)
-            hints.ai_family = AF_INET6;
-        else
-            hints.ai_family = 0;
-        rc = getaddrinfo(argv[i], argv[i + 1], &hints, &info);
-        if(rc != 0) {
-            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rc));
-            exit(1);
-        }
-
-        i++;
-        if(i >= argc)
-            goto usage;
-
-        infop = info;
-        while(infop) {
-            memcpy(&bootstrap_nodes[num_bootstrap_nodes],
-                   infop->ai_addr, infop->ai_addrlen);
-            infop = infop->ai_next;
-            num_bootstrap_nodes++;
-        }
-        freeaddrinfo(info);
-
-        i++;
-    }
-
-    /* If you set dht_debug to a stream, every action taken by the DHT will
-       be logged. */
-    if(!quiet)
-        dht_debug = stdout;
-
-    /* We need an IPv4 and an IPv6 socket, bound to a stable port.  Rumour
-       has it that uTorrent works better when it is the same as your
-       Bittorrent port. */
-    if(ipv4) {
-        s = socket(PF_INET, SOCK_DGRAM, 0);
-        if(s < 0) {
-            perror("socket(IPv4)");
-        }
-    }
-
-    if(ipv6) {
-        s6 = socket(PF_INET6, SOCK_DGRAM, 0);
-        if(s6 < 0) {
-            perror("socket(IPv6)");
-        }
-    }
-
-    if(s < 0 && s6 < 0) {
-        fprintf(stderr, "Eek!");
-        exit(1);
-    }
-
-
-    if(s >= 0) {
-        sin.sin_port = htons(port);
-        rc = bind(s, (struct sockaddr*)&sin, sizeof(sin));
-        if(rc < 0) {
-            perror("bind(IPv4)");
-            exit(1);
-        }
-    }
-
-    if(s6 >= 0) {
-        int rc;
-        int val = 1;
-
-        rc = setsockopt(s6, IPPROTO_IPV6, IPV6_V6ONLY,
-                        (char *)&val, sizeof(val));
-        if(rc < 0) {
-            perror("setsockopt(IPV6_V6ONLY)");
-            exit(1);
-        }
-
-        /* BEP-32 mandates that we should bind this socket to one of our
-           global IPv6 addresses.  In this simple example, this only
-           happens if the user used the -b flag. */
-
-        sin6.sin6_port = htons(port);
-        rc = bind(s6, (struct sockaddr*)&sin6, sizeof(sin6));
-        if(rc < 0) {
-            perror("bind(IPv6)");
-            exit(1);
-        }
-    }
-
-    /* Init the dht.  This sets the socket into non-blocking mode. */
-    rc = dht_init(s, s6, myid, (unsigned char*)"JC\0\0");
-    if(rc < 0) {
-        perror("dht_init");
-        exit(1);
-    }
-
-    init_signals();
-
-    /* For bootstrapping, we need an initial list of nodes.  This could be
-       hard-wired, but can also be obtained from the nodes key of a torrent
-       file, or from the PORT bittorrent message.
-
-       Dht_ping_node is the brutal way of bootstrapping -- it actually
-       sends a message to the peer.  If you're going to bootstrap from
-       a massive number of nodes (for example because you're restoring from
-       a dump) and you already know their ids, it's better to use
-       dht_insert_node.  If the ids are incorrect, the DHT will recover. */
-    for(i = 0; i < num_bootstrap_nodes; i++) {
-        dht_ping_node((struct sockaddr*)&bootstrap_nodes[i],
-                      sizeof(bootstrap_nodes[i]));
-        usleep(random() % 100000);
-    }
-
-    while(1) {
-        struct timeval tv;
-        fd_set readfds;
-        tv.tv_sec = tosleep;
-        tv.tv_usec = random() % 1000000;
-
-        FD_ZERO(&readfds);
-        if(s >= 0)
-            FD_SET(s, &readfds);
-        if(s6 >= 0)
-            FD_SET(s6, &readfds);
-        rc = select(s > s6 ? s + 1 : s6 + 1, &readfds, NULL, NULL, &tv);
-        if(rc < 0) {
-            if(errno != EINTR) {
-                perror("select");
-                sleep(1);
-            }
-        }
-        
-        if(exiting)
-            break;
-
-        if(rc > 0) {
-            fromlen = sizeof(from);
-            if(s >= 0 && FD_ISSET(s, &readfds))
-                rc = recvfrom(s, buf, sizeof(buf) - 1, 0,
-                              (struct sockaddr*)&from, &fromlen);
-            else if(s6 >= 0 && FD_ISSET(s6, &readfds))
-                rc = recvfrom(s6, buf, sizeof(buf) - 1, 0,
-                              (struct sockaddr*)&from, &fromlen);
-            else
-                abort();
-        }
-
-        if(rc > 0) {
-            buf[rc] = '\0';
-            rc = dht_periodic(buf, rc, (struct sockaddr*)&from, fromlen,
-                              &tosleep, callback, NULL);
-        } else {
-            rc = dht_periodic(NULL, 0, NULL, 0, &tosleep, callback, NULL);
-        }
-        if(rc < 0) {
-            if(errno == EINTR) {
-                continue;
-            } else {
-                perror("dht_periodic");
-                if(rc == EINVAL || rc == EFAULT)
-                    abort();
-                tosleep = 1;
-            }
-        }
-
-        /* This is how you trigger a search for a torrent hash.  If port
-           (the second argument) is non-zero, it also performs an announce.
-           Since peers expire announced data after 30 minutes, it's a good
-           idea to reannounce every 28 minutes or so. */
-        if(searching) {
-            if(s >= 0)
-                dht_search(hash, 0, AF_INET, callback, NULL);
-            if(s6 >= 0)
-                dht_search(hash, 0, AF_INET6, callback, NULL);
-            searching = 0;
-        }
-
-        /* For debugging, or idle curiosity. */
-        if(dumping) {
-            dht_dump_tables(stdout);
-            dumping = 0;
-        }
-    }
-
-    {
-        struct sockaddr_in sin[500];
-        struct sockaddr_in6 sin6[500];
-        int num = 500, num6 = 500;
-        int i;
-        i = dht_get_nodes(sin, &num, sin6, &num6);
-        printf("Found %d (%d + %d) good nodes.\n", i, num, num6);
-    }
-
-    dht_uninit();
-    return 0;
-    
- usage:
-    printf("Usage: dht-example [-q] [-4] [-6] [-i filename] [-b address]...\n"
-           "                   port [address port]...\n");
-    exit(1);
-}
-
-/* Functions called by the DHT. */
-
-int
-dht_blacklisted(const struct sockaddr *sa, int salen)
-{
-    return 0;
-}
-
-/* We need to provide a reasonably strong cryptographic hashing function.
-   Here's how we'd do it if we had RSA's MD5 code. */
-#if 0
-void
-dht_hash(void *hash_return, int hash_size,
-         const void *v1, int len1,
-         const void *v2, int len2,
-         const void *v3, int len3)
-{
-    static MD5_CTX ctx;
-    MD5Init(&ctx);
-    MD5Update(&ctx, v1, len1);
-    MD5Update(&ctx, v2, len2);
-    MD5Update(&ctx, v3, len3);
-    MD5Final(&ctx);
-    if(hash_size > 16)
-        memset((char*)hash_return + 16, 0, hash_size - 16);
-    memcpy(hash_return, ctx.digest, hash_size > 16 ? 16 : hash_size);
-}
-#else
-/* But for this example, we might as well use something weaker. */
-void
-dht_hash(void *hash_return, int hash_size,
-         const void *v1, int len1,
-         const void *v2, int len2,
-         const void *v3, int len3)
-{
-    const char *c1 = v1, *c2 = v2, *c3 = v3;
-    char key[9];                /* crypt is limited to 8 characters */
-    int i;
-
-    memset(key, 0, 9);
-#define CRYPT_HAPPY(c) ((c % 0x60) + 0x20)
-
-    for(i = 0; i < 2 && i < len1; i++)
-        key[i] = CRYPT_HAPPY(c1[i]);
-    for(i = 0; i < 4 && i < len1; i++)
-        key[2 + i] = CRYPT_HAPPY(c2[i]);
-    for(i = 0; i < 2 && i < len1; i++)
-        key[6 + i] = CRYPT_HAPPY(c3[i]);
-    strncpy(hash_return, crypt(key, "jc"), hash_size);
-}
-#endif
-
-int
-dht_random_bytes(void *buf, size_t size)
-{
-    int fd, rc, save;
-
-    fd = open("/dev/urandom", O_RDONLY);
-    if(fd < 0)
-        return -1;
-
-    rc = read(fd, buf, size);
-
-    save = errno;
-    close(fd);
-    errno = save;
-
-    return rc;
-}
diff --git a/third-party/dht/dht.c b/third-party/dht/dht.c
deleted file mode 100644 (file)
index 61522bf..0000000
+++ /dev/null
@@ -1,2969 +0,0 @@
-/*
-Copyright (c) 2009-2011 by Juliusz Chroboczek
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-/* Please, please, please.
-
-   You are welcome to integrate this code in your favourite Bittorrent
-   client.  Please remember, however, that it is meant to be usable by
-   others, including myself.  This means no C++, no relicensing, and no
-   gratuitious changes to the coding style.  And please send back any
-   improvements to the author. */
-
-/* For memmem. */
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/time.h>
-
-#ifndef WIN32
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#else
-#include <w32api.h>
-#define WINVER WindowsXP
-#include <ws2tcpip.h>
-#endif
-
-#include "dht.h"
-
-#ifndef HAVE_MEMMEM
-#ifdef __GLIBC__
-#define HAVE_MEMMEM
-#endif
-#endif
-
-#ifndef MSG_CONFIRM
-#define MSG_CONFIRM 0
-#endif
-
-#ifdef WIN32
-
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-static int
-set_nonblocking(int fd, int nonblocking)
-{
-    int rc;
-
-    unsigned long mode = !!nonblocking;
-    rc = ioctlsocket(fd, FIONBIO, &mode);
-    if(rc != 0)
-        errno = WSAGetLastError();
-    return (rc == 0 ? 0 : -1);
-}
-
-static int
-random(void)
-{
-    return rand();
-}
-extern const char *inet_ntop(int, const void *, char *, socklen_t);
-
-#else
-
-static int
-set_nonblocking(int fd, int nonblocking)
-{
-    int rc;
-    rc = fcntl(fd, F_GETFL, 0);
-    if(rc < 0)
-        return -1;
-
-    rc = fcntl(fd, F_SETFL, nonblocking?(rc | O_NONBLOCK):(rc & ~O_NONBLOCK));
-    if(rc < 0)
-        return -1;
-
-    return 0;
-}
-
-#endif
-
-/* We set sin_family to 0 to mark unused slots. */
-#if AF_INET == 0 || AF_INET6 == 0
-#error You lose
-#endif
-
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-/* nothing */
-#elif defined(__GNUC__)
-#define inline __inline
-#if  (__GNUC__ >= 3)
-#define restrict __restrict
-#else
-#define restrict /**/
-#endif
-#else
-#define inline /**/
-#define restrict /**/
-#endif
-
-#define MAX(x, y) ((x) >= (y) ? (x) : (y))
-#define MIN(x, y) ((x) <= (y) ? (x) : (y))
-
-struct node {
-    unsigned char id[20];
-    struct sockaddr_storage ss;
-    int sslen;
-    time_t time;                /* time of last message received */
-    time_t reply_time;          /* time of last correct reply received */
-    time_t pinged_time;         /* time of last request */
-    int pinged;                 /* how many requests we sent since last reply */
-    struct node *next;
-};
-
-struct bucket {
-    int af;
-    unsigned char first[20];
-    int count;                  /* number of nodes */
-    int time;                   /* time of last reply in this bucket */
-    struct node *nodes;
-    struct sockaddr_storage cached;  /* the address of a likely candidate */
-    int cachedlen;
-    struct bucket *next;
-};
-
-struct search_node {
-    unsigned char id[20];
-    struct sockaddr_storage ss;
-    int sslen;
-    time_t request_time;        /* the time of the last unanswered request */
-    time_t reply_time;          /* the time of the last reply */
-    int pinged;
-    unsigned char token[40];
-    int token_len;
-    int replied;                /* whether we have received a reply */
-    int acked;                  /* whether they acked our announcement */
-};
-
-/* When performing a search, we search for up to SEARCH_NODES closest nodes
-   to the destination, and use the additional ones to backtrack if any of
-   the target 8 turn out to be dead. */
-#define SEARCH_NODES 14
-
-struct search {
-    unsigned short tid;
-    int af;
-    time_t step_time;           /* the time of the last search_step */
-    unsigned char id[20];
-    unsigned short port;        /* 0 for pure searches */
-    int done;
-    struct search_node nodes[SEARCH_NODES];
-    int numnodes;
-    struct search *next;
-};
-
-struct peer {
-    time_t time;
-    unsigned char ip[16];
-    unsigned short len;
-    unsigned short port;
-};
-
-/* The maximum number of peers we store for a given hash. */
-#ifndef DHT_MAX_PEERS
-#define DHT_MAX_PEERS 2048
-#endif
-
-/* The maximum number of hashes we're willing to track. */
-#ifndef DHT_MAX_HASHES
-#define DHT_MAX_HASHES 16384
-#endif
-
-/* The maximum number of searches we keep data about. */
-#ifndef DHT_MAX_SEARCHES
-#define DHT_MAX_SEARCHES 1024
-#endif
-
-/* The time after which we consider a search to be expirable. */
-#ifndef DHT_SEARCH_EXPIRE_TIME
-#define DHT_SEARCH_EXPIRE_TIME (62 * 60)
-#endif
-
-struct storage {
-    unsigned char id[20];
-    int numpeers, maxpeers;
-    struct peer *peers;
-    struct storage *next;
-};
-
-static struct storage * find_storage(const unsigned char *id);
-static void flush_search_node(struct search_node *n, struct search *sr);
-
-static int send_ping(const struct sockaddr *sa, int salen,
-                     const unsigned char *tid, int tid_len);
-static int send_pong(const struct sockaddr *sa, int salen,
-                     const unsigned char *tid, int tid_len);
-static int send_find_node(const struct sockaddr *sa, int salen,
-                          const unsigned char *tid, int tid_len,
-                          const unsigned char *target, int want, int confirm);
-static int send_nodes_peers(const struct sockaddr *sa, int salen,
-                            const unsigned char *tid, int tid_len,
-                            const unsigned char *nodes, int nodes_len,
-                            const unsigned char *nodes6, int nodes6_len,
-                            int af, struct storage *st,
-                            const unsigned char *token, int token_len);
-static int send_closest_nodes(const struct sockaddr *sa, int salen,
-                              const unsigned char *tid, int tid_len,
-                              const unsigned char *id, int want,
-                              int af, struct storage *st,
-                              const unsigned char *token, int token_len);
-static int send_get_peers(const struct sockaddr *sa, int salen,
-                          unsigned char *tid, int tid_len,
-                          unsigned char *infohash, int want, int confirm);
-static int send_announce_peer(const struct sockaddr *sa, int salen,
-                              unsigned char *tid, int tid_len,
-                              unsigned char *infohas, unsigned short port,
-                              unsigned char *token, int token_len, int confirm);
-static int send_peer_announced(const struct sockaddr *sa, int salen,
-                               unsigned char *tid, int tid_len);
-static int send_error(const struct sockaddr *sa, int salen,
-                      unsigned char *tid, int tid_len,
-                      int code, const char *message);
-
-#define ERROR 0
-#define REPLY 1
-#define PING 2
-#define FIND_NODE 3
-#define GET_PEERS 4
-#define ANNOUNCE_PEER 5
-
-#define WANT4 1
-#define WANT6 2
-
-static int parse_message(const unsigned char *buf, int buflen,
-                         unsigned char *tid_return, int *tid_len,
-                         unsigned char *id_return,
-                         unsigned char *info_hash_return,
-                         unsigned char *target_return,
-                         unsigned short *port_return,
-                         unsigned char *token_return, int *token_len,
-                         unsigned char *nodes_return, int *nodes_len,
-                         unsigned char *nodes6_return, int *nodes6_len,
-                         unsigned char *values_return, int *values_len,
-                         unsigned char *values6_return, int *values6_len,
-                         int *want_return);
-
-static const unsigned char zeroes[20] = {0};
-static const unsigned char ones[20] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF
-};
-static const unsigned char v4prefix[16] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0
-};
-
-static int dht_socket = -1;
-static int dht_socket6 = -1;
-
-static time_t search_time;
-static time_t confirm_nodes_time;
-static time_t rotate_secrets_time;
-
-static unsigned char myid[20];
-static int have_v = 0;
-static unsigned char my_v[9];
-static unsigned char secret[8];
-static unsigned char oldsecret[8];
-
-static struct bucket *buckets = NULL;
-static struct bucket *buckets6 = NULL;
-static struct storage *storage;
-static int numstorage;
-
-static struct search *searches = NULL;
-static int numsearches;
-static unsigned short search_id;
-
-/* The maximum number of nodes that we snub.  There is probably little
-   reason to increase this value. */
-#ifndef DHT_MAX_BLACKLISTED
-#define DHT_MAX_BLACKLISTED 10
-#endif
-static struct sockaddr_storage blacklist[DHT_MAX_BLACKLISTED];
-int next_blacklisted;
-
-static struct timeval now;
-static time_t mybucket_grow_time, mybucket6_grow_time;
-static time_t expire_stuff_time;
-
-#define MAX_TOKEN_BUCKET_TOKENS 400
-static time_t token_bucket_time;
-static int token_bucket_tokens;
-
-FILE *dht_debug = NULL;
-
-#ifdef __GNUC__
-    __attribute__ ((format (printf, 1, 2)))
-#endif
-static void
-debugf(const char *format, ...)
-{
-    va_list args;
-    va_start(args, format);
-    if(dht_debug)
-        vfprintf(dht_debug, format, args);
-    va_end(args);
-    if(dht_debug)
-        fflush(dht_debug);
-}
-
-static void
-debug_printable(const unsigned char *buf, int buflen)
-{
-    int i;
-    if(dht_debug) {
-        for(i = 0; i < buflen; i++)
-            putc(buf[i] >= 32 && buf[i] <= 126 ? buf[i] : '.', dht_debug);
-    }
-}
-
-static void
-print_hex(FILE *f, const unsigned char *buf, int buflen)
-{
-    int i;
-    for(i = 0; i < buflen; i++)
-        fprintf(f, "%02x", buf[i]);
-}
-
-static int
-is_martian(const struct sockaddr *sa)
-{
-    switch(sa->sa_family) {
-    case AF_INET: {
-        struct sockaddr_in *sin = (struct sockaddr_in*)sa;
-        const unsigned char *address = (const unsigned char*)&sin->sin_addr;
-        return sin->sin_port == 0 ||
-            (address[0] == 0) ||
-            (address[0] == 127) ||
-            ((address[0] & 0xE0) == 0xE0);
-    }
-    case AF_INET6: {
-        struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
-        const unsigned char *address = (const unsigned char*)&sin6->sin6_addr;
-        return sin6->sin6_port == 0 ||
-            (address[0] == 0xFF) ||
-            (address[0] == 0xFE && (address[1] & 0xC0) == 0x80) ||
-            (memcmp(address, zeroes, 15) == 0 &&
-             (address[15] == 0 || address[15] == 1)) ||
-            (memcmp(address, v4prefix, 12) == 0);
-    }
-
-    default:
-        return 0;
-    }
-}
-
-/* Forget about the ``XOR-metric''.  An id is just a path from the
-   root of the tree, so bits are numbered from the start. */
-
-static int
-id_cmp(const unsigned char *restrict id1, const unsigned char *restrict id2)
-{
-    /* Memcmp is guaranteed to perform an unsigned comparison. */
-    return memcmp(id1, id2, 20);
-}
-
-/* Find the lowest 1 bit in an id. */
-static int
-lowbit(const unsigned char *id)
-{
-    int i, j;
-    for(i = 19; i >= 0; i--)
-        if(id[i] != 0)
-            break;
-
-    if(i < 0)
-        return -1;
-
-    for(j = 7; j >= 0; j--)
-        if((id[i] & (0x80 >> j)) != 0)
-            break;
-
-    return 8 * i + j;
-}
-
-/* Find how many bits two ids have in common. */
-static int
-common_bits(const unsigned char *id1, const unsigned char *id2)
-{
-    int i, j;
-    unsigned char xor;
-    for(i = 0; i < 20; i++) {
-        if(id1[i] != id2[i])
-            break;
-    }
-
-    if(i == 20)
-        return 160;
-
-    xor = id1[i] ^ id2[i];
-
-    j = 0;
-    while((xor & 0x80) == 0) {
-        xor <<= 1;
-        j++;
-    }
-
-    return 8 * i + j;
-}
-
-/* Determine whether id1 or id2 is closer to ref */
-static int
-xorcmp(const unsigned char *id1, const unsigned char *id2,
-       const unsigned char *ref)
-{
-    int i;
-    for(i = 0; i < 20; i++) {
-        unsigned char xor1, xor2;
-        if(id1[i] == id2[i])
-            continue;
-        xor1 = id1[i] ^ ref[i];
-        xor2 = id2[i] ^ ref[i];
-        if(xor1 < xor2)
-            return -1;
-        else
-            return 1;
-    }
-    return 0;
-}
-
-/* We keep buckets in a sorted linked list.  A bucket b ranges from
-   b->first inclusive up to b->next->first exclusive. */
-static int
-in_bucket(const unsigned char *id, struct bucket *b)
-{
-    return id_cmp(b->first, id) <= 0 &&
-        (b->next == NULL || id_cmp(id, b->next->first) < 0);
-}
-
-static struct bucket *
-find_bucket(unsigned const char *id, int af)
-{
-    struct bucket *b = af == AF_INET ? buckets : buckets6;
-
-    if(b == NULL)
-        return NULL;
-
-    while(1) {
-        if(b->next == NULL)
-            return b;
-        if(id_cmp(id, b->next->first) < 0)
-            return b;
-        b = b->next;
-    }
-}
-
-static struct bucket *
-previous_bucket(struct bucket *b)
-{
-    struct bucket *p = b->af == AF_INET ? buckets : buckets6;
-
-    if(b == p)
-        return NULL;
-
-    while(1) {
-        if(p->next == NULL)
-            return NULL;
-        if(p->next == b)
-            return p;
-        p = p->next;
-    }
-}
-
-/* Every bucket contains an unordered list of nodes. */
-static struct node *
-find_node(const unsigned char *id, int af)
-{
-    struct bucket *b = find_bucket(id, af);
-    struct node *n;
-
-    if(b == NULL)
-        return NULL;
-
-    n = b->nodes;
-    while(n) {
-        if(id_cmp(n->id, id) == 0)
-            return n;
-        n = n->next;
-    }
-    return NULL;
-}
-
-/* Return a random node in a bucket. */
-static struct node *
-random_node(struct bucket *b)
-{
-    struct node *n;
-    int nn;
-
-    if(b->count == 0)
-        return NULL;
-
-    nn = random() % b->count;
-    n = b->nodes;
-    while(nn > 0 && n) {
-        n = n->next;
-        nn--;
-    }
-    return n;
-}
-
-/* Return the middle id of a bucket. */
-static int
-bucket_middle(struct bucket *b, unsigned char *id_return)
-{
-    int bit1 = lowbit(b->first);
-    int bit2 = b->next ? lowbit(b->next->first) : -1;
-    int bit = MAX(bit1, bit2) + 1;
-
-    if(bit >= 160)
-        return -1;
-
-    memcpy(id_return, b->first, 20);
-    id_return[bit / 8] |= (0x80 >> (bit % 8));
-    return 1;
-}
-
-/* Return a random id within a bucket. */
-static int
-bucket_random(struct bucket *b, unsigned char *id_return)
-{
-    int bit1 = lowbit(b->first);
-    int bit2 = b->next ? lowbit(b->next->first) : -1;
-    int bit = MAX(bit1, bit2) + 1;
-    int i;
-
-    if(bit >= 160) {
-        memcpy(id_return, b->first, 20);
-        return 1;
-    }
-
-    memcpy(id_return, b->first, bit / 8);
-    id_return[bit / 8] = b->first[bit / 8] & (0xFF00 >> (bit % 8));
-    id_return[bit / 8] |= random() & 0xFF >> (bit % 8);
-    for(i = bit / 8 + 1; i < 20; i++)
-        id_return[i] = random() & 0xFF;
-    return 1;
-}
-
-/* Insert a new node into a bucket. */
-static struct node *
-insert_node(struct node *node)
-{
-    struct bucket *b = find_bucket(node->id, node->ss.ss_family);
-
-    if(b == NULL)
-        return NULL;
-
-    node->next = b->nodes;
-    b->nodes = node;
-    b->count++;
-    return node;
-}
-
-/* This is our definition of a known-good node. */
-static int
-node_good(struct node *node)
-{
-    return
-        node->pinged <= 2 &&
-        node->reply_time >= now.tv_sec - 7200 &&
-        node->time >= now.tv_sec - 900;
-}
-
-/* Our transaction-ids are 4-bytes long, with the first two bytes identi-
-   fying the kind of request, and the remaining two a sequence number in
-   host order. */
-
-static void
-make_tid(unsigned char *tid_return, const char *prefix, unsigned short seqno)
-{
-    tid_return[0] = prefix[0] & 0xFF;
-    tid_return[1] = prefix[1] & 0xFF;
-    memcpy(tid_return + 2, &seqno, 2);
-}
-
-static int
-tid_match(const unsigned char *tid, const char *prefix,
-          unsigned short *seqno_return)
-{
-    if(tid[0] == (prefix[0] & 0xFF) && tid[1] == (prefix[1] & 0xFF)) {
-        if(seqno_return)
-            memcpy(seqno_return, tid + 2, 2);
-        return 1;
-    } else
-        return 0;
-}
-
-/* Every bucket caches the address of a likely node.  Ping it. */
-static int
-send_cached_ping(struct bucket *b)
-{
-    unsigned char tid[4];
-    int rc;
-    /* We set family to 0 when there's no cached node. */
-    if(b->cached.ss_family == 0)
-        return 0;
-
-    debugf("Sending ping to cached node.\n");
-    make_tid(tid, "pn", 0);
-    rc = send_ping((struct sockaddr*)&b->cached, b->cachedlen, tid, 4);
-    b->cached.ss_family = 0;
-    b->cachedlen = 0;
-    return rc;
-}
-
-/* Called whenever we send a request to a node, increases the ping count
-   and, if that reaches 3, sends a ping to a new candidate. */
-static void
-pinged(struct node *n, struct bucket *b)
-{
-    n->pinged++;
-    n->pinged_time = now.tv_sec;
-    if(n->pinged >= 3)
-        send_cached_ping(b ? b : find_bucket(n->id, n->ss.ss_family));
-}
-
-/* The internal blacklist is an LRU cache of nodes that have sent
-   incorrect messages. */
-static void
-blacklist_node(const unsigned char *id, const struct sockaddr *sa, int salen)
-{
-    int i;
-
-    debugf("Blacklisting broken node.\n");
-
-    if(id) {
-        struct node *n;
-        struct search *sr;
-        /* Make the node easy to discard. */
-        n = find_node(id, sa->sa_family);
-        if(n) {
-            n->pinged = 3;
-            pinged(n, NULL);
-        }
-        /* Discard it from any searches in progress. */
-        sr = searches;
-        while(sr) {
-            for(i = 0; i < sr->numnodes; i++)
-                if(id_cmp(sr->nodes[i].id, id) == 0)
-                    flush_search_node(&sr->nodes[i], sr);
-            sr = sr->next;
-        }
-    }
-    /* And make sure we don't hear from it again. */
-    memcpy(&blacklist[next_blacklisted], sa, salen);
-    next_blacklisted = (next_blacklisted + 1) % DHT_MAX_BLACKLISTED;
-}
-
-static int
-node_blacklisted(const struct sockaddr *sa, int salen)
-{
-    int i;
-
-    if((unsigned)salen > sizeof(struct sockaddr_storage))
-        abort();
-
-    if(dht_blacklisted(sa, salen))
-        return 1;
-
-    for(i = 0; i < DHT_MAX_BLACKLISTED; i++) {
-        if(memcmp(&blacklist[i], sa, salen) == 0)
-            return 1;
-    }
-
-    return 0;
-}
-
-/* Split a bucket into two equal parts. */
-static struct bucket *
-split_bucket(struct bucket *b)
-{
-    struct bucket *new;
-    struct node *nodes;
-    int rc;
-    unsigned char new_id[20];
-
-    rc = bucket_middle(b, new_id);
-    if(rc < 0)
-        return NULL;
-
-    new = calloc(1, sizeof(struct bucket));
-    if(new == NULL)
-        return NULL;
-
-    new->af = b->af;
-
-    send_cached_ping(b);
-
-    memcpy(new->first, new_id, 20);
-    new->time = b->time;
-
-    nodes = b->nodes;
-    b->nodes = NULL;
-    b->count = 0;
-    new->next = b->next;
-    b->next = new;
-    while(nodes) {
-        struct node *n;
-        n = nodes;
-        nodes = nodes->next;
-        insert_node(n);
-    }
-    return b;
-}
-
-/* We just learnt about a node, not necessarily a new one.  Confirm is 1 if
-   the node sent a message, 2 if it sent us a reply. */
-static struct node *
-new_node(const unsigned char *id, const struct sockaddr *sa, int salen,
-         int confirm)
-{
-    struct bucket *b = find_bucket(id, sa->sa_family);
-    struct node *n;
-    int mybucket, split;
-
-    if(b == NULL)
-        return NULL;
-
-    if(id_cmp(id, myid) == 0)
-        return NULL;
-
-    if(is_martian(sa) || node_blacklisted(sa, salen))
-        return NULL;
-
-    mybucket = in_bucket(myid, b);
-
-    if(confirm == 2)
-        b->time = now.tv_sec;
-
-    n = b->nodes;
-    while(n) {
-        if(id_cmp(n->id, id) == 0) {
-            if(confirm || n->time < now.tv_sec - 15 * 60) {
-                /* Known node.  Update stuff. */
-                memcpy((struct sockaddr*)&n->ss, sa, salen);
-                if(confirm)
-                    n->time = now.tv_sec;
-                if(confirm >= 2) {
-                    n->reply_time = now.tv_sec;
-                    n->pinged = 0;
-                    n->pinged_time = 0;
-                }
-            }
-            return n;
-        }
-        n = n->next;
-    }
-
-    /* New node. */
-
-    if(mybucket) {
-        if(sa->sa_family == AF_INET)
-            mybucket_grow_time = now.tv_sec;
-        else
-            mybucket6_grow_time = now.tv_sec;
-    }
-
-    /* First, try to get rid of a known-bad node. */
-    n = b->nodes;
-    while(n) {
-        if(n->pinged >= 3 && n->pinged_time < now.tv_sec - 15) {
-            memcpy(n->id, id, 20);
-            memcpy((struct sockaddr*)&n->ss, sa, salen);
-            n->time = confirm ? now.tv_sec : 0;
-            n->reply_time = confirm >= 2 ? now.tv_sec : 0;
-            n->pinged_time = 0;
-            n->pinged = 0;
-            return n;
-        }
-        n = n->next;
-    }
-
-    if(b->count >= 8) {
-        /* Bucket full.  Ping a dubious node */
-        int dubious = 0;
-        n = b->nodes;
-        while(n) {
-            /* Pick the first dubious node that we haven't pinged in the
-               last 15 seconds.  This gives nodes the time to reply, but
-               tends to concentrate on the same nodes, so that we get rid
-               of bad nodes fast. */
-            if(!node_good(n)) {
-                dubious = 1;
-                if(n->pinged_time < now.tv_sec - 15) {
-                    unsigned char tid[4];
-                    debugf("Sending ping to dubious node.\n");
-                    make_tid(tid, "pn", 0);
-                    send_ping((struct sockaddr*)&n->ss, n->sslen,
-                              tid, 4);
-                    n->pinged++;
-                    n->pinged_time = now.tv_sec;
-                    break;
-                }
-            }
-            n = n->next;
-        }
-
-        split = 0;
-        if(mybucket) {
-            if(!dubious)
-                split = 1;
-            /* If there's only one bucket, split eagerly.  This is
-               incorrect unless there's more than 8 nodes in the DHT. */
-            else if(b->af == AF_INET && buckets->next == NULL)
-                split = 1;
-            else if(b->af == AF_INET6 && buckets6->next == NULL)
-                split = 1;
-        }
-
-        if(split) {
-            debugf("Splitting.\n");
-            b = split_bucket(b);
-            return new_node(id, sa, salen, confirm);
-        }
-
-        /* No space for this node.  Cache it away for later. */
-        if(confirm || b->cached.ss_family == 0) {
-            memcpy(&b->cached, sa, salen);
-            b->cachedlen = salen;
-        }
-
-        return NULL;
-    }
-
-    /* Create a new node. */
-    n = calloc(1, sizeof(struct node));
-    if(n == NULL)
-        return NULL;
-    memcpy(n->id, id, 20);
-    memcpy(&n->ss, sa, salen);
-    n->sslen = salen;
-    n->time = confirm ? now.tv_sec : 0;
-    n->reply_time = confirm >= 2 ? now.tv_sec : 0;
-    n->next = b->nodes;
-    b->nodes = n;
-    b->count++;
-    return n;
-}
-
-/* Called periodically to purge known-bad nodes.  Note that we're very
-   conservative here: broken nodes in the table don't do much harm, we'll
-   recover as soon as we find better ones. */
-static int
-expire_buckets(struct bucket *b)
-{
-    while(b) {
-        struct node *n, *p;
-        int changed = 0;
-
-        while(b->nodes && b->nodes->pinged >= 4) {
-            n = b->nodes;
-            b->nodes = n->next;
-            b->count--;
-            changed = 1;
-            free(n);
-        }
-
-        p = b->nodes;
-        while(p) {
-            while(p->next && p->next->pinged >= 4) {
-                n = p->next;
-                p->next = n->next;
-                b->count--;
-                changed = 1;
-                free(n);
-            }
-            p = p->next;
-        }
-
-        if(changed)
-            send_cached_ping(b);
-
-        b = b->next;
-    }
-    expire_stuff_time = now.tv_sec + 120 + random() % 240;
-    return 1;
-}
-
-/* While a search is in progress, we don't necessarily keep the nodes being
-   walked in the main bucket table.  A search in progress is identified by
-   a unique transaction id, a short (and hence small enough to fit in the
-   transaction id of the protocol packets). */
-
-static struct search *
-find_search(unsigned short tid, int af)
-{
-    struct search *sr = searches;
-    while(sr) {
-        if(sr->tid == tid && sr->af == af)
-            return sr;
-        sr = sr->next;
-    }
-    return NULL;
-}
-
-/* A search contains a list of nodes, sorted by decreasing distance to the
-   target.  We just got a new candidate, insert it at the right spot or
-   discard it. */
-
-static int
-insert_search_node(unsigned char *id,
-                   const struct sockaddr *sa, int salen,
-                   struct search *sr, int replied,
-                   unsigned char *token, int token_len)
-{
-    struct search_node *n;
-    int i, j;
-
-    if(sa->sa_family != sr->af) {
-        debugf("Attempted to insert node in the wrong family.\n");
-        return 0;
-    }
-
-    for(i = 0; i < sr->numnodes; i++) {
-        if(id_cmp(id, sr->nodes[i].id) == 0) {
-            n = &sr->nodes[i];
-            goto found;
-        }
-        if(xorcmp(id, sr->nodes[i].id, sr->id) < 0)
-            break;
-    }
-
-    if(i == SEARCH_NODES)
-        return 0;
-
-    if(sr->numnodes < SEARCH_NODES)
-        sr->numnodes++;
-
-    for(j = sr->numnodes - 1; j > i; j--) {
-        sr->nodes[j] = sr->nodes[j - 1];
-    }
-
-    n = &sr->nodes[i];
-
-    memset(n, 0, sizeof(struct search_node));
-    memcpy(n->id, id, 20);
-
-found:
-    memcpy(&n->ss, sa, salen);
-    n->sslen = salen;
-
-    if(replied) {
-        n->replied = 1;
-        n->reply_time = now.tv_sec;
-        n->request_time = 0;
-        n->pinged = 0;
-    }
-    if(token) {
-        if(token_len >= 40) {
-            debugf("Eek!  Overlong token.\n");
-        } else {
-            memcpy(n->token, token, token_len);
-            n->token_len = token_len;
-        }
-    }
-
-    return 1;
-}
-
-static void
-flush_search_node(struct search_node *n, struct search *sr)
-{
-    int i = n - sr->nodes, j;
-    for(j = i; j < sr->numnodes - 1; j++)
-        sr->nodes[j] = sr->nodes[j + 1];
-    sr->numnodes--;
-}
-
-static void
-expire_searches(void)
-{
-    struct search *sr = searches, *previous = NULL;
-
-    while(sr) {
-        struct search *next = sr->next;
-        if(sr->step_time < now.tv_sec - DHT_SEARCH_EXPIRE_TIME) {
-            if(previous)
-                previous->next = next;
-            else
-                searches = next;
-            free(sr);
-            numsearches--;
-        } else {
-            previous = sr;
-        }
-        sr = next;
-    }
-}
-
-/* This must always return 0 or 1, never -1, not even on failure (see below). */
-static int
-search_send_get_peers(struct search *sr, struct search_node *n)
-{
-    struct node *node;
-    unsigned char tid[4];
-
-    if(n == NULL) {
-        int i;
-        for(i = 0; i < sr->numnodes; i++) {
-            if(sr->nodes[i].pinged < 3 && !sr->nodes[i].replied &&
-               sr->nodes[i].request_time < now.tv_sec - 15)
-                n = &sr->nodes[i];
-        }
-    }
-
-    if(!n || n->pinged >= 3 || n->replied ||
-       n->request_time >= now.tv_sec - 15)
-        return 0;
-
-    debugf("Sending get_peers.\n");
-    make_tid(tid, "gp", sr->tid);
-    send_get_peers((struct sockaddr*)&n->ss, n->sslen, tid, 4, sr->id, -1,
-                   n->reply_time >= now.tv_sec - 15);
-    n->pinged++;
-    n->request_time = now.tv_sec;
-    /* If the node happens to be in our main routing table, mark it
-       as pinged. */
-    node = find_node(n->id, n->ss.ss_family);
-    if(node) pinged(node, NULL);
-    return 1;
-}
-
-/* When a search is in progress, we periodically call search_step to send
-   further requests. */
-static void
-search_step(struct search *sr, dht_callback *callback, void *closure)
-{
-    int i, j;
-    int all_done = 1;
-
-    /* Check if the first 8 live nodes have replied. */
-    j = 0;
-    for(i = 0; i < sr->numnodes && j < 8; i++) {
-        struct search_node *n = &sr->nodes[i];
-        if(n->pinged >= 3)
-            continue;
-        if(!n->replied) {
-            all_done = 0;
-            break;
-        }
-        j++;
-    }
-
-    if(all_done) {
-        if(sr->port == 0) {
-            goto done;
-        } else {
-            int all_acked = 1;
-            j = 0;
-            for(i = 0; i < sr->numnodes && j < 8; i++) {
-                struct search_node *n = &sr->nodes[i];
-                struct node *node;
-                unsigned char tid[4];
-                if(n->pinged >= 3)
-                    continue;
-                /* A proposed extension to the protocol consists in
-                   omitting the token when storage tables are full.  While
-                   I don't think this makes a lot of sense -- just sending
-                   a positive reply is just as good --, let's deal with it. */
-                if(n->token_len == 0)
-                    n->acked = 1;
-                if(!n->acked) {
-                    all_acked = 0;
-                    debugf("Sending announce_peer.\n");
-                    make_tid(tid, "ap", sr->tid);
-                    send_announce_peer((struct sockaddr*)&n->ss,
-                                       sizeof(struct sockaddr_storage),
-                                       tid, 4, sr->id, sr->port,
-                                       n->token, n->token_len,
-                                       n->reply_time >= now.tv_sec - 15);
-                    n->pinged++;
-                    n->request_time = now.tv_sec;
-                    node = find_node(n->id, n->ss.ss_family);
-                    if(node) pinged(node, NULL);
-                }
-                j++;
-            }
-            if(all_acked)
-                goto done;
-        }
-        sr->step_time = now.tv_sec;
-        return;
-    }
-
-    if(sr->step_time + 15 >= now.tv_sec)
-        return;
-
-    j = 0;
-    for(i = 0; i < sr->numnodes; i++) {
-        j += search_send_get_peers(sr, &sr->nodes[i]);
-        if(j >= 3)
-            break;
-    }
-    sr->step_time = now.tv_sec;
-    return;
-
- done:
-    sr->done = 1;
-    if(callback)
-        (*callback)(closure,
-                    sr->af == AF_INET ?
-                    DHT_EVENT_SEARCH_DONE : DHT_EVENT_SEARCH_DONE6,
-                    sr->id, NULL, 0);
-    sr->step_time = now.tv_sec;
-}
-
-static struct search *
-new_search(void)
-{
-    struct search *sr, *oldest = NULL;
-
-    /* Find the oldest done search */
-    sr = searches;
-    while(sr) {
-        if(sr->done &&
-           (oldest == NULL || oldest->step_time > sr->step_time))
-            oldest = sr;
-        sr = sr->next;
-    }
-
-    /* The oldest slot is expired. */
-    if(oldest && oldest->step_time < now.tv_sec - DHT_SEARCH_EXPIRE_TIME)
-        return oldest;
-
-    /* Allocate a new slot. */
-    if(numsearches < DHT_MAX_SEARCHES) {
-        sr = calloc(1, sizeof(struct search));
-        if(sr != NULL) {
-            sr->next = searches;
-            searches = sr;
-            numsearches++;
-            return sr;
-        }
-    }
-
-    /* Oh, well, never mind.  Reuse the oldest slot. */
-    return oldest;
-}
-
-/* Insert the contents of a bucket into a search structure. */
-static void
-insert_search_bucket(struct bucket *b, struct search *sr)
-{
-    struct node *n;
-    n = b->nodes;
-    while(n) {
-        insert_search_node(n->id, (struct sockaddr*)&n->ss, n->sslen,
-                           sr, 0, NULL, 0);
-        n = n->next;
-    }
-}
-
-/* Start a search.  If port is non-zero, perform an announce when the
-   search is complete. */
-int
-dht_search(const unsigned char *id, int port, int af,
-           dht_callback *callback, void *closure)
-{
-    struct search *sr;
-    struct storage *st;
-    struct bucket *b = find_bucket(id, af);
-
-    if(b == NULL) {
-        errno = EAFNOSUPPORT;
-        return -1;
-    }
-
-    /* Try to answer this search locally.  In a fully grown DHT this
-       is very unlikely, but people are running modified versions of
-       this code in private DHTs with very few nodes.  What's wrong
-       with flooding? */
-    if(callback) {
-        st = find_storage(id);
-        if(st) {
-            unsigned short swapped;
-            unsigned char buf[18];
-            int i;
-
-            debugf("Found local data (%d peers).\n", st->numpeers);
-
-            for(i = 0; i < st->numpeers; i++) {
-                swapped = htons(st->peers[i].port);
-                if(st->peers[i].len == 4) {
-                    memcpy(buf, st->peers[i].ip, 4);
-                    memcpy(buf + 4, &swapped, 2);
-                    (*callback)(closure, DHT_EVENT_VALUES, id,
-                                (void*)buf, 6);
-                } else if(st->peers[i].len == 16) {
-                    memcpy(buf, st->peers[i].ip, 16);
-                    memcpy(buf + 16, &swapped, 2);
-                    (*callback)(closure, DHT_EVENT_VALUES6, id,
-                                (void*)buf, 18);
-                }
-            }
-        }
-    }
-
-    sr = searches;
-    while(sr) {
-        if(sr->af == af && id_cmp(sr->id, id) == 0)
-            break;
-        sr = sr->next;
-    }
-
-    if(sr) {
-        /* We're reusing data from an old search.  Reusing the same tid
-           means that we can merge replies for both searches. */
-        int i;
-        sr->done = 0;
-    again:
-        for(i = 0; i < sr->numnodes; i++) {
-            struct search_node *n;
-            n = &sr->nodes[i];
-            /* Discard any doubtful nodes. */
-            if(n->pinged >= 3 || n->reply_time < now.tv_sec - 7200) {
-                flush_search_node(n, sr);
-                goto again;
-            }
-            n->pinged = 0;
-            n->token_len = 0;
-            n->replied = 0;
-            n->acked = 0;
-        }
-    } else {
-        sr = new_search();
-        if(sr == NULL) {
-            errno = ENOSPC;
-            return -1;
-        }
-        sr->af = af;
-        sr->tid = search_id++;
-        sr->step_time = 0;
-        memcpy(sr->id, id, 20);
-        sr->done = 0;
-        sr->numnodes = 0;
-    }
-
-    sr->port = port;
-
-    insert_search_bucket(b, sr);
-
-    if(sr->numnodes < SEARCH_NODES) {
-        struct bucket *p = previous_bucket(b);
-        if(b->next)
-            insert_search_bucket(b->next, sr);
-        if(p)
-            insert_search_bucket(p, sr);
-    }
-    if(sr->numnodes < SEARCH_NODES)
-        insert_search_bucket(find_bucket(myid, af), sr);
-
-    search_step(sr, callback, closure);
-    search_time = now.tv_sec;
-    return 1;
-}
-
-/* A struct storage stores all the stored peer addresses for a given info
-   hash. */
-
-static struct storage *
-find_storage(const unsigned char *id)
-{
-    struct storage *st = storage;
-
-    while(st) {
-        if(id_cmp(id, st->id) == 0)
-            break;
-        st = st->next;
-    }
-    return st;
-}
-
-static int
-storage_store(const unsigned char *id,
-              const struct sockaddr *sa, unsigned short port)
-{
-    int i, len;
-    struct storage *st;
-    unsigned char *ip;
-
-    if(sa->sa_family == AF_INET) {
-        struct sockaddr_in *sin = (struct sockaddr_in*)sa;
-        ip = (unsigned char*)&sin->sin_addr;
-        len = 4;
-    } else if(sa->sa_family == AF_INET6) {
-        struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
-        ip = (unsigned char*)&sin6->sin6_addr;
-        len = 16;
-    } else {
-        return -1;
-    }
-
-    st = find_storage(id);
-
-    if(st == NULL) {
-        if(numstorage >= DHT_MAX_HASHES)
-            return -1;
-        st = calloc(1, sizeof(struct storage));
-        if(st == NULL) return -1;
-        memcpy(st->id, id, 20);
-        st->next = storage;
-        storage = st;
-        numstorage++;
-    }
-
-    for(i = 0; i < st->numpeers; i++) {
-        if(st->peers[i].port == port && st->peers[i].len == len &&
-           memcmp(st->peers[i].ip, ip, len) == 0)
-            break;
-    }
-
-    if(i < st->numpeers) {
-        /* Already there, only need to refresh */
-        st->peers[i].time = now.tv_sec;
-        return 0;
-    } else {
-        struct peer *p;
-        if(i >= st->maxpeers) {
-            /* Need to expand the array. */
-            struct peer *new_peers;
-            int n;
-            if(st->maxpeers >= DHT_MAX_PEERS)
-                return 0;
-            n = st->maxpeers == 0 ? 2 : 2 * st->maxpeers;
-            n = MIN(n, DHT_MAX_PEERS);
-            new_peers = realloc(st->peers, n * sizeof(struct peer));
-            if(new_peers == NULL)
-                return -1;
-            st->peers = new_peers;
-            st->maxpeers = n;
-        }
-        p = &st->peers[st->numpeers++];
-        p->time = now.tv_sec;
-        p->len = len;
-        memcpy(p->ip, ip, len);
-        p->port = port;
-        return 1;
-    }
-}
-
-static int
-expire_storage(void)
-{
-    struct storage *st = storage, *previous = NULL;
-    while(st) {
-        int i = 0;
-        while(i < st->numpeers) {
-            if(st->peers[i].time < now.tv_sec - 32 * 60) {
-                if(i != st->numpeers - 1)
-                    st->peers[i] = st->peers[st->numpeers - 1];
-                st->numpeers--;
-            } else {
-                i++;
-            }
-        }
-
-        if(st->numpeers == 0) {
-            free(st->peers);
-            if(previous)
-                previous->next = st->next;
-            else
-                storage = st->next;
-            free(st);
-            if(previous)
-                st = previous->next;
-            else
-                st = storage;
-            numstorage--;
-            if(numstorage < 0) {
-                debugf("Eek... numstorage became negative.\n");
-                numstorage = 0;
-            }
-        } else {
-            previous = st;
-            st = st->next;
-        }
-    }
-    return 1;
-}
-
-static int
-rotate_secrets(void)
-{
-    int rc;
-
-    rotate_secrets_time = now.tv_sec + 900 + random() % 1800;
-
-    memcpy(oldsecret, secret, sizeof(secret));
-    rc = dht_random_bytes(secret, sizeof(secret));
-
-    if(rc < 0)
-        return -1;
-
-    return 1;
-}
-
-#ifndef TOKEN_SIZE
-#define TOKEN_SIZE 8
-#endif
-
-static void
-make_token(const struct sockaddr *sa, int old, unsigned char *token_return)
-{
-    void *ip;
-    int iplen;
-    unsigned short port;
-
-    if(sa->sa_family == AF_INET) {
-        struct sockaddr_in *sin = (struct sockaddr_in*)sa;
-        ip = &sin->sin_addr;
-        iplen = 4;
-        port = htons(sin->sin_port);
-    } else if(sa->sa_family == AF_INET6) {
-        struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
-        ip = &sin6->sin6_addr;
-        iplen = 16;
-        port = htons(sin6->sin6_port);
-    } else {
-        abort();
-    }
-
-    dht_hash(token_return, TOKEN_SIZE,
-             old ? oldsecret : secret, sizeof(secret),
-             ip, iplen, (unsigned char*)&port, 2);
-}
-static int
-token_match(const unsigned char *token, int token_len,
-            const struct sockaddr *sa)
-{
-    unsigned char t[TOKEN_SIZE];
-    if(token_len != TOKEN_SIZE)
-        return 0;
-    make_token(sa, 0, t);
-    if(memcmp(t, token, TOKEN_SIZE) == 0)
-        return 1;
-    make_token(sa, 1, t);
-    if(memcmp(t, token, TOKEN_SIZE) == 0)
-        return 1;
-    return 0;
-}
-
-int
-dht_nodes(int af, int *good_return, int *dubious_return, int *cached_return,
-          int *incoming_return)
-{
-    int good = 0, dubious = 0, cached = 0, incoming = 0;
-    struct bucket *b = af == AF_INET ? buckets : buckets6;
-
-    while(b) {
-        struct node *n = b->nodes;
-        while(n) {
-            if(node_good(n)) {
-                good++;
-                if(n->time > n->reply_time)
-                    incoming++;
-            } else {
-                dubious++;
-            }
-            n = n->next;
-        }
-        if(b->cached.ss_family > 0)
-            cached++;
-        b = b->next;
-    }
-    if(good_return)
-        *good_return = good;
-    if(dubious_return)
-        *dubious_return = dubious;
-    if(cached_return)
-        *cached_return = cached;
-    if(incoming_return)
-        *incoming_return = incoming;
-    return good + dubious;
-}
-
-static void
-dump_bucket(FILE *f, struct bucket *b)
-{
-    struct node *n = b->nodes;
-    fprintf(f, "Bucket ");
-    print_hex(f, b->first, 20);
-    fprintf(f, " count %d age %d%s%s:\n",
-            b->count, (int)(now.tv_sec - b->time),
-            in_bucket(myid, b) ? " (mine)" : "",
-            b->cached.ss_family ? " (cached)" : "");
-    while(n) {
-        char buf[512];
-        unsigned short port;
-        fprintf(f, "    Node ");
-        print_hex(f, n->id, 20);
-        if(n->ss.ss_family == AF_INET) {
-            struct sockaddr_in *sin = (struct sockaddr_in*)&n->ss;
-            inet_ntop(AF_INET, &sin->sin_addr, buf, 512);
-            port = ntohs(sin->sin_port);
-        } else if(n->ss.ss_family == AF_INET6) {
-            struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&n->ss;
-            inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 512);
-            port = ntohs(sin6->sin6_port);
-        } else {
-            snprintf(buf, 512, "unknown(%d)", n->ss.ss_family);
-            port = 0;
-        }
-
-        if(n->ss.ss_family == AF_INET6)
-            fprintf(f, " [%s]:%d ", buf, port);
-        else
-            fprintf(f, " %s:%d ", buf, port);
-        if(n->time != n->reply_time)
-            fprintf(f, "age %ld, %ld",
-                    (long)(now.tv_sec - n->time),
-                    (long)(now.tv_sec - n->reply_time));
-        else
-            fprintf(f, "age %ld", (long)(now.tv_sec - n->time));
-        if(n->pinged)
-            fprintf(f, " (%d)", n->pinged);
-        if(node_good(n))
-            fprintf(f, " (good)");
-        fprintf(f, "\n");
-        n = n->next;
-    }
-
-}
-
-void
-dht_dump_tables(FILE *f)
-{
-    int i;
-    struct bucket *b;
-    struct storage *st = storage;
-    struct search *sr = searches;
-
-    fprintf(f, "My id ");
-    print_hex(f, myid, 20);
-    fprintf(f, "\n");
-
-    b = buckets;
-    while(b) {
-        dump_bucket(f, b);
-        b = b->next;
-    }
-
-    fprintf(f, "\n");
-
-    b = buckets6;
-    while(b) {
-        dump_bucket(f, b);
-        b = b->next;
-    }
-
-    while(sr) {
-        fprintf(f, "\nSearch%s id ", sr->af == AF_INET6 ? " (IPv6)" : "");
-        print_hex(f, sr->id, 20);
-        fprintf(f, " age %d%s\n", (int)(now.tv_sec - sr->step_time),
-               sr->done ? " (done)" : "");
-        for(i = 0; i < sr->numnodes; i++) {
-            struct search_node *n = &sr->nodes[i];
-            fprintf(f, "Node %d id ", i);
-            print_hex(f, n->id, 20);
-            fprintf(f, " bits %d age ", common_bits(sr->id, n->id));
-            if(n->request_time)
-                fprintf(f, "%d, ", (int)(now.tv_sec - n->request_time));
-            fprintf(f, "%d", (int)(now.tv_sec - n->reply_time));
-            if(n->pinged)
-                fprintf(f, " (%d)", n->pinged);
-            fprintf(f, "%s%s.\n",
-                    find_node(n->id, AF_INET) ? " (known)" : "",
-                    n->replied ? " (replied)" : "");
-        }
-        sr = sr->next;
-    }
-
-    while(st) {
-        fprintf(f, "\nStorage ");
-        print_hex(f, st->id, 20);
-        fprintf(f, " %d/%d nodes:", st->numpeers, st->maxpeers);
-        for(i = 0; i < st->numpeers; i++) {
-            char buf[100];
-            if(st->peers[i].len == 4) {
-                inet_ntop(AF_INET, st->peers[i].ip, buf, 100);
-            } else if(st->peers[i].len == 16) {
-                buf[0] = '[';
-                inet_ntop(AF_INET6, st->peers[i].ip, buf + 1, 98);
-                strcat(buf, "]");
-            } else {
-                strcpy(buf, "???");
-            }
-            fprintf(f, " %s:%u (%ld)",
-                    buf, st->peers[i].port,
-                    (long)(now.tv_sec - st->peers[i].time));
-        }
-        st = st->next;
-    }
-
-    fprintf(f, "\n\n");
-    fflush(f);
-}
-
-int
-dht_init(int s, int s6, const unsigned char *id, const unsigned char *v)
-{
-    int rc;
-
-    if(dht_socket >= 0 || dht_socket6 >= 0 || buckets || buckets6) {
-        errno = EBUSY;
-        return -1;
-    }
-
-    searches = NULL;
-    numsearches = 0;
-
-    storage = NULL;
-    numstorage = 0;
-
-    if(s >= 0) {
-        buckets = calloc(sizeof(struct bucket), 1);
-        if(buckets == NULL)
-            return -1;
-        buckets->af = AF_INET;
-
-        rc = set_nonblocking(s, 1);
-        if(rc < 0)
-            goto fail;
-    }
-
-    if(s6 >= 0) {
-        buckets6 = calloc(sizeof(struct bucket), 1);
-        if(buckets6 == NULL)
-            return -1;
-        buckets6->af = AF_INET6;
-
-        rc = set_nonblocking(s6, 1);
-        if(rc < 0)
-            goto fail;
-    }
-
-    memcpy(myid, id, 20);
-    if(v) {
-        memcpy(my_v, "1:v4:", 5);
-        memcpy(my_v + 5, v, 4);
-        have_v = 1;
-    } else {
-        have_v = 0;
-    }
-
-    gettimeofday(&now, NULL);
-
-    mybucket_grow_time = now.tv_sec;
-    mybucket6_grow_time = now.tv_sec;
-    confirm_nodes_time = now.tv_sec + random() % 3;
-
-    search_id = random() & 0xFFFF;
-    search_time = 0;
-
-    next_blacklisted = 0;
-
-    token_bucket_time = now.tv_sec;
-    token_bucket_tokens = MAX_TOKEN_BUCKET_TOKENS;
-
-    memset(secret, 0, sizeof(secret));
-    rc = rotate_secrets();
-    if(rc < 0)
-        goto fail;
-
-    dht_socket = s;
-    dht_socket6 = s6;
-
-    expire_buckets(buckets);
-    expire_buckets(buckets6);
-
-    return 1;
-
- fail:
-    free(buckets);
-    buckets = NULL;
-    return -1;
-}
-
-int
-dht_uninit()
-{
-    if(dht_socket < 0 && dht_socket6 < 0) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    dht_socket = -1;
-    dht_socket6 = -1;
-
-    while(buckets) {
-        struct bucket *b = buckets;
-        buckets = b->next;
-        while(b->nodes) {
-            struct node *n = b->nodes;
-            b->nodes = n->next;
-            free(n);
-        }
-        free(b);
-    }
-
-    while(buckets6) {
-        struct bucket *b = buckets6;
-        buckets6 = b->next;
-        while(b->nodes) {
-            struct node *n = b->nodes;
-            b->nodes = n->next;
-            free(n);
-        }
-        free(b);
-    }
-
-    while(storage) {
-        struct storage *st = storage;
-        storage = storage->next;
-        free(st->peers);
-        free(st);
-    }
-
-    while(searches) {
-        struct search *sr = searches;
-        searches = searches->next;
-        free(sr);
-    }
-
-    return 1;
-}
-
-/* Rate control for requests we receive. */
-
-static int
-token_bucket(void)
-{
-    if(token_bucket_tokens == 0) {
-        token_bucket_tokens = MIN(MAX_TOKEN_BUCKET_TOKENS,
-                                  100 * (now.tv_sec - token_bucket_time));
-        token_bucket_time = now.tv_sec;
-    }
-
-    if(token_bucket_tokens == 0)
-        return 0;
-
-    token_bucket_tokens--;
-    return 1;
-}
-
-static int
-neighbourhood_maintenance(int af)
-{
-    unsigned char id[20];
-    struct bucket *b = find_bucket(myid, af);
-    struct bucket *q;
-    struct node *n;
-
-    if(b == NULL)
-        return 0;
-
-    memcpy(id, myid, 20);
-    id[19] = random() & 0xFF;
-    q = b;
-    if(q->next && (q->count == 0 || (random() & 7) == 0))
-        q = b->next;
-    if(q->count == 0 || (random() & 7) == 0) {
-        struct bucket *r;
-        r = previous_bucket(b);
-        if(r && r->count > 0)
-            q = r;
-    }
-
-    if(q) {
-        /* Since our node-id is the same in both DHTs, it's probably
-           profitable to query both families. */
-        int want = dht_socket >= 0 && dht_socket6 >= 0 ? (WANT4 | WANT6) : -1;
-        n = random_node(q);
-        if(n) {
-            unsigned char tid[4];
-            debugf("Sending find_node for%s neighborhood maintenance.\n",
-                   af == AF_INET6 ? " IPv6" : "");
-            make_tid(tid, "fn", 0);
-            send_find_node((struct sockaddr*)&n->ss, n->sslen,
-                           tid, 4, id, want,
-                           n->reply_time >= now.tv_sec - 15);
-            pinged(n, q);
-        }
-        return 1;
-    }
-    return 0;
-}
-
-static int
-bucket_maintenance(int af)
-{
-    struct bucket *b;
-
-    b = af == AF_INET ? buckets : buckets6;
-
-    while(b) {
-        struct bucket *q;
-        if(b->time < now.tv_sec - 600) {
-            /* This bucket hasn't seen any positive confirmation for a long
-               time.  Pick a random id in this bucket's range, and send
-               a request to a random node. */
-            unsigned char id[20];
-            struct node *n;
-            int rc;
-
-            rc = bucket_random(b, id);
-            if(rc < 0)
-                memcpy(id, b->first, 20);
-
-            q = b;
-            /* If the bucket is empty, we try to fill it from a neighbour.
-               We also sometimes do it gratuitiously to recover from
-               buckets full of broken nodes. */
-            if(q->next && (q->count == 0 || (random() & 7) == 0))
-                q = b->next;
-            if(q->count == 0 || (random() & 7) == 0) {
-                struct bucket *r;
-                r = previous_bucket(b);
-                if(r && r->count > 0)
-                    q = r;
-            }
-
-            if(q) {
-                n = random_node(q);
-                if(n) {
-                    unsigned char tid[4];
-                    int want = -1;
-
-                    if(dht_socket >= 0 && dht_socket6 >= 0) {
-                        struct bucket *otherbucket;
-                        otherbucket =
-                            find_bucket(id, af == AF_INET ? AF_INET6 : AF_INET);
-                        if(otherbucket && otherbucket->count < 8)
-                            /* The corresponding bucket in the other family
-                               is emptyish -- querying both is useful. */
-                            want = WANT4 | WANT6;
-                        else if(random() % 37 == 0)
-                            /* Most of the time, this just adds overhead.
-                               However, it might help stitch back one of
-                               the DHTs after a network collapse, so query
-                               both, but only very occasionally. */
-                            want = WANT4 | WANT6;
-                    }
-
-                    debugf("Sending find_node for%s bucket maintenance.\n",
-                           af == AF_INET6 ? " IPv6" : "");
-                    make_tid(tid, "fn", 0);
-                    send_find_node((struct sockaddr*)&n->ss, n->sslen,
-                                   tid, 4, id, want,
-                                   n->reply_time >= now.tv_sec - 15);
-                    pinged(n, q);
-                    /* In order to avoid sending queries back-to-back,
-                       give up for now and reschedule us soon. */
-                    return 1;
-                }
-            }
-        }
-        b = b->next;
-    }
-    return 0;
-}
-
-int
-dht_periodic(const void *buf, size_t buflen,
-             const struct sockaddr *from, int fromlen,
-             time_t *tosleep,
-             dht_callback *callback, void *closure)
-{
-    gettimeofday(&now, NULL);
-
-    if(buflen > 0) {
-        int message;
-        unsigned char tid[16], id[20], info_hash[20], target[20];
-        unsigned char nodes[256], nodes6[1024], token[128];
-        int tid_len = 16, token_len = 128;
-        int nodes_len = 256, nodes6_len = 1024;
-        unsigned short port;
-        unsigned char values[2048], values6[2048];
-        int values_len = 2048, values6_len = 2048;
-        int want;
-        unsigned short ttid;
-
-        if(is_martian(from))
-            goto dontread;
-
-        if(node_blacklisted(from, fromlen)) {
-            debugf("Received packet from blacklisted node.\n");
-            goto dontread;
-        }
-
-        if(((char*)buf)[buflen] != '\0') {
-            debugf("Unterminated message.\n");
-            errno = EINVAL;
-            return -1;
-        }
-
-        message = parse_message(buf, buflen, tid, &tid_len, id, info_hash,
-                                target, &port, token, &token_len,
-                                nodes, &nodes_len, nodes6, &nodes6_len,
-                                values, &values_len, values6, &values6_len,
-                                &want);
-
-        if(message < 0 || message == ERROR || id_cmp(id, zeroes) == 0) {
-            debugf("Unparseable message: ");
-            debug_printable(buf, buflen);
-            debugf("\n");
-            goto dontread;
-        }
-
-        if(id_cmp(id, myid) == 0) {
-            debugf("Received message from self.\n");
-            goto dontread;
-        }
-
-        if(message > REPLY) {
-            /* Rate limit requests. */
-            if(!token_bucket()) {
-                debugf("Dropping request due to rate limiting.\n");
-                goto dontread;
-            }
-        }
-
-        switch(message) {
-        case REPLY:
-            if(tid_len != 4) {
-                debugf("Broken node truncates transaction ids: ");
-                debug_printable(buf, buflen);
-                debugf("\n");
-                /* This is really annoying, as it means that we will
-                   time-out all our searches that go through this node.
-                   Kill it. */
-                blacklist_node(id, from, fromlen);
-                goto dontread;
-            }
-            if(tid_match(tid, "pn", NULL)) {
-                debugf("Pong!\n");
-                new_node(id, from, fromlen, 2);
-            } else if(tid_match(tid, "fn", NULL) ||
-                      tid_match(tid, "gp", NULL)) {
-                int gp = 0;
-                struct search *sr = NULL;
-                if(tid_match(tid, "gp", &ttid)) {
-                    gp = 1;
-                    sr = find_search(ttid, from->sa_family);
-                }
-                debugf("Nodes found (%d+%d)%s!\n", nodes_len/26, nodes6_len/38,
-                       gp ? " for get_peers" : "");
-                if(nodes_len % 26 != 0 || nodes6_len % 38 != 0) {
-                    debugf("Unexpected length for node info!\n");
-                    blacklist_node(id, from, fromlen);
-                } else if(gp && sr == NULL) {
-                    debugf("Unknown search!\n");
-                    new_node(id, from, fromlen, 1);
-                } else {
-                    int i;
-                    new_node(id, from, fromlen, 2);
-                    for(i = 0; i < nodes_len / 26; i++) {
-                        unsigned char *ni = nodes + i * 26;
-                        struct sockaddr_in sin;
-                        if(id_cmp(ni, myid) == 0)
-                            continue;
-                        memset(&sin, 0, sizeof(sin));
-                        sin.sin_family = AF_INET;
-                        memcpy(&sin.sin_addr, ni + 20, 4);
-                        memcpy(&sin.sin_port, ni + 24, 2);
-                        new_node(ni, (struct sockaddr*)&sin, sizeof(sin), 0);
-                        if(sr && sr->af == AF_INET) {
-                            insert_search_node(ni,
-                                               (struct sockaddr*)&sin,
-                                               sizeof(sin),
-                                               sr, 0, NULL, 0);
-                        }
-                    }
-                    for(i = 0; i < nodes6_len / 38; i++) {
-                        unsigned char *ni = nodes6 + i * 38;
-                        struct sockaddr_in6 sin6;
-                        if(id_cmp(ni, myid) == 0)
-                            continue;
-                        memset(&sin6, 0, sizeof(sin6));
-                        sin6.sin6_family = AF_INET6;
-                        memcpy(&sin6.sin6_addr, ni + 20, 16);
-                        memcpy(&sin6.sin6_port, ni + 36, 2);
-                        new_node(ni, (struct sockaddr*)&sin6, sizeof(sin6), 0);
-                        if(sr && sr->af == AF_INET6) {
-                            insert_search_node(ni,
-                                               (struct sockaddr*)&sin6,
-                                               sizeof(sin6),
-                                               sr, 0, NULL, 0);
-                        }
-                    }
-                    if(sr)
-                        /* Since we received a reply, the number of
-                           requests in flight has decreased.  Let's push
-                           another request. */
-                        search_send_get_peers(sr, NULL);
-                }
-                if(sr) {
-                    insert_search_node(id, from, fromlen, sr,
-                                       1, token, token_len);
-                    if(values_len > 0 || values6_len > 0) {
-                        debugf("Got values (%d+%d)!\n",
-                               values_len / 6, values6_len / 18);
-                        if(callback) {
-                            if(values_len > 0)
-                                (*callback)(closure, DHT_EVENT_VALUES, sr->id,
-                                            (void*)values, values_len);
-
-                            if(values6_len > 0)
-                                (*callback)(closure, DHT_EVENT_VALUES6, sr->id,
-                                            (void*)values6, values6_len);
-                        }
-                    }
-                }
-            } else if(tid_match(tid, "ap", &ttid)) {
-                struct search *sr;
-                debugf("Got reply to announce_peer.\n");
-                sr = find_search(ttid, from->sa_family);
-                if(!sr) {
-                    debugf("Unknown search!\n");
-                    new_node(id, from, fromlen, 1);
-                } else {
-                    int i;
-                    new_node(id, from, fromlen, 2);
-                    for(i = 0; i < sr->numnodes; i++)
-                        if(id_cmp(sr->nodes[i].id, id) == 0) {
-                            sr->nodes[i].request_time = 0;
-                            sr->nodes[i].reply_time = now.tv_sec;
-                            sr->nodes[i].acked = 1;
-                            sr->nodes[i].pinged = 0;
-                            break;
-                        }
-                    /* See comment for gp above. */
-                    search_send_get_peers(sr, NULL);
-                }
-            } else {
-                debugf("Unexpected reply: ");
-                debug_printable(buf, buflen);
-                debugf("\n");
-            }
-            break;
-        case PING:
-            debugf("Ping (%d)!\n", tid_len);
-            new_node(id, from, fromlen, 1);
-            debugf("Sending pong.\n");
-            send_pong(from, fromlen, tid, tid_len);
-            break;
-        case FIND_NODE:
-            debugf("Find node!\n");
-            new_node(id, from, fromlen, 1);
-            debugf("Sending closest nodes (%d).\n", want);
-            send_closest_nodes(from, fromlen,
-                               tid, tid_len, target, want,
-                               0, NULL, NULL, 0);
-            break;
-        case GET_PEERS:
-            debugf("Get_peers!\n");
-            new_node(id, from, fromlen, 1);
-            if(id_cmp(info_hash, zeroes) == 0) {
-                debugf("Eek!  Got get_peers with no info_hash.\n");
-                send_error(from, fromlen, tid, tid_len,
-                           203, "Get_peers with no info_hash");
-                break;
-            } else {
-                struct storage *st = find_storage(info_hash);
-                unsigned char token[TOKEN_SIZE];
-                make_token(from, 0, token);
-                if(st && st->numpeers > 0) {
-                     debugf("Sending found%s peers.\n",
-                            from->sa_family == AF_INET6 ? " IPv6" : "");
-                     send_closest_nodes(from, fromlen,
-                                        tid, tid_len,
-                                        info_hash, want,
-                                        from->sa_family, st,
-                                        token, TOKEN_SIZE);
-                } else {
-                    debugf("Sending nodes for get_peers.\n");
-                    send_closest_nodes(from, fromlen,
-                                       tid, tid_len, info_hash, want,
-                                       0, NULL, token, TOKEN_SIZE);
-                }
-            }
-            break;
-        case ANNOUNCE_PEER:
-            debugf("Announce peer!\n");
-            new_node(id, from, fromlen, 1);
-            if(id_cmp(info_hash, zeroes) == 0) {
-                debugf("Announce_peer with no info_hash.\n");
-                send_error(from, fromlen, tid, tid_len,
-                           203, "Announce_peer with no info_hash");
-                break;
-            }
-            if(!token_match(token, token_len, from)) {
-                debugf("Incorrect token for announce_peer.\n");
-                send_error(from, fromlen, tid, tid_len,
-                           203, "Announce_peer with wrong token");
-                break;
-            }
-            if(port == 0) {
-                debugf("Announce_peer with forbidden port %d.\n", port);
-                send_error(from, fromlen, tid, tid_len,
-                           203, "Announce_peer with forbidden port number");
-                break;
-            }
-            storage_store(info_hash, from, port);
-            /* Note that if storage_store failed, we lie to the requestor.
-               This is to prevent them from backtracking, and hence
-               polluting the DHT. */
-            debugf("Sending peer announced.\n");
-            send_peer_announced(from, fromlen, tid, tid_len);
-        }
-    }
-
- dontread:
-    if(now.tv_sec >= rotate_secrets_time)
-        rotate_secrets();
-
-    if(now.tv_sec >= expire_stuff_time) {
-        expire_buckets(buckets);
-        expire_buckets(buckets6);
-        expire_storage();
-        expire_searches();
-    }
-
-    if(search_time > 0 && now.tv_sec >= search_time) {
-        struct search *sr;
-        sr = searches;
-        while(sr) {
-            if(!sr->done && sr->step_time + 5 <= now.tv_sec) {
-                search_step(sr, callback, closure);
-            }
-            sr = sr->next;
-        }
-
-        search_time = 0;
-
-        sr = searches;
-        while(sr) {
-            if(!sr->done) {
-                time_t tm = sr->step_time + 15 + random() % 10;
-                if(search_time == 0 || search_time > tm)
-                    search_time = tm;
-            }
-            sr = sr->next;
-        }
-    }
-
-    if(now.tv_sec >= confirm_nodes_time) {
-        int soon = 0;
-
-        soon |= bucket_maintenance(AF_INET);
-        soon |= bucket_maintenance(AF_INET6);
-
-        if(!soon) {
-            if(mybucket_grow_time >= now.tv_sec - 150)
-                soon |= neighbourhood_maintenance(AF_INET);
-            if(mybucket6_grow_time >= now.tv_sec - 150)
-                soon |= neighbourhood_maintenance(AF_INET6);
-        }
-
-        /* In order to maintain all buckets' age within 600 seconds, worst
-           case is roughly 27 seconds, assuming the table is 22 bits deep.
-           We want to keep a margin for neighborhood maintenance, so keep
-           this within 25 seconds. */
-        if(soon)
-            confirm_nodes_time = now.tv_sec + 5 + random() % 20;
-        else
-            confirm_nodes_time = now.tv_sec + 60 + random() % 120;
-    }
-
-    if(confirm_nodes_time > now.tv_sec)
-        *tosleep = confirm_nodes_time - now.tv_sec;
-    else
-        *tosleep = 0;
-
-    if(search_time > 0) {
-        if(search_time <= now.tv_sec)
-            *tosleep = 0;
-        else if(*tosleep > search_time - now.tv_sec)
-            *tosleep = search_time - now.tv_sec;
-    }
-
-    return 1;
-}
-
-int
-dht_get_nodes(struct sockaddr_in *sin, int *num,
-              struct sockaddr_in6 *sin6, int *num6)
-{
-    int i, j;
-    struct bucket *b;
-    struct node *n;
-
-    i = 0;
-
-    /* For restoring to work without discarding too many nodes, the list
-       must start with the contents of our bucket. */
-    b = find_bucket(myid, AF_INET);
-    if(b == NULL)
-        goto no_ipv4;
-
-    n = b->nodes;
-    while(n && i < *num) {
-        if(node_good(n)) {
-            sin[i] = *(struct sockaddr_in*)&n->ss;
-            i++;
-        }
-        n = n->next;
-    }
-
-    b = buckets;
-    while(b && i < *num) {
-        if(!in_bucket(myid, b)) {
-            n = b->nodes;
-            while(n && i < *num) {
-                if(node_good(n)) {
-                    sin[i] = *(struct sockaddr_in*)&n->ss;
-                    i++;
-                }
-                n = n->next;
-            }
-        }
-        b = b->next;
-    }
-
- no_ipv4:
-
-    j = 0;
-
-    b = find_bucket(myid, AF_INET6);
-    if(b == NULL)
-        goto no_ipv6;
-
-    n = b->nodes;
-    while(n && j < *num6) {
-        if(node_good(n)) {
-            sin6[j] = *(struct sockaddr_in6*)&n->ss;
-            j++;
-        }
-        n = n->next;
-    }
-
-    b = buckets6;
-    while(b && j < *num6) {
-        if(!in_bucket(myid, b)) {
-            n = b->nodes;
-            while(n && j < *num6) {
-                if(node_good(n)) {
-                    sin6[j] = *(struct sockaddr_in6*)&n->ss;
-                    j++;
-                }
-                n = n->next;
-            }
-        }
-        b = b->next;
-    }
-
- no_ipv6:
-
-    *num = i;
-    *num6 = j;
-    return i + j;
-}
-
-int
-dht_insert_node(const unsigned char *id, struct sockaddr *sa, int salen)
-{
-    struct node *n;
-
-    if(sa->sa_family != AF_INET) {
-        errno = EAFNOSUPPORT;
-        return -1;
-    }
-
-    n = new_node(id, (struct sockaddr*)sa, salen, 0);
-    return !!n;
-}
-
-int
-dht_ping_node(struct sockaddr *sa, int salen)
-{
-    unsigned char tid[4];
-
-    debugf("Sending ping.\n");
-    make_tid(tid, "pn", 0);
-    return send_ping(sa, salen, tid, 4);
-}
-
-/* We could use a proper bencoding printer and parser, but the format of
-   DHT messages is fairly stylised, so this seemed simpler. */
-
-#define CHECK(offset, delta, size)                      \
-    if(delta < 0 || offset + delta > size) goto fail
-
-#define INC(offset, delta, size)                        \
-    CHECK(offset, delta, size);                         \
-    offset += delta
-
-#define COPY(buf, offset, src, delta, size)             \
-    CHECK(offset, delta, size);                         \
-    memcpy(buf + offset, src, delta);                   \
-    offset += delta;
-
-#define ADD_V(buf, offset, size)                        \
-    if(have_v) {                                        \
-        COPY(buf, offset, my_v, sizeof(my_v), size);    \
-    }
-
-static int
-dht_send(const void *buf, size_t len, int flags,
-         const struct sockaddr *sa, int salen)
-{
-    int s;
-
-    if(salen == 0)
-        abort();
-
-    if(node_blacklisted(sa, salen)) {
-        debugf("Attempting to send to blacklisted node.\n");
-        errno = EPERM;
-        return -1;
-    }
-
-    if(sa->sa_family == AF_INET)
-        s = dht_socket;
-    else if(sa->sa_family == AF_INET6)
-        s = dht_socket6;
-    else
-        s = -1;
-
-    if(s < 0) {
-        errno = EAFNOSUPPORT;
-        return -1;
-    }
-
-    return sendto(s, buf, len, flags, sa, salen);
-}
-
-int
-send_ping(const struct sockaddr *sa, int salen,
-          const unsigned char *tid, int tid_len)
-{
-    char buf[512];
-    int i = 0, rc;
-    rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
-    COPY(buf, i, myid, 20, 512);
-    rc = snprintf(buf + i, 512 - i, "e1:q4:ping1:t%d:", tid_len);
-    INC(i, rc, 512);
-    COPY(buf, i, tid, tid_len, 512);
-    ADD_V(buf, i, 512);
-    rc = snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
-    return dht_send(buf, i, 0, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-int
-send_pong(const struct sockaddr *sa, int salen,
-          const unsigned char *tid, int tid_len)
-{
-    char buf[512];
-    int i = 0, rc;
-    rc = snprintf(buf + i, 512 - i, "d1:rd2:id20:"); INC(i, rc, 512);
-    COPY(buf, i, myid, 20, 512);
-    rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len); INC(i, rc, 512);
-    COPY(buf, i, tid, tid_len, 512);
-    ADD_V(buf, i, 512);
-    rc = snprintf(buf + i, 512 - i, "1:y1:re"); INC(i, rc, 512);
-    return dht_send(buf, i, 0, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-int
-send_find_node(const struct sockaddr *sa, int salen,
-               const unsigned char *tid, int tid_len,
-               const unsigned char *target, int want, int confirm)
-{
-    char buf[512];
-    int i = 0, rc;
-    rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
-    COPY(buf, i, myid, 20, 512);
-    rc = snprintf(buf + i, 512 - i, "6:target20:"); INC(i, rc, 512);
-    COPY(buf, i, target, 20, 512);
-    if(want > 0) {
-        rc = snprintf(buf + i, 512 - i, "4:wantl%s%se",
-                      (want & WANT4) ? "2:n4" : "",
-                      (want & WANT6) ? "2:n6" : "");
-        INC(i, rc, 512);
-    }
-    rc = snprintf(buf + i, 512 - i, "e1:q9:find_node1:t%d:", tid_len);
-    INC(i, rc, 512);
-    COPY(buf, i, tid, tid_len, 512);
-    ADD_V(buf, i, 512);
-    rc = snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
-    return dht_send(buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-int
-send_nodes_peers(const struct sockaddr *sa, int salen,
-                 const unsigned char *tid, int tid_len,
-                 const unsigned char *nodes, int nodes_len,
-                 const unsigned char *nodes6, int nodes6_len,
-                 int af, struct storage *st,
-                 const unsigned char *token, int token_len)
-{
-    char buf[2048];
-    int i = 0, rc, j0, j, k, len;
-
-    rc = snprintf(buf + i, 2048 - i, "d1:rd2:id20:"); INC(i, rc, 2048);
-    COPY(buf, i, myid, 20, 2048);
-    if(nodes_len > 0) {
-        rc = snprintf(buf + i, 2048 - i, "5:nodes%d:", nodes_len);
-        INC(i, rc, 2048);
-        COPY(buf, i, nodes, nodes_len, 2048);
-    }
-    if(nodes6_len > 0) {
-         rc = snprintf(buf + i, 2048 - i, "6:nodes6%d:", nodes6_len);
-         INC(i, rc, 2048);
-         COPY(buf, i, nodes6, nodes6_len, 2048);
-    }
-    if(token_len > 0) {
-        rc = snprintf(buf + i, 2048 - i, "5:token%d:", token_len);
-        INC(i, rc, 2048);
-        COPY(buf, i, token, token_len, 2048);
-    }
-
-    if(st && st->numpeers > 0) {
-        /* We treat the storage as a circular list, and serve a randomly
-           chosen slice.  In order to make sure we fit within 1024 octets,
-           we limit ourselves to 50 peers. */
-
-        len = af == AF_INET ? 4 : 16;
-        j0 = random() % st->numpeers;
-        j = j0;
-        k = 0;
-
-        rc = snprintf(buf + i, 2048 - i, "6:valuesl"); INC(i, rc, 2048);
-        do {
-            if(st->peers[j].len == len) {
-                unsigned short swapped;
-                swapped = htons(st->peers[j].port);
-                rc = snprintf(buf + i, 2048 - i, "%d:", len + 2);
-                INC(i, rc, 2048);
-                COPY(buf, i, st->peers[j].ip, len, 2048);
-                COPY(buf, i, &swapped, 2, 2048);
-                k++;
-            }
-            j = (j + 1) % st->numpeers;
-        } while(j != j0 && k < 50);
-        rc = snprintf(buf + i, 2048 - i, "e"); INC(i, rc, 2048);
-    }
-
-    rc = snprintf(buf + i, 2048 - i, "e1:t%d:", tid_len); INC(i, rc, 2048);
-    COPY(buf, i, tid, tid_len, 2048);
-    ADD_V(buf, i, 2048);
-    rc = snprintf(buf + i, 2048 - i, "1:y1:re"); INC(i, rc, 2048);
-
-    return dht_send(buf, i, 0, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-static int
-insert_closest_node(unsigned char *nodes, int numnodes,
-                    const unsigned char *id, struct node *n)
-{
-    int i, size;
-
-    if(n->ss.ss_family == AF_INET)
-        size = 26;
-    else if(n->ss.ss_family == AF_INET6)
-        size = 38;
-    else
-        abort();
-
-    for(i = 0; i< numnodes; i++) {
-        if(id_cmp(n->id, nodes + size * i) == 0)
-            return numnodes;
-        if(xorcmp(n->id, nodes + size * i, id) < 0)
-            break;
-    }
-
-    if(i == 8)
-        return numnodes;
-
-    if(numnodes < 8)
-        numnodes++;
-
-    if(i < numnodes - 1)
-        memmove(nodes + size * (i + 1), nodes + size * i,
-                size * (numnodes - i - 1));
-
-    if(n->ss.ss_family == AF_INET) {
-        struct sockaddr_in *sin = (struct sockaddr_in*)&n->ss;
-        memcpy(nodes + size * i, n->id, 20);
-        memcpy(nodes + size * i + 20, &sin->sin_addr, 4);
-        memcpy(nodes + size * i + 24, &sin->sin_port, 2);
-    } else if(n->ss.ss_family == AF_INET6) {
-        struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&n->ss;
-        memcpy(nodes + size * i, n->id, 20);
-        memcpy(nodes + size * i + 20, &sin6->sin6_addr, 16);
-        memcpy(nodes + size * i + 36, &sin6->sin6_port, 2);
-    } else {
-        abort();
-    }
-
-    return numnodes;
-}
-
-static int
-buffer_closest_nodes(unsigned char *nodes, int numnodes,
-                     const unsigned char *id, struct bucket *b)
-{
-    struct node *n = b->nodes;
-    while(n) {
-        if(node_good(n))
-            numnodes = insert_closest_node(nodes, numnodes, id, n);
-        n = n->next;
-    }
-    return numnodes;
-}
-
-int
-send_closest_nodes(const struct sockaddr *sa, int salen,
-                   const unsigned char *tid, int tid_len,
-                   const unsigned char *id, int want,
-                   int af, struct storage *st,
-                   const unsigned char *token, int token_len)
-{
-    unsigned char nodes[8 * 26];
-    unsigned char nodes6[8 * 38];
-    int numnodes = 0, numnodes6 = 0;
-    struct bucket *b;
-
-    if(want < 0)
-        want = sa->sa_family == AF_INET ? WANT4 : WANT6;
-
-    if((want & WANT4)) {
-        b = find_bucket(id, AF_INET);
-        if(b) {
-            numnodes = buffer_closest_nodes(nodes, numnodes, id, b);
-            if(b->next)
-                numnodes = buffer_closest_nodes(nodes, numnodes, id, b->next);
-            b = previous_bucket(b);
-            if(b)
-                numnodes = buffer_closest_nodes(nodes, numnodes, id, b);
-        }
-    }
-
-    if((want & WANT6)) {
-        b = find_bucket(id, AF_INET6);
-        if(b) {
-            numnodes6 = buffer_closest_nodes(nodes6, numnodes6, id, b);
-            if(b->next)
-                numnodes6 =
-                    buffer_closest_nodes(nodes6, numnodes6, id, b->next);
-            b = previous_bucket(b);
-            if(b)
-                numnodes6 = buffer_closest_nodes(nodes6, numnodes6, id, b);
-        }
-    }
-    debugf("  (%d+%d nodes.)\n", numnodes, numnodes6);
-
-    return send_nodes_peers(sa, salen, tid, tid_len,
-                            nodes, numnodes * 26,
-                            nodes6, numnodes6 * 38,
-                            af, st, token, token_len);
-}
-
-int
-send_get_peers(const struct sockaddr *sa, int salen,
-               unsigned char *tid, int tid_len, unsigned char *infohash,
-               int want, int confirm)
-{
-    char buf[512];
-    int i = 0, rc;
-
-    rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
-    COPY(buf, i, myid, 20, 512);
-    rc = snprintf(buf + i, 512 - i, "9:info_hash20:"); INC(i, rc, 512);
-    COPY(buf, i, infohash, 20, 512);
-    if(want > 0) {
-        rc = snprintf(buf + i, 512 - i, "4:wantl%s%se",
-                      (want & WANT4) ? "2:n4" : "",
-                      (want & WANT6) ? "2:n6" : "");
-        INC(i, rc, 512);
-    }
-    rc = snprintf(buf + i, 512 - i, "e1:q9:get_peers1:t%d:", tid_len);
-    INC(i, rc, 512);
-    COPY(buf, i, tid, tid_len, 512);
-    ADD_V(buf, i, 512);
-    rc = snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
-    return dht_send(buf, i, confirm ? MSG_CONFIRM : 0, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-int
-send_announce_peer(const struct sockaddr *sa, int salen,
-                   unsigned char *tid, int tid_len,
-                   unsigned char *infohash, unsigned short port,
-                   unsigned char *token, int token_len, int confirm)
-{
-    char buf[512];
-    int i = 0, rc;
-
-    rc = snprintf(buf + i, 512 - i, "d1:ad2:id20:"); INC(i, rc, 512);
-    COPY(buf, i, myid, 20, 512);
-    rc = snprintf(buf + i, 512 - i, "9:info_hash20:"); INC(i, rc, 512);
-    COPY(buf, i, infohash, 20, 512);
-    rc = snprintf(buf + i, 512 - i, "4:porti%ue5:token%d:", (unsigned)port,
-                  token_len);
-    INC(i, rc, 512);
-    COPY(buf, i, token, token_len, 512);
-    rc = snprintf(buf + i, 512 - i, "e1:q13:announce_peer1:t%d:", tid_len);
-    INC(i, rc, 512);
-    COPY(buf, i, tid, tid_len, 512);
-    ADD_V(buf, i, 512);
-    rc = snprintf(buf + i, 512 - i, "1:y1:qe"); INC(i, rc, 512);
-
-    return dht_send(buf, i, confirm ? 0 : MSG_CONFIRM, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-static int
-send_peer_announced(const struct sockaddr *sa, int salen,
-                    unsigned char *tid, int tid_len)
-{
-    char buf[512];
-    int i = 0, rc;
-
-    rc = snprintf(buf + i, 512 - i, "d1:rd2:id20:"); INC(i, rc, 512);
-    COPY(buf, i, myid, 20, 512);
-    rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len);
-    INC(i, rc, 512);
-    COPY(buf, i, tid, tid_len, 512);
-    ADD_V(buf, i, 512);
-    rc = snprintf(buf + i, 512 - i, "1:y1:re"); INC(i, rc, 512);
-    return dht_send(buf, i, 0, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-static int
-send_error(const struct sockaddr *sa, int salen,
-           unsigned char *tid, int tid_len,
-           int code, const char *message)
-{
-    char buf[512];
-    int i = 0, rc;
-
-    rc = snprintf(buf + i, 512 - i, "d1:eli%de%d:",
-                  code, (int)strlen(message));
-    INC(i, rc, 512);
-    COPY(buf, i, message, (int)strlen(message), 512);
-    rc = snprintf(buf + i, 512 - i, "e1:t%d:", tid_len); INC(i, rc, 512);
-    COPY(buf, i, tid, tid_len, 512);
-    ADD_V(buf, i, 512);
-    rc = snprintf(buf + i, 512 - i, "1:y1:ee"); INC(i, rc, 512);
-    return dht_send(buf, i, 0, sa, salen);
-
- fail:
-    errno = ENOSPC;
-    return -1;
-}
-
-#undef CHECK
-#undef INC
-#undef COPY
-#undef ADD_V
-
-#ifdef HAVE_MEMMEM
-
-static void *
-dht_memmem(const void *haystack, size_t haystacklen,
-           const void *needle, size_t needlelen)
-{
-    return memmem(haystack, haystacklen, needle, needlelen);
-}
-
-#else
-
-static void *
-dht_memmem(const void *haystack, size_t haystacklen,
-           const void *needle, size_t needlelen)
-{
-    const char *h = haystack;
-    const char *n = needle;
-    size_t i;
-
-    /* size_t is unsigned */
-    if(needlelen > haystacklen)
-        return NULL;
-
-    for(i = 0; i <= haystacklen - needlelen; i++) {
-        if(memcmp(h + i, n, needlelen) == 0)
-            return (void*)(h + i);
-    }
-    return NULL;
-}
-
-#endif
-
-static int
-parse_message(const unsigned char *buf, int buflen,
-              unsigned char *tid_return, int *tid_len,
-              unsigned char *id_return, unsigned char *info_hash_return,
-              unsigned char *target_return, unsigned short *port_return,
-              unsigned char *token_return, int *token_len,
-              unsigned char *nodes_return, int *nodes_len,
-              unsigned char *nodes6_return, int *nodes6_len,
-              unsigned char *values_return, int *values_len,
-              unsigned char *values6_return, int *values6_len,
-              int *want_return)
-{
-    const unsigned char *p;
-
-    /* This code will happily crash if the buffer is not NUL-terminated. */
-    if(buf[buflen] != '\0') {
-        debugf("Eek!  parse_message with unterminated buffer.\n");
-        return -1;
-    }
-
-#define CHECK(ptr, len)                                                 \
-    if(((unsigned char*)ptr) + (len) > (buf) + (buflen)) goto overflow;
-
-    if(tid_return) {
-        p = dht_memmem(buf, buflen, "1:t", 3);
-        if(p) {
-            long l;
-            char *q;
-            l = strtol((char*)p + 3, &q, 10);
-            if(q && *q == ':' && l > 0 && l < *tid_len) {
-                CHECK(q + 1, l);
-                memcpy(tid_return, q + 1, l);
-                *tid_len = l;
-            } else
-                *tid_len = 0;
-        }
-    }
-    if(id_return) {
-        p = dht_memmem(buf, buflen, "2:id20:", 7);
-        if(p) {
-            CHECK(p + 7, 20);
-            memcpy(id_return, p + 7, 20);
-        } else {
-            memset(id_return, 0, 20);
-        }
-    }
-    if(info_hash_return) {
-        p = dht_memmem(buf, buflen, "9:info_hash20:", 14);
-        if(p) {
-            CHECK(p + 14, 20);
-            memcpy(info_hash_return, p + 14, 20);
-        } else {
-            memset(info_hash_return, 0, 20);
-        }
-    }
-    if(port_return) {
-        p = dht_memmem(buf, buflen, "porti", 5);
-        if(p) {
-            long l;
-            char *q;
-            l = strtol((char*)p + 5, &q, 10);
-            if(q && *q == 'e' && l > 0 && l < 0x10000)
-                *port_return = l;
-            else
-                *port_return = 0;
-        } else
-            *port_return = 0;
-    }
-    if(target_return) {
-        p = dht_memmem(buf, buflen, "6:target20:", 11);
-        if(p) {
-            CHECK(p + 11, 20);
-            memcpy(target_return, p + 11, 20);
-        } else {
-            memset(target_return, 0, 20);
-        }
-    }
-    if(token_return) {
-        p = dht_memmem(buf, buflen, "5:token", 7);
-        if(p) {
-            long l;
-            char *q;
-            l = strtol((char*)p + 7, &q, 10);
-            if(q && *q == ':' && l > 0 && l < *token_len) {
-                CHECK(q + 1, l);
-                memcpy(token_return, q + 1, l);
-                *token_len = l;
-            } else
-                *token_len = 0;
-        } else
-            *token_len = 0;
-    }
-
-    if(nodes_len) {
-        p = dht_memmem(buf, buflen, "5:nodes", 7);
-        if(p) {
-            long l;
-            char *q;
-            l = strtol((char*)p + 7, &q, 10);
-            if(q && *q == ':' && l > 0 && l < *nodes_len) {
-                CHECK(q + 1, l);
-                memcpy(nodes_return, q + 1, l);
-                *nodes_len = l;
-            } else
-                *nodes_len = 0;
-        } else
-            *nodes_len = 0;
-    }
-
-    if(nodes6_len) {
-        p = dht_memmem(buf, buflen, "6:nodes6", 8);
-        if(p) {
-            long l;
-            char *q;
-            l = strtol((char*)p + 8, &q, 10);
-            if(q && *q == ':' && l > 0 && l < *nodes6_len) {
-                CHECK(q + 1, l);
-                memcpy(nodes6_return, q + 1, l);
-                *nodes6_len = l;
-            } else
-                *nodes6_len = 0;
-        } else
-            *nodes6_len = 0;
-    }
-
-    if(values_len || values6_len) {
-        p = dht_memmem(buf, buflen, "6:valuesl", 9);
-        if(p) {
-            int i = p - buf + 9;
-            int j = 0, j6 = 0;
-            while(1) {
-                long l;
-                char *q;
-                l = strtol((char*)buf + i, &q, 10);
-                if(q && *q == ':' && l > 0) {
-                    CHECK(q + 1, l);
-                    i = q + 1 + l - (char*)buf;
-                    if(l == 6) {
-                        if(j + l > *values_len)
-                            continue;
-                        memcpy((char*)values_return + j, q + 1, l);
-                        j += l;
-                    } else if(l == 18) {
-                        if(j6 + l > *values6_len)
-                            continue;
-                        memcpy((char*)values6_return + j6, q + 1, l);
-                        j6 += l;
-                    } else {
-                        debugf("Received weird value -- %d bytes.\n", (int)l);
-                    }
-                } else {
-                    break;
-                }
-            }
-            if(i >= buflen || buf[i] != 'e')
-                debugf("eek... unexpected end for values.\n");
-            if(values_len)
-                *values_len = j;
-            if(values6_len)
-                *values6_len = j6;
-        } else {
-            if(values_len)
-                *values_len = 0;
-            if(values6_len)
-                *values6_len = 0;
-        }
-    }
-
-    if(want_return) {
-        p = dht_memmem(buf, buflen, "4:wantl", 7);
-        if(p) {
-            int i = p - buf + 7;
-            *want_return = 0;
-            while(buf[i] > '0' && buf[i] <= '9' && buf[i + 1] == ':' &&
-                  i + 2 + buf[i] - '0' < buflen) {
-                CHECK(buf + i + 2, buf[i] - '0');
-                if(buf[i] == '2' && memcmp(buf + i + 2, "n4", 2) == 0)
-                    *want_return |= WANT4;
-                else if(buf[i] == '2' && memcmp(buf + i + 2, "n6", 2) == 0)
-                    *want_return |= WANT6;
-                else
-                    debugf("eek... unexpected want flag (%c)\n", buf[i]);
-                i += 2 + buf[i] - '0';
-            }
-            if(i >= buflen || buf[i] != 'e')
-                debugf("eek... unexpected end for want.\n");
-        } else {
-            *want_return = -1;
-        }
-    }
-
-#undef CHECK
-
-    if(dht_memmem(buf, buflen, "1:y1:r", 6))
-        return REPLY;
-    if(dht_memmem(buf, buflen, "1:y1:e", 6))
-        return ERROR;
-    if(!dht_memmem(buf, buflen, "1:y1:q", 6))
-        return -1;
-    if(dht_memmem(buf, buflen, "1:q4:ping", 9))
-        return PING;
-    if(dht_memmem(buf, buflen, "1:q9:find_node", 14))
-       return FIND_NODE;
-    if(dht_memmem(buf, buflen, "1:q9:get_peers", 14))
-        return GET_PEERS;
-    if(dht_memmem(buf, buflen, "1:q13:announce_peer", 19))
-       return ANNOUNCE_PEER;
-    return -1;
-
- overflow:
-    debugf("Truncated message.\n");
-    return -1;
-}
diff --git a/third-party/dht/dht.h b/third-party/dht/dht.h
deleted file mode 100644 (file)
index 2a0c633..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-Copyright (c) 2009-2011 by Juliusz Chroboczek
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-typedef void
-dht_callback(void *closure, int event,
-             const unsigned char *info_hash,
-             const void *data, size_t data_len);
-
-#define DHT_EVENT_NONE 0
-#define DHT_EVENT_VALUES 1
-#define DHT_EVENT_VALUES6 2
-#define DHT_EVENT_SEARCH_DONE 3
-#define DHT_EVENT_SEARCH_DONE6 4
-
-extern FILE *dht_debug;
-
-int dht_init(int s, int s6, const unsigned char *id, const unsigned char *v);
-int dht_insert_node(const unsigned char *id, struct sockaddr *sa, int salen);
-int dht_ping_node(struct sockaddr *sa, int salen);
-int dht_periodic(const void *buf, size_t buflen,
-                 const struct sockaddr *from, int fromlen,
-                 time_t *tosleep, dht_callback *callback, void *closure);
-int dht_search(const unsigned char *id, int port, int af,
-               dht_callback *callback, void *closure);
-int dht_nodes(int af,
-              int *good_return, int *dubious_return, int *cached_return,
-              int *incoming_return);
-void dht_dump_tables(FILE *f);
-int dht_get_nodes(struct sockaddr_in *sin, int *num,
-                  struct sockaddr_in6 *sin6, int *num6);
-int dht_uninit(void);
-
-/* This must be provided by the user. */
-int dht_blacklisted(const struct sockaddr *sa, int salen);
-void dht_hash(void *hash_return, int hash_size,
-              const void *v1, int len1,
-              const void *v2, int len2,
-              const void *v3, int len3);
-int dht_random_bytes(void *buf, size_t size);
diff --git a/third-party/libb64/AUTHORS b/third-party/libb64/AUTHORS
deleted file mode 100644 (file)
index bf4a9f4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-libb64: Base64 Encoding/Decoding Routines
-======================================
-
-Authors:
--------
-
-Chris Venter   chris.venter@gmail.com  http://controlaltfire.com
-
-Contributors:
-------------
-
-Mario Rugiero
-Shlok Datye
-Peter K. Lee
-
diff --git a/third-party/libb64/CHANGELOG b/third-party/libb64/CHANGELOG
deleted file mode 100644 (file)
index c1c0844..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-libb64: Base64 Encoding/Decoding Routines
-======================================
-
-## Changelog ##
-
-Version 1.2.1 Release
----------------------
-Fixed a long-standing bug in src/cdecode.c where value_in was not correctly
-checked against the bounds [0..decoding_size)
-Thanks to both Mario Rugiero and Shlok Datye for pointing this out.
-Added some simple example code to answer some of the most common misconceptions
-people have about the library usage.
-
-Version 1.2 Release
--------------------
-Removed the b64dec, b64enc, encoder and decoder programs in favour of
-a better example, called base64, which encodes and decodes 
-depending on its arguments.
-
-Created a solution for Microsoft Visual Studio C++ Express 2010
-edition, which simply builds the base64 example as a console application.
-
-Version 1.1 Release
--------------------
-Modified encode.h to (correctly) read from the iostream argument,
-instead of std::cin.
-Thanks to Peter K. Lee for the heads-up.
-
-No API changes.
-
-Version 1.0 Release
--------------------
-The current content is the changeset.
diff --git a/third-party/libb64/INSTALL b/third-party/libb64/INSTALL
deleted file mode 100644 (file)
index b05f5db..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-libb64: Base64 Encoding/Decoding Routines
-======================================
-
-Requirements:
-------------
-This piece of software has minimal requirements.
-
-I have tested it on the following systems:
-
-- a Linux machine, with the following specs:
-(this was the original development machine)
-       * FedoraCore 4
-       * kernel v. 2.6.11 (stock FC4 kernel)
-       * gcc version 4.0.1 20050727 (Red Hat 4.0.1-5)
-       * glibc-2.3.5-10
-       * make v. 3.80
-       * some arb version of makedepend
-
-- Windows XP machine
-       * MSYS 1.0
-       * MinGW 5.1.4
-       * gcc version 3.4.5 (mingw-vista special r3)
-
-- Windows XP machine (same as above)
-       * Microsoft Visual Studio 2010, Version 10.0.30319.1 RTMRel
-       
-Barring any serious screwups on my part, this code should compile and run sweetly
-under Cygwin and other systems too. If you DO get it running under some weird arch/os setup,
-send me a mail, please.
-
-Compiling:
----------
-There is no configure. It would be overkill for something so simple...
-Run make in the root directory.
-
-Installing:
-----------
-Since the current targets are a standalone executable and a static library
-(fancy name for archive) with some headers, an install script has not been implemented yet.
-Simply copy the executable into your path, and use it.
-
---
-peace out
-Chris
diff --git a/third-party/libb64/LICENSE b/third-party/libb64/LICENSE
deleted file mode 100644 (file)
index a6b5606..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright-Only Dedication (based on United States law) 
-or Public Domain Certification
-
-The person or persons who have associated work with this document (the
-"Dedicator" or "Certifier") hereby either (a) certifies that, to the best of
-his knowledge, the work of authorship identified is in the public domain of the
-country from which the work is published, or (b) hereby dedicates whatever
-copyright the dedicators holds in the work of authorship identified below (the
-"Work") to the public domain. A certifier, moreover, dedicates any copyright
-interest he may have in the associated work, and for these purposes, is
-described as a "dedicator" below.
-
-A certifier has taken reasonable steps to verify the copyright status of this
-work. Certifier recognizes that his good faith efforts may not shield him from
-liability if in fact the work certified is not in the public domain.
-
-Dedicator makes this dedication for the benefit of the public at large and to
-the detriment of the Dedicator's heirs and successors. Dedicator intends this
-dedication to be an overt act of relinquishment in perpetuity of all present
-and future rights under copyright law, whether vested or contingent, in the
-Work. Dedicator understands that such relinquishment of all rights includes
-the relinquishment of all rights to enforce (by lawsuit or otherwise) those
-copyrights in the Work.
-
-Dedicator recognizes that, once placed in the public domain, the Work may be
-freely reproduced, distributed, transmitted, used, modified, built upon, or
-otherwise exploited by anyone for any purpose, commercial or non-commercial,
-and in any way, including by methods that have not yet been invented or
-conceived.
\ No newline at end of file
diff --git a/third-party/libb64/Makefile.am b/third-party/libb64/Makefile.am
deleted file mode 100644 (file)
index 4d0cd42..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-noinst_LIBRARIES = libb64.a
-libb64_a_SOURCES = cdecode.c cencode.c
-noinst_HEADERS = b64/cdecode.h b64/cencode.h
-EXTRA_DIST = AUTHORS CHANGELOG INSTALL LICENSE README
diff --git a/third-party/libb64/README b/third-party/libb64/README
deleted file mode 100644 (file)
index 132f02f..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-b64: Base64 Encoding/Decoding Routines
-======================================
-
-Overview:
---------
-libb64 is a library of ANSI C routines for fast encoding/decoding data into and
-from a base64-encoded format. C++ wrappers are included, as well as the source
-code for standalone encoding and decoding executables.
-
-base64 consists of ASCII text, and is therefore a useful encoding for storing 
-binary data in a text file, such as xml, or sending binary data over text-only
-email.
-
-References:
-----------
-* Wikipedia article:
-       http://en.wikipedia.org/wiki/Base64
-* base64, another implementation of a commandline en/decoder:
-       http://www.fourmilab.ch/webtools/base64/
-
-Why?
----
-I did this because I need an implementation of base64 encoding and decoding,
-without any licensing problems. Most OS implementations are released under
-either the GNU/GPL, or a BSD-variant, which is not what I require.
-
-Also, the chance to actually use the co-routine implementation in code is rare,
-and its use here is fitting. I couldn't pass up the chance.
-For more information on this technique, see "Coroutines in C", by Simon Tatham,
-which can be found online here: 
-http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
-
-So then, under which license do I release this code? On to the next section...
-
-License:
--------
-This work is released under into the Public Domain.
-It basically boils down to this: I put this work in the public domain, and you
-can take it and do whatever you want with it.
-
-An example of this "license" is the Creative Commons Public Domain License, a
-copy of which can be found in the LICENSE file, and also online at
-http://creativecommons.org/licenses/publicdomain/
-
-Commandline Use:
----------------
-There is a new executable available, it is simply called base64.
-It can encode and decode files, as instructed by the user.
-
-To encode a file:
-$ ./base64 -e filea fileb
-fileb will now be the base64-encoded version of filea.
-
-To decode a file:
-$ ./base64 -d fileb filec
-filec will now be identical to filea.
-
-Programming:
------------
-Some C++ wrappers are provided as well, so you don't have to get your hands
-dirty. Encoding from standard input to standard output is as simple as
-
-       #include <b64/encode.h>
-       #include <iostream>
-       int main()
-       {
-               base64::encoder E;
-               E.encode(std::cin, std::cout);
-               return 0;
-       }
-
-Both standalone executables and a static library is provided in the package,
-
-Example code:
-------------
-The 'examples' directory contains some simple example C code, that demonstrates
-how to use the C interface of the library.
-
-Implementation:
---------------
-It is DAMN fast, if I may say so myself. The C code uses a little trick which
-has been used to implement coroutines, of which one can say that this
-implementation is an example.
-
-(To see how the libb64 codebase compares with some other BASE64 implementations
-available, see the BENCHMARKS file)
-
-The trick involves the fact that a switch-statement may legally cross into
-sub-blocks. A very thorough and enlightening essay on co-routines in C, using
-this method, can be found in the above mentioned "Coroutines in C", by Simon
-Tatham: http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
-
-For example, an RLE decompressing routine, adapted from the article:
-1      static int STATE = 0;
-2      static int len, c;
-3      switch (STATE)
-4      {
-5              while (1)
-6              {
-7                      c = getchar();
-8                      if (c == EOF) return EOF;
-9                      if (c == 0xFF) {
-10                             len = getchar();
-11                             c = getchar();
-12                             while (len--)
-13                             {
-14                                     STATE = 0;
-15                                     return c;
-16     case 0:
-17                             }
-18                     } else
-19                             STATE = 1;
-20                             return c;
-21     case 1:
-22                     }
-23             }
-24     }
-
-As can be seen from this example, a coroutine depends on a state variable,
-which it sets directly before exiting (lines 14 and 119). The next time the
-routine is entered, the switch moves control to the specific point directly
-after the previous exit (lines 16 and 21).hands
-
-(As an aside, in the mentioned article the combination of the top-level switch,
-the various setting of the state, the return of a value, and the labelling of
-the exit point is wrapped in #define macros, making the structure of the
-routine even clearer.)
-
-The obvious problem with any such routine is the static keyword.
-Any static variables in a function spell doom for multithreaded applications.
-Also, in situations where this coroutine is used by more than one other
-coroutines, the consistency is disturbed.
-
-What is needed is a structure for storing these variabled, which is passed to
-the routine seperately. This obviously breaks the modularity of the function,
-since now the caller has to worry about and care for the internal state of the
-routine (the callee). This allows for a fast, multithreading-enabled
-implementation, which may (obviously) be wrapped in a C++ object for ease of
-use.
-
-The base64 encoding and decoding functionality in this package is implemented
-in exactly this way, providing both a high-speed high-maintanence C interface,
-and a wrapped C++ which is low-maintanence and only slightly less performant.
diff --git a/third-party/libb64/b64/cdecode.h b/third-party/libb64/b64/cdecode.h
deleted file mode 100644 (file)
index 5729853..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-cdecode.h - c header for a base64 decoding algorithm
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#ifndef BASE64_CDECODE_H
-#define BASE64_CDECODE_H
-
-typedef enum
-{
-       step_a, step_b, step_c, step_d
-} base64_decodestep;
-
-typedef struct
-{
-       base64_decodestep step;
-       char plainchar;
-} base64_decodestate;
-
-void base64_init_decodestate(base64_decodestate* state_in);
-
-int base64_decode_value(char value_in);
-
-int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in);
-
-#endif /* BASE64_CDECODE_H */
-
diff --git a/third-party/libb64/b64/cencode.h b/third-party/libb64/b64/cencode.h
deleted file mode 100644 (file)
index cf32131..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-cencode.h - c header for a base64 encoding algorithm
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#ifndef BASE64_CENCODE_H
-#define BASE64_CENCODE_H
-
-typedef enum
-{
-       step_A, step_B, step_C
-} base64_encodestep;
-
-typedef struct
-{
-       base64_encodestep step;
-       char result;
-       int stepcount;
-} base64_encodestate;
-
-void base64_init_encodestate(base64_encodestate* state_in);
-
-char base64_encode_value(char value_in);
-
-int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
-
-int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
-
-#endif /* BASE64_CENCODE_H */
-
diff --git a/third-party/libb64/cdecode.c b/third-party/libb64/cdecode.c
deleted file mode 100644 (file)
index d9ca881..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-cdecoder.c - c source to a base64 decoding algorithm implementation
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#include <b64/cdecode.h>
-
-int base64_decode_value(char value_in)
-{
-       static const signed char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
-       static const char decoding_size = sizeof(decoding);
-       value_in -= 43;
-       if (value_in < 0 || value_in >= decoding_size) return -1;
-       return decoding[(int)value_in];
-}
-
-void base64_init_decodestate(base64_decodestate* state_in)
-{
-       state_in->step = step_a;
-       state_in->plainchar = 0;
-}
-
-int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in)
-{
-       const char* codechar = code_in;
-       char* plainchar = plaintext_out;
-       int fragment;
-       
-       *plainchar = state_in->plainchar;
-       
-       switch (state_in->step)
-       {
-               while (1)
-               {
-       case step_a:
-                       do {
-                               if (codechar == code_in+length_in)
-                               {
-                                       state_in->step = step_a;
-                                       state_in->plainchar = *plainchar;
-                                       return plainchar - plaintext_out;
-                               }
-                               fragment = base64_decode_value(*codechar++);
-                       } while (fragment < 0);
-                       *plainchar    = (fragment & 0x03f) << 2;
-       case step_b:
-                       do {
-                               if (codechar == code_in+length_in)
-                               {
-                                       state_in->step = step_b;
-                                       state_in->plainchar = *plainchar;
-                                       return plainchar - plaintext_out;
-                               }
-                               fragment = base64_decode_value(*codechar++);
-                       } while (fragment < 0);
-                       *plainchar++ |= (fragment & 0x030) >> 4;
-                       *plainchar    = (fragment & 0x00f) << 4;
-       case step_c:
-                       do {
-                               if (codechar == code_in+length_in)
-                               {
-                                       state_in->step = step_c;
-                                       state_in->plainchar = *plainchar;
-                                       return plainchar - plaintext_out;
-                               }
-                               fragment = base64_decode_value(*codechar++);
-                       } while (fragment < 0);
-                       *plainchar++ |= (fragment & 0x03c) >> 2;
-                       *plainchar    = (fragment & 0x003) << 6;
-       case step_d:
-                       do {
-                               if (codechar == code_in+length_in)
-                               {
-                                       state_in->step = step_d;
-                                       state_in->plainchar = *plainchar;
-                                       return plainchar - plaintext_out;
-                               }
-                               fragment = base64_decode_value(*codechar++);
-                       } while (fragment < 0);
-                       *plainchar++   |= (fragment & 0x03f);
-               }
-       }
-       /* control should not reach here */
-       return plainchar - plaintext_out;
-}
-
diff --git a/third-party/libb64/cencode.c b/third-party/libb64/cencode.c
deleted file mode 100644 (file)
index de3902f..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-cencoder.c - c source to a base64 encoding algorithm implementation
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#include <b64/cencode.h>
-
-/*
-const int CHARS_PER_LINE = 72;
-*/
-
-void base64_init_encodestate(base64_encodestate* state_in)
-{
-       state_in->step = step_A;
-       state_in->result = 0;
-       state_in->stepcount = 0;
-}
-
-char base64_encode_value(char value_in)
-{
-       static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-       if (value_in > 63) return '=';
-       return encoding[(int)value_in];
-}
-
-int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
-{
-       const char* plainchar = plaintext_in;
-       const char* const plaintextend = plaintext_in + length_in;
-       char* codechar = code_out;
-       char result;
-       char fragment;
-       
-       result = state_in->result;
-       
-       switch (state_in->step)
-       {
-               while (1)
-               {
-       case step_A:
-                       if (plainchar == plaintextend)
-                       {
-                               state_in->result = result;
-                               state_in->step = step_A;
-                               return codechar - code_out;
-                       }
-                       fragment = *plainchar++;
-                       result = (fragment & 0x0fc) >> 2;
-                       *codechar++ = base64_encode_value(result);
-                       result = (fragment & 0x003) << 4;
-       case step_B:
-                       if (plainchar == plaintextend)
-                       {
-                               state_in->result = result;
-                               state_in->step = step_B;
-                               return codechar - code_out;
-                       }
-                       fragment = *plainchar++;
-                       result |= (fragment & 0x0f0) >> 4;
-                       *codechar++ = base64_encode_value(result);
-                       result = (fragment & 0x00f) << 2;
-       case step_C:
-                       if (plainchar == plaintextend)
-                       {
-                               state_in->result = result;
-                               state_in->step = step_C;
-                               return codechar - code_out;
-                       }
-                       fragment = *plainchar++;
-                       result |= (fragment & 0x0c0) >> 6;
-                       *codechar++ = base64_encode_value(result);
-                       result  = (fragment & 0x03f) >> 0;
-                       *codechar++ = base64_encode_value(result);
-                       
-                       /*
-                       ++(state_in->stepcount);
-                       if (state_in->stepcount == CHARS_PER_LINE/4)
-                       {
-                               *codechar++ = '\n';
-                               state_in->stepcount = 0;
-                       }
-                       */
-               }
-       }
-       /* control should not reach here */
-       return codechar - code_out;
-}
-
-int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
-{
-       char* codechar = code_out;
-       
-       switch (state_in->step)
-       {
-       case step_B:
-               *codechar++ = base64_encode_value(state_in->result);
-               *codechar++ = '=';
-               *codechar++ = '=';
-               break;
-       case step_C:
-               *codechar++ = base64_encode_value(state_in->result);
-               *codechar++ = '=';
-               break;
-       case step_A:
-               break;
-       }
-       /*
-       *codechar++ = '\n';
-       */
-       
-       return codechar - code_out;
-}
-
diff --git a/third-party/libnatpmp/Changelog.txt b/third-party/libnatpmp/Changelog.txt
deleted file mode 100644 (file)
index 7558b1a..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-$Id: Changelog.txt,v 1.29 2011/08/07 16:59:33 nanard Exp $
-
-2011/08/07:
-  Patch to build on debian/kFreeBSD.
-
-2011/07/15:
-  Put 3 clauses BSD licence at the top of source files.
-
-2011/06/18:
-  --no-undefined => -Wl,--no-undefined
-  adding a natpmpc.1 man page
-
-2011/05/19:
-  Small fix in libnatpmpmodule.c thanks to Manuel Mausz
-
-2011/01/03:
-  Added an argument to initnatpmp() in order to force the gateway to be used
-
-2011/01/01:
-  fix in make install
-
-2010/05/21:
-  make install now working under MacOSX (and BSD)
-
-2010/04/12:
-  cplusplus stuff in natpmp.h
-
-2010/02/02:
-  Fixed compilation under Mac OS X
-
-2009/12/19:
-  improve and fix building under Windows.
-  Project files for MS Visual Studio 2008
-  More simple (and working) code for Win32.
-  More checks in the /proc/net/route parsing. Add some comments.
-
-2009/08/04:
-  improving getgateway.c for windows
-
-2009/07/13:
-  Adding Haiku code in getgateway.c
-
-2009/06/04:
-  Adding Python module thanks to David Wu
-
-2009/03/10:
-  Trying to have windows get gateway working if not using DHCP
-
-2009/02/27:
-  dont include declspec.h if not under WIN32.
-
-2009/01/23:
-  Prefixed the libraries name with lib
-
-2008/10/06:
-  Fixed a memory leak in getdefaultgateway() (USE_SYSCTL_NET_ROUTE)
-
-2008/07/03:
-  Adding WIN32 code from Robbie Hanson
-
-2008/06/30:
-  added a Solaris implementation for getgateway().
-  added a LICENCE file to the distribution
-
-2008/05/29:
-  Anonymous unions are forbidden in ANSI C. That was causing problems with
-  non-GCC compilers.
-
-2008/04/28:
-  introduced strnatpmperr()
-  improved natpmpc.c sample
-  make install now install the binary
-
-2007/12/13:
-  Fixed getgateway.c for working under OS X ;)
-  Fixed values for NATPMP_PROTOCOL_TCP and NATPMP_PROTOCOL_UDP
-
-2007/12/11:
-  Fixed getgateway.c for compilation under Mac OS X
-
-2007/12/01:
-  added some comments in .h
-
-2007/11/30:
-  implemented almost everything
-
diff --git a/third-party/libnatpmp/LICENSE b/third-party/libnatpmp/LICENSE
deleted file mode 100644 (file)
index 5bae1be..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 2007-2011, Thomas BERNARD 
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/third-party/libnatpmp/Makefile.am b/third-party/libnatpmp/Makefile.am
deleted file mode 100644 (file)
index de9fb74..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-noinst_LIBRARIES = libnatpmp.a
-
-AM_CFLAGS = @PTHREAD_CFLAGS@ -DENABLE_STRNATPMPERR
-
-libnatpmp_a_SOURCES = \
-    getgateway.c \
-    natpmp.c \
-    wingettimeofday.c
-
-noinst_HEADERS = \
-    declspec.h \
-    getgateway.h \
-    natpmp.h \
-    wingettimeofday.h
-
-EXTRA_DIST = \
-    README \
-    LICENSE
diff --git a/third-party/libnatpmp/README b/third-party/libnatpmp/README
deleted file mode 100644 (file)
index 269392d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-libnatpmp (c) 2007-2009 Thomas Bernard
-contact : miniupnp@free.fr
-
-see http://miniupnp.free.fr/libnatpmp.html
-or http://miniupnp.tuxfamily.org/libnatpmp.html
-for some documentation and code samples.
-
diff --git a/third-party/libnatpmp/declspec.h b/third-party/libnatpmp/declspec.h
deleted file mode 100644 (file)
index ea479d1..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __DECLSPEC_H__
-#define __DECLSPEC_H__
-
-#if defined(WIN32) && !defined(STATICLIB)
-       #ifdef NATPMP_EXPORTS
-               #define LIBSPEC __declspec(dllexport)
-       #else
-               #define LIBSPEC __declspec(dllimport)
-       #endif
-#else
-       #define LIBSPEC
-#endif
-
-#endif
-
diff --git a/third-party/libnatpmp/getgateway.c b/third-party/libnatpmp/getgateway.c
deleted file mode 100644 (file)
index cb84dee..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-/* $Id: getgateway.c,v 1.22 2011/08/08 21:20:51 nanard Exp $ */
-/* libnatpmp
-
-Copyright (c) 2007-2011, Thomas BERNARD 
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <stdio.h>
-#include <ctype.h>
-#ifndef WIN32
-#include <netinet/in.h>
-#endif
-#if !defined(_MSC_VER)
-#include <sys/param.h>
-#endif
-/* There is no portable method to get the default route gateway.
- * So below are four (or five ?) differents functions implementing this.
- * Parsing /proc/net/route is for linux.
- * sysctl is the way to access such informations on BSD systems.
- * Many systems should provide route information through raw PF_ROUTE
- * sockets.
- * In MS Windows, default gateway is found by looking into the registry
- * or by using GetBestRoute(). */
-#ifdef __linux__
-#define USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#endif
-
-#if defined(BSD) || defined(__FreeBSD_kernel__)
-#undef USE_PROC_NET_ROUTE
-#define USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#endif
-
-#ifdef __APPLE__
-#undef USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#define USE_SYSCTL_NET_ROUTE
-#endif
-
-#if (defined(sun) && defined(__SVR4))
-#undef USE_PROC_NET_ROUTE
-#define USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#endif
-
-#ifdef WIN32
-#undef USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-//#define USE_WIN32_CODE
-#define USE_WIN32_CODE_2
-#endif
-
-#ifdef __CYGWIN__
-#undef USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#define USE_WIN32_CODE
-#include <stdarg.h>
-#include <w32api/windef.h>
-#include <w32api/winbase.h>
-#include <w32api/winreg.h>
-#endif 
-
-#ifdef __HAIKU__
-#include <stdlib.h>
-#include <unistd.h>
-#include <net/if.h>
-#include <sys/sockio.h>
-#define USE_HAIKU_CODE
-#endif 
-
-#ifdef USE_SYSCTL_NET_ROUTE
-#include <stdlib.h>
-#include <sys/sysctl.h>
-#include <sys/socket.h>
-#include <net/route.h>
-#endif
-#ifdef USE_SOCKET_ROUTE
-#include <unistd.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/route.h>
-#endif
-
-#ifdef USE_WIN32_CODE
-#include <unknwn.h>
-#include <winreg.h>
-#define MAX_KEY_LENGTH 255
-#define MAX_VALUE_LENGTH 16383
-#endif
-
-#ifdef USE_WIN32_CODE_2
-#include <windows.h>
-#include <iphlpapi.h>
-#endif
-
-#include "getgateway.h"
-
-#ifndef WIN32
-#define SUCCESS (0)
-#define FAILED  (-1)
-#endif
-
-#ifdef USE_PROC_NET_ROUTE
-/*
- parse /proc/net/route which is as follow :
-
-Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT           
-wlan0   0001A8C0        00000000        0001    0       0       0       00FFFFFF        0       0       0              
-eth0    0000FEA9        00000000        0001    0       0       0       0000FFFF        0       0       0              
-wlan0   00000000        0101A8C0        0003    0       0       0       00000000        0       0       0              
-eth0    00000000        00000000        0001    0       0       1000    00000000        0       0       0              
-
- One header line, and then one line by route by route table entry.
-*/
-int getdefaultgateway(in_addr_t * addr)
-{
-       unsigned long d, g;
-       char buf[256];
-       int line = 0;
-       FILE * f;
-       char * p;
-       f = fopen("/proc/net/route", "r");
-       if(!f)
-               return FAILED;
-       while(fgets(buf, sizeof(buf), f)) {
-               if(line > 0) {  /* skip the first line */
-                       p = buf;
-                       /* skip the interface name */
-                       while(*p && !isspace(*p))
-                               p++;
-                       while(*p && isspace(*p))
-                               p++;
-                       if(sscanf(p, "%lx%lx", &d, &g)==2) {
-                               if(d == 0 && g != 0) { /* default */
-                                       *addr = g;
-                                       fclose(f);
-                                       return SUCCESS;
-                               }
-                       }
-               }
-               line++;
-       }
-       /* default route not found ! */
-       if(f)
-               fclose(f);
-       return FAILED;
-}
-#endif /* #ifdef USE_PROC_NET_ROUTE */
-
-
-#ifdef USE_SYSCTL_NET_ROUTE
-
-#define ROUNDUP(a) \
-       ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
-int getdefaultgateway(in_addr_t * addr)
-{
-#if 0
-       /* net.route.0.inet.dump.0.0 ? */
-       int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
-                    NET_RT_DUMP, 0, 0/*tableid*/};
-#endif
-       /* net.route.0.inet.flags.gateway */
-       int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
-                    NET_RT_FLAGS, RTF_GATEWAY};
-       size_t l;
-       char * buf, * p;
-       struct rt_msghdr * rt;
-       struct sockaddr * sa;
-       struct sockaddr * sa_tab[RTAX_MAX];
-       int i;
-       int r = FAILED;
-       if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
-               return FAILED;
-       }
-       if(l>0) {
-               buf = malloc(l);
-               if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
-                       free(buf);
-                       return FAILED;
-               }
-               for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
-                       rt = (struct rt_msghdr *)p;
-                       sa = (struct sockaddr *)(rt + 1);
-                       for(i=0; i<RTAX_MAX; i++) {
-                               if(rt->rtm_addrs & (1 << i)) {
-                                       sa_tab[i] = sa;
-                                       sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
-                               } else {
-                                       sa_tab[i] = NULL;
-                               }
-                       }
-                       if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
-              && sa_tab[RTAX_DST]->sa_family == AF_INET
-              && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
-                               if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
-                                       *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
-                                       r = SUCCESS;
-                               }
-                       }
-               }
-               free(buf);
-       }
-       return r;
-}
-#endif /* #ifdef USE_SYSCTL_NET_ROUTE */
-
-
-#ifdef USE_SOCKET_ROUTE
-/* Thanks to Darren Kenny for this code */
-#define NEXTADDR(w, u) \
-        if (rtm_addrs & (w)) {\
-            l = sizeof(struct sockaddr); memmove(cp, &(u), l); cp += l;\
-        }
-
-#define rtm m_rtmsg.m_rtm
-
-struct {
-  struct rt_msghdr m_rtm;
-  char       m_space[512];
-} m_rtmsg;
-
-int getdefaultgateway(in_addr_t *addr)
-{
-  int s, seq, l, rtm_addrs, i;
-  pid_t pid;
-  struct sockaddr so_dst, so_mask;
-  char *cp = m_rtmsg.m_space; 
-  struct sockaddr *gate = NULL, *sa;
-  struct rt_msghdr *msg_hdr;
-
-  pid = getpid();
-  seq = 0;
-  rtm_addrs = RTA_DST | RTA_NETMASK;
-
-  memset(&so_dst, 0, sizeof(so_dst));
-  memset(&so_mask, 0, sizeof(so_mask));
-  memset(&rtm, 0, sizeof(struct rt_msghdr));
-
-  rtm.rtm_type = RTM_GET;
-  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
-  rtm.rtm_version = RTM_VERSION;
-  rtm.rtm_seq = ++seq;
-  rtm.rtm_addrs = rtm_addrs; 
-
-  so_dst.sa_family = AF_INET;
-  so_mask.sa_family = AF_INET;
-
-  NEXTADDR(RTA_DST, so_dst);
-  NEXTADDR(RTA_NETMASK, so_mask);
-
-  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
-
-  s = socket(PF_ROUTE, SOCK_RAW, 0);
-
-  if (write(s, (char *)&m_rtmsg, l) < 0) {
-      close(s);
-      return FAILED;
-  }
-
-  do {
-    l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
-  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-                        
-  close(s);
-
-  msg_hdr = &rtm;
-
-  cp = ((char *)(msg_hdr + 1));
-  if (msg_hdr->rtm_addrs) {
-    for (i = 1; i; i <<= 1)
-      if (i & msg_hdr->rtm_addrs) {
-        sa = (struct sockaddr *)cp;
-        if (i == RTA_GATEWAY )
-          gate = sa;
-
-        cp += sizeof(struct sockaddr);
-      }
-  } else {
-      return FAILED;
-  }
-
-
-  if (gate != NULL ) {
-      *addr = ((struct sockaddr_in *)gate)->sin_addr.s_addr;
-      return SUCCESS;
-  } else {
-      return FAILED;
-  }
-}
-#endif /* #ifdef USE_SOCKET_ROUTE */
-
-#ifdef USE_WIN32_CODE
-LIBSPEC int getdefaultgateway(in_addr_t * addr)
-{
-       HKEY networkCardsKey;
-       HKEY networkCardKey;
-       HKEY interfacesKey;
-       HKEY interfaceKey;
-       DWORD i = 0;
-       DWORD numSubKeys = 0;
-       TCHAR keyName[MAX_KEY_LENGTH];
-       DWORD keyNameLength = MAX_KEY_LENGTH;
-       TCHAR keyValue[MAX_VALUE_LENGTH];
-       DWORD keyValueLength = MAX_VALUE_LENGTH;
-       DWORD keyValueType = REG_SZ;
-       TCHAR gatewayValue[MAX_VALUE_LENGTH];
-       DWORD gatewayValueLength = MAX_VALUE_LENGTH;
-       DWORD gatewayValueType = REG_MULTI_SZ;
-       int done = 0;
-       
-       //const char * networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
-       //const char * interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
-#ifdef UNICODE
-       LPCTSTR networkCardsPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
-       LPCTSTR interfacesPath = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
-#define STR_SERVICENAME         L"ServiceName"
-#define STR_DHCPDEFAULTGATEWAY L"DhcpDefaultGateway"
-#define STR_DEFAULTGATEWAY     L"DefaultGateway"
-#else
-       LPCTSTR networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
-       LPCTSTR interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
-#define STR_SERVICENAME         "ServiceName"
-#define STR_DHCPDEFAULTGATEWAY "DhcpDefaultGateway"
-#define STR_DEFAULTGATEWAY     "DefaultGateway"
-#endif
-       // The windows registry lists its primary network devices in the following location:
-       // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
-       // 
-       // Each network device has its own subfolder, named with an index, with various properties:
-       // -NetworkCards
-       //   -5
-       //     -Description = Broadcom 802.11n Network Adapter
-       //     -ServiceName = {E35A72F8-5065-4097-8DFE-C7790774EE4D}
-       //   -8
-       //     -Description = Marvell Yukon 88E8058 PCI-E Gigabit Ethernet Controller
-       //     -ServiceName = {86226414-5545-4335-A9D1-5BD7120119AD}
-       // 
-       // The above service name is the name of a subfolder within:
-       // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
-       // 
-       // There may be more subfolders in this interfaces path than listed in the network cards path above:
-       // -Interfaces
-       //   -{3a539854-6a70-11db-887c-806e6f6e6963}
-       //     -DhcpIPAddress = 0.0.0.0
-       //     -[more]
-       //   -{E35A72F8-5065-4097-8DFE-C7790774EE4D}
-       //     -DhcpIPAddress = 10.0.1.4
-       //     -DhcpDefaultGateway = 10.0.1.1
-       //     -[more]
-       //   -{86226414-5545-4335-A9D1-5BD7120119AD}
-       //     -DhcpIpAddress = 10.0.1.5
-       //     -DhcpDefaultGateay = 10.0.1.1
-       //     -[more]
-       // 
-       // In order to extract this information, we enumerate each network card, and extract the ServiceName value.
-       // This is then used to open the interface subfolder, and attempt to extract a DhcpDefaultGateway value.
-       // Once one is found, we're done.
-       // 
-       // It may be possible to simply enumerate the interface folders until we find one with a DhcpDefaultGateway value.
-       // However, the technique used is the technique most cited on the web, and we assume it to be more correct.
-       
-       if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predifined key 
-                                        networkCardsPath,   // Name of registry subkey to open
-                                        0,                  // Reserved - must be zero
-                                        KEY_READ,           // Mask - desired access rights
-                                        &networkCardsKey))  // Pointer to output key
-       {
-               // Unable to open network cards keys
-               return -1;
-       }
-       
-       if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predefined key
-                                        interfacesPath,     // Name of registry subkey to open
-                                        0,                  // Reserved - must be zero
-                                        KEY_READ,           // Mask - desired access rights
-                                        &interfacesKey))    // Pointer to output key
-       {
-               // Unable to open interfaces key
-               RegCloseKey(networkCardsKey);
-               return -1;
-       }
-       
-       // Figure out how many subfolders are within the NetworkCards folder
-       RegQueryInfoKey(networkCardsKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-       
-       //printf( "Number of subkeys: %u\n", (unsigned int)numSubKeys);
-       
-       // Enumrate through each subfolder within the NetworkCards folder
-       for(i = 0; i < numSubKeys && !done; i++)
-       {
-               keyNameLength = MAX_KEY_LENGTH;
-               if(ERROR_SUCCESS == RegEnumKeyEx(networkCardsKey, // Open registry key
-                                                i,               // Index of subkey to retrieve
-                                                keyName,         // Buffer that receives the name of the subkey
-                                                &keyNameLength,  // Variable that receives the size of the above buffer
-                                                NULL,            // Reserved - must be NULL
-                                                NULL,            // Buffer that receives the class string
-                                                NULL,            // Variable that receives the size of the above buffer
-                                                NULL))           // Variable that receives the last write time of subkey
-               {
-                       if(RegOpenKeyEx(networkCardsKey,  keyName, 0, KEY_READ, &networkCardKey) == ERROR_SUCCESS)
-                       {
-                               keyValueLength = MAX_VALUE_LENGTH;
-                               if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey,   // Open registry key
-                                                                   STR_SERVICENAME,    // Name of key to query
-                                                                   NULL,             // Reserved - must be NULL
-                                                                   &keyValueType,    // Receives value type
-                                                                   (LPBYTE)keyValue, // Receives value
-                                                                   &keyValueLength)) // Receives value length in bytes
-                               {
-//                                     printf("keyValue: %s\n", keyValue);                             
-                                       if(RegOpenKeyEx(interfacesKey, keyValue, 0, KEY_READ, &interfaceKey) == ERROR_SUCCESS)
-                                       {
-                                               gatewayValueLength = MAX_VALUE_LENGTH;
-                                               if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey,         // Open registry key
-                                                                                   STR_DHCPDEFAULTGATEWAY, // Name of key to query
-                                                                                   NULL,                 // Reserved - must be NULL
-                                                                                   &gatewayValueType,    // Receives value type
-                                                                                   (LPBYTE)gatewayValue, // Receives value
-                                                                                   &gatewayValueLength)) // Receives value length in bytes
-                                               {
-                                                       // Check to make sure it's a string
-                                                       if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
-                                                       {
-                                                               //printf("gatewayValue: %s\n", gatewayValue);
-                                                               done = 1;
-                                                       }
-                                               }
-                                               else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey,         // Open registry key
-                                                                                   STR_DEFAULTGATEWAY, // Name of key to query
-                                                                                   NULL,                 // Reserved - must be NULL
-                                                                                   &gatewayValueType,    // Receives value type
-                                                                                   (LPBYTE)gatewayValue,// Receives value
-                                                                                   &gatewayValueLength)) // Receives value length in bytes
-                                               {
-                                                       // Check to make sure it's a string
-                                                       if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
-                                                       {
-                                                               //printf("gatewayValue: %s\n", gatewayValue);
-                                                               done = 1;
-                                                       }
-                                               }
-                                               RegCloseKey(interfaceKey);
-                                       }
-                               }
-                               RegCloseKey(networkCardKey);
-                       }
-               }
-       }
-       
-       RegCloseKey(interfacesKey);
-       RegCloseKey(networkCardsKey);
-       
-       if(done)
-       {
-#if UNICODE
-               char tmp[32];
-               for(i = 0; i < 32; i++) {
-                       tmp[i] = (char)gatewayValue[i];
-                       if(!tmp[i])
-                               break;
-               }
-               tmp[31] = '\0';
-               *addr = inet_addr(tmp);
-#else
-               *addr = inet_addr(gatewayValue);
-#endif
-               return 0;
-       }
-       
-       return -1;
-}
-#endif /* #ifdef USE_WIN32_CODE */
-
-#ifdef USE_WIN32_CODE_2
-int getdefaultgateway(in_addr_t *addr)
-{
-       MIB_IPFORWARDROW ip_forward;
-       memset(&ip_forward, 0, sizeof(ip_forward));
-       if(GetBestRoute(inet_addr("0.0.0.0"), 0, &ip_forward) != NO_ERROR)
-               return -1;
-       *addr = ip_forward.dwForwardNextHop;
-       return 0;
-}
-#endif /* #ifdef USE_WIN32_CODE_2 */
-
-#ifdef USE_HAIKU_CODE
-int getdefaultgateway(in_addr_t *addr)
-{
-    int fd, ret = -1;
-    struct ifconf config;
-    void *buffer = NULL;
-    struct ifreq *interface;
-
-    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        return -1;
-    }
-    if (ioctl(fd, SIOCGRTSIZE, &config, sizeof(config)) != 0) {
-        goto fail;
-    }
-    if (config.ifc_value < 1) {
-        goto fail; /* No routes */
-    }
-    if ((buffer = malloc(config.ifc_value)) == NULL) {
-        goto fail;
-    }
-    config.ifc_len = config.ifc_value;
-    config.ifc_buf = buffer;
-    if (ioctl(fd, SIOCGRTTABLE, &config, sizeof(config)) != 0) {
-        goto fail;
-    }
-    for (interface = buffer;
-      (uint8_t *)interface < (uint8_t *)buffer + config.ifc_len; ) {
-        struct route_entry route = interface->ifr_route;
-        int intfSize;
-        if (route.flags & (RTF_GATEWAY | RTF_DEFAULT)) {
-            *addr = ((struct sockaddr_in *)route.gateway)->sin_addr.s_addr;
-            ret = 0;
-            break;
-        }
-        intfSize = sizeof(route) + IF_NAMESIZE;
-        if (route.destination != NULL) {
-            intfSize += route.destination->sa_len;
-        }
-        if (route.mask != NULL) {
-            intfSize += route.mask->sa_len;
-        }
-        if (route.gateway != NULL) {
-            intfSize += route.gateway->sa_len;
-        }
-        interface = (struct ifreq *)((uint8_t *)interface + intfSize);
-    }
-fail:
-    free(buffer);
-    close(fd);
-    return ret;
-}
-#endif /* #ifdef USE_HAIKU_CODE */
-
-
diff --git a/third-party/libnatpmp/getgateway.h b/third-party/libnatpmp/getgateway.h
deleted file mode 100644 (file)
index 32af909..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* $Id: getgateway.h,v 1.5 2011/07/15 08:30:11 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2011, Thomas BERNARD 
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef __GETGATEWAY_H__
-#define __GETGATEWAY_H__
-
-#ifdef WIN32
-#if !defined(_MSC_VER)
-#include <stdint.h>
-#else
-typedef unsigned long uint32_t;
-typedef unsigned short uint16_t;
-#endif
-#define in_addr_t uint32_t
-#endif
-#include "declspec.h"
-
-/* getdefaultgateway() :
- * return value :
- *    0 : success
- *   -1 : failure    */
-LIBSPEC int getdefaultgateway(in_addr_t * addr);
-
-#endif
diff --git a/third-party/libnatpmp/natpmp.c b/third-party/libnatpmp/natpmp.c
deleted file mode 100644 (file)
index 6f3caf1..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/* $Id: natpmp.c,v 1.14 2011/07/15 08:30:11 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2011, Thomas BERNARD 
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifdef __linux__
-#define _BSD_SOURCE 1
-#endif
-#include <string.h>
-#include <time.h>
-#if !defined(_MSC_VER)
-#include <sys/time.h>
-#endif
-#ifdef WIN32
-#include <errno.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define ECONNREFUSED WSAECONNREFUSED
-#include "wingettimeofday.h"
-#else
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#define closesocket close
-#endif
-#include "natpmp.h"
-#include "getgateway.h"
-
-LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw)
-{
-#ifdef WIN32
-       u_long ioctlArg = 1;
-#else
-       int flags; 
-#endif
-       struct sockaddr_in addr;
-       if(!p)
-               return NATPMP_ERR_INVALIDARGS;
-       memset(p, 0, sizeof(natpmp_t));
-       p->s = socket(PF_INET, SOCK_DGRAM, 0);
-       if(p->s < 0)
-               return NATPMP_ERR_SOCKETERROR;
-#ifdef WIN32
-       if(ioctlsocket(p->s, FIONBIO, &ioctlArg) == SOCKET_ERROR)
-               return NATPMP_ERR_FCNTLERROR;
-#else
-       if((flags = fcntl(p->s, F_GETFL, 0)) < 0)
-               return NATPMP_ERR_FCNTLERROR;
-       if(fcntl(p->s, F_SETFL, flags | O_NONBLOCK) < 0)
-               return NATPMP_ERR_FCNTLERROR;
-#endif
-
-       if(forcegw) {
-               p->gateway = forcedgw;
-       } else {
-               if(getdefaultgateway(&(p->gateway)) < 0)
-                       return NATPMP_ERR_CANNOTGETGATEWAY;
-       }
-       
-       memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
-       addr.sin_port = htons(NATPMP_PORT);
-       addr.sin_addr.s_addr = p->gateway;
-       if(connect(p->s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
-               return NATPMP_ERR_CONNECTERR;
-       return 0;
-}
-
-LIBSPEC int closenatpmp(natpmp_t * p)
-{
-       if(!p)
-               return NATPMP_ERR_INVALIDARGS;
-       if(closesocket(p->s) < 0)
-               return NATPMP_ERR_CLOSEERR;
-       return 0;
-}
-
-int sendpendingrequest(natpmp_t * p)
-{
-       int r;
-/*     struct sockaddr_in addr;*/
-       if(!p)
-               return NATPMP_ERR_INVALIDARGS;
-/*     memset(&addr, 0, sizeof(addr));
-       addr.sin_family = AF_INET;
-       addr.sin_port = htons(NATPMP_PORT);
-       addr.sin_addr.s_addr = p->gateway;
-       r = (int)sendto(p->s, p->pending_request, p->pending_request_len, 0,
-                          (struct sockaddr *)&addr, sizeof(addr));*/
-       r = (int)send(p->s, p->pending_request, p->pending_request_len, 0);
-       return (r<0) ? NATPMP_ERR_SENDERR : r;
-}
-
-int sendnatpmprequest(natpmp_t * p)
-{
-       int n;
-       if(!p)
-               return NATPMP_ERR_INVALIDARGS;
-       /* TODO : check if no request is allready pending */
-       p->has_pending_request = 1;
-       p->try_number = 1;
-       n = sendpendingrequest(p);
-       gettimeofday(&p->retry_time, NULL);     // check errors !
-       p->retry_time.tv_usec += 250000;        /* add 250ms */
-       if(p->retry_time.tv_usec >= 1000000) {
-               p->retry_time.tv_usec -= 1000000;
-               p->retry_time.tv_sec++;
-       }
-       return n;
-}
-
-LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout)
-{
-       struct timeval now;
-       if(!p || !timeout)
-               return NATPMP_ERR_INVALIDARGS;
-       if(!p->has_pending_request)
-               return NATPMP_ERR_NOPENDINGREQ;
-       if(gettimeofday(&now, NULL) < 0)
-               return NATPMP_ERR_GETTIMEOFDAYERR;
-       timeout->tv_sec = p->retry_time.tv_sec - now.tv_sec;
-       timeout->tv_usec = p->retry_time.tv_usec - now.tv_usec;
-       if(timeout->tv_usec < 0) {
-               timeout->tv_usec += 1000000;
-               timeout->tv_sec--;
-       }
-       return 0;
-}
-
-LIBSPEC int sendpublicaddressrequest(natpmp_t * p)
-{
-       if(!p)
-               return NATPMP_ERR_INVALIDARGS;
-       //static const unsigned char request[] = { 0, 0 };
-       p->pending_request[0] = 0;
-       p->pending_request[1] = 0;
-       p->pending_request_len = 2;
-       // TODO: return 0 instead of sizeof(request) ??
-       return sendnatpmprequest(p);
-}
-
-LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
-                              uint16_t privateport, uint16_t publicport,
-                                                         uint32_t lifetime)
-{
-       if(!p || (protocol!=NATPMP_PROTOCOL_TCP && protocol!=NATPMP_PROTOCOL_UDP))
-               return NATPMP_ERR_INVALIDARGS;
-       p->pending_request[0] = 0;
-       p->pending_request[1] = protocol;
-       p->pending_request[2] = 0;
-       p->pending_request[3] = 0;
-       *((uint16_t *)(p->pending_request + 4)) = htons(privateport);
-       *((uint16_t *)(p->pending_request + 6)) = htons(publicport);
-       *((uint32_t *)(p->pending_request + 8)) = htonl(lifetime);
-       p->pending_request_len = 12;
-       return sendnatpmprequest(p);
-}
-
-LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response)
-{
-       unsigned char buf[16];
-       struct sockaddr_in addr;
-       socklen_t addrlen = sizeof(addr);
-       int n;
-       if(!p)
-               return NATPMP_ERR_INVALIDARGS;
-       n = recvfrom(p->s, buf, sizeof(buf), 0,
-                    (struct sockaddr *)&addr, &addrlen);
-       if(n<0)
-               switch(errno) {
-               /*case EAGAIN:*/
-               case EWOULDBLOCK:
-                       n = NATPMP_TRYAGAIN;
-                       break;
-               case ECONNREFUSED:
-                       n = NATPMP_ERR_NOGATEWAYSUPPORT;
-                       break;
-               default:
-                       n = NATPMP_ERR_RECVFROM;
-               }
-       /* check that addr is correct (= gateway) */
-       else if(addr.sin_addr.s_addr != p->gateway)
-               n = NATPMP_ERR_WRONGPACKETSOURCE;
-       else {
-               response->resultcode = ntohs(*((uint16_t *)(buf + 2)));
-               response->epoch = ntohl(*((uint32_t *)(buf + 4)));
-               if(buf[0] != 0)
-                       n = NATPMP_ERR_UNSUPPORTEDVERSION;
-               else if(buf[1] < 128 || buf[1] > 130)
-                       n = NATPMP_ERR_UNSUPPORTEDOPCODE;
-               else if(response->resultcode != 0) {
-                       switch(response->resultcode) {
-                       case 1:
-                               n = NATPMP_ERR_UNSUPPORTEDVERSION;
-                               break;
-                       case 2:
-                               n = NATPMP_ERR_NOTAUTHORIZED;
-                               break;
-                       case 3:
-                               n = NATPMP_ERR_NETWORKFAILURE;
-                               break;
-                       case 4:
-                               n = NATPMP_ERR_OUTOFRESOURCES;
-                               break;
-                       case 5:
-                               n = NATPMP_ERR_UNSUPPORTEDOPCODE;
-                               break;
-                       default:
-                               n = NATPMP_ERR_UNDEFINEDERROR;
-                       }
-               } else {
-                       response->type = buf[1] & 0x7f;
-                       if(buf[1] == 128)
-                               //response->publicaddress.addr = *((uint32_t *)(buf + 8));
-                               response->pnu.publicaddress.addr.s_addr = *((uint32_t *)(buf + 8));
-                       else {
-                               response->pnu.newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8)));
-                               response->pnu.newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10)));
-                               response->pnu.newportmapping.lifetime = ntohl(*((uint32_t *)(buf + 12)));
-                       }
-                       n = 0;
-               }
-       }
-       return n;
-}
-
-int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response)
-{
-       int n;
-       if(!p || !response)
-               return NATPMP_ERR_INVALIDARGS;
-       if(!p->has_pending_request)
-               return NATPMP_ERR_NOPENDINGREQ;
-       n = readnatpmpresponse(p, response);
-       if(n<0) {
-               if(n==NATPMP_TRYAGAIN) {
-                       struct timeval now;
-                       gettimeofday(&now, NULL);       // check errors !
-                       if(timercmp(&now, &p->retry_time, >=)) {
-                               int delay, r;
-                               if(p->try_number >= 9) {
-                                       return NATPMP_ERR_NOGATEWAYSUPPORT;
-                               }
-                               /*printf("retry! %d\n", p->try_number);*/
-                               delay = 250 * (1<<p->try_number);       // ms
-                               /*for(i=0; i<p->try_number; i++)
-                                       delay += delay;*/
-                               p->retry_time.tv_sec += (delay / 1000);
-                               p->retry_time.tv_usec += (delay % 1000) * 1000;
-                               if(p->retry_time.tv_usec >= 1000000) {
-                                       p->retry_time.tv_usec -= 1000000;
-                                       p->retry_time.tv_sec++;
-                               }
-                               p->try_number++;
-                               r = sendpendingrequest(p);
-                               if(r<0)
-                                       return r;
-                       }
-               }
-       } else {
-               p->has_pending_request = 0;
-       }
-       return n;
-}
-
-#ifdef ENABLE_STRNATPMPERR
-LIBSPEC const char * strnatpmperr(int r)
-{
-       const char * s;
-       switch(r) {
-       case NATPMP_ERR_INVALIDARGS:
-               s = "invalid arguments";
-               break;
-       case NATPMP_ERR_SOCKETERROR:
-               s = "socket() failed";
-               break;
-       case NATPMP_ERR_CANNOTGETGATEWAY:
-               s = "cannot get default gateway ip address";
-               break;
-       case NATPMP_ERR_CLOSEERR:
-#ifdef WIN32
-               s = "closesocket() failed";
-#else
-               s = "close() failed";
-#endif
-               break;
-       case NATPMP_ERR_RECVFROM:
-               s = "recvfrom() failed";
-               break;
-       case NATPMP_ERR_NOPENDINGREQ:
-               s = "no pending request";
-               break;
-       case NATPMP_ERR_NOGATEWAYSUPPORT:
-               s = "the gateway does not support nat-pmp";
-               break;
-       case NATPMP_ERR_CONNECTERR:
-               s = "connect() failed";
-               break;
-       case NATPMP_ERR_WRONGPACKETSOURCE:
-               s = "packet not received from the default gateway";
-               break;
-       case NATPMP_ERR_SENDERR:
-               s = "send() failed";
-               break;
-       case NATPMP_ERR_FCNTLERROR:
-               s = "fcntl() failed";
-               break;
-       case NATPMP_ERR_GETTIMEOFDAYERR:
-               s = "gettimeofday() failed";
-               break;
-       case NATPMP_ERR_UNSUPPORTEDVERSION:
-               s = "unsupported nat-pmp version error from server";
-               break;
-       case NATPMP_ERR_UNSUPPORTEDOPCODE:
-               s = "unsupported nat-pmp opcode error from server";
-               break;
-       case NATPMP_ERR_UNDEFINEDERROR:
-               s = "undefined nat-pmp server error";
-               break;
-       case NATPMP_ERR_NOTAUTHORIZED:
-               s = "not authorized";
-               break;
-       case NATPMP_ERR_NETWORKFAILURE:
-               s = "network failure";
-               break;
-       case NATPMP_ERR_OUTOFRESOURCES:
-               s = "nat-pmp server out of resources";
-               break;
-       default:
-               s = "Unknown libnatpmp error";
-       }
-       return s;
-}
-#endif
-
diff --git a/third-party/libnatpmp/natpmp.h b/third-party/libnatpmp/natpmp.h
deleted file mode 100644 (file)
index 369743c..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* $Id: natpmp.h,v 1.15 2011/07/15 08:30:11 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2011, Thomas BERNARD 
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef __NATPMP_H__
-#define __NATPMP_H__
-
-/* NAT-PMP Port as defined by the NAT-PMP draft */
-#define NATPMP_PORT (5351)
-
-#include <time.h>
-#if !defined(_MSC_VER)
-#include <sys/time.h>
-#endif
-#ifdef WIN32
-#include <winsock2.h>
-#if !defined(_MSC_VER)
-#include <stdint.h>
-#else
-typedef unsigned long uint32_t;
-typedef unsigned short uint16_t;
-#endif
-#define in_addr_t uint32_t
-#include "declspec.h"
-#else
-#define LIBSPEC
-#include <netinet/in.h>
-#endif
-
-typedef struct {
-       int s;  /* socket */
-       in_addr_t gateway;      /* default gateway (IPv4) */
-       int has_pending_request;
-       unsigned char pending_request[12];
-       int pending_request_len;
-       int try_number;
-       struct timeval retry_time;
-} natpmp_t;
-
-typedef struct {
-       uint16_t type;  /* NATPMP_RESPTYPE_* */
-       uint16_t resultcode;    /* NAT-PMP response code */
-       uint32_t epoch; /* Seconds since start of epoch */
-       union {
-               struct {
-                       //in_addr_t addr;
-                       struct in_addr addr;
-               } publicaddress;
-               struct {
-                       uint16_t privateport;
-                       uint16_t mappedpublicport;
-                       uint32_t lifetime;
-               } newportmapping;
-       } pnu;
-} natpmpresp_t;
-
-/* possible values for type field of natpmpresp_t */
-#define NATPMP_RESPTYPE_PUBLICADDRESS (0)
-#define NATPMP_RESPTYPE_UDPPORTMAPPING (1)
-#define NATPMP_RESPTYPE_TCPPORTMAPPING (2)
-
-/* Values to pass to sendnewportmappingrequest() */
-#define NATPMP_PROTOCOL_UDP (1)
-#define NATPMP_PROTOCOL_TCP (2)
-
-/* return values */
-/* NATPMP_ERR_INVALIDARGS : invalid arguments passed to the function */
-#define NATPMP_ERR_INVALIDARGS (-1)
-/* NATPMP_ERR_SOCKETERROR : socket() failed. check errno for details */
-#define NATPMP_ERR_SOCKETERROR (-2)
-/* NATPMP_ERR_CANNOTGETGATEWAY : can't get default gateway IP */
-#define NATPMP_ERR_CANNOTGETGATEWAY (-3)
-/* NATPMP_ERR_CLOSEERR : close() failed. check errno for details */
-#define NATPMP_ERR_CLOSEERR (-4)
-/* NATPMP_ERR_RECVFROM : recvfrom() failed. check errno for details */
-#define NATPMP_ERR_RECVFROM (-5)
-/* NATPMP_ERR_NOPENDINGREQ : readnatpmpresponseorretry() called while
- * no NAT-PMP request was pending */
-#define NATPMP_ERR_NOPENDINGREQ (-6)
-/* NATPMP_ERR_NOGATEWAYSUPPORT : the gateway does not support NAT-PMP */
-#define NATPMP_ERR_NOGATEWAYSUPPORT (-7)
-/* NATPMP_ERR_CONNECTERR : connect() failed. check errno for details */
-#define NATPMP_ERR_CONNECTERR (-8)
-/* NATPMP_ERR_WRONGPACKETSOURCE : packet not received from the network gateway */
-#define NATPMP_ERR_WRONGPACKETSOURCE (-9)
-/* NATPMP_ERR_SENDERR : send() failed. check errno for details */
-#define NATPMP_ERR_SENDERR (-10)
-/* NATPMP_ERR_FCNTLERROR : fcntl() failed. check errno for details */
-#define NATPMP_ERR_FCNTLERROR (-11)
-/* NATPMP_ERR_GETTIMEOFDAYERR : gettimeofday() failed. check errno for details */
-#define NATPMP_ERR_GETTIMEOFDAYERR (-12)
-
-/* */
-#define NATPMP_ERR_UNSUPPORTEDVERSION (-14)
-#define NATPMP_ERR_UNSUPPORTEDOPCODE (-15)
-
-/* Errors from the server : */
-#define NATPMP_ERR_UNDEFINEDERROR (-49)
-#define NATPMP_ERR_NOTAUTHORIZED (-51)
-#define NATPMP_ERR_NETWORKFAILURE (-52)
-#define NATPMP_ERR_OUTOFRESOURCES (-53)
-
-/* NATPMP_TRYAGAIN : no data available for the moment. try again later */
-#define NATPMP_TRYAGAIN (-100)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* initnatpmp()
- * initialize a natpmp_t object
- * With forcegw=1 the gateway is not detected automaticaly.
- * Return values :
- * 0 = OK
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_SOCKETERROR
- * NATPMP_ERR_FCNTLERROR
- * NATPMP_ERR_CANNOTGETGATEWAY
- * NATPMP_ERR_CONNECTERR */
-LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw);
-
-/* closenatpmp()
- * close resources associated with a natpmp_t object
- * Return values :
- * 0 = OK
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_CLOSEERR */
-LIBSPEC int closenatpmp(natpmp_t * p);
-
-/* sendpublicaddressrequest()
- * send a public address NAT-PMP request to the network gateway
- * Return values :
- * 2 = OK (size of the request)
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_SENDERR */
-LIBSPEC int sendpublicaddressrequest(natpmp_t * p);
-
-/* sendnewportmappingrequest()
- * send a new port mapping NAT-PMP request to the network gateway
- * Arguments :
- * protocol is either NATPMP_PROTOCOL_TCP or NATPMP_PROTOCOL_UDP,
- * lifetime is in seconds.
- * To remove a port mapping, set lifetime to zero.
- * To remove all port mappings to the host, set lifetime and both ports
- * to zero.
- * Return values :
- * 12 = OK (size of the request)
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_SENDERR */
-LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
-                              uint16_t privateport, uint16_t publicport,
-                                                         uint32_t lifetime);
-
-/* getnatpmprequesttimeout()
- * fills the timeval structure with the timeout duration of the
- * currently pending NAT-PMP request.
- * Return values :
- * 0 = OK
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_GETTIMEOFDAYERR
- * NATPMP_ERR_NOPENDINGREQ */
-LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout);
-
-/* readnatpmpresponseorretry()
- * fills the natpmpresp_t structure if possible
- * Return values :
- * 0 = OK
- * NATPMP_TRYAGAIN
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_NOPENDINGREQ
- * NATPMP_ERR_NOGATEWAYSUPPORT
- * NATPMP_ERR_RECVFROM
- * NATPMP_ERR_WRONGPACKETSOURCE
- * NATPMP_ERR_UNSUPPORTEDVERSION
- * NATPMP_ERR_UNSUPPORTEDOPCODE
- * NATPMP_ERR_NOTAUTHORIZED
- * NATPMP_ERR_NETWORKFAILURE
- * NATPMP_ERR_OUTOFRESOURCES
- * NATPMP_ERR_UNSUPPORTEDOPCODE
- * NATPMP_ERR_UNDEFINEDERROR */
-LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response);
-
-#ifdef ENABLE_STRNATPMPERR
-LIBSPEC const char * strnatpmperr(int t);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/third-party/libnatpmp/wingettimeofday.c b/third-party/libnatpmp/wingettimeofday.c
deleted file mode 100644 (file)
index d71582b..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* $Id: wingettimeofday.c,v 1.4 2011/07/15 08:30:11 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2011, Thomas BERNARD 
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifdef WIN32
-#if defined(_MSC_VER)
-struct timeval {
-       long    tv_sec;
-       long    tv_usec;
-};
-#else
-#include <sys/time.h>
-#endif
-
-typedef struct _FILETIME {
-    unsigned long dwLowDateTime;
-    unsigned long dwHighDateTime;
-} FILETIME;
-
-void __stdcall GetSystemTimeAsFileTime(FILETIME*);
-  
-int gettimeofday(struct timeval* p, void* tz /* IGNORED */) {
-  union {
-   long long ns100; /*time since 1 Jan 1601 in 100ns units */
-   FILETIME ft;
-  } _now;
-
-       if(!p)
-               return -1;
-  GetSystemTimeAsFileTime( &(_now.ft) );
-  p->tv_usec =(long)((_now.ns100 / 10LL) % 1000000LL );
-  p->tv_sec = (long)((_now.ns100-(116444736000000000LL))/10000000LL);
-  return 0;
-}
-#endif
-
diff --git a/third-party/libnatpmp/wingettimeofday.h b/third-party/libnatpmp/wingettimeofday.h
deleted file mode 100644 (file)
index db76b09..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $Id: wingettimeofday.h,v 1.2 2011/07/15 08:30:11 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2011, Thomas BERNARD 
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef __WINGETTIMEOFDAY_H__
-#define __WINGETTIMEOFDAY_H__
-#ifdef WIN32
-#if defined(_MSC_VER)
-#include <time.h>
-#else
-#include <sys/time.h>
-#endif
-int gettimeofday(struct timeval* p, void* tz /* IGNORED */);
-#endif
-#endif
diff --git a/third-party/libutp/LICENSE b/third-party/libutp/LICENSE
deleted file mode 100644 (file)
index 73acb81..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2010 BitTorrent, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/third-party/libutp/Makefile.am b/third-party/libutp/Makefile.am
deleted file mode 100644 (file)
index 847f596..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-AM_CPPFLAGS = -fno-exceptions -fno-rtti -ansi -DPOSIX
-
-noinst_LIBRARIES = libutp.a
-libutp_a_SOURCES = utp.cpp utp_utils.cpp
-noinst_HEADERS = StdAfx.h  templates.h  utp_config_example.h  utp.h  utp_config.h utp_utils.h  utypes.h
-EXTRA_DIST = LICENSE README.md
diff --git a/third-party/libutp/README.md b/third-party/libutp/README.md
deleted file mode 100644 (file)
index 83270e6..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-# libutp - The uTorrent Transport Protocol library.
-Copyright (c) 2010 BitTorrent, Inc.
-
-uTP is a TCP-like implementation of [LEDBAT][ledbat] documented as a BitTorrent
-extension in [BEP-29][bep29]. uTP provides provides reliable, ordered delivery
-while maintaining minimum extra delay. It is implemented on top of UDP to be
-cross-platform and functional today. As a result, uTP is the primary transport
-for uTorrent peer-to-peer connections.
-
-uTP is written in C++, but the external interface is strictly C (ANSI C89).
-
-## The Interface
-
-The uTP socket interface is a bit different from the Berkeley socket API to
-avoid the need for our own select() implementation, and to make it easier to
-write event-based code with minimal buffering.
-
-When you create a uTP socket, you register a set of callbacks. Most notably, the
-on_read callback is a reactive callback which occurs when bytes arrive off the
-network. The write side of the socket is proactive, and you call UTP_Write to
-indicate the number of bytes you wish to write. As packets are created, the
-on_write callback is called for each packet, so you can fill the buffers with
-data.
-
-The libutp interface is not thread-safe. It was designed for use in a
-single-threaded asyncronous context, although with proper synchronization
-it may be used from a multi-threaded environment as well.
-
-See utp.h for more details and other API documentation.
-
-## Examples
-
-See the utp_test and utp_file directories for examples.
-
-## Building
-
-uTP has been known to build on Windows with MSVC and on linux and OS X with gcc.
-On Windows, use the MSVC project files (utp.sln, and friends). On other platforms,
-building the shared library is as simple as:
-
-    make
-
-To build one of the examples, which will statically link in everything it needs
-from libutp:
-
-    cd utp_test && make
-
-## Packaging and API
-
-The libutp API is considered unstable, and probably always will be. We encourage
-you to test with the version of libutp you have, and be mindful when upgrading.
-For this reason, it is probably also a good idea to bundle libutp with your
-application.
-
-## License
-
-libutp is released under the [MIT][lic] license.
-
-## Related Work
-
-Research and analysis of congestion control mechanisms can be found [here.][survey]
-
-[ledbat]: http://datatracker.ietf.org/wg/ledbat/charter/
-[bep29]: http://www.bittorrent.org/beps/bep_0029.html
-[lic]: http://www.opensource.org/licenses/mit-license.php
-[survey]: http://datatracker.ietf.org/doc/draft-ietf-ledbat-survey/
diff --git a/third-party/libutp/StdAfx.h b/third-party/libutp/StdAfx.h
deleted file mode 100644 (file)
index 4000395..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#if !defined(AFX_STDAFX_H__C1470942_E9DA_4913_BEF1_9BA7584E595B__INCLUDED_)\r
-#define AFX_STDAFX_H__C1470942_E9DA_4913_BEF1_9BA7584E595B__INCLUDED_\r
-\r
-#if _MSC_VER > 1000\r
-#pragma once\r
-#endif // _MSC_VER > 1000\r
-\r
-// I don't have anything to put here, but some projects use precompiled headers,\r
-// so I include StdAfx.h anyway, so they don't have to edit the files to compile normally.\r
-\r
-#endif // !defined(AFX_STDAFX_H__C1470942_E9DA_4913_BEF1_9BA7584E595B__INCLUDED_)\r
diff --git a/third-party/libutp/templates.h b/third-party/libutp/templates.h
deleted file mode 100644 (file)
index 9684b52..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-#ifndef __TEMPLATES_H__\r
-#define __TEMPLATES_H__\r
-\r
-#include "utypes.h"\r
-#include <assert.h>\r
-\r
-#if defined(POSIX)\r
-/* Allow over-writing FORCEINLINE from makefile because gcc 3.4.4 for buffalo\r
-   doesn't seem to support __attribute__((always_inline)) in -O0 build\r
-   (strangely, it works in -Os build) */\r
-#ifndef FORCEINLINE\r
-// The always_inline attribute asks gcc to inline the function even if no optimization is being requested.\r
-// This macro should be used exclusive-or with the inline directive (use one or the other but not both)\r
-// since Microsoft uses __forceinline to also mean inline,\r
-// and this code is following a Microsoft compatibility model.\r
-// Just setting the attribute without also specifying the inline directive apparently won't inline the function,\r
-// as evidenced by multiply-defined symbols found at link time.\r
-#define FORCEINLINE inline __attribute__((always_inline))\r
-#endif\r
-#endif\r
-\r
-#ifdef __GNUC__\r
-// Used for gcc tool chains accepting but not supporting pragma pack\r
-// See http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html\r
-#define PACKED_ATTRIBUTE __attribute__((__packed__))\r
-#else\r
-#define PACKED_ATTRIBUTE\r
-#endif\r
-\r
-#ifdef __GNUC__\r
-#define ALIGNED_ATTRIBUTE(x)  __attribute__((aligned (x)))\r
-#else\r
-#define ALIGNED_ATTRIBUTE(x)\r
-#endif\r
-\r
-// Utility templates\r
-#undef min\r
-#undef max\r
-\r
-template <typename T> static inline T min(T a, T b) { if (a < b) return a; return b; }\r
-template <typename T> static inline T max(T a, T b) { if (a > b) return a; return b; }\r
-\r
-template <typename T> static inline T min(T a, T b, T c) { return min(min(a,b),c); }\r
-template <typename T> static inline T max(T a, T b, T c) { return max(max(a,b),c); }\r
-template <typename T> static inline T clamp(T v, T mi, T ma)\r
-{\r
-       if (v > ma) v = ma;\r
-       if (v < mi) v = mi;\r
-       return v;\r
-}\r
-\r
-#if (defined(__SVR4) && defined(__sun))\r
-#pragma pack(1)\r
-#else\r
-#pragma pack(push,1)\r
-#endif\r
-\r
-namespace aux\r
-{\r
-       FORCEINLINE uint16 host_to_network(uint16 i) { return htons(i); }\r
-       FORCEINLINE uint32 host_to_network(uint32 i) { return htonl(i); }\r
-       FORCEINLINE int32 host_to_network(int32 i) { return htonl(i); }\r
-       FORCEINLINE uint16 network_to_host(uint16 i) { return ntohs(i); }\r
-       FORCEINLINE uint32 network_to_host(uint32 i) { return ntohl(i); }\r
-       FORCEINLINE int32 network_to_host(int32 i) { return ntohl(i); }\r
-}\r
-\r
-template <class T>\r
-struct PACKED_ATTRIBUTE big_endian\r
-{\r
-       T operator=(T i) { m_integer = aux::host_to_network(i); return i; }\r
-       operator T() const { return aux::network_to_host(m_integer); }\r
-private:\r
-       T m_integer;\r
-};\r
-\r
-typedef big_endian<int32> int32_big;\r
-typedef big_endian<uint32> uint32_big;\r
-typedef big_endian<uint16> uint16_big;\r
-\r
-#if (defined(__SVR4) && defined(__sun))\r
-#pragma pack(0)\r
-#else\r
-#pragma pack(pop)\r
-#endif\r
-\r
-template<typename T> static inline void zeromem(T *a, size_t count = 1) { memset(a, 0, count * sizeof(T)); }\r
-\r
-typedef int SortCompareProc(const void *, const void *);\r
-\r
-template<typename T> static FORCEINLINE void QuickSortT(T *base, size_t num, int (*comp)(const T *, const T *)) { qsort(base, num, sizeof(T), (SortCompareProc*)comp); }\r
-\r
-\r
-// WARNING: The template parameter MUST be a POD type!\r
-template <typename T, size_t minsize = 16> class Array {\r
-protected:\r
-       T *mem;\r
-       size_t alloc,count;\r
-\r
-public:\r
-       Array(size_t init) { Init(init); }\r
-       Array() { Init(); }\r
-       ~Array() { Free(); }\r
-\r
-       void inline Init() { mem = NULL; alloc = count = 0; }\r
-       void inline Init(size_t init) { Init(); if (init) Resize(init); }\r
-       size_t inline GetCount() const { return count; }\r
-       size_t inline GetAlloc() const { return alloc; }\r
-       void inline SetCount(size_t c) { count = c; }\r
-\r
-       inline T& operator[](size_t offset) { assert(offset ==0 || offset<alloc); return mem[offset]; }\r
-       inline const T& operator[](size_t offset) const { assert(offset ==0 || offset<alloc); return mem[offset]; }\r
-\r
-       void inline Resize(size_t a) {\r
-               if (a == 0) { free(mem); Init(); }\r
-               else { mem = (T*)realloc(mem, (alloc=a) * sizeof(T)); }\r
-       }\r
-\r
-       void Grow() { Resize(::max<size_t>(minsize, alloc * 2)); }\r
-\r
-       inline size_t Append(const T &t) {\r
-               if (count >= alloc) Grow();\r
-               size_t r=count++;\r
-               mem[r] = t;\r
-               return r;\r
-       }\r
-\r
-       T inline &Append() {\r
-               if (count >= alloc) Grow();\r
-               return mem[count++];\r
-       }\r
-\r
-       void inline Compact() {\r
-               Resize(count);\r
-       }\r
-\r
-       void inline Free() {\r
-               free(mem);\r
-               Init();\r
-       }\r
-\r
-       void inline Clear() {\r
-               count = 0;\r
-       }\r
-\r
-       bool inline MoveUpLast(size_t index) {\r
-               assert(index < count);\r
-               size_t c = --count;\r
-               if (index != c) {\r
-                       mem[index] = mem[c];\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-\r
-       bool inline MoveUpLastExist(const T &v) {\r
-               return MoveUpLast(LookupElementExist(v));\r
-       }\r
-\r
-       size_t inline LookupElement(const T &v) const {\r
-               for(size_t i = 0; i != count; i++)\r
-                       if (mem[i] == v)\r
-                               return i;\r
-               return (size_t) -1;\r
-       }\r
-\r
-       bool inline HasElement(const T &v) const {\r
-               return LookupElement(v) != -1;\r
-       }\r
-\r
-       typedef int SortCompareProc(const T *a, const T *b);\r
-\r
-       void Sort(SortCompareProc* proc, size_t start, size_t end) {\r
-               QuickSortT(&mem[start], end - start, proc);\r
-       }\r
-\r
-       void Sort(SortCompareProc* proc, size_t start) {\r
-               Sort(proc, start, count);\r
-       }\r
-\r
-       void Sort(SortCompareProc* proc) {\r
-               Sort(proc, 0, count);\r
-       }\r
-};\r
-\r
-#endif //__TEMPLATES_H__\r
diff --git a/third-party/libutp/utp.cpp b/third-party/libutp/utp.cpp
deleted file mode 100644 (file)
index 3a4b2b2..0000000
+++ /dev/null
@@ -1,2867 +0,0 @@
-#include <StdAfx.h>\r
-\r
-#include "utp.h"\r
-#include "templates.h"\r
-\r
-#include <stdio.h>\r
-#include <assert.h>\r
-#include <string.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <errno.h>\r
-#include <limits.h> // for UINT_MAX\r
-\r
-#ifdef WIN32\r
-#include "win32_inet_ntop.h"\r
-\r
-// newer versions of MSVC define these in errno.h\r
-#ifndef ECONNRESET\r
-#define ECONNRESET WSAECONNRESET\r
-#define EMSGSIZE WSAEMSGSIZE\r
-#define ECONNREFUSED WSAECONNREFUSED\r
-#define ETIMEDOUT WSAETIMEDOUT\r
-#endif\r
-#endif\r
-\r
-#ifdef POSIX\r
-typedef sockaddr_storage SOCKADDR_STORAGE;\r
-#endif // POSIX\r
-\r
-// number of bytes to increase max window size by, per RTT. This is\r
-// scaled down linearly proportional to off_target. i.e. if all packets\r
-// in one window have 0 delay, window size will increase by this number.\r
-// Typically it's less. TCP increases one MSS per RTT, which is 1500\r
-#define MAX_CWND_INCREASE_BYTES_PER_RTT 3000\r
-#define CUR_DELAY_SIZE 3\r
-// experiments suggest that a clock skew of 10 ms per 325 seconds\r
-// is not impossible. Reset delay_base every 13 minutes. The clock\r
-// skew is dealt with by observing the delay base in the other\r
-// direction, and adjusting our own upwards if the opposite direction\r
-// delay base keeps going down\r
-#define DELAY_BASE_HISTORY 13\r
-#define MAX_WINDOW_DECAY 100 // ms\r
-\r
-#define REORDER_BUFFER_SIZE 32\r
-#define REORDER_BUFFER_MAX_SIZE 511\r
-#define OUTGOING_BUFFER_MAX_SIZE 511\r
-\r
-#define PACKET_SIZE 350\r
-\r
-// this is the minimum max_window value. It can never drop below this\r
-#define MIN_WINDOW_SIZE 10\r
-\r
-// when window sizes are smaller than one packet_size, this\r
-// will pace the packets to average at the given window size\r
-// if it's not set, it will simply not send anything until\r
-// there's a timeout\r
-#define USE_PACKET_PACING 1\r
-\r
-// if we receive 4 or more duplicate acks, we resend the packet\r
-// that hasn't been acked yet\r
-#define DUPLICATE_ACKS_BEFORE_RESEND 3\r
-\r
-#define DELAYED_ACK_BYTE_THRESHOLD 2400 // bytes\r
-#define DELAYED_ACK_TIME_THRESHOLD 100 // milliseconds\r
-\r
-#define RST_INFO_TIMEOUT 10000\r
-#define RST_INFO_LIMIT 1000\r
-// 29 seconds determined from measuring many home NAT devices\r
-#define KEEPALIVE_INTERVAL 29000\r
-\r
-\r
-#define SEQ_NR_MASK 0xFFFF\r
-#define ACK_NR_MASK 0xFFFF\r
-\r
-#define DIV_ROUND_UP(num, denom) ((num + denom - 1) / denom)\r
-\r
-#include "utp_utils.h"\r
-#include "utp_config.h"\r
-\r
-#define LOG_UTP if (g_log_utp) utp_log\r
-#define LOG_UTPV if (g_log_utp_verbose) utp_log\r
-\r
-uint32 g_current_ms;\r
-\r
-// The totals are derived from the following data:\r
-//  45: IPv6 address including embedded IPv4 address\r
-//  11: Scope Id\r
-//   2: Brackets around IPv6 address when port is present\r
-//   6: Port (including colon)\r
-//   1: Terminating null byte\r
-char addrbuf[65];\r
-char addrbuf2[65];\r
-#define addrfmt(x, s) x.fmt(s, sizeof(s))\r
-\r
-#if (defined(__SVR4) && defined(__sun))\r
-#pragma pack(1)\r
-#else\r
-#pragma pack(push,1)\r
-#endif\r
-\r
-struct PACKED_ATTRIBUTE PackedSockAddr {\r
-\r
-       // The values are always stored here in network byte order\r
-       union {\r
-               byte _in6[16];          // IPv6\r
-               uint16 _in6w[8];        // IPv6, word based (for convenience)\r
-               uint32 _in6d[4];        // Dword access\r
-               in6_addr _in6addr;      // For convenience\r
-       } _in;\r
-\r
-       // Host byte order\r
-       uint16 _port;\r
-\r
-#define _sin4 _in._in6d[3]     // IPv4 is stored where it goes if mapped\r
-\r
-#define _sin6 _in._in6\r
-#define _sin6w _in._in6w\r
-#define _sin6d _in._in6d\r
-\r
-       byte get_family() const\r
-       {\r
-               return (IN6_IS_ADDR_V4MAPPED(&_in._in6addr) != 0) ? AF_INET : AF_INET6;\r
-       }\r
-\r
-       bool operator==(const PackedSockAddr& rhs) const\r
-       {\r
-               if (&rhs == this)\r
-                       return true;\r
-               if (_port != rhs._port)\r
-                       return false;\r
-               return memcmp(_sin6, rhs._sin6, sizeof(_sin6)) == 0;\r
-       }\r
-       bool operator!=(const PackedSockAddr& rhs) const { return !(*this == rhs); }\r
-\r
-       PackedSockAddr(const SOCKADDR_STORAGE* sa, socklen_t len)\r
-       {\r
-               if (sa->ss_family == AF_INET) {\r
-                       assert(len >= sizeof(sockaddr_in));\r
-                       const sockaddr_in *sin = (sockaddr_in*)sa;\r
-                       _sin6w[0] = 0;\r
-                       _sin6w[1] = 0;\r
-                       _sin6w[2] = 0;\r
-                       _sin6w[3] = 0;\r
-                       _sin6w[4] = 0;\r
-                       _sin6w[5] = 0xffff;\r
-                       _sin4 = sin->sin_addr.s_addr;\r
-                       _port = ntohs(sin->sin_port);\r
-               } else {\r
-                       assert(len >= sizeof(sockaddr_in6));\r
-                       const sockaddr_in6 *sin6 = (sockaddr_in6*)sa;\r
-                       _in._in6addr = sin6->sin6_addr;\r
-                       _port = ntohs(sin6->sin6_port);\r
-               }\r
-       }\r
-\r
-       SOCKADDR_STORAGE get_sockaddr_storage(socklen_t *len = NULL) const\r
-       {\r
-               SOCKADDR_STORAGE sa;\r
-               const byte family = get_family();\r
-               if (family == AF_INET) {\r
-                       sockaddr_in *sin = (sockaddr_in*)&sa;\r
-                       if (len) *len = sizeof(sockaddr_in);\r
-                       memset(sin, 0, sizeof(sockaddr_in));\r
-                       sin->sin_family = family;\r
-                       sin->sin_port = htons(_port);\r
-                       sin->sin_addr.s_addr = _sin4;\r
-               } else {\r
-                       sockaddr_in6 *sin6 = (sockaddr_in6*)&sa;\r
-                       memset(sin6, 0, sizeof(sockaddr_in6));\r
-                       if (len) *len = sizeof(sockaddr_in6);\r
-                       sin6->sin6_family = family;\r
-                       sin6->sin6_addr = _in._in6addr;\r
-                       sin6->sin6_port = htons(_port);\r
-               }\r
-               return sa;\r
-       }\r
-\r
-       cstr fmt(str s, size_t len) const\r
-       {\r
-               memset(s, 0, len);\r
-               const byte family = get_family();\r
-               str i;\r
-               if (family == AF_INET) {\r
-                       inet_ntop(family, (uint32*)&_sin4, s, len);\r
-                       i = s;\r
-                       while (*++i) {}\r
-               } else {\r
-                       i = s;\r
-                       *i++ = '[';\r
-                       inet_ntop(family, (in6_addr*)&_in._in6addr, i, len-1);\r
-                       while (*++i) {}\r
-                       *i++ = ']';\r
-               }\r
-               snprintf(i, len - (i-s), ":%u", _port);\r
-               return s;\r
-       }\r
-} ALIGNED_ATTRIBUTE(4);\r
-\r
-struct PACKED_ATTRIBUTE RST_Info {\r
-       PackedSockAddr addr;\r
-       uint32 connid;\r
-       uint32 timestamp;\r
-       uint16 ack_nr;\r
-};\r
-\r
-// these packet sizes are including the uTP header wich\r
-// is either 20 or 23 bytes depending on version\r
-#define PACKET_SIZE_EMPTY_BUCKET 0\r
-#define PACKET_SIZE_EMPTY 23\r
-#define PACKET_SIZE_SMALL_BUCKET 1\r
-#define PACKET_SIZE_SMALL 373\r
-#define PACKET_SIZE_MID_BUCKET 2\r
-#define PACKET_SIZE_MID 723\r
-#define PACKET_SIZE_BIG_BUCKET 3\r
-#define PACKET_SIZE_BIG 1400\r
-#define PACKET_SIZE_HUGE_BUCKET 4\r
-\r
-struct PACKED_ATTRIBUTE PacketFormat {\r
-       // connection ID\r
-       uint32_big connid;\r
-       uint32_big tv_sec;\r
-       uint32_big tv_usec;\r
-       uint32_big reply_micro;\r
-       // receive window size in PACKET_SIZE chunks\r
-       byte windowsize;\r
-       // Type of the first extension header\r
-       byte ext;\r
-       // Flags\r
-       byte flags;\r
-       // Sequence number\r
-       uint16_big seq_nr;\r
-       // Acknowledgment number\r
-       uint16_big ack_nr;\r
-};\r
-\r
-struct PACKED_ATTRIBUTE PacketFormatAck {\r
-       PacketFormat pf;\r
-       byte ext_next;\r
-       byte ext_len;\r
-       byte acks[4];\r
-};\r
-\r
-struct PACKED_ATTRIBUTE PacketFormatExtensions {\r
-       PacketFormat pf;\r
-       byte ext_next;\r
-       byte ext_len;\r
-       byte extensions[8];\r
-};\r
-\r
-struct PACKED_ATTRIBUTE PacketFormatV1 {\r
-       // packet_type (4 high bits)\r
-       // protocol version (4 low bits)\r
-       byte ver_type;\r
-       byte version() const { return ver_type & 0xf; }\r
-       byte type() const { return ver_type >> 4; }\r
-       void set_version(byte v) { ver_type = (ver_type & 0xf0) | (v & 0xf); }\r
-       void set_type(byte t) { ver_type = (ver_type & 0xf) | (t << 4); }\r
-\r
-       // Type of the first extension header\r
-       byte ext;\r
-       // connection ID\r
-       uint16_big connid;\r
-       uint32_big tv_usec;\r
-       uint32_big reply_micro;\r
-       // receive window size in bytes\r
-       uint32_big windowsize;\r
-       // Sequence number\r
-       uint16_big seq_nr;\r
-       // Acknowledgment number\r
-       uint16_big ack_nr;\r
-};\r
-\r
-struct PACKED_ATTRIBUTE PacketFormatAckV1 {\r
-       PacketFormatV1 pf;\r
-       byte ext_next;\r
-       byte ext_len;\r
-       byte acks[4];\r
-};\r
-\r
-struct PACKED_ATTRIBUTE PacketFormatExtensionsV1 {\r
-       PacketFormatV1 pf;\r
-       byte ext_next;\r
-       byte ext_len;\r
-       byte extensions[8];\r
-};\r
-\r
-#if (defined(__SVR4) && defined(__sun))\r
-#pragma pack(0)\r
-#else\r
-#pragma pack(pop)\r
-#endif\r
-\r
-enum {\r
-       ST_DATA = 0,            // Data packet.\r
-       ST_FIN = 1,                     // Finalize the connection. This is the last packet.\r
-       ST_STATE = 2,           // State packet. Used to transmit an ACK with no data.\r
-       ST_RESET = 3,           // Terminate connection forcefully.\r
-       ST_SYN = 4,                     // Connect SYN\r
-       ST_NUM_STATES,          // used for bounds checking\r
-};\r
-\r
-static const cstr flagnames[] = {\r
-       "ST_DATA","ST_FIN","ST_STATE","ST_RESET","ST_SYN"\r
-};\r
-\r
-enum CONN_STATE {\r
-       CS_IDLE = 0,\r
-       CS_SYN_SENT = 1,\r
-       CS_CONNECTED = 2,\r
-       CS_CONNECTED_FULL = 3,\r
-       CS_GOT_FIN = 4,\r
-       CS_DESTROY_DELAY = 5,\r
-       CS_FIN_SENT = 6,\r
-       CS_RESET = 7,\r
-       CS_DESTROY = 8,\r
-};\r
-\r
-static const cstr statenames[] = {\r
-       "IDLE","SYN_SENT","CONNECTED","CONNECTED_FULL","GOT_FIN","DESTROY_DELAY","FIN_SENT","RESET","DESTROY"\r
-};\r
-\r
-struct OutgoingPacket {\r
-       size_t length;\r
-       size_t payload;\r
-       uint64 time_sent; // microseconds\r
-       uint transmissions:31;\r
-       bool need_resend:1;\r
-       byte data[1];\r
-};\r
-\r
-void no_read(void *socket, const byte *bytes, size_t count) {}\r
-void no_write(void *socket, byte *bytes, size_t count) {}\r
-size_t no_rb_size(void *socket) { return 0; }\r
-void no_state(void *socket, int state) {}\r
-void no_error(void *socket, int errcode) {}\r
-void no_overhead(void *socket, bool send, size_t count, int type) {}\r
-\r
-UTPFunctionTable zero_funcs = {\r
-       &no_read,\r
-       &no_write,\r
-       &no_rb_size,\r
-       &no_state,\r
-       &no_error,\r
-       &no_overhead,\r
-};\r
-\r
-struct SizableCircularBuffer {\r
-       // This is the mask. Since it's always a power of 2, adding 1 to this value will return the size.\r
-       size_t mask;\r
-       // This is the elements that the circular buffer points to\r
-       void **elements;\r
-\r
-       void *get(size_t i) { assert(elements); return elements ? elements[i & mask] : NULL; }\r
-       void put(size_t i, void *data) { assert(elements); elements[i&mask] = data; }\r
-\r
-       void grow(size_t item, size_t index);\r
-       void ensure_size(size_t item, size_t index) { if (index > mask) grow(item, index); }\r
-       size_t size() { return mask + 1; }\r
-};\r
-\r
-static struct UTPGlobalStats _global_stats;\r
-\r
-// Item contains the element we want to make space for\r
-// index is the index in the list.\r
-void SizableCircularBuffer::grow(size_t item, size_t index)\r
-{\r
-       // Figure out the new size.\r
-       size_t size = mask + 1;\r
-       do size *= 2; while (index >= size);\r
-\r
-       // Allocate the new buffer\r
-       void **buf = (void**)calloc(size, sizeof(void*));\r
-\r
-       size--;\r
-\r
-       // Copy elements from the old buffer to the new buffer\r
-       for (size_t i = 0; i <= mask; i++) {\r
-               buf[(item - index + i) & size] = get(item - index + i);\r
-       }\r
-\r
-       // Swap to the newly allocated buffer\r
-       mask = size;\r
-       free(elements);\r
-       elements = buf;\r
-}\r
-\r
-// compare if lhs is less than rhs, taking wrapping\r
-// into account. if lhs is close to UINT_MAX and rhs\r
-// is close to 0, lhs is assumed to have wrapped and\r
-// considered smaller\r
-bool wrapping_compare_less(uint32 lhs, uint32 rhs)\r
-{\r
-       // distance walking from lhs to rhs, downwards\r
-       const uint32 dist_down = lhs - rhs;\r
-       // distance walking from lhs to rhs, upwards\r
-       const uint32 dist_up = rhs - lhs;\r
-\r
-       // if the distance walking up is shorter, lhs\r
-       // is less than rhs. If the distance walking down\r
-       // is shorter, then rhs is less than lhs\r
-       return dist_up < dist_down;\r
-}\r
-\r
-struct DelayHist {\r
-       uint32 delay_base;\r
-\r
-       // this is the history of delay samples,\r
-       // normalized by using the delay_base. These\r
-       // values are always greater than 0 and measures\r
-       // the queuing delay in microseconds\r
-       uint32 cur_delay_hist[CUR_DELAY_SIZE];\r
-       size_t cur_delay_idx;\r
-\r
-       // this is the history of delay_base. It's\r
-       // a number that doesn't have an absolute meaning\r
-       // only relative. It doesn't make sense to initialize\r
-       // it to anything other than values relative to\r
-       // what's been seen in the real world.\r
-       uint32 delay_base_hist[DELAY_BASE_HISTORY];\r
-       size_t delay_base_idx;\r
-       // the time when we last stepped the delay_base_idx\r
-       uint32 delay_base_time;\r
-\r
-       bool delay_base_initialized;\r
-\r
-       void clear()\r
-       {\r
-               delay_base_initialized = false;\r
-               delay_base = 0;\r
-               cur_delay_idx = 0;\r
-               delay_base_idx = 0;\r
-               delay_base_time = g_current_ms;\r
-               for (size_t i = 0; i < CUR_DELAY_SIZE; i++) {\r
-                       cur_delay_hist[i] = 0;\r
-               }\r
-               for (size_t i = 0; i < DELAY_BASE_HISTORY; i++) {\r
-                       delay_base_hist[i] = 0;\r
-               }\r
-       }\r
-\r
-       void shift(const uint32 offset)\r
-       {\r
-               // the offset should never be "negative"\r
-               // assert(offset < 0x10000000);\r
-\r
-               // increase all of our base delays by this amount\r
-               // this is used to take clock skew into account\r
-               // by observing the other side's changes in its base_delay\r
-               for (size_t i = 0; i < DELAY_BASE_HISTORY; i++) {\r
-                       delay_base_hist[i] += offset;\r
-               }\r
-               delay_base += offset;\r
-       }\r
-\r
-       void add_sample(const uint32 sample)\r
-       {\r
-               // The two clocks (in the two peers) are assumed not to\r
-               // progress at the exact same rate. They are assumed to be\r
-               // drifting, which causes the delay samples to contain\r
-               // a systematic error, either they are under-\r
-               // estimated or over-estimated. This is why we update the\r
-               // delay_base every two minutes, to adjust for this.\r
-\r
-               // This means the values will keep drifting and eventually wrap.\r
-               // We can cross the wrapping boundry in two directions, either\r
-               // going up, crossing the highest value, or going down, crossing 0.\r
-\r
-               // if the delay_base is close to the max value and sample actually\r
-               // wrapped on the other end we would see something like this:\r
-               // delay_base = 0xffffff00, sample = 0x00000400\r
-               // sample - delay_base = 0x500 which is the correct difference\r
-\r
-               // if the delay_base is instead close to 0, and we got an even lower\r
-               // sample (that will eventually update the delay_base), we may see\r
-               // something like this:\r
-               // delay_base = 0x00000400, sample = 0xffffff00\r
-               // sample - delay_base = 0xfffffb00\r
-               // this needs to be interpreted as a negative number and the actual\r
-               // recorded delay should be 0.\r
-\r
-               // It is important that all arithmetic that assume wrapping\r
-               // is done with unsigned intergers. Signed integers are not guaranteed\r
-               // to wrap the way unsigned integers do. At least GCC takes advantage\r
-               // of this relaxed rule and won't necessarily wrap signed ints.\r
-\r
-               // remove the clock offset and propagation delay.\r
-               // delay base is min of the sample and the current\r
-               // delay base. This min-operation is subject to wrapping\r
-               // and care needs to be taken to correctly choose the\r
-               // true minimum.\r
-\r
-               // specifically the problem case is when delay_base is very small\r
-               // and sample is very large (because it wrapped past zero), sample\r
-               // needs to be considered the smaller\r
-\r
-               if (!delay_base_initialized) {\r
-                       // delay_base being 0 suggests that we haven't initialized\r
-                       // it or its history with any real measurements yet. Initialize\r
-                       // everything with this sample.\r
-                       for (size_t i = 0; i < DELAY_BASE_HISTORY; i++) {\r
-                               // if we don't have a value, set it to the current sample\r
-                               delay_base_hist[i] = sample;\r
-                               continue;\r
-                       }\r
-                       delay_base = sample;\r
-                       delay_base_initialized = true;\r
-               }\r
-\r
-               if (wrapping_compare_less(sample, delay_base_hist[delay_base_idx])) {\r
-                       // sample is smaller than the current delay_base_hist entry\r
-                       // update it\r
-                       delay_base_hist[delay_base_idx] = sample;\r
-               }\r
-\r
-               // is sample lower than delay_base? If so, update delay_base\r
-               if (wrapping_compare_less(sample, delay_base)) {\r
-                       // sample is smaller than the current delay_base\r
-                       // update it\r
-                       delay_base = sample;\r
-               }\r
-               \r
-               // this operation may wrap, and is supposed to\r
-               const uint32 delay = sample - delay_base;\r
-               // sanity check. If this is triggered, something fishy is going on\r
-               // it means the measured sample was greater than 32 seconds!\r
-//             assert(delay < 0x2000000);\r
-\r
-               cur_delay_hist[cur_delay_idx] = delay;\r
-               cur_delay_idx = (cur_delay_idx + 1) % CUR_DELAY_SIZE;\r
-\r
-               // once every minute\r
-               if (g_current_ms - delay_base_time > 60 * 1000) {\r
-                       delay_base_time = g_current_ms;\r
-                       delay_base_idx = (delay_base_idx + 1) % DELAY_BASE_HISTORY;\r
-                       // clear up the new delay base history spot by initializing\r
-                       // it to the current sample, then update it \r
-                       delay_base_hist[delay_base_idx] = sample;\r
-                       delay_base = delay_base_hist[0];\r
-                       // Assign the lowest delay in the last 2 minutes to delay_base\r
-                       for (size_t i = 0; i < DELAY_BASE_HISTORY; i++) {\r
-                               if (wrapping_compare_less(delay_base_hist[i], delay_base))\r
-                                       delay_base = delay_base_hist[i];\r
-                       }\r
-               }\r
-       }\r
-\r
-       uint32 get_value()\r
-       {\r
-               uint32 value = UINT_MAX;\r
-               for (size_t i = 0; i < CUR_DELAY_SIZE; i++) {\r
-                       value = min<uint32>(cur_delay_hist[i], value);\r
-               }\r
-               // value could be UINT_MAX if we have no samples yet...\r
-               return value;\r
-       }\r
-};\r
-\r
-struct UTPSocket {\r
-       PackedSockAddr addr;\r
-\r
-       size_t idx;\r
-\r
-       uint16 reorder_count;\r
-       byte duplicate_ack;\r
-\r
-       // the number of bytes we've received but not acked yet\r
-       size_t bytes_since_ack;\r
-\r
-       // the number of packets in the send queue. Packets that haven't\r
-       // yet been sent count as well as packets marked as needing resend\r
-       // the oldest un-acked packet in the send queue is seq_nr - cur_window_packets\r
-       uint16 cur_window_packets;\r
-\r
-       // how much of the window is used, number of bytes in-flight\r
-       // packets that have not yet been sent do not count, packets\r
-       // that are marked as needing to be re-sent (due to a timeout)\r
-       // don't count either\r
-       size_t cur_window;\r
-       // maximum window size, in bytes\r
-       size_t max_window;\r
-       // SO_SNDBUF setting, in bytes\r
-       size_t opt_sndbuf;\r
-       // SO_RCVBUF setting, in bytes\r
-       size_t opt_rcvbuf;\r
-\r
-       // Is a FIN packet in the reassembly buffer?\r
-       bool got_fin:1;\r
-       // Timeout procedure\r
-       bool fast_timeout:1;\r
-\r
-       // max receive window for other end, in bytes\r
-       size_t max_window_user;\r
-       // 0 = original uTP header, 1 = second revision\r
-       byte version;\r
-       CONN_STATE state;\r
-       // TickCount when we last decayed window (wraps)\r
-       int32 last_rwin_decay;\r
-\r
-       // the sequence number of the FIN packet. This field is only set\r
-       // when we have received a FIN, and the flag field has the FIN flag set.\r
-       // it is used to know when it is safe to destroy the socket, we must have\r
-       // received all packets up to this sequence number first.\r
-       uint16 eof_pkt;\r
-\r
-       // All sequence numbers up to including this have been properly received\r
-       // by us\r
-       uint16 ack_nr;\r
-       // This is the sequence number for the next packet to be sent.\r
-       uint16 seq_nr;\r
-\r
-       uint16 timeout_seq_nr;\r
-\r
-       // This is the sequence number of the next packet we're allowed to\r
-       // do a fast resend with. This makes sure we only do a fast-resend\r
-       // once per packet. We can resend the packet with this sequence number\r
-       // or any later packet (with a higher sequence number).\r
-       uint16 fast_resend_seq_nr;\r
-\r
-       uint32 reply_micro;\r
-\r
-       // the time when we need to send another ack. If there's\r
-       // nothing to ack, this is a very large number\r
-       uint32 ack_time;\r
-\r
-       uint32 last_got_packet;\r
-       uint32 last_sent_packet;\r
-       uint32 last_measured_delay;\r
-       uint32 last_maxed_out_window;\r
-\r
-       // the last time we added send quota to the connection\r
-       // when adding send quota, this is subtracted from the\r
-       // current time multiplied by max_window / rtt\r
-       // which is the current allowed send rate.\r
-       int32 last_send_quota;\r
-\r
-       // the number of bytes we are allowed to send on\r
-       // this connection. If this is more than one packet\r
-       // size when we run out of data to send, it is clamped\r
-       // to the packet size\r
-       // this value is multiplied by 100 in order to get\r
-       // higher accuracy when dealing with low rates\r
-       int32 send_quota;\r
-\r
-       SendToProc *send_to_proc;\r
-       void *send_to_userdata;\r
-       UTPFunctionTable func;\r
-       void *userdata;\r
-\r
-       // Round trip time\r
-       uint rtt;\r
-       // Round trip time variance\r
-       uint rtt_var;\r
-       // Round trip timeout\r
-       uint rto;\r
-       DelayHist rtt_hist;\r
-       uint retransmit_timeout;\r
-       // The RTO timer will timeout here.\r
-       uint rto_timeout;\r
-       // When the window size is set to zero, start this timer. It will send a new packet every 30secs.\r
-       uint32 zerowindow_time;\r
-\r
-       uint32 conn_seed;\r
-       // Connection ID for packets I receive\r
-       uint32 conn_id_recv;\r
-       // Connection ID for packets I send\r
-       uint32 conn_id_send;\r
-       // Last rcv window we advertised, in bytes\r
-       size_t last_rcv_win;\r
-\r
-       DelayHist our_hist;\r
-       DelayHist their_hist;\r
-\r
-       // extension bytes from SYN packet\r
-       byte extensions[8];\r
-\r
-       SizableCircularBuffer inbuf, outbuf;\r
-\r
-#ifdef _DEBUG\r
-       // Public stats, returned by UTP_GetStats().  See utp.h\r
-       UTPStats _stats;\r
-#endif // _DEBUG\r
-\r
-       // Calculates the current receive window\r
-       size_t get_rcv_window() const\r
-       {\r
-               // If we don't have a connection (such as during connection\r
-               // establishment, always act as if we have an empty buffer).\r
-               if (!userdata) return opt_rcvbuf;\r
-\r
-               // Trim window down according to what's already in buffer.\r
-               const size_t numbuf = func.get_rb_size(userdata);\r
-               assert((int)numbuf >= 0);\r
-               return opt_rcvbuf > numbuf ? opt_rcvbuf - numbuf : 0;\r
-       }\r
-\r
-       // Test if we're ready to decay max_window\r
-       // XXX this breaks when spaced by > INT_MAX/2, which is 49\r
-       // days; the failure mode in that case is we do an extra decay\r
-       // or fail to do one when we really shouldn't.\r
-       bool can_decay_win(int32 msec) const\r
-       {\r
-               return msec - last_rwin_decay >= MAX_WINDOW_DECAY;\r
-       }\r
-\r
-       // If we can, decay max window, returns true if we actually did so\r
-       void maybe_decay_win()\r
-       {\r
-               if (can_decay_win(g_current_ms)) {\r
-                       // TCP uses 0.5\r
-                       max_window = (size_t)(max_window * .5);\r
-                       last_rwin_decay = g_current_ms;\r
-                       if (max_window < MIN_WINDOW_SIZE)\r
-                               max_window = MIN_WINDOW_SIZE;\r
-               }\r
-       }\r
-\r
-       size_t get_header_size() const\r
-       {\r
-               return (version ? sizeof(PacketFormatV1) : sizeof(PacketFormat));\r
-       }\r
-\r
-       size_t get_header_extensions_size() const\r
-       {\r
-               return (version ? sizeof(PacketFormatExtensionsV1) : sizeof(PacketFormatExtensions));\r
-       }\r
-\r
-       void sent_ack()\r
-       {\r
-               ack_time = g_current_ms + 0x70000000;\r
-               bytes_since_ack = 0;\r
-       }\r
-\r
-       size_t get_udp_mtu() const\r
-       {\r
-               socklen_t len;\r
-               SOCKADDR_STORAGE sa = addr.get_sockaddr_storage(&len);\r
-               return UTP_GetUDPMTU((const struct sockaddr *)&sa, len);\r
-       }\r
-\r
-       size_t get_udp_overhead() const\r
-       {\r
-               socklen_t len;\r
-               SOCKADDR_STORAGE sa = addr.get_sockaddr_storage(&len);\r
-               return UTP_GetUDPOverhead((const struct sockaddr *)&sa, len);\r
-       }\r
-\r
-       uint64 get_global_utp_bytes_sent() const\r
-       {\r
-               socklen_t len;\r
-               SOCKADDR_STORAGE sa = addr.get_sockaddr_storage(&len);\r
-               return UTP_GetGlobalUTPBytesSent((const struct sockaddr *)&sa, len);\r
-       }\r
-\r
-       size_t get_overhead() const\r
-       {\r
-               return get_udp_overhead() + get_header_size();\r
-       }\r
-\r
-       void send_data(PacketFormat* b, size_t length, bandwidth_type_t type);\r
-\r
-       void send_ack(bool synack = false);\r
-\r
-       void send_keep_alive();\r
-\r
-       static void send_rst(SendToProc *send_to_proc, void *send_to_userdata,\r
-                                                const PackedSockAddr &addr, uint32 conn_id_send,\r
-                                                uint16 ack_nr, uint16 seq_nr, byte version);\r
-\r
-       void send_packet(OutgoingPacket *pkt);\r
-\r
-       bool is_writable(size_t to_write);\r
-\r
-       bool flush_packets();\r
-\r
-       void write_outgoing_packet(size_t payload, uint flags);\r
-\r
-       void update_send_quota();\r
-\r
-#ifdef _DEBUG\r
-       void check_invariant();\r
-#endif\r
-\r
-       void check_timeouts();\r
-\r
-       int ack_packet(uint16 seq);\r
-\r
-       size_t selective_ack_bytes(uint base, const byte* mask, byte len, int64& min_rtt);\r
-\r
-       void selective_ack(uint base, const byte *mask, byte len);\r
-\r
-       void apply_ledbat_ccontrol(size_t bytes_acked, uint32 actual_delay, int64 min_rtt);\r
-\r
-       size_t get_packet_size();\r
-};\r
-\r
-Array<RST_Info> g_rst_info;\r
-Array<UTPSocket*> g_utp_sockets;\r
-\r
-static void UTP_RegisterSentPacket(size_t length) {\r
-       if (length <= PACKET_SIZE_MID) {\r
-               if (length <= PACKET_SIZE_EMPTY) {\r
-                       _global_stats._nraw_send[PACKET_SIZE_EMPTY_BUCKET]++;\r
-               } else if (length <= PACKET_SIZE_SMALL) {\r
-                       _global_stats._nraw_send[PACKET_SIZE_SMALL_BUCKET]++;\r
-               } else\r
-                       _global_stats._nraw_send[PACKET_SIZE_MID_BUCKET]++;\r
-       } else {\r
-               if (length <= PACKET_SIZE_BIG) {\r
-                       _global_stats._nraw_send[PACKET_SIZE_BIG_BUCKET]++;\r
-               } else\r
-                       _global_stats._nraw_send[PACKET_SIZE_HUGE_BUCKET]++;\r
-       }\r
-}\r
-\r
-void send_to_addr(SendToProc *send_to_proc, void *send_to_userdata, const byte *p, size_t len, const PackedSockAddr &addr)\r
-{\r
-       socklen_t tolen;\r
-       SOCKADDR_STORAGE to = addr.get_sockaddr_storage(&tolen);\r
-       UTP_RegisterSentPacket(len);\r
-       send_to_proc(send_to_userdata, p, len, (const struct sockaddr *)&to, tolen);\r
-}\r
-\r
-void UTPSocket::send_data(PacketFormat* b, size_t length, bandwidth_type_t type)\r
-{\r
-       // time stamp this packet with local time, the stamp goes into\r
-       // the header of every packet at the 8th byte for 8 bytes :\r
-       // two integers, check packet.h for more\r
-       uint64 time = UTP_GetMicroseconds();\r
-\r
-       PacketFormatV1* b1 = (PacketFormatV1*)b;\r
-       if (version == 0) {\r
-               b->tv_sec = (uint32)(time / 1000000);\r
-               b->tv_usec = time % 1000000;\r
-               b->reply_micro = reply_micro;\r
-       } else {\r
-               b1->tv_usec = (uint32)time;\r
-               b1->reply_micro = reply_micro;\r
-       }\r
-\r
-       last_sent_packet = g_current_ms;\r
-\r
-#ifdef _DEBUG\r
-       _stats._nbytes_xmit += length;\r
-       ++_stats._nxmit;\r
-#endif\r
-       if (userdata) {\r
-               size_t n;\r
-               if (type == payload_bandwidth) {\r
-                       // if this packet carries payload, just\r
-                       // count the header as overhead\r
-                       type = header_overhead;\r
-                       n = get_overhead();\r
-               } else {\r
-                       n = length + get_udp_overhead();\r
-               }\r
-               func.on_overhead(userdata, true, n, type);\r
-       }\r
-#if g_log_utp_verbose\r
-       int flags = version == 0 ? b->flags : b1->type();\r
-       uint16 seq_nr = version == 0 ? b->seq_nr : b1->seq_nr;\r
-       uint16 ack_nr = version == 0 ? b->ack_nr : b1->ack_nr;\r
-       LOG_UTPV("0x%08x: send %s len:%u id:%u timestamp:"I64u" reply_micro:%u flags:%s seq_nr:%u ack_nr:%u",\r
-                        this, addrfmt(addr, addrbuf), (uint)length, conn_id_send, time, reply_micro, flagnames[flags],\r
-                        seq_nr, ack_nr);\r
-#endif\r
-       send_to_addr(send_to_proc, send_to_userdata, (const byte*)b, length, addr);\r
-}\r
-\r
-void UTPSocket::send_ack(bool synack)\r
-{\r
-       PacketFormatExtensions pfe;\r
-       zeromem(&pfe);\r
-       PacketFormatExtensionsV1& pfe1 = (PacketFormatExtensionsV1&)pfe;\r
-       PacketFormatAck& pfa = (PacketFormatAck&)pfe1;\r
-       PacketFormatAckV1& pfa1 = (PacketFormatAckV1&)pfe1;\r
-\r
-       size_t len;\r
-       last_rcv_win = get_rcv_window();\r
-       if (version == 0) {\r
-               pfa.pf.connid = conn_id_send;\r
-               pfa.pf.ack_nr = (uint16)ack_nr;\r
-               pfa.pf.seq_nr = (uint16)seq_nr;\r
-               pfa.pf.flags = ST_STATE;\r
-               pfa.pf.ext = 0;\r
-               pfa.pf.windowsize = (byte)DIV_ROUND_UP(last_rcv_win, PACKET_SIZE);\r
-               len = sizeof(PacketFormat);\r
-       } else {\r
-               pfa1.pf.set_version(1);\r
-               pfa1.pf.set_type(ST_STATE);\r
-               pfa1.pf.ext = 0;\r
-               pfa1.pf.connid = conn_id_send;\r
-               pfa1.pf.ack_nr = ack_nr;\r
-               pfa1.pf.seq_nr = seq_nr;\r
-               pfa1.pf.windowsize = (uint32)last_rcv_win;\r
-               len = sizeof(PacketFormatV1);\r
-       }\r
-\r
-       // we never need to send EACK for connections\r
-       // that are shutting down\r
-       if (reorder_count != 0 && state < CS_GOT_FIN) {\r
-               // if reorder count > 0, send an EACK.\r
-               // reorder count should always be 0\r
-               // for synacks, so this should not be\r
-               // as synack\r
-               assert(!synack);\r
-               if (version == 0) {\r
-                       pfa.pf.ext = 1;\r
-                       pfa.ext_next = 0;\r
-                       pfa.ext_len = 4;\r
-               } else {\r
-                       pfa1.pf.ext = 1;\r
-                       pfa1.ext_next = 0;\r
-                       pfa1.ext_len = 4;\r
-               }\r
-               uint m = 0;\r
-\r
-               // reorder count should only be non-zero\r
-               // if the packet ack_nr + 1 has not yet\r
-               // been received\r
-               assert(inbuf.get(ack_nr + 1) == NULL);\r
-               size_t window = min<size_t>(14+16, inbuf.size());\r
-               // Generate bit mask of segments received.\r
-               for (size_t i = 0; i < window; i++) {\r
-                       if (inbuf.get(ack_nr + i + 2) != NULL) {\r
-                               m |= 1 << i;\r
-                               LOG_UTPV("0x%08x: EACK packet [%u]", this, ack_nr + i + 2);\r
-                       }\r
-               }\r
-               if (version == 0) {\r
-                       pfa.acks[0] = (byte)m;\r
-                       pfa.acks[1] = (byte)(m >> 8);\r
-                       pfa.acks[2] = (byte)(m >> 16);\r
-                       pfa.acks[3] = (byte)(m >> 24);\r
-               } else {\r
-                       pfa1.acks[0] = (byte)m;\r
-                       pfa1.acks[1] = (byte)(m >> 8);\r
-                       pfa1.acks[2] = (byte)(m >> 16);\r
-                       pfa1.acks[3] = (byte)(m >> 24);\r
-               }\r
-               len += 4 + 2;\r
-               LOG_UTPV("0x%08x: Sending EACK %u [%u] bits:[%032b]", this, ack_nr, conn_id_send, m);\r
-       } else if (synack) {\r
-               // we only send "extensions" in response to SYN\r
-               // and the reorder count is 0 in that state\r
-\r
-               LOG_UTPV("0x%08x: Sending ACK %u [%u] with extension bits", this, ack_nr, conn_id_send);\r
-               if (version == 0) {\r
-                       pfe.pf.ext = 2;\r
-                       pfe.ext_next = 0;\r
-                       pfe.ext_len = 8;\r
-                       memset(pfe.extensions, 0, 8);\r
-               } else {\r
-                       pfe1.pf.ext = 2;\r
-                       pfe1.ext_next = 0;\r
-                       pfe1.ext_len = 8;\r
-                       memset(pfe1.extensions, 0, 8);\r
-               }\r
-               len += 8 + 2;\r
-       } else {\r
-               LOG_UTPV("0x%08x: Sending ACK %u [%u]", this, ack_nr, conn_id_send);\r
-       }\r
-\r
-       sent_ack();\r
-       send_data((PacketFormat*)&pfe, len, ack_overhead);\r
-}\r
-\r
-void UTPSocket::send_keep_alive()\r
-{\r
-       ack_nr--;\r
-       LOG_UTPV("0x%08x: Sending KeepAlive ACK %u [%u]", this, ack_nr, conn_id_send);\r
-       send_ack();\r
-       ack_nr++;\r
-}\r
-\r
-void UTPSocket::send_rst(SendToProc *send_to_proc, void *send_to_userdata,\r
-                                                const PackedSockAddr &addr, uint32 conn_id_send, uint16 ack_nr, uint16 seq_nr, byte version)\r
-{\r
-       PacketFormat pf;\r
-       zeromem(&pf);\r
-       PacketFormatV1& pf1 = (PacketFormatV1&)pf;\r
-\r
-       size_t len;\r
-       if (version == 0) {\r
-               pf.connid = conn_id_send;\r
-               pf.ack_nr = ack_nr;\r
-               pf.seq_nr = seq_nr;\r
-               pf.flags = ST_RESET;\r
-               pf.ext = 0;\r
-               pf.windowsize = 0;\r
-               len = sizeof(PacketFormat);\r
-       } else {\r
-               pf1.set_version(1);\r
-               pf1.set_type(ST_RESET);\r
-               pf1.ext = 0;\r
-               pf1.connid = conn_id_send;\r
-               pf1.ack_nr = ack_nr;\r
-               pf1.seq_nr = seq_nr;\r
-               pf1.windowsize = 0;\r
-               len = sizeof(PacketFormatV1);\r
-       }\r
-\r
-       LOG_UTPV("%s: Sending RST id:%u seq_nr:%u ack_nr:%u", addrfmt(addr, addrbuf), conn_id_send, seq_nr, ack_nr);\r
-       LOG_UTPV("send %s len:%u id:%u", addrfmt(addr, addrbuf), (uint)len, conn_id_send);\r
-       send_to_addr(send_to_proc, send_to_userdata, (const byte*)&pf1, len, addr);\r
-}\r
-\r
-void UTPSocket::send_packet(OutgoingPacket *pkt)\r
-{\r
-       // only count against the quota the first time we\r
-       // send the packet. Don't enforce quota when closing\r
-       // a socket. Only enforce the quota when we're sending\r
-       // at slow rates (max window < packet size)\r
-       size_t max_send = min(max_window, opt_sndbuf, max_window_user);\r
-\r
-       if (pkt->transmissions == 0 || pkt->need_resend) {\r
-               cur_window += pkt->payload;\r
-       }\r
-\r
-       size_t packet_size = get_packet_size();\r
-       if (pkt->transmissions == 0 && max_send < packet_size) {\r
-               assert(state == CS_FIN_SENT ||\r
-                          (int32)pkt->payload <= send_quota / 100);\r
-               send_quota = send_quota - (int32)(pkt->payload * 100);\r
-       }\r
-\r
-       pkt->need_resend = false;\r
-\r
-       PacketFormatV1* p1 = (PacketFormatV1*)pkt->data;\r
-       PacketFormat* p = (PacketFormat*)pkt->data;\r
-       if (version == 0) {\r
-               p->ack_nr = ack_nr;\r
-       } else {\r
-               p1->ack_nr = ack_nr;\r
-       }\r
-       pkt->time_sent = UTP_GetMicroseconds();\r
-       pkt->transmissions++;\r
-       sent_ack();\r
-       send_data((PacketFormat*)pkt->data, pkt->length,\r
-               (state == CS_SYN_SENT) ? connect_overhead\r
-               : (pkt->transmissions == 1) ? payload_bandwidth\r
-               : retransmit_overhead);\r
-}\r
-\r
-bool UTPSocket::is_writable(size_t to_write)\r
-{\r
-       // return true if it's OK to stuff another packet into the\r
-       // outgoing queue. Since we may be using packet pacing, we\r
-       // might not actually send the packet right away to affect the\r
-       // cur_window. The only thing that happens when we add another\r
-       // packet is that cur_window_packets is increased.\r
-       size_t max_send = min(max_window, opt_sndbuf, max_window_user);\r
-\r
-       size_t packet_size = get_packet_size();\r
-\r
-       if (cur_window + packet_size >= max_window)\r
-               last_maxed_out_window = g_current_ms;\r
-\r
-       // if we don't have enough quota, we can't write regardless\r
-       if (USE_PACKET_PACING) {\r
-               if (send_quota / 100 < (int32)to_write) return false;\r
-       }\r
-\r
-       // subtract one to save space for the FIN packet\r
-       if (cur_window_packets >= OUTGOING_BUFFER_MAX_SIZE - 1) return false;\r
-\r
-       // if sending another packet would not make the window exceed\r
-       // the max_window, we can write\r
-       if (cur_window + packet_size <= max_send) return true;\r
-\r
-       // if the window size is less than a packet, and we have enough\r
-       // quota to send a packet, we can write, even though it would\r
-       // make the window exceed the max size\r
-       // the last condition is needed to not put too many packets\r
-       // in the send buffer. cur_window isn't updated until we flush\r
-       // the send buffer, so we need to take the number of packets\r
-       // into account\r
-       if (USE_PACKET_PACING) {\r
-               if (max_window < to_write &&\r
-                       cur_window < max_window &&\r
-                       cur_window_packets == 0) {\r
-                       return true;\r
-               }\r
-       }\r
-\r
-       return false;\r
-}\r
-\r
-bool UTPSocket::flush_packets()\r
-{\r
-       size_t packet_size = get_packet_size();\r
-\r
-       // send packets that are waiting on the pacer to be sent\r
-       // i has to be an unsigned 16 bit counter to wrap correctly\r
-       // signed types are not guaranteed to wrap the way you expect\r
-       for (uint16 i = seq_nr - cur_window_packets; i != seq_nr; ++i) {\r
-               OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(i);\r
-               if (pkt == 0 || (pkt->transmissions > 0 && pkt->need_resend == false)) continue;\r
-               // have we run out of quota?\r
-               if (!is_writable(pkt->payload)) {\r
-                       return true;\r
-               }\r
-\r
-               // Nagle check\r
-               // don't send the last packet if we have one packet in-flight\r
-               // and the current packet is still smaller than packet_size.\r
-               if (i != ((seq_nr - 1) & ACK_NR_MASK) ||\r
-                       cur_window_packets == 1 ||\r
-                       pkt->payload >= packet_size) {\r
-                       send_packet(pkt);\r
-\r
-                       // No need to send another ack if there is nothing to reorder.\r
-                       if (reorder_count == 0) {\r
-                               sent_ack();\r
-                       }\r
-               }\r
-       }\r
-       return false;\r
-}\r
-\r
-void UTPSocket::write_outgoing_packet(size_t payload, uint flags)\r
-{\r
-       // Setup initial timeout timer\r
-       if (cur_window_packets == 0) {\r
-               retransmit_timeout = rto;\r
-               rto_timeout = g_current_ms + retransmit_timeout;\r
-               assert(cur_window == 0);\r
-       }\r
-\r
-       size_t packet_size = get_packet_size();\r
-       do {\r
-               assert(cur_window_packets < OUTGOING_BUFFER_MAX_SIZE);\r
-               assert(flags == ST_DATA || flags == ST_FIN);\r
-\r
-               size_t added = 0;\r
-\r
-               OutgoingPacket *pkt = NULL;\r
-               \r
-               if (cur_window_packets > 0) {\r
-                       pkt = (OutgoingPacket*)outbuf.get(seq_nr - 1);\r
-               }\r
-\r
-               const size_t header_size = get_header_size();\r
-               bool append = true;\r
-\r
-               // if there's any room left in the last packet in the window\r
-               // and it hasn't been sent yet, fill that frame first\r
-               if (payload && pkt && !pkt->transmissions && pkt->payload < packet_size) {\r
-                       // Use the previous unsent packet\r
-                       added = min(payload + pkt->payload, max<size_t>(packet_size, pkt->payload)) - pkt->payload;\r
-                       pkt = (OutgoingPacket*)realloc(pkt,\r
-                                                                                  (sizeof(OutgoingPacket) - 1) +\r
-                                                                                  header_size +\r
-                                                                                  pkt->payload + added);\r
-                       outbuf.put(seq_nr - 1, pkt);\r
-                       append = false;\r
-                       assert(!pkt->need_resend);\r
-               } else {\r
-                       // Create the packet to send.\r
-                       added = payload;\r
-                       pkt = (OutgoingPacket*)malloc((sizeof(OutgoingPacket) - 1) +\r
-                                                                                 header_size +\r
-                                                                                 added);\r
-                       pkt->payload = 0;\r
-                       pkt->transmissions = 0;\r
-                       pkt->need_resend = false;\r
-               }\r
-\r
-               if (added) {\r
-                       // Fill it with data from the upper layer.\r
-                       func.on_write(userdata, pkt->data + header_size + pkt->payload, added);\r
-               }\r
-               pkt->payload += added;\r
-               pkt->length = header_size + pkt->payload;\r
-\r
-               last_rcv_win = get_rcv_window();\r
-\r
-               PacketFormat* p = (PacketFormat*)pkt->data;\r
-               PacketFormatV1* p1 = (PacketFormatV1*)pkt->data;\r
-               if (version == 0) {\r
-                       p->connid = conn_id_send;\r
-                       p->ext = 0;\r
-                       p->windowsize = (byte)DIV_ROUND_UP(last_rcv_win, PACKET_SIZE);\r
-                       p->ack_nr = ack_nr;\r
-                       p->flags = flags;\r
-               } else {\r
-                       p1->set_version(1);\r
-                       p1->set_type(flags);\r
-                       p1->ext = 0;\r
-                       p1->connid = conn_id_send;\r
-                       p1->windowsize = (uint32)last_rcv_win;\r
-                       p1->ack_nr = ack_nr;\r
-               }\r
-\r
-               if (append) {\r
-                       // Remember the message in the outgoing queue.\r
-                       outbuf.ensure_size(seq_nr, cur_window_packets);\r
-                       outbuf.put(seq_nr, pkt);\r
-                       if (version == 0) p->seq_nr = seq_nr;\r
-                       else p1->seq_nr = seq_nr;\r
-                       seq_nr++;\r
-                       cur_window_packets++;\r
-               }\r
-\r
-               payload -= added;\r
-\r
-       } while (payload);\r
-\r
-       flush_packets();\r
-}\r
-\r
-void UTPSocket::update_send_quota()\r
-{\r
-       int dt = g_current_ms - last_send_quota;\r
-       if (dt == 0) return;\r
-       last_send_quota = g_current_ms;\r
-       size_t add = max_window * dt * 100 / (rtt_hist.delay_base?rtt_hist.delay_base:50);\r
-       if (add > max_window * 100 && add > MAX_CWND_INCREASE_BYTES_PER_RTT * 100) add = max_window;\r
-       send_quota += (int32)add;\r
-//     LOG_UTPV("0x%08x: UTPSocket::update_send_quota dt:%d rtt:%u max_window:%u quota:%d",\r
-//                      this, dt, rtt, (uint)max_window, send_quota / 100);\r
-}\r
-\r
-#ifdef _DEBUG\r
-void UTPSocket::check_invariant()\r
-{\r
-       if (reorder_count > 0) {\r
-               assert(inbuf.get(ack_nr + 1) == NULL);\r
-       }\r
-\r
-       size_t outstanding_bytes = 0;\r
-       for (int i = 0; i < cur_window_packets; ++i) {\r
-               OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(seq_nr - i - 1);\r
-               if (pkt == 0 || pkt->transmissions == 0 || pkt->need_resend) continue;\r
-               outstanding_bytes += pkt->payload;\r
-       }\r
-       assert(outstanding_bytes == cur_window);\r
-}\r
-#endif\r
-\r
-void UTPSocket::check_timeouts()\r
-{\r
-#ifdef _DEBUG\r
-       check_invariant();\r
-#endif\r
-\r
-       // this invariant should always be true\r
-       assert(cur_window_packets == 0 || outbuf.get(seq_nr - cur_window_packets));\r
-\r
-       LOG_UTPV("0x%08x: CheckTimeouts timeout:%d max_window:%u cur_window:%u quota:%d "\r
-                        "state:%s cur_window_packets:%u bytes_since_ack:%u ack_time:%d",\r
-                        this, (int)(rto_timeout - g_current_ms), (uint)max_window, (uint)cur_window,\r
-                        send_quota / 100, statenames[state], cur_window_packets,\r
-                        (uint)bytes_since_ack, (int)(g_current_ms - ack_time));\r
-\r
-       update_send_quota();\r
-       flush_packets();\r
-\r
-\r
-       if (USE_PACKET_PACING) {\r
-               // In case the new send quota made it possible to send another packet\r
-               // Mark the socket as writable. If we don't use pacing, the send\r
-               // quota does not affect if the socket is writeable\r
-               // if we don't use packet pacing, the writable event is triggered\r
-               // whenever the cur_window falls below the max_window, so we don't\r
-               // need this check then\r
-               if (state == CS_CONNECTED_FULL && is_writable(get_packet_size())) {\r
-                       state = CS_CONNECTED;\r
-                       LOG_UTPV("0x%08x: Socket writable. max_window:%u cur_window:%u quota:%d packet_size:%u",\r
-                                        this, (uint)max_window, (uint)cur_window, send_quota / 100, (uint)get_packet_size());\r
-                       func.on_state(userdata, UTP_STATE_WRITABLE);\r
-               }\r
-       }\r
-\r
-       switch (state) {\r
-       case CS_SYN_SENT:\r
-       case CS_CONNECTED_FULL:\r
-       case CS_CONNECTED:\r
-       case CS_FIN_SENT: {\r
-\r
-               // Reset max window...\r
-               if ((int)(g_current_ms - zerowindow_time) >= 0 && max_window_user == 0) {\r
-                       max_window_user = PACKET_SIZE;\r
-               }\r
-\r
-               if ((int)(g_current_ms - rto_timeout) >= 0 &&\r
-                       (!(USE_PACKET_PACING) || cur_window_packets > 0) &&\r
-                       rto_timeout > 0) {\r
-\r
-                       /*\r
-                       OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(seq_nr - cur_window_packets);\r
-                       \r
-                       // If there were a lot of retransmissions, force recomputation of round trip time\r
-                       if (pkt->transmissions >= 4)\r
-                               rtt = 0;\r
-                       */\r
-\r
-                       // Increase RTO\r
-                       const uint new_timeout = retransmit_timeout * 2;\r
-                       if (new_timeout >= 30000 || (state == CS_SYN_SENT && new_timeout > 6000)) {\r
-                               // more than 30 seconds with no reply. kill it.\r
-                               // if we haven't even connected yet, give up sooner. 6 seconds\r
-                               // means 2 tries at the following timeouts: 3, 6 seconds\r
-                               if (state == CS_FIN_SENT)\r
-                                       state = CS_DESTROY;\r
-                               else\r
-                                       state = CS_RESET;\r
-                               func.on_error(userdata, ETIMEDOUT);\r
-                               goto getout;\r
-                       }\r
-\r
-                       retransmit_timeout = new_timeout;\r
-                       rto_timeout = g_current_ms + new_timeout;\r
-\r
-                       // On Timeout\r
-                       duplicate_ack = 0;\r
-\r
-                       // rate = min_rate\r
-                       max_window = get_packet_size();\r
-                       send_quota = max<int32>((int32)max_window * 100, send_quota);\r
-\r
-                       // every packet should be considered lost\r
-                       for (int i = 0; i < cur_window_packets; ++i) {\r
-                               OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(seq_nr - i - 1);\r
-                               if (pkt == 0 || pkt->transmissions == 0 || pkt->need_resend) continue;\r
-                               pkt->need_resend = true;\r
-                               assert(cur_window >= pkt->payload);\r
-                               cur_window -= pkt->payload;\r
-                       }\r
-\r
-                       // used in parse_log.py\r
-                       LOG_UTP("0x%08x: Packet timeout. Resend. seq_nr:%u. timeout:%u max_window:%u",\r
-                                       this, seq_nr - cur_window_packets, retransmit_timeout, (uint)max_window);\r
-\r
-                       fast_timeout = true;\r
-                       timeout_seq_nr = seq_nr;\r
-\r
-                       if (cur_window_packets > 0) {\r
-                               OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(seq_nr - cur_window_packets);\r
-                               assert(pkt);\r
-                               send_quota = max<int32>((int32)pkt->length * 100, send_quota);\r
-\r
-                               // Re-send the packet.\r
-                               send_packet(pkt);\r
-                       }\r
-               }\r
-\r
-               // Mark the socket as writable\r
-               if (state == CS_CONNECTED_FULL && is_writable(get_packet_size())) {\r
-                       state = CS_CONNECTED;\r
-                       LOG_UTPV("0x%08x: Socket writable. max_window:%u cur_window:%u quota:%d packet_size:%u",\r
-                                        this, (uint)max_window, (uint)cur_window, send_quota / 100, (uint)get_packet_size());\r
-                       func.on_state(userdata, UTP_STATE_WRITABLE);\r
-               }\r
-\r
-               if (state >= CS_CONNECTED && state <= CS_FIN_SENT) {\r
-                       // Send acknowledgment packets periodically, or when the threshold is reached\r
-                       if (bytes_since_ack > DELAYED_ACK_BYTE_THRESHOLD ||\r
-                               (int)(g_current_ms - ack_time) >= 0) {\r
-                               send_ack();\r
-                       }\r
-\r
-                       if ((int)(g_current_ms - last_sent_packet) >= KEEPALIVE_INTERVAL) {\r
-                               send_keep_alive();\r
-                       }\r
-               }\r
-\r
-               break;\r
-       }\r
-\r
-       // Close?\r
-       case CS_GOT_FIN:\r
-       case CS_DESTROY_DELAY:\r
-               if ((int)(g_current_ms - rto_timeout) >= 0) {\r
-                       state = (state == CS_DESTROY_DELAY) ? CS_DESTROY : CS_RESET;\r
-                       if (cur_window_packets > 0 && userdata) {\r
-                               func.on_error(userdata, ECONNRESET);\r
-                       }\r
-               }\r
-               break;\r
-       // prevent warning\r
-       case CS_IDLE:\r
-       case CS_RESET:\r
-       case CS_DESTROY:\r
-               break;\r
-       }\r
-\r
-       getout:\r
-\r
-       // make sure we don't accumulate quota when we don't have\r
-       // anything to send\r
-       int32 limit = max<int32>((int32)max_window / 2, 5 * (int32)get_packet_size()) * 100;\r
-       if (send_quota > limit) send_quota = limit;\r
-}\r
-\r
-// returns:\r
-// 0: the packet was acked.\r
-// 1: it means that the packet had already been acked\r
-// 2: the packet has not been sent yet\r
-int UTPSocket::ack_packet(uint16 seq)\r
-{\r
-       OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(seq);\r
-\r
-       // the packet has already been acked (or not sent)\r
-       if (pkt == NULL) {\r
-               LOG_UTPV("0x%08x: got ack for:%u (already acked, or never sent)", this, seq);\r
-               return 1;\r
-       }\r
-\r
-       // can't ack packets that haven't been sent yet!\r
-       if (pkt->transmissions == 0) {\r
-               LOG_UTPV("0x%08x: got ack for:%u (never sent, pkt_size:%u need_resend:%u)",\r
-                                this, seq, (uint)pkt->payload, pkt->need_resend);\r
-               return 2;\r
-       }\r
-\r
-       LOG_UTPV("0x%08x: got ack for:%u (pkt_size:%u need_resend:%u)",\r
-                        this, seq, (uint)pkt->payload, pkt->need_resend);\r
-\r
-       outbuf.put(seq, NULL);\r
-\r
-       // if we never re-sent the packet, update the RTT estimate\r
-       if (pkt->transmissions == 1) {\r
-               // Estimate the round trip time.\r
-               const uint32 ertt = (uint32)((UTP_GetMicroseconds() - pkt->time_sent) / 1000);\r
-               if (rtt == 0) {\r
-                       // First round trip time sample\r
-                       rtt = ertt;\r
-                       rtt_var = ertt / 2;\r
-                       // sanity check. rtt should never be more than 6 seconds\r
-//                     assert(rtt < 6000);\r
-               } else {\r
-                       // Compute new round trip times\r
-                       const int delta = (int)rtt - ertt;\r
-                       rtt_var = rtt_var + (int)(abs(delta) - rtt_var) / 4;\r
-                       rtt = rtt - rtt/8 + ertt/8;\r
-                       // sanity check. rtt should never be more than 6 seconds\r
-//                     assert(rtt < 6000);\r
-                       rtt_hist.add_sample(ertt);\r
-               }\r
-               rto = max<uint>(rtt + rtt_var * 4, 500);\r
-               LOG_UTPV("0x%08x: rtt:%u avg:%u var:%u rto:%u",\r
-                                this, ertt, rtt, rtt_var, rto);\r
-       }\r
-       retransmit_timeout = rto;\r
-       rto_timeout = g_current_ms + rto;\r
-       // if need_resend is set, this packet has already\r
-       // been considered timed-out, and is not included in\r
-       // the cur_window anymore\r
-       if (!pkt->need_resend) {\r
-               assert(cur_window >= pkt->payload);\r
-               cur_window -= pkt->payload;\r
-       }\r
-       free(pkt);\r
-       return 0;\r
-}\r
-\r
-// count the number of bytes that were acked by the EACK header\r
-size_t UTPSocket::selective_ack_bytes(uint base, const byte* mask, byte len, int64& min_rtt)\r
-{\r
-       if (cur_window_packets == 0) return 0;\r
-\r
-       size_t acked_bytes = 0;\r
-       int bits = len * 8;\r
-\r
-       do {\r
-               uint v = base + bits;\r
-\r
-               // ignore bits that haven't been sent yet\r
-               // see comment in UTPSocket::selective_ack\r
-               if (((seq_nr - v - 1) & ACK_NR_MASK) >= (uint16)(cur_window_packets - 1))\r
-                       continue;\r
-\r
-               // ignore bits that represents packets we haven't sent yet\r
-               // or packets that have already been acked\r
-               OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(v);\r
-               if (!pkt || pkt->transmissions == 0)\r
-                       continue;\r
-\r
-               // Count the number of segments that were successfully received past it.\r
-               if (bits >= 0 && mask[bits>>3] & (1 << (bits & 7))) {\r
-                       assert((int)(pkt->payload) >= 0);\r
-                       acked_bytes += pkt->payload;\r
-                       min_rtt = min<int64>(min_rtt, UTP_GetMicroseconds() - pkt->time_sent);\r
-                       continue;\r
-               }\r
-       } while (--bits >= -1);\r
-       return acked_bytes;\r
-}\r
-\r
-enum { MAX_EACK = 128 };\r
-\r
-void UTPSocket::selective_ack(uint base, const byte *mask, byte len)\r
-{\r
-       if (cur_window_packets == 0) return;\r
-\r
-       // the range is inclusive [0, 31] bits\r
-       int bits = len * 8 - 1;\r
-\r
-       int count = 0;\r
-\r
-       // resends is a stack of sequence numbers we need to resend. Since we\r
-       // iterate in reverse over the acked packets, at the end, the top packets\r
-       // are the ones we want to resend\r
-       int resends[MAX_EACK];\r
-       int nr = 0;\r
-\r
-       LOG_UTPV("0x%08x: Got EACK [%032b] base:%u", this, *(uint32*)mask, base);\r
-       do {\r
-               // we're iterating over the bits from higher sequence numbers\r
-               // to lower (kind of in reverse order, wich might not be very\r
-               // intuitive)\r
-               uint v = base + bits;\r
-\r
-               // ignore bits that haven't been sent yet\r
-               // and bits that fall below the ACKed sequence number\r
-               // this can happen if an EACK message gets\r
-               // reordered and arrives after a packet that ACKs up past\r
-               // the base for thie EACK message\r
-\r
-               // this is essentially the same as:\r
-               // if v >= seq_nr || v <= seq_nr - cur_window_packets\r
-               // but it takes wrapping into account\r
-\r
-               // if v == seq_nr the -1 will make it wrap. if v > seq_nr\r
-               // it will also wrap (since it will fall further below 0)\r
-               // and be > cur_window_packets.\r
-               // if v == seq_nr - cur_window_packets, the result will be\r
-               // seq_nr - (seq_nr - cur_window_packets) - 1\r
-               // == seq_nr - seq_nr + cur_window_packets - 1\r
-               // == cur_window_packets - 1 which will be caught by the\r
-               // test. If v < seq_nr - cur_window_packets the result will grow\r
-               // fall furhter outside of the cur_window_packets range.\r
-\r
-               // sequence number space:\r
-               //\r
-               //     rejected <   accepted   > rejected \r
-               // <============+--------------+============>\r
-               //              ^              ^\r
-               //              |              |\r
-               //        (seq_nr-wnd)         seq_nr\r
-\r
-               if (((seq_nr - v - 1) & ACK_NR_MASK) >= (uint16)(cur_window_packets - 1))\r
-                       continue;\r
-\r
-               // this counts as a duplicate ack, even though we might have\r
-               // received an ack for this packet previously (in another EACK\r
-               // message for instance)\r
-               bool bit_set = bits >= 0 && mask[bits>>3] & (1 << (bits & 7));\r
-\r
-               // if this packet is acked, it counts towards the duplicate ack counter\r
-               if (bit_set) count++;\r
-\r
-               // ignore bits that represents packets we haven't sent yet\r
-               // or packets that have already been acked\r
-               OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(v);\r
-               if (!pkt || pkt->transmissions == 0) {\r
-                       LOG_UTPV("0x%08x: skipping %u. pkt:%08x transmissions:%u %s",\r
-                                        this, v, pkt, pkt?pkt->transmissions:0, pkt?"(not sent yet?)":"(already acked?)");\r
-                       continue;\r
-               }\r
-\r
-               // Count the number of segments that were successfully received past it.\r
-               if (bit_set) {\r
-                       // the selective ack should never ACK the packet we're waiting for to decrement cur_window_packets\r
-                       assert((v & outbuf.mask) != ((seq_nr - cur_window_packets) & outbuf.mask));\r
-                       ack_packet(v);\r
-                       continue;\r
-               }\r
-\r
-               // Resend segments\r
-               // if count is less than our re-send limit, we haven't seen enough\r
-               // acked packets in front of this one to warrant a re-send.\r
-               // if count == 0, we're still going through the tail of zeroes\r
-               if (((v - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE &&\r
-                       count >= DUPLICATE_ACKS_BEFORE_RESEND &&\r
-                       duplicate_ack < DUPLICATE_ACKS_BEFORE_RESEND) {\r
-                       // resends is a stack, and we're mostly interested in the top of it\r
-                       // if we're full, just throw away the lower half\r
-                       if (nr >= MAX_EACK - 2) {\r
-                               memmove(resends, &resends[MAX_EACK/2], MAX_EACK/2 * sizeof(resends[0]));\r
-                               nr -= MAX_EACK / 2;\r
-                       }\r
-                       resends[nr++] = v;\r
-                       LOG_UTPV("0x%08x: no ack for %u", this, v);\r
-               } else {\r
-                       LOG_UTPV("0x%08x: not resending %u count:%d dup_ack:%u fast_resend_seq_nr:%u",\r
-                                        this, v, count, duplicate_ack, fast_resend_seq_nr);\r
-               }\r
-       } while (--bits >= -1);\r
-\r
-       if (((base - 1 - fast_resend_seq_nr) & ACK_NR_MASK) <= OUTGOING_BUFFER_MAX_SIZE &&\r
-               count >= DUPLICATE_ACKS_BEFORE_RESEND) {\r
-               // if we get enough duplicate acks to start\r
-               // resending, the first packet we should resend\r
-               // is base-1\r
-               resends[nr++] = (base - 1) & ACK_NR_MASK;\r
-       } else {\r
-               LOG_UTPV("0x%08x: not resending %u count:%d dup_ack:%u fast_resend_seq_nr:%u",\r
-                                this, base - 1, count, duplicate_ack, fast_resend_seq_nr);\r
-       }\r
-\r
-       bool back_off = false;\r
-       int i = 0;\r
-       while (nr > 0) {\r
-               uint v = resends[--nr];\r
-               // don't consider the tail of 0:es to be lost packets\r
-               // only unacked packets with acked packets after should\r
-               // be considered lost\r
-               OutgoingPacket *pkt = (OutgoingPacket*)outbuf.get(v);\r
-\r
-               // this may be an old (re-ordered) packet, and some of the\r
-               // packets in here may have been acked already. In which\r
-               // case they will not be in the send queue anymore\r
-               if (!pkt) continue;\r
-\r
-               // used in parse_log.py\r
-               LOG_UTP("0x%08x: Packet %u lost. Resending", this, v);\r
-\r
-               // On Loss\r
-               back_off = true;\r
-#ifdef _DEBUG\r
-               ++_stats._rexmit;\r
-#endif\r
-               send_packet(pkt);\r
-               fast_resend_seq_nr = v + 1;\r
-\r
-               // Re-send max 4 packets.\r
-               if (++i >= 4) break;\r
-       }\r
-\r
-       if (back_off)\r
-               maybe_decay_win();\r
-\r
-       duplicate_ack = count;\r
-}\r
-\r
-void UTPSocket::apply_ledbat_ccontrol(size_t bytes_acked, uint32 actual_delay, int64 min_rtt)\r
-{\r
-       // the delay can never be greater than the rtt. The min_rtt\r
-       // variable is the RTT in microseconds\r
-       \r
-       assert(min_rtt >= 0);\r
-       int32 our_delay = min<uint32>(our_hist.get_value(), uint32(min_rtt));\r
-       assert(our_delay != INT_MAX);\r
-       assert(our_delay >= 0);\r
-\r
-       SOCKADDR_STORAGE sa = addr.get_sockaddr_storage();\r
-       UTP_DelaySample((sockaddr*)&sa, our_delay / 1000);\r
-\r
-       // This test the connection under heavy load from foreground\r
-       // traffic. Pretend that our delays are very high to force the\r
-       // connection to use sub-packet size window sizes\r
-       //our_delay *= 4;\r
-\r
-       // target is microseconds\r
-       int target = CCONTROL_TARGET;\r
-       if (target <= 0) target = 100000;\r
-\r
-       double off_target = target - our_delay;\r
-\r
-       // this is the same as:\r
-       //\r
-       //    (min(off_target, target) / target) * (bytes_acked / max_window) * MAX_CWND_INCREASE_BYTES_PER_RTT\r
-       //\r
-       // so, it's scaling the max increase by the fraction of the window this ack represents, and the fraction\r
-       // of the target delay the current delay represents.\r
-       // The min() around off_target protects against crazy values of our_delay, which may happen when th\r
-       // timestamps wraps, or by just having a malicious peer sending garbage. This caps the increase\r
-       // of the window size to MAX_CWND_INCREASE_BYTES_PER_RTT per rtt.\r
-       // as for large negative numbers, this direction is already capped at the min packet size further down\r
-       // the min around the bytes_acked protects against the case where the window size was recently\r
-       // shrunk and the number of acked bytes exceeds that. This is considered no more than one full\r
-       // window, in order to keep the gain within sane boundries.\r
-\r
-       assert(bytes_acked > 0);\r
-       double window_factor = (double)min(bytes_acked, max_window) / (double)max(max_window, bytes_acked);\r
-       double delay_factor = off_target / target;\r
-       double scaled_gain = MAX_CWND_INCREASE_BYTES_PER_RTT * window_factor * delay_factor;\r
-\r
-       // since MAX_CWND_INCREASE_BYTES_PER_RTT is a cap on how much the window size (max_window)\r
-       // may increase per RTT, we may not increase the window size more than that proportional\r
-       // to the number of bytes that were acked, so that once one window has been acked (one rtt)\r
-       // the increase limit is not exceeded\r
-       // the +1. is to allow for floating point imprecision\r
-       assert(scaled_gain <= 1. + MAX_CWND_INCREASE_BYTES_PER_RTT * (int)min(bytes_acked, max_window) / (double)max(max_window, bytes_acked));\r
-\r
-       if (scaled_gain > 0 && g_current_ms - last_maxed_out_window > 300) {\r
-               // if it was more than 300 milliseconds since we tried to send a packet\r
-               // and stopped because we hit the max window, we're most likely rate\r
-               // limited (which prevents us from ever hitting the window size)\r
-               // if this is the case, we cannot let the max_window grow indefinitely\r
-               scaled_gain = 0;\r
-       }\r
-\r
-       if (scaled_gain + max_window < MIN_WINDOW_SIZE) {\r
-               max_window = MIN_WINDOW_SIZE;\r
-       } else {\r
-               max_window = (size_t)(max_window + scaled_gain);\r
-       }\r
-\r
-       // make sure that the congestion window is below max\r
-       // make sure that we don't shrink our window too small\r
-       max_window = clamp<size_t>(max_window, MIN_WINDOW_SIZE, opt_sndbuf);\r
-\r
-       // used in parse_log.py\r
-       LOG_UTP("0x%08x: actual_delay:%u our_delay:%d their_delay:%u off_target:%d max_window:%u "\r
-                       "delay_base:%u delay_sum:%d target_delay:%d acked_bytes:%u cur_window:%u "\r
-                       "scaled_gain:%f rtt:%u rate:%u quota:%d wnduser:%u rto:%u timeout:%d get_microseconds:"I64u" "\r
-                       "cur_window_packets:%u packet_size:%u their_delay_base:%u their_actual_delay:%u",\r
-                       this, actual_delay, our_delay / 1000, their_hist.get_value() / 1000,\r
-                       (int)off_target / 1000, (uint)(max_window),  our_hist.delay_base,\r
-                       (our_delay + their_hist.get_value()) / 1000, target / 1000, (uint)bytes_acked,\r
-                       (uint)(cur_window - bytes_acked), (float)(scaled_gain), rtt,\r
-                       (uint)(max_window * 1000 / (rtt_hist.delay_base?rtt_hist.delay_base:50)),\r
-                       send_quota / 100, (uint)max_window_user, rto, (int)(rto_timeout - g_current_ms),\r
-                       UTP_GetMicroseconds(), cur_window_packets, (uint)get_packet_size(),\r
-                       their_hist.delay_base, their_hist.delay_base + their_hist.get_value());\r
-}\r
-\r
-static void UTP_RegisterRecvPacket(UTPSocket *conn, size_t len)\r
-{\r
-#ifdef _DEBUG\r
-       ++conn->_stats._nrecv;\r
-       conn->_stats._nbytes_recv += len;\r
-#endif\r
-\r
-       if (len <= PACKET_SIZE_MID) {\r
-               if (len <= PACKET_SIZE_EMPTY) {\r
-                       _global_stats._nraw_recv[PACKET_SIZE_EMPTY_BUCKET]++;\r
-               } else if (len <= PACKET_SIZE_SMALL) {\r
-                       _global_stats._nraw_recv[PACKET_SIZE_SMALL_BUCKET]++;\r
-               } else \r
-                       _global_stats._nraw_recv[PACKET_SIZE_MID_BUCKET]++;\r
-       } else {\r
-               if (len <= PACKET_SIZE_BIG) {\r
-                       _global_stats._nraw_recv[PACKET_SIZE_BIG_BUCKET]++;\r
-               } else \r
-                       _global_stats._nraw_recv[PACKET_SIZE_HUGE_BUCKET]++;\r
-       }\r
-}\r
-\r
-// returns the max number of bytes of payload the uTP\r
-// connection is allowed to send\r
-size_t UTPSocket::get_packet_size()\r
-{\r
-       int header_size = version == 1\r
-               ? sizeof(PacketFormatV1)\r
-               : sizeof(PacketFormat);\r
-\r
-       size_t mtu = get_udp_mtu();\r
-\r
-       if (DYNAMIC_PACKET_SIZE_ENABLED) {\r
-               SOCKADDR_STORAGE sa = addr.get_sockaddr_storage();\r
-               size_t max_packet_size = UTP_GetPacketSize((sockaddr*)&sa);\r
-               return min(mtu - header_size, max_packet_size);\r
-       }\r
-       else\r
-       {\r
-               return mtu - header_size;\r
-       }\r
-}\r
-\r
-// Process an incoming packet\r
-// syn is true if this is the first packet received. It will cut off parsing\r
-// as soon as the header is done\r
-size_t UTP_ProcessIncoming(UTPSocket *conn, const byte *packet, size_t len, bool syn = false)\r
-{\r
-       UTP_RegisterRecvPacket(conn, len);\r
-\r
-       g_current_ms = UTP_GetMilliseconds();\r
-\r
-       conn->update_send_quota();\r
-\r
-       const PacketFormat *pf = (PacketFormat*)packet;\r
-       const PacketFormatV1 *pf1 = (PacketFormatV1*)packet;\r
-       const byte *packet_end = packet + len;\r
-\r
-       uint16 pk_seq_nr;\r
-       uint16 pk_ack_nr;\r
-       uint8 pk_flags;\r
-       if (conn->version == 0) {\r
-               pk_seq_nr = pf->seq_nr;\r
-               pk_ack_nr = pf->ack_nr;\r
-               pk_flags = pf->flags;\r
-       } else {\r
-               pk_seq_nr = pf1->seq_nr;\r
-               pk_ack_nr = pf1->ack_nr;\r
-               pk_flags = pf1->type();\r
-       }\r
-\r
-       if (pk_flags >= ST_NUM_STATES) return 0;\r
-\r
-       LOG_UTPV("0x%08x: Got %s. seq_nr:%u ack_nr:%u state:%s version:%u timestamp:"I64u" reply_micro:%u",\r
-                        conn, flagnames[pk_flags], pk_seq_nr, pk_ack_nr, statenames[conn->state], conn->version,\r
-                        conn->version == 0?(uint64)(pf->tv_sec) * 1000000 + pf->tv_usec:uint64(pf1->tv_usec),\r
-                        conn->version == 0?(uint32)(pf->reply_micro):(uint32)(pf1->reply_micro));\r
-\r
-       // mark receipt time\r
-       uint64 time = UTP_GetMicroseconds();\r
-\r
-       // RSTs are handled earlier, since the connid matches the send id not the recv id\r
-       assert(pk_flags != ST_RESET);\r
-\r
-       // TODO: maybe send a ST_RESET if we're in CS_RESET?\r
-\r
-       const byte *selack_ptr = NULL;\r
-\r
-       // Unpack UTP packet options\r
-       // Data pointer\r
-       const byte *data = (const byte*)pf + conn->get_header_size();\r
-       if (conn->get_header_size() > len) {\r
-               LOG_UTPV("0x%08x: Invalid packet size (less than header size)", conn);\r
-               return 0;\r
-       }\r
-       // Skip the extension headers\r
-       uint extension = conn->version == 0 ? pf->ext : pf1->ext;\r
-       if (extension != 0) {\r
-               do {\r
-                       // Verify that the packet is valid.\r
-                       data += 2;\r
-\r
-                       if ((int)(packet_end - data) < 0 || (int)(packet_end - data) < data[-1]) {\r
-                               LOG_UTPV("0x%08x: Invalid len of extensions", conn);\r
-                               return 0;\r
-                       }\r
-\r
-                       switch(extension) {\r
-                       case 1: // Selective Acknowledgment\r
-                               selack_ptr = data;\r
-                               break;\r
-                       case 2: // extension bits\r
-                               if (data[-1] != 8) {\r
-                                       LOG_UTPV("0x%08x: Invalid len of extension bits header", conn);\r
-                                       return 0;\r
-                               }\r
-                               memcpy(conn->extensions, data, 8);\r
-                               LOG_UTPV("0x%08x: got extension bits:%02x%02x%02x%02x%02x%02x%02x%02x", conn,\r
-                                       conn->extensions[0], conn->extensions[1], conn->extensions[2], conn->extensions[3],\r
-                                       conn->extensions[4], conn->extensions[5], conn->extensions[6], conn->extensions[7]);\r
-                       }\r
-                       extension = data[-2];\r
-                       data += data[-1];\r
-               } while (extension);\r
-       }\r
-\r
-       if (conn->state == CS_SYN_SENT) {\r
-               // if this is a syn-ack, initialize our ack_nr\r
-               // to match the sequence number we got from\r
-               // the other end\r
-               conn->ack_nr = (pk_seq_nr - 1) & SEQ_NR_MASK;\r
-       }\r
-\r
-       g_current_ms = UTP_GetMilliseconds();\r
-       conn->last_got_packet = g_current_ms;\r
-\r
-       if (syn) {\r
-               return 0;\r
-       }\r
-\r
-       // seqnr is the number of packets past the expected\r
-       // packet this is. ack_nr is the last acked, seq_nr is the\r
-       // current. Subtracring 1 makes 0 mean "this is the next\r
-       // expected packet".\r
-       const uint seqnr = (pk_seq_nr - conn->ack_nr - 1) & SEQ_NR_MASK;\r
-\r
-       // Getting an invalid sequence number?\r
-       if (seqnr >= REORDER_BUFFER_MAX_SIZE) {\r
-               if (seqnr >= (SEQ_NR_MASK + 1) - REORDER_BUFFER_MAX_SIZE && pk_flags != ST_STATE) {\r
-                       conn->ack_time = g_current_ms + min<uint>(conn->ack_time - g_current_ms, DELAYED_ACK_TIME_THRESHOLD);\r
-               }\r
-               LOG_UTPV("    Got old Packet/Ack (%u/%u)=%u!", pk_seq_nr, conn->ack_nr, seqnr);\r
-               return 0;\r
-       }\r
-\r
-       // Process acknowledgment\r
-       // acks is the number of packets that was acked\r
-       int acks = (pk_ack_nr - (conn->seq_nr - 1 - conn->cur_window_packets)) & ACK_NR_MASK;\r
-\r
-       // this happens when we receive an old ack nr\r
-       if (acks > conn->cur_window_packets) acks = 0;\r
-\r
-       // if we get the same ack_nr as in the last packet\r
-       // increase the duplicate_ack counter, otherwise reset\r
-       // it to 0\r
-       if (conn->cur_window_packets > 0) {\r
-               if (pk_ack_nr == ((conn->seq_nr - conn->cur_window_packets - 1) & ACK_NR_MASK) &&\r
-                       conn->cur_window_packets > 0) {\r
-                       //++conn->duplicate_ack;\r
-               } else {\r
-                       conn->duplicate_ack = 0;\r
-               }\r
-\r
-               // TODO: if duplicate_ack == DUPLICATE_ACK_BEFORE_RESEND\r
-               // and fast_resend_seq_nr <= ack_nr + 1\r
-               //    resend ack_nr + 1\r
-       }\r
-\r
-       // figure out how many bytes were acked\r
-       size_t acked_bytes = 0;\r
-\r
-       // the minimum rtt of all acks\r
-       // this is the upper limit on the delay we get back\r
-       // from the other peer. Our delay cannot exceed\r
-       // the rtt of the packet. If it does, clamp it.\r
-       // this is done in apply_ledbat_ccontrol()\r
-       int64 min_rtt = INT64_MAX;\r
-\r
-       for (int i = 0; i < acks; ++i) {\r
-               int seq = conn->seq_nr - conn->cur_window_packets + i;\r
-               OutgoingPacket *pkt = (OutgoingPacket*)conn->outbuf.get(seq);\r
-               if (pkt == 0 || pkt->transmissions == 0) continue;\r
-               assert((int)(pkt->payload) >= 0);\r
-               acked_bytes += pkt->payload;\r
-               min_rtt = min<int64>(min_rtt, UTP_GetMicroseconds() - pkt->time_sent);\r
-       }\r
-       \r
-       // count bytes acked by EACK\r
-       if (selack_ptr != NULL) {\r
-               acked_bytes += conn->selective_ack_bytes((pk_ack_nr + 2) & ACK_NR_MASK,\r
-                                                                                                selack_ptr, selack_ptr[-1], min_rtt);\r
-       }\r
-\r
-       LOG_UTPV("0x%08x: acks:%d acked_bytes:%u seq_nr:%d cur_window:%u cur_window_packets:%u relative_seqnr:%u max_window:%u min_rtt:%u rtt:%u",\r
-                        conn, acks, (uint)acked_bytes, conn->seq_nr, (uint)conn->cur_window, conn->cur_window_packets,\r
-                        seqnr, (uint)conn->max_window, (uint)(min_rtt / 1000), conn->rtt);\r
-\r
-       uint64 p;\r
-\r
-       if (conn->version == 0) {\r
-               p = uint64(pf->tv_sec) * 1000000 + pf->tv_usec;\r
-       } else {\r
-               p = pf1->tv_usec;\r
-       }\r
-\r
-       conn->last_measured_delay = g_current_ms;\r
-\r
-       // get delay in both directions\r
-       // record the delay to report back\r
-       const uint32 their_delay = (uint32)(p == 0 ? 0 : time - p);\r
-       conn->reply_micro = their_delay;\r
-       uint32 prev_delay_base = conn->their_hist.delay_base;\r
-       if (their_delay != 0) conn->their_hist.add_sample(their_delay);\r
-\r
-       // if their new delay base is less than their previous one\r
-       // we should shift our delay base in the other direction in order\r
-       // to take the clock skew into account\r
-       if (prev_delay_base != 0 &&\r
-               wrapping_compare_less(conn->their_hist.delay_base, prev_delay_base)) {\r
-               // never adjust more than 10 milliseconds\r
-               if (prev_delay_base - conn->their_hist.delay_base <= 10000) {\r
-                       conn->our_hist.shift(prev_delay_base - conn->their_hist.delay_base);\r
-               }\r
-       }\r
-\r
-       const uint32 actual_delay = conn->version==0\r
-               ?(pf->reply_micro==INT_MAX?0:uint32(pf->reply_micro))\r
-               :(uint32(pf1->reply_micro)==INT_MAX?0:uint32(pf1->reply_micro));\r
-\r
-       // if the actual delay is 0, it means the other end\r
-       // hasn't received a sample from us yet, and doesn't\r
-       // know what it is. We can't update out history unless\r
-       // we have a true measured sample\r
-       prev_delay_base = conn->our_hist.delay_base;\r
-       if (actual_delay != 0) conn->our_hist.add_sample(actual_delay);\r
-\r
-       // if our new delay base is less than our previous one\r
-       // we should shift the other end's delay base in the other\r
-       // direction in order to take the clock skew into account\r
-       // This is commented out because it creates bad interactions\r
-       // with our adjustment in the other direction. We don't really\r
-       // need our estimates of the other peer to be very accurate\r
-       // anyway. The problem with shifting here is that we're more\r
-       // likely shift it back later because of a low latency. This\r
-       // second shift back would cause us to shift our delay base\r
-       // which then get's into a death spiral of shifting delay bases\r
-/*     if (prev_delay_base != 0 &&\r
-               wrapping_compare_less(conn->our_hist.delay_base, prev_delay_base)) {\r
-               // never adjust more than 10 milliseconds\r
-               if (prev_delay_base - conn->our_hist.delay_base <= 10000) {\r
-                       conn->their_hist.Shift(prev_delay_base - conn->our_hist.delay_base);\r
-               }\r
-       }\r
-*/\r
-\r
-       // if the delay estimate exceeds the RTT, adjust the base_delay to\r
-       // compensate\r
-       if (conn->our_hist.get_value() > uint32(min_rtt)) {\r
-               conn->our_hist.shift(conn->our_hist.get_value() - min_rtt);\r
-       }\r
-\r
-       // only apply the congestion controller on acks\r
-       // if we don't have a delay measurement, there's\r
-       // no point in invoking the congestion control\r
-       if (actual_delay != 0 && acked_bytes >= 1)\r
-               conn->apply_ledbat_ccontrol(acked_bytes, actual_delay, min_rtt);\r
-\r
-       // sanity check, the other end should never ack packets\r
-       // past the point we've sent\r
-       if (acks <= conn->cur_window_packets) {\r
-               conn->max_window_user = conn->version == 0\r
-                       ? pf->windowsize * PACKET_SIZE : pf1->windowsize;\r
-\r
-               // If max user window is set to 0, then we startup a timer\r
-               // That will reset it to 1 after 15 seconds.\r
-               if (conn->max_window_user == 0)\r
-                       // Reset max_window_user to 1 every 15 seconds.\r
-                       conn->zerowindow_time = g_current_ms + 15000;\r
-\r
-               // Respond to connect message\r
-               // Switch to CONNECTED state.\r
-               if (conn->state == CS_SYN_SENT) {\r
-                       conn->state = CS_CONNECTED;\r
-                       conn->func.on_state(conn->userdata, UTP_STATE_CONNECT);\r
-\r
-               // We've sent a fin, and everything was ACKed (including the FIN),\r
-               // it's safe to destroy the socket. cur_window_packets == acks\r
-               // means that this packet acked all the remaining packets that\r
-               // were in-flight.\r
-               } else if (conn->state == CS_FIN_SENT && conn->cur_window_packets == acks) {\r
-                       conn->state = CS_DESTROY;\r
-               }\r
-\r
-               // Update fast resend counter\r
-               if (wrapping_compare_less(conn->fast_resend_seq_nr, (pk_ack_nr + 1) & ACK_NR_MASK))\r
-                       conn->fast_resend_seq_nr = pk_ack_nr + 1;\r
-\r
-               LOG_UTPV("0x%08x: fast_resend_seq_nr:%u", conn, conn->fast_resend_seq_nr);\r
-\r
-               for (int i = 0; i < acks; ++i) {\r
-                       int ack_status = conn->ack_packet(conn->seq_nr - conn->cur_window_packets);\r
-                       // if ack_status is 0, the packet was acked.\r
-                       // if acl_stauts is 1, it means that the packet had already been acked\r
-                       // if it's 2, the packet has not been sent yet\r
-                       // We need to break this loop in the latter case. This could potentially\r
-                       // happen if we get an ack_nr that does not exceed what we have stuffed\r
-                       // into the outgoing buffer, but does exceed what we have sent\r
-                       if (ack_status == 2) {\r
-#ifdef _DEBUG\r
-                               OutgoingPacket* pkt = (OutgoingPacket*)conn->outbuf.get(conn->seq_nr - conn->cur_window_packets);\r
-                               assert(pkt->transmissions == 0);\r
-#endif\r
-                               break;\r
-                       }\r
-                       conn->cur_window_packets--;\r
-               }\r
-#ifdef _DEBUG\r
-               if (conn->cur_window_packets == 0) assert(conn->cur_window == 0);\r
-#endif\r
-\r
-               // packets in front of this may have been acked by a\r
-               // selective ack (EACK). Keep decreasing the window packet size\r
-               // until we hit a packet that is still waiting to be acked\r
-               // in the send queue\r
-               // this is especially likely to happen when the other end\r
-               // has the EACK send bug older versions of uTP had\r
-               while (conn->cur_window_packets > 0 && !conn->outbuf.get(conn->seq_nr - conn->cur_window_packets))\r
-                       conn->cur_window_packets--;\r
-\r
-#ifdef _DEBUG\r
-               if (conn->cur_window_packets == 0) assert(conn->cur_window == 0);\r
-#endif\r
-\r
-               // this invariant should always be true\r
-               assert(conn->cur_window_packets == 0 || conn->outbuf.get(conn->seq_nr - conn->cur_window_packets));\r
-\r
-               // flush Nagle\r
-               if (conn->cur_window_packets == 1) {\r
-                       OutgoingPacket *pkt = (OutgoingPacket*)conn->outbuf.get(conn->seq_nr - 1);\r
-                       // do we still have quota?\r
-                       if (pkt->transmissions == 0 &&\r
-                               (!(USE_PACKET_PACING) || conn->send_quota / 100 >= (int32)pkt->length)) {\r
-                               conn->send_packet(pkt);\r
-\r
-                               // No need to send another ack if there is nothing to reorder.\r
-                               if (conn->reorder_count == 0) {\r
-                                       conn->sent_ack();\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // Fast timeout-retry\r
-               if (conn->fast_timeout) {\r
-                       LOG_UTPV("Fast timeout %u,%u,%u?", (uint)conn->cur_window, conn->seq_nr - conn->timeout_seq_nr, conn->timeout_seq_nr);\r
-                       // if the fast_resend_seq_nr is not pointing to the oldest outstanding packet, it suggests that we've already\r
-                       // resent the packet that timed out, and we should leave the fast-timeout mode.\r
-                       if (((conn->seq_nr - conn->cur_window_packets) & ACK_NR_MASK) != conn->fast_resend_seq_nr) {\r
-                               conn->fast_timeout = false;\r
-                       } else {\r
-                               // resend the oldest packet and increment fast_resend_seq_nr\r
-                               // to not allow another fast resend on it again\r
-                               OutgoingPacket *pkt = (OutgoingPacket*)conn->outbuf.get(conn->seq_nr - conn->cur_window_packets);\r
-                               if (pkt && pkt->transmissions > 0) {\r
-                                       LOG_UTPV("0x%08x: Packet %u fast timeout-retry.", conn, conn->seq_nr - conn->cur_window_packets);\r
-#ifdef _DEBUG\r
-                                       ++conn->_stats._fastrexmit;\r
-#endif\r
-                                       conn->fast_resend_seq_nr++;\r
-                                       conn->send_packet(pkt);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       // Process selective acknowledgent\r
-       if (selack_ptr != NULL) {\r
-               conn->selective_ack(pk_ack_nr + 2, selack_ptr, selack_ptr[-1]);\r
-       }\r
-\r
-       // this invariant should always be true\r
-       assert(conn->cur_window_packets == 0 || conn->outbuf.get(conn->seq_nr - conn->cur_window_packets));\r
-\r
-       LOG_UTPV("0x%08x: acks:%d acked_bytes:%u seq_nr:%u cur_window:%u cur_window_packets:%u quota:%d",\r
-                        conn, acks, (uint)acked_bytes, conn->seq_nr, (uint)conn->cur_window, conn->cur_window_packets,\r
-                        conn->send_quota / 100);\r
-\r
-       // In case the ack dropped the current window below\r
-       // the max_window size, Mark the socket as writable\r
-       if (conn->state == CS_CONNECTED_FULL && conn->is_writable(conn->get_packet_size())) {\r
-               conn->state = CS_CONNECTED;\r
-               LOG_UTPV("0x%08x: Socket writable. max_window:%u cur_window:%u quota:%d packet_size:%u",\r
-                                conn, (uint)conn->max_window, (uint)conn->cur_window, conn->send_quota / 100, (uint)conn->get_packet_size());\r
-               conn->func.on_state(conn->userdata, UTP_STATE_WRITABLE);\r
-       }\r
-\r
-       if (pk_flags == ST_STATE) {\r
-               // This is a state packet only.\r
-               return 0;\r
-       }\r
-\r
-       // The connection is not in a state that can accept data?\r
-       if (conn->state != CS_CONNECTED &&\r
-               conn->state != CS_CONNECTED_FULL &&\r
-               conn->state != CS_FIN_SENT) {\r
-               return 0;\r
-       }\r
-\r
-       // Is this a finalize packet?\r
-       if (pk_flags == ST_FIN && !conn->got_fin) {\r
-               LOG_UTPV("Got FIN eof_pkt:%u", pk_seq_nr);\r
-               conn->got_fin = true;\r
-               conn->eof_pkt = pk_seq_nr;\r
-               // at this point, it is possible for the\r
-               // other end to have sent packets with\r
-               // sequence numbers higher than seq_nr.\r
-               // if this is the case, our reorder_count\r
-               // is out of sync. This case is dealt with\r
-               // when we re-order and hit the eof_pkt.\r
-               // we'll just ignore any packets with\r
-               // sequence numbers past this\r
-       }\r
-\r
-       // Getting an in-order packet?\r
-       if (seqnr == 0) {\r
-               size_t count = packet_end - data;\r
-               if (count > 0 && conn->state != CS_FIN_SENT) {\r
-                       LOG_UTPV("0x%08x: Got Data len:%u (rb:%u)", conn, (uint)count, (uint)conn->func.get_rb_size(conn->userdata));\r
-                       // Post bytes to the upper layer\r
-                       conn->func.on_read(conn->userdata, data, count);\r
-               }\r
-               conn->ack_nr++;\r
-               conn->bytes_since_ack += count;\r
-\r
-               // Check if the next packet has been received too, but waiting\r
-               // in the reorder buffer.\r
-               for (;;) {\r
-\r
-                       if (conn->got_fin && conn->eof_pkt == conn->ack_nr) {\r
-                               if (conn->state != CS_FIN_SENT) {\r
-                                       conn->state = CS_GOT_FIN;\r
-                                       conn->rto_timeout = g_current_ms + min<uint>(conn->rto * 3, 60);\r
-\r
-                                       LOG_UTPV("0x%08x: Posting EOF", conn);\r
-                                       conn->func.on_state(conn->userdata, UTP_STATE_EOF);\r
-                               }\r
-\r
-                               // if the other end wants to close, ack immediately\r
-                               conn->send_ack();\r
-\r
-                               // reorder_count is not necessarily 0 at this point.\r
-                               // even though it is most of the time, the other end\r
-                               // may have sent packets with higher sequence numbers\r
-                               // than what later end up being eof_pkt\r
-                               // since we have received all packets up to eof_pkt\r
-                               // just ignore the ones after it.\r
-                               conn->reorder_count = 0;\r
-                       }\r
-\r
-                       // Quick get-out in case there is nothing to reorder\r
-                       if (conn->reorder_count == 0)\r
-                               break;\r
-\r
-                       // Check if there are additional buffers in the reorder buffers\r
-                       // that need delivery.\r
-                       byte *p = (byte*)conn->inbuf.get(conn->ack_nr+1);\r
-                       if (p == NULL)\r
-                               break;\r
-                       conn->inbuf.put(conn->ack_nr+1, NULL);\r
-                       count = *(uint*)p;\r
-                       if (count > 0 && conn->state != CS_FIN_SENT) {\r
-                               // Pass the bytes to the upper layer\r
-                               conn->func.on_read(conn->userdata, p + sizeof(uint), count);\r
-                       }\r
-                       conn->ack_nr++;\r
-                       conn->bytes_since_ack += count;\r
-\r
-                       // Free the element from the reorder buffer\r
-                       free(p);\r
-                       assert(conn->reorder_count > 0);\r
-                       conn->reorder_count--;\r
-               }\r
-\r
-               // start the delayed ACK timer\r
-               conn->ack_time = g_current_ms + min<uint>(conn->ack_time - g_current_ms, DELAYED_ACK_TIME_THRESHOLD);\r
-       } else {\r
-               // Getting an out of order packet.\r
-               // The packet needs to be remembered and rearranged later.\r
-\r
-               // if we have received a FIN packet, and the EOF-sequence number\r
-               // is lower than the sequence number of the packet we just received\r
-               // something is wrong.\r
-               if (conn->got_fin && pk_seq_nr > conn->eof_pkt) {\r
-                       LOG_UTPV("0x%08x: Got an invalid packet sequence number, past EOF "\r
-                               "reorder_count:%u len:%u (rb:%u)",\r
-                               conn, conn->reorder_count, (uint)(packet_end - data), (uint)conn->func.get_rb_size(conn->userdata));\r
-                       return 0;\r
-               }\r
-\r
-               // if the sequence number is entirely off the expected\r
-               // one, just drop it. We can't allocate buffer space in\r
-               // the inbuf entirely based on untrusted input\r
-               if (seqnr > 0x3ff) {\r
-                       LOG_UTPV("0x%08x: Got an invalid packet sequence number, too far off "\r
-                               "reorder_count:%u len:%u (rb:%u)",\r
-                               conn, conn->reorder_count, (uint)(packet_end - data), (uint)conn->func.get_rb_size(conn->userdata));\r
-                       return 0;\r
-               }\r
-\r
-               // we need to grow the circle buffer before we\r
-               // check if the packet is already in here, so that\r
-               // we don't end up looking at an older packet (since\r
-               // the indices wraps around).\r
-               conn->inbuf.ensure_size(pk_seq_nr + 1, seqnr + 1);\r
-\r
-               // Has this packet already been received? (i.e. a duplicate)\r
-               // If that is the case, just discard it.\r
-               if (conn->inbuf.get(pk_seq_nr) != NULL) {\r
-#ifdef _DEBUG\r
-                       ++conn->_stats._nduprecv;\r
-#endif\r
-                       return 0;\r
-               }\r
-\r
-               // Allocate memory to fit the packet that needs to re-ordered\r
-               byte *mem = (byte*)malloc((packet_end - data) + sizeof(uint));\r
-               *(uint*)mem = (uint)(packet_end - data);\r
-               memcpy(mem + sizeof(uint), data, packet_end - data);\r
-\r
-               // Insert into reorder buffer and increment the count\r
-               // of # of packets to be reordered.\r
-               // we add one to seqnr in order to leave the last\r
-               // entry empty, that way the assert in send_ack\r
-               // is valid. we have to add one to seqnr too, in order\r
-               // to make the circular buffer grow around the correct\r
-               // point (which is conn->ack_nr + 1).\r
-               assert(conn->inbuf.get(pk_seq_nr) == NULL);\r
-               assert((pk_seq_nr & conn->inbuf.mask) != ((conn->ack_nr+1) & conn->inbuf.mask));\r
-               conn->inbuf.put(pk_seq_nr, mem);\r
-               conn->reorder_count++;\r
-\r
-               LOG_UTPV("0x%08x: Got out of order data reorder_count:%u len:%u (rb:%u)",\r
-                       conn, conn->reorder_count, (uint)(packet_end - data), (uint)conn->func.get_rb_size(conn->userdata));\r
-\r
-               // Setup so the partial ACK message will get sent immediately.\r
-               conn->ack_time = g_current_ms + min<uint>(conn->ack_time - g_current_ms, 1);\r
-       }\r
-\r
-       // If ack_time or ack_bytes indicate that we need to send and ack, send one\r
-       // here instead of waiting for the timer to trigger\r
-       LOG_UTPV("bytes_since_ack:%u ack_time:%d",\r
-                        (uint)conn->bytes_since_ack, (int)(g_current_ms - conn->ack_time));\r
-       if (conn->state == CS_CONNECTED || conn->state == CS_CONNECTED_FULL) {\r
-               if (conn->bytes_since_ack > DELAYED_ACK_BYTE_THRESHOLD ||\r
-                       (int)(g_current_ms - conn->ack_time) >= 0) {\r
-                       conn->send_ack();\r
-               }\r
-       }\r
-       return (size_t)(packet_end - data);\r
-}\r
-\r
-inline bool UTP_IsV1(PacketFormatV1 const* pf)\r
-{\r
-       return pf->version() == 1 && pf->type() < ST_NUM_STATES && pf->ext < 3;\r
-}\r
-\r
-void UTP_Free(UTPSocket *conn)\r
-{\r
-       LOG_UTPV("0x%08x: Killing socket", conn);\r
-\r
-       conn->func.on_state(conn->userdata, UTP_STATE_DESTROYING);\r
-       UTP_SetCallbacks(conn, NULL, NULL);\r
-\r
-       assert(conn->idx < g_utp_sockets.GetCount());\r
-       assert(g_utp_sockets[conn->idx] == conn);\r
-\r
-       // Unlink object from the global list\r
-       assert(g_utp_sockets.GetCount() > 0);\r
-\r
-       UTPSocket *last = g_utp_sockets[g_utp_sockets.GetCount() - 1];\r
-\r
-       assert(last->idx < g_utp_sockets.GetCount());\r
-       assert(g_utp_sockets[last->idx] == last);\r
-\r
-       last->idx = conn->idx;\r
-       \r
-       g_utp_sockets[conn->idx] = last;\r
-\r
-       // Decrease the count\r
-       g_utp_sockets.SetCount(g_utp_sockets.GetCount() - 1);\r
-\r
-       // Free all memory occupied by the socket object.\r
-       for (size_t i = 0; i <= conn->inbuf.mask; i++) {\r
-               free(conn->inbuf.elements[i]);\r
-       }\r
-       for (size_t i = 0; i <= conn->outbuf.mask; i++) {\r
-               free(conn->outbuf.elements[i]);\r
-       }\r
-       free(conn->inbuf.elements);\r
-       free(conn->outbuf.elements);\r
-\r
-       // Finally free the socket object\r
-       free(conn);\r
-}\r
-\r
-\r
-// Public functions:\r
-///////////////////////////////////////////////////////////////////////////////\r
-\r
-// Create a UTP socket\r
-UTPSocket *UTP_Create(SendToProc *send_to_proc, void *send_to_userdata, const struct sockaddr *addr, socklen_t addrlen)\r
-{\r
-       UTPSocket *conn = (UTPSocket*)calloc(1, sizeof(UTPSocket));\r
-\r
-       g_current_ms = UTP_GetMilliseconds();\r
-\r
-       UTP_SetCallbacks(conn, NULL, NULL);\r
-       conn->our_hist.clear();\r
-       conn->their_hist.clear();\r
-       conn->rto = 3000;\r
-       conn->rtt_var = 800;\r
-       conn->seq_nr = 1;\r
-       conn->ack_nr = 0;\r
-       conn->max_window_user = 255 * PACKET_SIZE;\r
-       conn->addr = PackedSockAddr((const SOCKADDR_STORAGE*)addr, addrlen);\r
-       conn->send_to_proc = send_to_proc;\r
-       conn->send_to_userdata = send_to_userdata;\r
-       conn->ack_time = g_current_ms + 0x70000000;\r
-       conn->last_got_packet = g_current_ms;\r
-       conn->last_sent_packet = g_current_ms;\r
-       conn->last_measured_delay = g_current_ms + 0x70000000;\r
-       conn->last_rwin_decay = int32(g_current_ms) - MAX_WINDOW_DECAY;\r
-       conn->last_send_quota = g_current_ms;\r
-       conn->send_quota = PACKET_SIZE * 100;\r
-       conn->cur_window_packets = 0;\r
-       conn->fast_resend_seq_nr = conn->seq_nr;\r
-\r
-       // default to version 1\r
-       UTP_SetSockopt(conn, SO_UTPVERSION, 1);\r
-\r
-       // we need to fit one packet in the window\r
-       // when we start the connection\r
-       conn->max_window = conn->get_packet_size();\r
-       conn->state = CS_IDLE;\r
-\r
-       conn->outbuf.mask = 15;\r
-       conn->inbuf.mask = 15;\r
-\r
-       conn->outbuf.elements = (void**)calloc(16, sizeof(void*));\r
-       conn->inbuf.elements = (void**)calloc(16, sizeof(void*));\r
-\r
-       conn->idx = g_utp_sockets.Append(conn);\r
-\r
-       LOG_UTPV("0x%08x: UTP_Create", conn);\r
-\r
-       return conn;\r
-}\r
-\r
-void UTP_SetCallbacks(UTPSocket *conn, UTPFunctionTable *funcs, void *userdata)\r
-{\r
-       assert(conn);\r
-\r
-       if (funcs == NULL) {\r
-               funcs = &zero_funcs;\r
-       }\r
-       conn->func = *funcs;\r
-       conn->userdata = userdata;\r
-}\r
-\r
-bool UTP_SetSockopt(UTPSocket* conn, int opt, int val)\r
-{\r
-       assert(conn);\r
-\r
-       switch (opt) {\r
-       case SO_SNDBUF:\r
-               assert(val >= 1);\r
-               conn->opt_sndbuf = val;\r
-               return true;\r
-       case SO_RCVBUF:\r
-               conn->opt_rcvbuf = val;\r
-               return true;\r
-       case SO_UTPVERSION:\r
-               assert(conn->state == CS_IDLE);\r
-               if (conn->state != CS_IDLE) {\r
-                       // too late\r
-                       return false;\r
-               }\r
-               if (conn->version == 1 && val == 0) {\r
-                       conn->reply_micro = INT_MAX;\r
-                       conn->opt_rcvbuf = 200 * 1024;\r
-                       conn->opt_sndbuf = OUTGOING_BUFFER_MAX_SIZE * PACKET_SIZE;\r
-               } else if (conn->version == 0 && val == 1) {\r
-                       conn->reply_micro = 0;\r
-                       conn->opt_rcvbuf = 3 * 1024 * 1024 + 512 * 1024;\r
-                       conn->opt_sndbuf = conn->opt_rcvbuf;\r
-               }\r
-               conn->version = val;\r
-               return true;\r
-       }\r
-\r
-       return false;\r
-}\r
-\r
-// Try to connect to a specified host.\r
-// 'initial' is the number of data bytes to send in the connect packet.\r
-void UTP_Connect(UTPSocket *conn)\r
-{\r
-       assert(conn);\r
-\r
-       assert(conn->state == CS_IDLE);\r
-       assert(conn->cur_window_packets == 0);\r
-       assert(conn->outbuf.get(conn->seq_nr) == NULL);\r
-       assert(sizeof(PacketFormatV1) == 20);\r
-\r
-       conn->state = CS_SYN_SENT;\r
-\r
-       g_current_ms = UTP_GetMilliseconds();\r
-\r
-       // Create and send a connect message\r
-       uint32 conn_seed = UTP_Random();\r
-\r
-       // we identify newer versions by setting the\r
-       // first two bytes to 0x0001\r
-       if (conn->version > 0) {\r
-               conn_seed &= 0xffff;\r
-       }\r
-\r
-       // used in parse_log.py\r
-       LOG_UTP("0x%08x: UTP_Connect conn_seed:%u packet_size:%u (B) "\r
-                       "target_delay:%u (ms) delay_history:%u "\r
-                       "delay_base_history:%u (minutes)",\r
-                       conn, conn_seed, PACKET_SIZE, CCONTROL_TARGET / 1000,\r
-                       CUR_DELAY_SIZE, DELAY_BASE_HISTORY);\r
-\r
-       // Setup initial timeout timer.\r
-       conn->retransmit_timeout = 3000;\r
-       conn->rto_timeout = g_current_ms + conn->retransmit_timeout;\r
-       conn->last_rcv_win = conn->get_rcv_window();\r
-\r
-       conn->conn_seed = conn_seed;\r
-       conn->conn_id_recv = conn_seed;\r
-       conn->conn_id_send = conn_seed+1;\r
-       // if you need compatibiltiy with 1.8.1, use this. it increases attackability though.\r
-       //conn->seq_nr = 1;\r
-       conn->seq_nr = UTP_Random();\r
-\r
-       // Create the connect packet.\r
-       const size_t header_ext_size = conn->get_header_extensions_size();\r
-\r
-       OutgoingPacket *pkt = (OutgoingPacket*)malloc(sizeof(OutgoingPacket) - 1 + header_ext_size);\r
-\r
-       PacketFormatExtensions* p = (PacketFormatExtensions*)pkt->data;\r
-       PacketFormatExtensionsV1* p1 = (PacketFormatExtensionsV1*)pkt->data;\r
-\r
-       memset(p, 0, header_ext_size);\r
-       // SYN packets are special, and have the receive ID in the connid field,\r
-       // instead of conn_id_send.\r
-       if (conn->version == 0) {\r
-               p->pf.connid = conn->conn_id_recv;\r
-               p->pf.ext = 2;\r
-               p->pf.windowsize = (byte)DIV_ROUND_UP(conn->last_rcv_win, PACKET_SIZE);\r
-               p->pf.seq_nr = conn->seq_nr;\r
-               p->pf.flags = ST_SYN;\r
-               p->ext_next = 0;\r
-               p->ext_len = 8;\r
-               memset(p->extensions, 0, 8);\r
-       } else {\r
-               p1->pf.set_version(1);\r
-               p1->pf.set_type(ST_SYN);\r
-               p1->pf.ext = 2;\r
-               p1->pf.connid = conn->conn_id_recv;\r
-               p1->pf.windowsize = (uint32)conn->last_rcv_win;\r
-               p1->pf.seq_nr = conn->seq_nr;\r
-               p1->ext_next = 0;\r
-               p1->ext_len = 8;\r
-               memset(p1->extensions, 0, 8);\r
-       }\r
-       pkt->transmissions = 0;\r
-       pkt->length = header_ext_size;\r
-       pkt->payload = 0;\r
-\r
-       //LOG_UTPV("0x%08x: Sending connect %s [%u].",\r
-       //               conn, addrfmt(conn->addr, addrbuf), conn_seed);\r
-\r
-       // Remember the message in the outgoing queue.\r
-       conn->outbuf.ensure_size(conn->seq_nr, conn->cur_window_packets);\r
-       conn->outbuf.put(conn->seq_nr, pkt);\r
-       conn->seq_nr++;\r
-       conn->cur_window_packets++;\r
-\r
-       conn->send_packet(pkt);\r
-}\r
-\r
-bool UTP_IsIncomingUTP(UTPGotIncomingConnection *incoming_proc,\r
-                                          SendToProc *send_to_proc, void *send_to_userdata,\r
-                                          const byte *buffer, size_t len, const struct sockaddr *to, socklen_t tolen)\r
-{\r
-       const PackedSockAddr addr((const SOCKADDR_STORAGE*)to, tolen);\r
-\r
-       if (len < sizeof(PacketFormat) && len < sizeof(PacketFormatV1)) {\r
-               LOG_UTPV("recv %s len:%u too small", addrfmt(addr, addrbuf), (uint)len);\r
-               return false;\r
-       }\r
-\r
-       const PacketFormat* p = (PacketFormat*)buffer;\r
-       const PacketFormatV1* p1 = (PacketFormatV1*)buffer;\r
-\r
-       const byte version = UTP_IsV1(p1);\r
-       const uint32 id = (version == 0) ? p->connid : uint32(p1->connid);\r
-\r
-       if (version == 0 && len < sizeof(PacketFormat)) {\r
-               LOG_UTPV("recv %s len:%u version:%u too small", addrfmt(addr, addrbuf), (uint)len, version);\r
-               return false;\r
-       }\r
-\r
-       if (version == 1 && len < sizeof(PacketFormatV1)) {\r
-               LOG_UTPV("recv %s len:%u version:%u too small", addrfmt(addr, addrbuf), (uint)len, version);\r
-               return false;\r
-       }\r
-\r
-       LOG_UTPV("recv %s len:%u id:%u", addrfmt(addr, addrbuf), (uint)len, id);\r
-\r
-       const PacketFormat *pf = (PacketFormat*)p;\r
-       const PacketFormatV1 *pf1 = (PacketFormatV1*)p;\r
-\r
-       if (version == 0) {\r
-               LOG_UTPV("recv id:%u seq_nr:%u ack_nr:%u", id, (uint)pf->seq_nr, (uint)pf->ack_nr);\r
-       } else {\r
-               LOG_UTPV("recv id:%u seq_nr:%u ack_nr:%u", id, (uint)pf1->seq_nr, (uint)pf1->ack_nr);\r
-       }\r
-\r
-       const byte flags = version == 0 ? pf->flags : pf1->type();\r
-\r
-       for (size_t i = 0; i < g_utp_sockets.GetCount(); i++) {\r
-               UTPSocket *conn = g_utp_sockets[i];\r
-               //LOG_UTPV("Examining UTPSocket %s for %s and (seed:%u s:%u r:%u) for %u",\r
-               //              addrfmt(conn->addr, addrbuf), addrfmt(addr, addrbuf2), conn->conn_seed, conn->conn_id_send, conn->conn_id_recv, id);\r
-               if (conn->addr != addr)\r
-                       continue;\r
-\r
-               if (flags == ST_RESET && (conn->conn_id_send == id || conn->conn_id_recv == id)) {\r
-                       LOG_UTPV("0x%08x: recv RST for existing connection", conn);\r
-                       if (!conn->userdata || conn->state == CS_FIN_SENT) {\r
-                               conn->state = CS_DESTROY;\r
-                       } else {\r
-                               conn->state = CS_RESET;\r
-                       }\r
-                       if (conn->userdata) {\r
-                               conn->func.on_overhead(conn->userdata, false, len + conn->get_udp_overhead(),\r
-                                                                          close_overhead);\r
-                               const int err = conn->state == CS_SYN_SENT ?\r
-                                       ECONNREFUSED :\r
-                                       ECONNRESET;\r
-                               conn->func.on_error(conn->userdata, err);\r
-                       }\r
-                       return true;\r
-               } else if (flags != ST_SYN && conn->conn_id_recv == id) {\r
-                       LOG_UTPV("0x%08x: recv processing", conn);\r
-                       const size_t read = UTP_ProcessIncoming(conn, buffer, len);\r
-                       if (conn->userdata) {\r
-                               conn->func.on_overhead(conn->userdata, false,\r
-                                       (len - read) + conn->get_udp_overhead(),\r
-                                       header_overhead);\r
-                       }\r
-                       return true;\r
-               }\r
-       }\r
-\r
-       if (flags == ST_RESET) {\r
-               LOG_UTPV("recv RST for unknown connection");\r
-               return true;\r
-       }\r
-\r
-       const uint32 seq_nr = version == 0 ? pf->seq_nr : pf1->seq_nr;\r
-       if (flags != ST_SYN) {\r
-               for (size_t i = 0; i < g_rst_info.GetCount(); i++) {\r
-                       if (g_rst_info[i].connid != id)\r
-                               continue;\r
-                       if (g_rst_info[i].addr != addr)\r
-                               continue;\r
-                       if (seq_nr != g_rst_info[i].ack_nr)\r
-                               continue;\r
-                       g_rst_info[i].timestamp = UTP_GetMilliseconds();\r
-                       LOG_UTPV("recv not sending RST to non-SYN (stored)");\r
-                       return true;\r
-               }\r
-               if (g_rst_info.GetCount() > RST_INFO_LIMIT) {\r
-                       LOG_UTPV("recv not sending RST to non-SYN (limit at %u stored)", (uint)g_rst_info.GetCount());\r
-                       return true;\r
-               }\r
-               LOG_UTPV("recv send RST to non-SYN (%u stored)", (uint)g_rst_info.GetCount());\r
-               RST_Info &r = g_rst_info.Append();\r
-               r.addr = addr;\r
-               r.connid = id;\r
-               r.ack_nr = seq_nr;\r
-               r.timestamp = UTP_GetMilliseconds();\r
-\r
-               UTPSocket::send_rst(send_to_proc, send_to_userdata, addr, id, seq_nr, UTP_Random(), version);\r
-               return true;\r
-       }\r
-\r
-       if (incoming_proc) {\r
-               LOG_UTPV("Incoming connection from %s uTP version:%u", addrfmt(addr, addrbuf), version);\r
-\r
-               // Create a new UTP socket to handle this new connection\r
-               UTPSocket *conn = UTP_Create(send_to_proc, send_to_userdata, to, tolen);\r
-               // Need to track this value to be able to detect duplicate CONNECTs\r
-               conn->conn_seed = id;\r
-               // This is value that identifies this connection for them.\r
-               conn->conn_id_send = id;\r
-               // This is value that identifies this connection for us.\r
-               conn->conn_id_recv = id+1;\r
-               conn->ack_nr = seq_nr;\r
-               conn->seq_nr = UTP_Random();\r
-               conn->fast_resend_seq_nr = conn->seq_nr;\r
-\r
-               UTP_SetSockopt(conn, SO_UTPVERSION, version);\r
-               conn->state = CS_CONNECTED;\r
-\r
-               const size_t read = UTP_ProcessIncoming(conn, buffer, len, true);\r
-\r
-               LOG_UTPV("0x%08x: recv send connect ACK", conn);\r
-               conn->send_ack(true);\r
-\r
-               incoming_proc(send_to_userdata, conn);\r
-\r
-               // we report overhead after incoming_proc, because the callbacks are setup now\r
-               if (conn->userdata) {\r
-                       // SYN\r
-                       conn->func.on_overhead(conn->userdata, false, (len - read) + conn->get_udp_overhead(),\r
-                                                                  header_overhead);\r
-                       // SYNACK\r
-                       conn->func.on_overhead(conn->userdata, true, conn->get_overhead(),\r
-                                                                  ack_overhead);\r
-               }\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
-bool UTP_HandleICMP(const byte* buffer, size_t len, const struct sockaddr *to, socklen_t tolen)\r
-{\r
-       const PackedSockAddr addr((const SOCKADDR_STORAGE*)to, tolen);\r
-\r
-       // Want the whole packet so we have connection ID\r
-       if (len < sizeof(PacketFormat)) {\r
-               return false;\r
-       }\r
-\r
-       const PacketFormat* p = (PacketFormat*)buffer;\r
-       const PacketFormatV1* p1 = (PacketFormatV1*)buffer;\r
-\r
-       const byte version = UTP_IsV1(p1);\r
-       const uint32 id = (version == 0) ? p->connid : uint32(p1->connid);\r
-\r
-       for (size_t i = 0; i < g_utp_sockets.GetCount(); ++i) {\r
-               UTPSocket *conn = g_utp_sockets[i];\r
-               if (conn->addr == addr &&\r
-                       conn->conn_id_recv == id) {\r
-                       // Don't pass on errors for idle/closed connections\r
-                       if (conn->state != CS_IDLE) {\r
-                               if (!conn->userdata || conn->state == CS_FIN_SENT) {\r
-                                       LOG_UTPV("0x%08x: icmp packet causing socket destruction", conn);\r
-                                       conn->state = CS_DESTROY;\r
-                               } else {\r
-                                       conn->state = CS_RESET;\r
-                               }\r
-                               if (conn->userdata) {\r
-                                       const int err = conn->state == CS_SYN_SENT ?\r
-                                               ECONNREFUSED :\r
-                                               ECONNRESET;\r
-                                       LOG_UTPV("0x%08x: icmp packet causing error on socket:%d", conn, err);\r
-                                       conn->func.on_error(conn->userdata, err);\r
-                               }\r
-                       }\r
-                       return true;\r
-               }\r
-       }\r
-       return false;\r
-}\r
-\r
-// Write bytes to the UTP socket.\r
-// Returns true if the socket is still writable.\r
-bool UTP_Write(UTPSocket *conn, size_t bytes)\r
-{\r
-       assert(conn);\r
-\r
-#ifdef g_log_utp_verbose\r
-       size_t param = bytes;\r
-#endif\r
-\r
-       if (conn->state != CS_CONNECTED) {\r
-               LOG_UTPV("0x%08x: UTP_Write %u bytes = false (not CS_CONNECTED)", conn, (uint)bytes);\r
-               return false;\r
-       }\r
-\r
-       g_current_ms = UTP_GetMilliseconds();\r
-\r
-       conn->update_send_quota();\r
-\r
-       // don't send unless it will all fit in the window\r
-       size_t packet_size = conn->get_packet_size();\r
-       size_t num_to_send = min<size_t>(bytes, packet_size);\r
-       while (conn->is_writable(num_to_send)) {\r
-               // Send an outgoing packet.\r
-               // Also add it to the outgoing of packets that have been sent but not ACKed.\r
-\r
-               if (num_to_send == 0) {\r
-                       LOG_UTPV("0x%08x: UTP_Write %u bytes = true", conn, (uint)param);\r
-                       return true;\r
-               }\r
-               bytes -= num_to_send;\r
-\r
-               LOG_UTPV("0x%08x: Sending packet. seq_nr:%u ack_nr:%u wnd:%u/%u/%u rcv_win:%u size:%u quota:%d cur_window_packets:%u",\r
-                                conn, conn->seq_nr, conn->ack_nr,\r
-                                (uint)(conn->cur_window + num_to_send),\r
-                                (uint)conn->max_window, (uint)conn->max_window_user,\r
-                                (uint)conn->last_rcv_win, num_to_send, conn->send_quota / 100,\r
-                                conn->cur_window_packets);\r
-               conn->write_outgoing_packet(num_to_send, ST_DATA);\r
-               num_to_send = min<size_t>(bytes, packet_size);\r
-       }\r
-\r
-       // mark the socket as not being writable.\r
-       conn->state = CS_CONNECTED_FULL;\r
-       LOG_UTPV("0x%08x: UTP_Write %u bytes = false", conn, (uint)bytes);\r
-       return false;\r
-}\r
-\r
-void UTP_RBDrained(UTPSocket *conn)\r
-{\r
-       assert(conn);\r
-\r
-       const size_t rcvwin = conn->get_rcv_window();\r
-\r
-       if (rcvwin > conn->last_rcv_win) {\r
-               // If last window was 0 send ACK immediately, otherwise should set timer\r
-               if (conn->last_rcv_win == 0) {\r
-                       conn->send_ack();\r
-               } else {\r
-                       conn->ack_time = g_current_ms + min<uint>(conn->ack_time - g_current_ms, DELAYED_ACK_TIME_THRESHOLD);\r
-               }\r
-       }\r
-}\r
-\r
-void UTP_CheckTimeouts()\r
-{\r
-       g_current_ms = UTP_GetMilliseconds();\r
-\r
-       for (size_t i = 0; i < g_rst_info.GetCount(); i++) {\r
-               if ((int)(g_current_ms - g_rst_info[i].timestamp) >= RST_INFO_TIMEOUT) {\r
-                       g_rst_info.MoveUpLast(i);\r
-                       i--;\r
-               }\r
-       }\r
-       if (g_rst_info.GetCount() != g_rst_info.GetAlloc()) {\r
-               g_rst_info.Compact();\r
-       }\r
-\r
-       for (size_t i = 0; i != g_utp_sockets.GetCount(); i++) {\r
-               UTPSocket *conn = g_utp_sockets[i];\r
-               conn->check_timeouts();\r
-\r
-               // Check if the object was deleted\r
-               if (conn->state == CS_DESTROY) {\r
-                       LOG_UTPV("0x%08x: Destroying", conn);\r
-                       UTP_Free(conn);\r
-                       i--;\r
-               }\r
-       }\r
-}\r
-\r
-size_t UTP_GetPacketSize(UTPSocket *socket)\r
-{\r
-       return socket->get_packet_size();\r
-}\r
-\r
-void UTP_GetPeerName(UTPSocket *conn, struct sockaddr *addr, socklen_t *addrlen)\r
-{\r
-       assert(conn);\r
-\r
-       socklen_t len;\r
-       const SOCKADDR_STORAGE sa = conn->addr.get_sockaddr_storage(&len);\r
-       *addrlen = min(len, *addrlen);\r
-       memcpy(addr, &sa, *addrlen);\r
-}\r
-\r
-void UTP_GetDelays(UTPSocket *conn, int32 *ours, int32 *theirs, uint32 *age)\r
-{\r
-       assert(conn);\r
-\r
-       if (ours) *ours = conn->our_hist.get_value();\r
-       if (theirs) *theirs = conn->their_hist.get_value();\r
-       if (age) *age = g_current_ms - conn->last_measured_delay;\r
-}\r
-\r
-#ifdef _DEBUG\r
-void UTP_GetStats(UTPSocket *conn, UTPStats *stats)\r
-{\r
-       assert(conn);\r
-\r
-       *stats = conn->_stats;\r
-}\r
-#endif // _DEBUG\r
-\r
-void UTP_GetGlobalStats(UTPGlobalStats *stats)\r
-{\r
-       *stats = _global_stats;\r
-}\r
-\r
-// Close the UTP socket.\r
-// It is not valid for the upper layer to refer to socket after it is closed.\r
-// Data will keep to try being delivered after the close.\r
-void UTP_Close(UTPSocket *conn)\r
-{\r
-       assert(conn);\r
-\r
-       assert(conn->state != CS_DESTROY_DELAY && conn->state != CS_FIN_SENT && conn->state != CS_DESTROY);\r
-\r
-       LOG_UTPV("0x%08x: UTP_Close in state:%s", conn, statenames[conn->state]);\r
-\r
-       switch(conn->state) {\r
-       case CS_CONNECTED:\r
-       case CS_CONNECTED_FULL:\r
-               conn->state = CS_FIN_SENT;\r
-               conn->write_outgoing_packet(0, ST_FIN);\r
-               break;\r
-\r
-       case CS_SYN_SENT:\r
-               conn->rto_timeout = UTP_GetMilliseconds() + min<uint>(conn->rto * 2, 60);\r
-       case CS_GOT_FIN:\r
-               conn->state = CS_DESTROY_DELAY;\r
-               break;\r
-\r
-       default:\r
-               conn->state = CS_DESTROY;\r
-               break;\r
-       }\r
-}\r
diff --git a/third-party/libutp/utp.h b/third-party/libutp/utp.h
deleted file mode 100644 (file)
index 0086d4c..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef __UTP_H__\r
-#define __UTP_H__\r
-\r
-#include "utypes.h"\r
-\r
-#ifdef WIN32\r
-#define _CRT_SECURE_NO_DEPRECATE\r
-#define WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-#include <winsock2.h>\r
-#include <ws2tcpip.h>\r
-#pragma comment(lib,"ws2_32.lib")\r
-#else\r
-#include <stdlib.h>\r
-#include <sys/types.h>\r
-#include <sys/socket.h>\r
-#include <netinet/in.h>\r
-#include <arpa/inet.h>\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-struct UTPSocket;\r
-\r
-// Used to set sockopt on a uTP socket to set the version of uTP\r
-// to use for outgoing connections. This can only be called before\r
-// the uTP socket is connected\r
-#define SO_UTPVERSION 99\r
-\r
-enum {\r
-       // socket has reveived syn-ack (notification only for outgoing connection completion)\r
-       // this implies writability\r
-       UTP_STATE_CONNECT = 1,\r
-\r
-       // socket is able to send more data\r
-       UTP_STATE_WRITABLE = 2,\r
-\r
-       // connection closed\r
-       UTP_STATE_EOF = 3,\r
-\r
-       // socket is being destroyed, meaning all data has been sent if possible.\r
-       // it is not valid to refer to the socket after this state change occurs\r
-       UTP_STATE_DESTROYING = 4,\r
-};\r
-\r
-// Callbacks called by a uTP socket (register with UTP_SetCallbacks)\r
-\r
-// The uTP socket layer calls this when bytes have been received from the network.\r
-typedef void UTPOnReadProc(void *userdata, const byte *bytes, size_t count);\r
-\r
-// The uTP socket layer calls this to fill the outgoing buffer with bytes.\r
-// The uTP layer takes responsibility that those bytes will be delivered.\r
-typedef void UTPOnWriteProc(void *userdata, byte *bytes, size_t count);\r
-\r
-// The uTP socket layer calls this to retrieve number of bytes currently in read buffer\r
-typedef size_t UTPGetRBSize(void *userdata);\r
-\r
-// The uTP socket layer calls this whenever the socket becomes writable.\r
-typedef void UTPOnStateChangeProc(void *userdata, int state);\r
-\r
-// The uTP socket layer calls this when an error occurs on the socket.\r
-// These errors currently include ECONNREFUSED, ECONNRESET and ETIMEDOUT, but\r
-// could eventually include any BSD socket error.\r
-typedef void UTPOnErrorProc(void *userdata, int errcode);\r
-\r
-// The uTP socket layer calls this to report overhead statistics\r
-typedef void UTPOnOverheadProc(void *userdata, bool send, size_t count, int type);\r
-\r
-struct UTPFunctionTable {\r
-       UTPOnReadProc *on_read;\r
-       UTPOnWriteProc *on_write;\r
-       UTPGetRBSize *get_rb_size;\r
-       UTPOnStateChangeProc *on_state;\r
-       UTPOnErrorProc *on_error;\r
-       UTPOnOverheadProc *on_overhead;\r
-};\r
-\r
-\r
-// The uTP socket layer calls this when a new incoming uTP connection is established\r
-// this implies writability\r
-typedef void UTPGotIncomingConnection(void *userdata, struct UTPSocket* s);\r
-\r
-// The uTP socket layer calls this to send UDP packets\r
-typedef void SendToProc(void *userdata, const byte *p, size_t len, const struct sockaddr *to, socklen_t tolen);\r
-\r
-\r
-// Functions which can be called with a uTP socket\r
-\r
-// Create a uTP socket\r
-struct UTPSocket *UTP_Create(SendToProc *send_to_proc, void *send_to_userdata,\r
-                                         const struct sockaddr *addr, socklen_t addrlen);\r
-\r
-// Setup the callbacks - must be done before connect or on incoming connection\r
-void UTP_SetCallbacks(struct UTPSocket *socket, struct UTPFunctionTable *func, void *userdata);\r
-\r
-// Valid options include SO_SNDBUF, SO_RCVBUF and SO_UTPVERSION\r
-bool UTP_SetSockopt(struct UTPSocket *socket, int opt, int val);\r
-\r
-// Try to connect to a specified host.\r
-void UTP_Connect(struct UTPSocket *socket);\r
-\r
-// Process a UDP packet from the network. This will process a packet for an existing connection,\r
-// or create a new connection and call incoming_proc. Returns true if the packet was processed\r
-// in some way, false if the packet did not appear to be uTP.\r
-bool UTP_IsIncomingUTP(UTPGotIncomingConnection *incoming_proc,\r
-                                          SendToProc *send_to_proc, void *send_to_userdata,\r
-                                          const byte *buffer, size_t len, const struct sockaddr *to, socklen_t tolen);\r
-\r
-// Process an ICMP received UDP packet.\r
-bool UTP_HandleICMP(const byte* buffer, size_t len, const struct sockaddr *to, socklen_t tolen);\r
-\r
-// Write bytes to the uTP socket.\r
-// Returns true if the socket is still writable.\r
-bool UTP_Write(struct UTPSocket *socket, size_t count);\r
-\r
-// Notify the uTP socket of buffer drain\r
-void UTP_RBDrained(struct UTPSocket *socket);\r
-\r
-// Call periodically to process timeouts and other periodic events\r
-void UTP_CheckTimeouts(void);\r
-\r
-// Retrieves the peer address of the specified socket, stores this address in the\r
-// sockaddr structure pointed to by the addr argument, and stores the length of this\r
-// address in the object pointed to by the addrlen argument.\r
-void UTP_GetPeerName(struct UTPSocket *socket, struct sockaddr *addr, socklen_t *addrlen);\r
-\r
-void UTP_GetDelays(struct UTPSocket *socket, int32 *ours, int32 *theirs, uint32 *age);\r
-\r
-size_t UTP_GetPacketSize(struct UTPSocket *socket);\r
-\r
-#ifdef _DEBUG\r
-struct UTPStats {\r
-       uint64 _nbytes_recv;    // total bytes received\r
-       uint64 _nbytes_xmit;    // total bytes transmitted\r
-       uint32 _rexmit;         // retransmit counter\r
-       uint32 _fastrexmit;     // fast retransmit counter\r
-       uint32 _nxmit;          // transmit counter\r
-       uint32 _nrecv;          // receive counter (total)\r
-       uint32 _nduprecv;       // duplicate receive counter\r
-};\r
-\r
-// Get stats for UTP socket\r
-void UTP_GetStats(struct UTPSocket *socket, UTPStats *stats);\r
-#endif\r
-\r
-// Close the UTP socket.\r
-// It is not valid to issue commands for this socket after it is closed.\r
-// This does not actually destroy the socket until outstanding data is sent, at which\r
-// point the socket will change to the UTP_STATE_DESTROYING state.\r
-void UTP_Close(struct UTPSocket *socket);\r
-\r
-struct UTPGlobalStats {\r
-       uint32 _nraw_recv[5];   // total packets recieved less than 300/600/1200/MTU bytes fpr all connections (global)\r
-       uint32 _nraw_send[5];   // total packets sent less than 300/600/1200/MTU bytes for all connections (global)\r
-};\r
-\r
-void UTP_GetGlobalStats(struct UTPGlobalStats *stats);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif //__UTP_H__\r
diff --git a/third-party/libutp/utp_config.h b/third-party/libutp/utp_config.h
deleted file mode 100644 (file)
index 7ee870a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#define CCONTROL_TARGET (100 * 1000) // us
-#define RATE_CHECK_INTERVAL 10000 // ms
-#define DYNAMIC_PACKET_SIZE_ENABLED false
-#define DYNAMIC_PACKET_SIZE_FACTOR 2
-// This should return the global number of bytes sent, used for determining dynamic
-// packet size based on rate
-
-#warning implement this in libtransmission
-uint64 UTP_GetGlobalUTPBytesSent(const struct sockaddr *remote, socklen_t remotelen) { return 0; }
-
-enum bandwidth_type_t {
-       payload_bandwidth, connect_overhead,
-       close_overhead, ack_overhead,
-       header_overhead, retransmit_overhead
-};
-
-#ifdef WIN32
-#define I64u "%I64u"
-#else
-#define I64u "%Lu"
-#endif
-#ifdef WIN32
-#define snprintf _snprintf
-#endif
-
-#define g_log_utp 0
-#define g_log_utp_verbose 0
-void utp_log(char const* fmt, ...)
-{
-       /*
-       printf("[%u] ", UTP_GetMilliseconds());
-       va_list vl;
-       va_start(vl, fmt);
-       vprintf(fmt, vl);
-       va_end(vl);
-       puts("");
-       fflush(stdout);
-       */
-};
diff --git a/third-party/libutp/utp_config_example.h b/third-party/libutp/utp_config_example.h
deleted file mode 100644 (file)
index ea5b5c6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#define CCONTROL_TARGET (100 * 1000) // us\r
-#define RATE_CHECK_INTERVAL 10000 // ms\r
-#define DYNAMIC_PACKET_SIZE_ENABLED false\r
-#define DYNAMIC_PACKET_SIZE_FACTOR 2\r
-// This should return the global number of bytes sent, used for determining dynamic\r
-// packet size based on rate\r
-uint64 UTP_GetGlobalUTPBytesSent(const struct sockaddr *remote, socklen_t remotelen) { return 0; }\r
-\r
-enum bandwidth_type_t {\r
-       payload_bandwidth, connect_overhead,\r
-       close_overhead, ack_overhead,\r
-       header_overhead, retransmit_overhead\r
-};\r
-\r
-#ifdef WIN32\r
-#define I64u "%I64u"\r
-#else\r
-#define I64u "%Lu"\r
-#endif\r
-#ifdef WIN32\r
-#define snprintf _snprintf\r
-#endif\r
-\r
-#define g_log_utp 0\r
-#define g_log_utp_verbose 0\r
-void utp_log(char const* fmt, ...);\r
diff --git a/third-party/libutp/utp_utils.cpp b/third-party/libutp/utp_utils.cpp
deleted file mode 100644 (file)
index 5515e62..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-#include "StdAfx.h"\r
-\r
-#include "utypes.h"\r
-#include <assert.h>\r
-#include <stdlib.h>\r
-\r
-#ifdef WIN32\r
-\r
-#define WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-#include <winsock2.h>\r
-#include <ws2tcpip.h>\r
-\r
-typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);\r
-static GetTickCount64Proc *pt2GetTickCount64;\r
-static GetTickCount64Proc *pt2RealGetTickCount;\r
-\r
-static uint64 startPerformanceCounter;\r
-static uint64 startGetTickCount;\r
-// MSVC 6 standard doesn't like division with uint64s\r
-static double counterPerMicrosecond;\r
-\r
-uint64 UTGetTickCount64()\r
-{\r
-       if (pt2GetTickCount64) {\r
-               return pt2GetTickCount64();\r
-       }\r
-       if (pt2RealGetTickCount) {\r
-               uint64 v = pt2RealGetTickCount();\r
-               // fix return value from GetTickCount\r
-               return (DWORD)v | ((v >> 0x18) & 0xFFFFFFFF00000000);\r
-       }\r
-       return (uint64)GetTickCount();\r
-}\r
-\r
-void Time_Initialize()\r
-{\r
-       HMODULE kernel32 = GetModuleHandleA("kernel32.dll");\r
-       pt2GetTickCount64 = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount64");\r
-       // not a typo. GetTickCount actually returns 64 bits\r
-       pt2RealGetTickCount = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount");\r
-\r
-       uint64 frequency;\r
-       QueryPerformanceCounter((LARGE_INTEGER*)&startPerformanceCounter);\r
-       QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);\r
-       counterPerMicrosecond = (double)frequency / 1000000.0f;\r
-       startGetTickCount = UTGetTickCount64();\r
-}\r
-\r
-int64 abs64(int64 x) { return x < 0 ? -x : x; }\r
-\r
-static uint64 GetMicroseconds()\r
-{\r
-       static bool time_init = false;\r
-       if (!time_init) {\r
-               time_init = true;\r
-               Time_Initialize();\r
-       }\r
-\r
-       uint64 counter;\r
-       uint64 tick;\r
-\r
-       QueryPerformanceCounter((LARGE_INTEGER*) &counter);\r
-       tick = UTGetTickCount64();\r
-\r
-       // unfortunately, QueryPerformanceCounter is not guaranteed\r
-       // to be monotonic. Make it so.\r
-       int64 ret = (int64)(((int64)counter - (int64)startPerformanceCounter) / counterPerMicrosecond);\r
-       // if the QPC clock leaps more than one second off GetTickCount64()\r
-       // something is seriously fishy. Adjust QPC to stay monotonic\r
-       int64 tick_diff = tick - startGetTickCount;\r
-       if (abs64(ret / 100000 - tick_diff / 100) > 10) {\r
-               startPerformanceCounter -= (uint64)((int64)(tick_diff * 1000 - ret) * counterPerMicrosecond);\r
-               ret = (int64)((counter - startPerformanceCounter) / counterPerMicrosecond);\r
-       }\r
-       return ret;\r
-}\r
-\r
-#else //!WIN32\r
-\r
-#include <time.h>\r
-#include <sys/time.h>          // Linux needs both time.h and sys/time.h\r
-#include <stdlib.h>\r
-\r
-#include <unistd.h>\r
-#include <sys/socket.h>\r
-#include <arpa/inet.h>\r
-\r
-#if defined(__APPLE__)\r
-#include <mach/mach_time.h>\r
-\r
-static uint64 GetMicroseconds()\r
-{\r
-       // http://developer.apple.com/mac/library/qa/qa2004/qa1398.html\r
-       // http://www.macresearch.org/tutorial_performance_and_time\r
-       static mach_timebase_info_data_t sTimebaseInfo;\r
-       static uint64_t start_tick = 0;\r
-       uint64_t tick;\r
-       // Returns a counter in some fraction of a nanoseconds\r
-       tick = mach_absolute_time();  \r
-       if (sTimebaseInfo.denom == 0) {\r
-               // Get the timer ratio to convert mach_absolute_time to nanoseconds\r
-               mach_timebase_info(&sTimebaseInfo); \r
-               start_tick = tick;\r
-       }\r
-       // Calculate the elapsed time, convert it to microseconds and return it.\r
-       return ((tick - start_tick) * sTimebaseInfo.numer) / (sTimebaseInfo.denom * 1000);\r
-}\r
-\r
-#else //!__APPLE__\r
-\r
-/* Unfortunately, #ifdef CLOCK_MONOTONIC is not enough to make sure that\r
-   POSIX clocks work -- we could be running a recent libc with an ancient\r
-   kernel (think OpenWRT). -- jch */\r
-\r
-static uint64_t GetMicroseconds()\r
-{\r
-       static int have_posix_clocks = -1;\r
-       int rc;\r
-\r
-#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(CLOCK_MONOTONIC)\r
-       if (have_posix_clocks < 0) {\r
-               struct timespec ts;\r
-               rc = clock_gettime(CLOCK_MONOTONIC, &ts);\r
-               if (rc < 0) {\r
-                       have_posix_clocks = 0;\r
-               } else {\r
-                       have_posix_clocks = 1;\r
-               }\r
-       }\r
-\r
-       if (have_posix_clocks) {\r
-               struct timespec ts;\r
-               rc = clock_gettime(CLOCK_MONOTONIC, &ts);\r
-               return uint64(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;\r
-       }\r
-#endif\r
-       {\r
-               struct timeval tv;\r
-               rc = gettimeofday(&tv, NULL);\r
-               return uint64(tv.tv_sec) * 1000000 + tv.tv_usec;\r
-       }\r
-}\r
-#endif //!__APPLE__\r
-\r
-#endif //!WIN32\r
-\r
-uint64 UTP_GetMicroseconds()\r
-{\r
-       static uint64 offset = 0, previous = 0;\r
-\r
-       uint64 now = GetMicroseconds() + offset;\r
-       if (previous > now) {\r
-               /* Eek! */\r
-               offset += previous - now;\r
-               now = previous;\r
-       }\r
-       previous = now;\r
-       return now;\r
-}\r
-\r
-uint32 UTP_GetMilliseconds()\r
-{\r
-       return UTP_GetMicroseconds() / 1000;\r
-}\r
-\r
-\r
-#define ETHERNET_MTU 1500\r
-#define IPV4_HEADER_SIZE 20\r
-#define IPV6_HEADER_SIZE 40\r
-#define UDP_HEADER_SIZE 8\r
-#define GRE_HEADER_SIZE 24\r
-#define PPPOE_HEADER_SIZE 8\r
-#define MPPE_HEADER_SIZE 2\r
-// packets have been observed in the wild that were fragmented\r
-// with a payload of 1416 for the first fragment\r
-// There are reports of routers that have MTU sizes as small as 1392\r
-#define FUDGE_HEADER_SIZE 36\r
-#define TEREDO_MTU 1280\r
-\r
-#define UDP_IPV4_OVERHEAD (IPV4_HEADER_SIZE + UDP_HEADER_SIZE)\r
-#define UDP_IPV6_OVERHEAD (IPV6_HEADER_SIZE + UDP_HEADER_SIZE)\r
-#define UDP_TEREDO_OVERHEAD (UDP_IPV4_OVERHEAD + UDP_IPV6_OVERHEAD)\r
-\r
-#define UDP_IPV4_MTU (ETHERNET_MTU - IPV4_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE - FUDGE_HEADER_SIZE)\r
-#define UDP_IPV6_MTU (ETHERNET_MTU - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE - FUDGE_HEADER_SIZE)\r
-#define UDP_TEREDO_MTU (TEREDO_MTU - IPV6_HEADER_SIZE - UDP_HEADER_SIZE)\r
-\r
-uint16 UTP_GetUDPMTU(const struct sockaddr *remote, socklen_t remotelen)\r
-{\r
-       // Since we don't know the local address of the interface,\r
-       // be conservative and assume all IPv6 connections are Teredo.\r
-       return remote->sa_family == AF_INET6 ? UDP_TEREDO_MTU : UDP_IPV4_MTU;\r
-}\r
-\r
-uint16 UTP_GetUDPOverhead(const struct sockaddr *remote, socklen_t remotelen)\r
-{\r
-       // Since we don't know the local address of the interface,\r
-       // be conservative and assume all IPv6 connections are Teredo.\r
-       return remote->sa_family == AF_INET6 ? UDP_TEREDO_OVERHEAD : UDP_IPV4_OVERHEAD;\r
-}\r
-\r
-uint32 UTP_Random()\r
-{\r
-       return rand();\r
-}\r
-\r
-void UTP_DelaySample(const struct sockaddr *remote, int sample_ms) {}\r
-size_t UTP_GetPacketSize(const struct sockaddr *remote) { return 1500; }\r
-\r
diff --git a/third-party/libutp/utp_utils.h b/third-party/libutp/utp_utils.h
deleted file mode 100644 (file)
index 033984f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// This should return the MTU to the destination\r
-uint16 UTP_GetUDPMTU(const struct sockaddr *remote, socklen_t remotelen);\r
-// This should return the number of bytes of UDP overhead for one packet to the\r
-// destination, for overhead calculation only\r
-uint16 UTP_GetUDPOverhead(const struct sockaddr *remote, socklen_t remotelen);\r
-// This should return monotonically increasing milliseconds, start point does not matter\r
-uint32 UTP_GetMilliseconds();\r
-// This should return monotonically increasing microseconds, start point does not matter\r
-uint64 UTP_GetMicroseconds();\r
-// This should return a random uint32\r
-uint32 UTP_Random();\r
-// This is called every time we have a delay sample is made\r
-void UTP_DelaySample(const struct sockaddr *remote, int sample_ms);\r
-// Should return the max packet size to use when sending to the given address\r
-size_t UTP_GetPacketSize(const struct sockaddr *remote);\r
-\r
diff --git a/third-party/libutp/utypes.h b/third-party/libutp/utypes.h
deleted file mode 100644 (file)
index 79bafcd..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __UTYPES_H__\r
-#define __UTYPES_H__\r
-\r
-// standard types\r
-typedef unsigned char byte;\r
-typedef unsigned char uint8;\r
-typedef signed char int8;\r
-typedef unsigned short uint16;\r
-typedef signed short int16;\r
-typedef unsigned int uint;\r
-typedef unsigned int uint32;\r
-typedef signed int int32;\r
-\r
-#ifdef _MSC_VER\r
-typedef unsigned __int64 uint64;\r
-typedef signed __int64 int64;\r
-#else\r
-typedef unsigned long long uint64;\r
-typedef long long int64;\r
-#endif\r
-\r
-/* compile-time assert */\r
-#ifndef CASSERT\r
-#define CASSERT( exp, name ) typedef int is_not_##name [ (exp ) ? 1 : -1 ];\r
-#endif\r
-\r
-CASSERT(8 == sizeof(uint64), sizeof_uint64_is_8)\r
-CASSERT(8 == sizeof(int64), sizeof_int64_is_8)\r
-\r
-#ifndef INT64_MAX\r
-#define INT64_MAX 0x7fffffffffffffffLL\r
-#endif\r
-\r
-// always ANSI\r
-typedef const char * cstr;\r
-typedef char * str;\r
-\r
-#ifndef __cplusplus\r
-typedef uint8 bool;\r
-#endif\r
-\r
-#endif //__UTYPES_H__\r
diff --git a/third-party/miniupnp/Changelog.txt b/third-party/miniupnp/Changelog.txt
deleted file mode 100644 (file)
index 53e9a11..0000000
+++ /dev/null
@@ -1,585 +0,0 @@
-$Id: Changelog.txt,v 1.193 2014/02/05 17:26:45 nanard Exp $
-miniUPnP client Changelog.
-
-2014/02/05:
-  handle EINPROGRESS after connect()
-
-2014/02/03:
-  minixml now handle XML comments
-
-VERSION 1.9 : released 2014/01/31
-
-2014/01/31:
-  added argument remoteHost to UPNP_GetSpecificPortMappingEntry()
-  increment API_VERSION to 10
-
-2013/12/09:
-  --help and -h arguments in upnpc.c
-
-2013/10/07:
-  fixed potential buffer overrun in miniwget.c
-  Modified UPNP_GetValidIGD() to check for ExternalIpAddress
-
-2013/08/01:
-  define MAXHOSTNAMELEN if not already done
-
-2013/06/06:
-  update upnpreplyparse to allow larger values (128 chars instead of 64)
-
-2013/05/14:
-  Update upnpreplyparse to take into account "empty" elements
-  validate upnpreplyparse.c code with "make check"
-
-2013/05/03:
-  Fix Solaris build thanks to Maciej MaÅ‚ecki
-
-2013/04/27:
-  Fix testminiwget.sh for BSD
-
-2013/03/23:
-  Fixed Makefile for *BSD
-
-2013/03/11:
-  Update Makefile to use JNAerator version 0.11
-
-2013/02/11:
-  Fix testminiwget.sh for use with dash
-  Use $(DESTDIR) in Makefile
-
-VERSION 1.8 : released 2013/02/06
-
-2012/10/16:
-  fix testminiwget with no IPv6 support
-
-2012/09/27:
-  Rename all include guards to not clash with C99
-  (7.1.3 Reserved identifiers).
-
-2012/08/30:
-  Added -e option to upnpc program (set description for port mappings)
-
-2012/08/29:
-  Python 3 support (thanks to Christopher Foo)
-
-2012/08/11:
-  Fix a memory link in UPNP_GetValidIGD()
-  Try to handle scope id in link local IPv6 URL under MS Windows
-
-2012/07/20:
-  Disable HAS_IP_MREQN on DragonFly BSD
-
-2012/06/28:
-  GetUPNPUrls() now inserts scope into link-local IPv6 addresses
-
-2012/06/23:
-  More error return checks in upnpc.c
-  #define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
-  parseURL() now parses IPv6 addresses scope
-  new parameter for miniwget() : IPv6 address scope
-  increment API_VERSION to 9
-
-2012/06/20:
-  fixed CMakeLists.txt
-
-2012/05/29
-  Improvements in testminiwget.sh
-
-VERSION 1.7 : released 2012/05/24
-
-2012/05/01:
-  Cleanup settings of CFLAGS in Makefile
-  Fix signed/unsigned integer comparaisons
-
-2012/04/20:
-  Allow to specify protocol with TCP or UDP for -A option
-
-2012/04/09:
-  Only try to fetch XML description once in UPNP_GetValidIGD()
-  Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments.
-
-2012/04/05:
-  minor improvements to minihttptestserver.c
-
-2012/03/15:
-  upnperrors.c returns valid error string for unrecognized error codes
-
-2012/03/08:
-  make minihttptestserver listen on loopback interface instead of 0.0.0.0
-
-2012/01/25:
-  Maven installation thanks to Alexey Kuznetsov
-
-2012/01/21:
-  Replace WIN32 macro by _WIN32
-
-2012/01/19:
-  Fixes in java wrappers thanks to Alexey Kuznetsov :
-    https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc
-  Make and install .deb packages (python) thanks to Alexey Kuznetsov :
-    https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc
-
-2012/01/07:
-  The multicast interface can now be specified by name with IPv4.
-
-2012/01/02:
-  Install man page
-
-2011/11/25:
-  added header to Port Mappings list in upnpc.c
-
-2011/10/09:
-  Makefile : make clean now removes jnaerator generated files.
-  MINIUPNPC_VERSION in miniupnpc.h (updated by make)
-
-2011/09/12:
-  added rootdescURL to UPNPUrls structure.
-
-VERSION 1.6 : released 2011/07/25
-
-2011/07/25:
-  Update doc for version 1.6 release
-
-2011/06/18:
-  Fix for windows in miniwget.c
-
-2011/06/04:
-  display remote host in port mapping listing
-
-2011/06/03:
-  Fix in make install : there were missing headers
-
-2011/05/26:
-  Fix the socket leak in miniwget thanks to Richard Marsh.
-  Permit to add leaseduration in -a command. Display lease duration.
-
-2011/05/15:
-  Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6
-
-2011/05/09:
-  add a test in testminiwget.sh.
-  more error checking in miniwget.c
-
-2011/05/06:
-  Adding some tool to test and validate miniwget.c
-  simplified and debugged miniwget.c
-
-2011/04/11:
-  moving ReceiveData() to a receivedata.c file.
-  parsing presentation url
-  adding IGD v2 WANIPv6FirewallControl commands
-
-2011/04/10:
-  update of miniupnpcmodule.c
-  comments in miniwget.c, update in testminiwget
-  Adding errors codes from IGD v2
-  new functions in upnpc.c for IGD v2
-
-2011/04/09:
-  Support for litteral ip v6 address in miniwget
-
-2011/04/08:
-  Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
-  Updating APIVERSION
-  Supporting IPV6 in upnpDiscover()
-  Adding a -6 option to upnpc command line tool
-
-2011/03/18:
-  miniwget/parseURL() : return an error when url param is null.
-  fixing GetListOfPortMappings()
-
-2011/03/14:
-  upnpDiscover() now reporting an error code.
-  improvements in comments.
-
-2011/03/11:
-  adding miniupnpcstrings.h.cmake and CMakeLists.txt files.
-
-2011/02/15:
-  Implementation of GetListOfPortMappings()
-
-2011/02/07:
-  updates to minixml to support character data starting with spaces
-  minixml now support CDATA
-  upnpreplyparse treats <NewPortListing> specificaly
-  change in simpleUPnPcommand to return the buffer (simplification)
-
-2011/02/06:
-  Added leaseDuration argument to AddPortMapping()
-  Starting to implement GetListOfPortMappings()
-
-2011/01/11:
-  updating wingenminiupnpcstrings.c
-
-2011/01/04:
-  improving updateminiupnpcstrings.sh
-
-VERSION 1.5 : released 2011/01/01
-
-2010/12/21:
-  use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
-
-2010/12/11:
-  Improvements on getHTTPResponse() code.
-
-2010/12/09:
-  new code for miniwget that handle Chunked transfer encoding
-  using getHTTPResponse() in SOAP call code
-  Adding MANIFEST.in for 'python setup.py bdist_rpm'
-
-2010/11/25:
-  changes to minissdpc.c to compile under Win32.
-  see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729
-
-2010/09/17:
-  Various improvement to Makefile from MichaÅ‚ Górny
-
-2010/08/05:
-  Adding the script "external-ip.sh" from Reuben Hawkins
-
-2010/06/09:
-  update to python module to match modification made on 2010/04/05
-  update to Java test code to match modification made on 2010/04/05
-  all UPNP_* function now return an error if the SOAP request failed
-  at HTTP level.
-
-2010/04/17:
-  Using GetBestRoute() under win32 in order to find the
-  right interface to use.
-
-2010/04/12:
-  Retrying with HTTP/1.1 if HTTP/1.0 failed. see
-  http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703
-
-2010/04/07:
-  avoid returning duplicates in upnpDiscover()
-
-2010/04/05:
-  Create a connecthostport.h/.c with connecthostport() function
-  and use it in miniwget and miniupnpc.
-  Use getnameinfo() instead of inet_ntop or inet_ntoa
-  Work to make miniupnpc IPV6 compatible...
-  Add java test code.
-  Big changes in order to support device having both WANIPConnection
-  and WANPPPConnection.
-
-2010/04/04:
-  Use getaddrinfo() instead of gethostbyname() in miniwget.
-
-2010/01/06:
-  #define _DARWIN_C_SOURCE for Mac OS X
-
-2009/12/19:
-  Improve MinGW32 build
-
-2009/12/11:
-  adding a MSVC9 project to build the static library and executable
-
-2009/12/10:
-  Fixing some compilation stuff for Windows/MinGW
-
-2009/12/07:
-  adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS
-  some fixes for Windows when using virtual ethernet adapters (it is the
-  case with VMWare installed).
-
-2009/12/04:
-  some fixes for AmigaOS compilation
-  Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked
-  transfer encoding)
-
-2009/12/03:
-  updating printIDG and testigddescparse.c for debug.
-  modifications to compile under AmigaOS
-  adding a testminiwget program
-  Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked
-  transfer encoding
-
-2009/11/26:
-  fixing updateminiupnpcstrings.sh to take into account
-  which command that does not return an error code.
-
-VERSION 1.4 : released 2009/10/30
-
-2009/10/16:
-  using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module.
-
-2009/10/10:
-  Some fixes for compilation under Solaris
-  compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464
-
-2009/09/21:
-  fixing the code to ignore EINTR during connect() calls.
-
-2009/08/07:
-  Set socket timeout for connect()
-  Some cleanup in miniwget.c
-
-2009/08/04:
-  remove multiple redirections with -d in upnpc.c
-  Print textual error code in upnpc.c
-  Ignore EINTR during the connect() and poll() calls.
-
-2009/07/29:
-  fix in updateminiupnpcstrings.sh if OS name contains "/"
-  Sending a correct value for MX: field in SSDP request
-
-2009/07/20:
-  Change the Makefile to compile under Mac OS X
-  Fixed a stackoverflow in getDevicesFromMiniSSDPD()
-
-2009/07/09:
-  Compile under Haiku
-  generate miniupnpcstrings.h.in from miniupnpcstrings.h
-
-2009/06/04:
-  patching to compile under CygWin and cross compile for minGW
-
-VERSION 1.3 :
-
-2009/04/17:
-  updating python module
-  Use strtoull() when using C99
-
-2009/02/28:
-  Fixed miniwget.c for compiling under sun
-
-2008/12/18:
-  cleanup in Makefile (thanks to Paul de Weerd)
-  minissdpc.c : win32 compatibility
-  miniupnpc.c : changed xmlns prefix from 'm' to 'u'
-  Removed NDEBUG (using DEBUG)
-
-2008/10/14:
-  Added the ExternalHost argument to DeletePortMapping()
-
-2008/10/11:
-  Added the ExternalHost argument to AddPortMapping()
-  Put a correct User-Agent: header in HTTP requests.
-
-VERSION 1.2 :
-
-2008/10/07:
-  Update docs
-
-2008/09/25:
-  Integrated sameport patch from Dario Meloni : Added a "sameport"
-  argument to upnpDiscover().
-
-2008/07/18:
-  small modif to make Clang happy :)
-
-2008/07/17:
-  #define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
-
-2008/07/14:
-  include declspec.h in installation (to /usr/include/miniupnpc)
-
-VERSION 1.1 :
-
-2008/07/04:
-  standard options for install/ln instead of gnu-specific stuff.
-
-2008/07/03:
-  now builds a .dll and .lib with win32. (mingw32)
-
-2008/04/28:
-  make install now install the binary of the upnpc tool
-
-2008/04/27:
-  added testupnpigd.py
-  added error strings for miniupnpc "internal" errors
-  improved python module error/exception reporting.
-
-2008/04/23:
-  Completely rewrite igd_desc_parse.c in order to be compatible with
-  Linksys WAG200G
-  Added testigddescparse
-  updated python module
-
-VERSION 1.0 :
-
-2008/02/21:
-  put some #ifdef DEBUG around DisplayNameValueList()
-
-2008/02/18:
-  Improved error reporting in upnpcommands.c
-  UPNP_GetStatusInfo() returns LastConnectionError
-
-2008/02/16:
-  better error handling in minisoap.c
-  improving display of "valid IGD found" in upnpc.c
-
-2008/02/03:
-  Fixing UPNP_GetValidIGD()
-  improved make install :)
-
-2007/12/22:
-  Adding upnperrors.c/h to provide a strupnperror() function
-  used to translate UPnP error codes to string.
-
-2007/12/19:
-  Fixing getDevicesFromMiniSSDPD()
-  improved error reporting of UPnP functions
-
-2007/12/18:
-  It is now possible to specify a different location for MiniSSDPd socket.
-  working with MiniSSDPd is now more efficient.
-  python module improved.
-
-2007/12/16:
-  improving error reporting
-
-2007/12/13:
-  Try to improve compatibility by using HTTP/1.0 instead of 1.1 and
-  XML a bit different for SOAP.
-
-2007/11/25:
-  fixed select() call for linux
-
-2007/11/15:
-  Added -fPIC to CFLAG for better shared library code.
-
-2007/11/02:
-  Fixed a potential socket leak in miniwget2()
-
-2007/10/16:
-  added a parameter to upnpDiscover() in order to allow the use of another
-  interface than the default multicast interface.
-
-2007/10/12:
-  Fixed the creation of symbolic link in Makefile
-
-2007/10/08:
-  Added man page
-
-2007/10/02:
-  fixed memory bug in GetUPNPUrls()
-
-2007/10/01:
-  fixes in the Makefile
-  Added UPNP_GetIGDFromUrl() and adapted the sample program accordingly.
-  Added SONAME in the shared library to please debian :)
-  fixed MS Windows compilation (minissdpd is not available under MS Windows).
-
-2007/09/25:
-  small change to Makefile to be able to install in a different location
-  (default is /usr)
-
-2007/09/24:
-  now compiling both shared and static library
-
-2007/09/19:
-  Cosmetic changes on upnpc.c
-
-2007/09/02:
-  adapting to new miniSSDPd (release version ?)
-
-2007/08/31:
-  Usage of miniSSDPd to skip discovery process.
-
-2007/08/27:
-  fixed python module to allow compilation with Python older than Python 2.4
-
-2007/06/12:
-  Added a python module.
-
-2007/05/19:
-  Fixed compilation under MinGW
-
-2007/05/15:
-  fixed a memory leak in AddPortMapping()
-  Added testupnpreplyparse executable to check the parsing of
-  upnp soap messages
-  minixml now ignore namespace prefixes.
-
-2007/04/26:
-  upnpc now displays external ip address with -s or -l
-
-2007/04/11:
-  changed MINIUPNPC_URL_MAXSIZE to 128 to accomodate the "BT Voyager 210"
-
-2007/03/19:
-  cleanup in miniwget.c
-
-2007/03/01:
-  Small typo fix...
-
-2007/01/30:
-  Now parsing the HTTP header from SOAP responses in order to
-  get content-length value.
-
-2007/01/29:
-  Fixed the Soap Query to speedup the HTTP request.
-  added some Win32 DLL stuff...
-
-2007/01/27:
-  Fixed some WIN32 compatibility issues
-
-2006/12/14:
-  Added UPNPIGD_IsConnected() function in miniupnp.c/.h
-  Added UPNP_GetValidIGD() in miniupnp.c/.h
-  cleaned upnpc.c main(). now using UPNP_GetValidIGD()
-
-2006/12/07:
-  Version 1.0-RC1 released
-
-2006/12/03:
-  Minor changes to compile under SunOS/Solaris
-
-2006/11/30:
-  made a minixml parser validator program
-  updated minixml to handle attributes correctly
-
-2006/11/22:
-  Added a -r option to the upnpc sample thanks to Alexander Hubmann.
-
-2006/11/19:
-  Cleanup code to make it more ANSI C compliant
-
-2006/11/10:
-  detect and display local lan address.
-
-2006/11/04:
-  Packets and Bytes Sent/Received are now unsigned int.
-
-2006/11/01:
-  Bug fix thanks to Giuseppe D'Angelo
-
-2006/10/31:
-  C++ compatibility for .h files.
-  Added a way to get ip Address on the LAN used to reach the IGD.
-
-2006/10/25:
-  Added M-SEARCH to the services in the discovery process.
-
-2006/10/22:
-  updated the Makefile to use makedepend, added a "make install"
-  update Makefile
-
-2006/10/20:
-  fixing the description url parsing thanks to patch sent by
-  Wayne Dawe.
-  Fixed/translated some comments.
-  Implemented a better discover process, first looking
-  for IGD then for root devices (as some devices only reply to
-  M-SEARCH for root devices).
-
-2006/09/02:
-  added freeUPNPDevlist() function.
-
-2006/08/04:
-  More command line arguments checking
-
-2006/08/01:
-  Added the .bat file to compile under Win32 with minGW32
-
-2006/07/31:
-  Fixed the rootdesc parser (igd_desc_parse.c)
-
-2006/07/20:
-  parseMSEARCHReply() is now returning the ST: line as well
-  starting changes to detect several UPnP devices on the network
-
-2006/07/19:
-  using GetCommonLinkProperties to get down/upload bitrate
-
diff --git a/third-party/miniupnp/LICENSE b/third-party/miniupnp/LICENSE
deleted file mode 100644 (file)
index ac89a75..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-MiniUPnPc
-Copyright (c) 2005-2011, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/third-party/miniupnp/Makefile.am b/third-party/miniupnp/Makefile.am
deleted file mode 100644 (file)
index cc6edb1..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-noinst_LIBRARIES = libminiupnp.a
-
-AM_CFLAGS = @PTHREAD_CFLAGS@ -DNDEBUG -D_GNU_SOURCE
-
-libminiupnp_a_SOURCES = \
-    connecthostport.c \
-    igd_desc_parse.c \
-    minisoap.c \
-    minissdpc.c \
-    miniupnpc.c \
-    miniwget.c \
-    minixml.c \
-    portlistingparse.c \
-    receivedata.c \
-    upnpcommands.c \
-    upnpreplyparse.c
-
-noinst_HEADERS = \
-    bsdqueue.h \
-    codelength.h \
-    connecthostport.h \
-    declspec.h \
-    igd_desc_parse.h \
-    minisoap.h \
-    minissdpc.h \
-    miniupnpc.h \
-    miniupnpctypes.h \
-    miniwget.h \
-    minixml.h \
-    portlistingparse.h \
-    receivedata.h \
-    upnpcommands.h \
-    upnpreplyparse.h
-
-EXTRA_DIST = \
-    README \
-    LICENSE \
-    miniupnpcstrings.h.in \
-    updateminiupnpcstrings.sh
-
-BUILT_SOURCES = \
-    miniupnpcstrings.h
-
-miniupnpcstrings.h: Makefile
-       $(srcdir)/updateminiupnpcstrings.sh $(srcdir)/VERSION $(srcdir)/miniupnpcstrings.h.in $@
-
-DISTCLEANFILES = $(builddir)/miniupnpcstrings.h
diff --git a/third-party/miniupnp/README b/third-party/miniupnp/README
deleted file mode 100644 (file)
index b23478d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-Project: miniupnp
-Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
-github: https://github.com/miniupnp/miniupnp
-freecode: http://freecode.com/projects/miniupnp
-Author: Thomas Bernard
-Copyright (c) 2005-2012 Thomas Bernard
-This software is subject to the conditions detailed in the
-LICENSE file provided within this distribution.
-
-
-For the comfort of Win32 users, bsdqueue.h is included in the distribution.
-Its licence is included in the header of the file.
-bsdqueue.h is a copy of the sys/queue.h of an OpenBSD system.
-
-
-* miniUPnP Client - miniUPnPc *
-
-To compile, simply run 'gmake' (could be 'make' on your system).
-Under win32, to compile with MinGW, type "mingw32make.bat".
-MS Visual C solution and project files are supplied in the msvc/ subdirectory.
-
-The compilation is known to work under linux, FreeBSD,
-OpenBSD, MacOS X, AmigaOS and cygwin.
-The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
-upx (http://upx.sourceforge.net) is used to compress the win32 .exe files.
-
-To install the library and headers on the system use :
-> su
-> make install
-> exit
-
-alternatively, to install into a specific location, use :
-> INSTALLPREFIX=/usr/local make install
-
-upnpc.c is a sample client using the libminiupnpc.
-To use the libminiupnpc in your application, link it with
-libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h,
-upnpcommands.h and miniwget.h :
-- upnpDiscover()
-- miniwget()
-- parserootdesc()
-- GetUPNPUrls()
-- UPNP_* (calling UPNP methods)
-
-Note : use #include <miniupnpc/miniupnpc.h> etc... for the includes
-and -lminiupnpc for the link
-
-Discovery process is speeded up when MiniSSDPd is running on the machine.
-
-
-* Python module *
-
-you can build a python module with 'make pythonmodule'
-and install it with 'make installpythonmodule'.
-setup.py (and setupmingw32.py) are included in the distribution.
-
-
-Feel free to contact me if you have any problem :
-e-mail : miniupnp@free.fr
-
-If you are using libminiupnpc in your application, please
-send me an email !
-
-For any question, you can use the web forum :
-http://miniupnp.tuxfamily.org/forum/
-
diff --git a/third-party/miniupnp/VERSION b/third-party/miniupnp/VERSION
deleted file mode 100644 (file)
index d3bdbdf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1.7
diff --git a/third-party/miniupnp/apiversions.txt b/third-party/miniupnp/apiversions.txt
deleted file mode 100644 (file)
index 69f61c7..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-$Id: apiversions.txt,v 1.3 2014/01/31 13:14:32 nanard Exp $
-
-Differences in API between miniUPnPc versions
-
-====================== miniUPnPc version 1.9 ======================
-API version 10
-
-upnpcommands.h:
-  added argument remoteHost to UPNP_GetSpecificPortMappingEntry()
-
-miniupnpc.h:
-  updated macros :
-    #define MINIUPNPC_VERSION      "1.9"
-    #define MINIUPNPC_API_VERSION  10
-
-====================== miniUPnPc version 1.8 ======================
-API version 9
-
-miniupnpc.h:
-  updated macros :
-    #define MINIUPNPC_VERSION      "1.8"
-    #define MINIUPNPC_API_VERSION  9
-  added "unsigned int scope_id;" to struct UPNPDev
-  added scope_id argument to GetUPNPUrls()
-
-
-
-====================== miniUPnPc version 1.7 ======================
-API version 8
-
-miniupnpc.h :
-  add new macros :
-    #define MINIUPNPC_VERSION      "1.7"
-    #define MINIUPNPC_API_VERSION  8
-  add rootdescURL to struct UPNPUrls
-
-
-
-====================== miniUPnPc version 1.6 ======================
-API version 8
-
-Adding support for IPv6.
-igd_desc_parse.h :
-  struct IGDdatas_service :
-    add char presentationurl[MINIUPNPC_URL_MAXSIZE];
-  struct IGDdatas :
-    add struct IGDdatas_service IPv6FC;
-miniupnpc.h :
-  new macros :
-    #define UPNPDISCOVER_SUCCESS (0)
-    #define UPNPDISCOVER_UNKNOWN_ERROR (-1)
-    #define UPNPDISCOVER_SOCKET_ERROR (-101)
-    #define UPNPDISCOVER_MEMORY_ERROR (-102)
-  simpleUPnPcommand() prototype changed (but is normaly not used by API users)
-  add arguments ipv6 and error to upnpDiscover() :
-     struct UPNPDev *
-     upnpDiscover(int delay, const char * multicastif,
-                  const char * minissdpdsock, int sameport,
-                  int ipv6,
-                  int * error);
-  add controlURL_6FC member to struct UPNPUrls :
-    struct UPNPUrls {
-       char * controlURL;
-       char * ipcondescURL;
-       char * controlURL_CIF;
-       char * controlURL_6FC;
-    };
-
-upnpcommands.h :
-  add leaseDuration argument to UPNP_AddPortMapping()
-  add desc, enabled and leaseDuration arguments to UPNP_GetSpecificPortMappingEntry()
-  add UPNP_GetListOfPortMappings() function (IGDv2)
-  add IGDv2 IPv6 related functions :
-    UPNP_GetFirewallStatus()
-    UPNP_GetOutboundPinholeTimeout()
-    UPNP_AddPinhole()
-    UPNP_UpdatePinhole()
-    UPNP_DeletePinhole()
-    UPNP_CheckPinholeWorking()
-    UPNP_GetPinholePackets()
-
-
-
-====================== miniUPnPc version 1.5 ======================
-API version 5
-
-new function :
-int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
-new macro in upnpcommands.h :
-#define UPNPCOMMAND_HTTP_ERROR
-
-====================== miniUPnPc version 1.4 ======================
-Same API as version 1.3
-
-====================== miniUPnPc version 1.3 ======================
-API version 4
-
-Use UNSIGNED_INTEGER type for
-UPNP_GetTotalBytesSent(), UPNP_GetTotalBytesReceived(),
-UPNP_GetTotalPacketsSent(), UPNP_GetTotalPacketsReceived()
-Add remoteHost argument to UPNP_AddPortMapping() and UPNP_DeletePortMapping()
-
-====================== miniUPnPc version 1.2 ======================
-API version 3
-
-added sameport argument to upnpDiscover()
-struct UPNPDev *
-upnpDiscover(int delay, const char * multicastif,
-             const char * minissdpdsock, int sameport);
-
-====================== miniUPnPc Version 1.1 ======================
-Same API as 1.0
-
-
-====================== miniUPnPc Version 1.0 ======================
-API version 2
-
-
-struct UPNPDev {
-      struct UPNPDev * pNext;
-      char * descURL;
-      char * st;
-      char buffer[2];
-};
-struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
-                              const char * minissdpdsock);
-
diff --git a/third-party/miniupnp/bsdqueue.h b/third-party/miniupnp/bsdqueue.h
deleted file mode 100644 (file)
index c6afe1f..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/*     $OpenBSD: queue.h,v 1.31 2005/11/25 08:06:25 otto Exp $ */
-/*     $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $       */
-
-/*
- * Copyright (c) 1991, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *     @(#)queue.h     8.5 (Berkeley) 8/20/94
- */
-
-#ifndef        _SYS_QUEUE_H_
-#define        _SYS_QUEUE_H_
-
-/*
- * This file defines five types of data structures: singly-linked lists,
- * lists, simple queues, tail queues, and circular queues.
- *
- *
- * A singly-linked list is headed by a single forward pointer. The elements
- * are singly linked for minimum space and pointer manipulation overhead at
- * the expense of O(n) removal for arbitrary elements. New elements can be
- * added to the list after an existing element or at the head of the list.
- * Elements being removed from the head of the list should use the explicit
- * macro for this purpose for optimum efficiency. A singly-linked list may
- * only be traversed in the forward direction.  Singly-linked lists are ideal
- * for applications with large datasets and few or no removals or for
- * implementing a LIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A simple queue is headed by a pair of pointers, one the head of the
- * list and the other to the tail of the list. The elements are singly
- * linked to save space, so elements can only be removed from the
- * head of the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the
- * list. A simple queue may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-#ifdef QUEUE_MACRO_DEBUG
-#define _Q_INVALIDATE(a) (a) = ((void *)-1)
-#else
-#define _Q_INVALIDATE(a)
-#endif
-
-/*
- * Singly-linked List definitions.
- */
-#define SLIST_HEAD(name, type)                                         \
-struct name {                                                          \
-       struct type *slh_first; /* first element */                     \
-}
-
-#define        SLIST_HEAD_INITIALIZER(head)                                    \
-       { NULL }
-
-#ifdef SLIST_ENTRY
-#undef SLIST_ENTRY
-#endif
-
-#define SLIST_ENTRY(type)                                              \
-struct {                                                               \
-       struct type *sle_next;  /* next element */                      \
-}
-
-/*
- * Singly-linked List access methods.
- */
-#define        SLIST_FIRST(head)       ((head)->slh_first)
-#define        SLIST_END(head)         NULL
-#define        SLIST_EMPTY(head)       (SLIST_FIRST(head) == SLIST_END(head))
-#define        SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
-
-#define        SLIST_FOREACH(var, head, field)                                 \
-       for((var) = SLIST_FIRST(head);                                  \
-           (var) != SLIST_END(head);                                   \
-           (var) = SLIST_NEXT(var, field))
-
-#define        SLIST_FOREACH_PREVPTR(var, varp, head, field)                   \
-       for ((varp) = &SLIST_FIRST((head));                             \
-           ((var) = *(varp)) != SLIST_END(head);                       \
-           (varp) = &SLIST_NEXT((var), field))
-
-/*
- * Singly-linked List functions.
- */
-#define        SLIST_INIT(head) {                                              \
-       SLIST_FIRST(head) = SLIST_END(head);                            \
-}
-
-#define        SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
-       (elm)->field.sle_next = (slistelm)->field.sle_next;             \
-       (slistelm)->field.sle_next = (elm);                             \
-} while (0)
-
-#define        SLIST_INSERT_HEAD(head, elm, field) do {                        \
-       (elm)->field.sle_next = (head)->slh_first;                      \
-       (head)->slh_first = (elm);                                      \
-} while (0)
-
-#define        SLIST_REMOVE_NEXT(head, elm, field) do {                        \
-       (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;  \
-} while (0)
-
-#define        SLIST_REMOVE_HEAD(head, field) do {                             \
-       (head)->slh_first = (head)->slh_first->field.sle_next;          \
-} while (0)
-
-#define SLIST_REMOVE(head, elm, type, field) do {                      \
-       if ((head)->slh_first == (elm)) {                               \
-               SLIST_REMOVE_HEAD((head), field);                       \
-       } else {                                                        \
-               struct type *curelm = (head)->slh_first;                \
-                                                                       \
-               while (curelm->field.sle_next != (elm))                 \
-                       curelm = curelm->field.sle_next;                \
-               curelm->field.sle_next =                                \
-                   curelm->field.sle_next->field.sle_next;             \
-               _Q_INVALIDATE((elm)->field.sle_next);                   \
-       }                                                               \
-} while (0)
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type)                                          \
-struct name {                                                          \
-       struct type *lh_first;  /* first element */                     \
-}
-
-#define LIST_HEAD_INITIALIZER(head)                                    \
-       { NULL }
-
-#define LIST_ENTRY(type)                                               \
-struct {                                                               \
-       struct type *le_next;   /* next element */                      \
-       struct type **le_prev;  /* address of previous next element */  \
-}
-
-/*
- * List access methods
- */
-#define        LIST_FIRST(head)                ((head)->lh_first)
-#define        LIST_END(head)                  NULL
-#define        LIST_EMPTY(head)                (LIST_FIRST(head) == LIST_END(head))
-#define        LIST_NEXT(elm, field)           ((elm)->field.le_next)
-
-#define LIST_FOREACH(var, head, field)                                 \
-       for((var) = LIST_FIRST(head);                                   \
-           (var)!= LIST_END(head);                                     \
-           (var) = LIST_NEXT(var, field))
-
-/*
- * List functions.
- */
-#define        LIST_INIT(head) do {                                            \
-       LIST_FIRST(head) = LIST_END(head);                              \
-} while (0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do {                    \
-       if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
-               (listelm)->field.le_next->field.le_prev =               \
-                   &(elm)->field.le_next;                              \
-       (listelm)->field.le_next = (elm);                               \
-       (elm)->field.le_prev = &(listelm)->field.le_next;               \
-} while (0)
-
-#define        LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
-       (elm)->field.le_prev = (listelm)->field.le_prev;                \
-       (elm)->field.le_next = (listelm);                               \
-       *(listelm)->field.le_prev = (elm);                              \
-       (listelm)->field.le_prev = &(elm)->field.le_next;               \
-} while (0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do {                                \
-       if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
-               (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
-       (head)->lh_first = (elm);                                       \
-       (elm)->field.le_prev = &(head)->lh_first;                       \
-} while (0)
-
-#define LIST_REMOVE(elm, field) do {                                   \
-       if ((elm)->field.le_next != NULL)                               \
-               (elm)->field.le_next->field.le_prev =                   \
-                   (elm)->field.le_prev;                               \
-       *(elm)->field.le_prev = (elm)->field.le_next;                   \
-       _Q_INVALIDATE((elm)->field.le_prev);                            \
-       _Q_INVALIDATE((elm)->field.le_next);                            \
-} while (0)
-
-#define LIST_REPLACE(elm, elm2, field) do {                            \
-       if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)     \
-               (elm2)->field.le_next->field.le_prev =                  \
-                   &(elm2)->field.le_next;                             \
-       (elm2)->field.le_prev = (elm)->field.le_prev;                   \
-       *(elm2)->field.le_prev = (elm2);                                \
-       _Q_INVALIDATE((elm)->field.le_prev);                            \
-       _Q_INVALIDATE((elm)->field.le_next);                            \
-} while (0)
-
-/*
- * Simple queue definitions.
- */
-#define SIMPLEQ_HEAD(name, type)                                       \
-struct name {                                                          \
-       struct type *sqh_first; /* first element */                     \
-       struct type **sqh_last; /* addr of last next element */         \
-}
-
-#define SIMPLEQ_HEAD_INITIALIZER(head)                                 \
-       { NULL, &(head).sqh_first }
-
-#define SIMPLEQ_ENTRY(type)                                            \
-struct {                                                               \
-       struct type *sqe_next;  /* next element */                      \
-}
-
-/*
- * Simple queue access methods.
- */
-#define        SIMPLEQ_FIRST(head)         ((head)->sqh_first)
-#define        SIMPLEQ_END(head)           NULL
-#define        SIMPLEQ_EMPTY(head)         (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
-#define        SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
-
-#define SIMPLEQ_FOREACH(var, head, field)                              \
-       for((var) = SIMPLEQ_FIRST(head);                                \
-           (var) != SIMPLEQ_END(head);                                 \
-           (var) = SIMPLEQ_NEXT(var, field))
-
-/*
- * Simple queue functions.
- */
-#define        SIMPLEQ_INIT(head) do {                                         \
-       (head)->sqh_first = NULL;                                       \
-       (head)->sqh_last = &(head)->sqh_first;                          \
-} while (0)
-
-#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {                     \
-       if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)        \
-               (head)->sqh_last = &(elm)->field.sqe_next;              \
-       (head)->sqh_first = (elm);                                      \
-} while (0)
-
-#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {                     \
-       (elm)->field.sqe_next = NULL;                                   \
-       *(head)->sqh_last = (elm);                                      \
-       (head)->sqh_last = &(elm)->field.sqe_next;                      \
-} while (0)
-
-#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {           \
-       if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
-               (head)->sqh_last = &(elm)->field.sqe_next;              \
-       (listelm)->field.sqe_next = (elm);                              \
-} while (0)
-
-#define SIMPLEQ_REMOVE_HEAD(head, field) do {                  \
-       if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
-               (head)->sqh_last = &(head)->sqh_first;                  \
-} while (0)
-
-/*
- * Tail queue definitions.
- */
-#define TAILQ_HEAD(name, type)                                         \
-struct name {                                                          \
-       struct type *tqh_first; /* first element */                     \
-       struct type **tqh_last; /* addr of last next element */         \
-}
-
-#define TAILQ_HEAD_INITIALIZER(head)                                   \
-       { NULL, &(head).tqh_first }
-
-#define TAILQ_ENTRY(type)                                              \
-struct {                                                               \
-       struct type *tqe_next;  /* next element */                      \
-       struct type **tqe_prev; /* address of previous next element */  \
-}
-
-/*
- * tail queue access methods
- */
-#define        TAILQ_FIRST(head)               ((head)->tqh_first)
-#define        TAILQ_END(head)                 NULL
-#define        TAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
-#define TAILQ_LAST(head, headname)                                     \
-       (*(((struct headname *)((head)->tqh_last))->tqh_last))
-/* XXX */
-#define TAILQ_PREV(elm, headname, field)                               \
-       (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-#define        TAILQ_EMPTY(head)                                               \
-       (TAILQ_FIRST(head) == TAILQ_END(head))
-
-#define TAILQ_FOREACH(var, head, field)                                        \
-       for((var) = TAILQ_FIRST(head);                                  \
-           (var) != TAILQ_END(head);                                   \
-           (var) = TAILQ_NEXT(var, field))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field)              \
-       for((var) = TAILQ_LAST(head, headname);                         \
-           (var) != TAILQ_END(head);                                   \
-           (var) = TAILQ_PREV(var, headname, field))
-
-/*
- * Tail queue functions.
- */
-#define        TAILQ_INIT(head) do {                                           \
-       (head)->tqh_first = NULL;                                       \
-       (head)->tqh_last = &(head)->tqh_first;                          \
-} while (0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do {                       \
-       if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
-               (head)->tqh_first->field.tqe_prev =                     \
-                   &(elm)->field.tqe_next;                             \
-       else                                                            \
-               (head)->tqh_last = &(elm)->field.tqe_next;              \
-       (head)->tqh_first = (elm);                                      \
-       (elm)->field.tqe_prev = &(head)->tqh_first;                     \
-} while (0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do {                       \
-       (elm)->field.tqe_next = NULL;                                   \
-       (elm)->field.tqe_prev = (head)->tqh_last;                       \
-       *(head)->tqh_last = (elm);                                      \
-       (head)->tqh_last = &(elm)->field.tqe_next;                      \
-} while (0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \
-       if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-               (elm)->field.tqe_next->field.tqe_prev =                 \
-                   &(elm)->field.tqe_next;                             \
-       else                                                            \
-               (head)->tqh_last = &(elm)->field.tqe_next;              \
-       (listelm)->field.tqe_next = (elm);                              \
-       (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
-} while (0)
-
-#define        TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
-       (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
-       (elm)->field.tqe_next = (listelm);                              \
-       *(listelm)->field.tqe_prev = (elm);                             \
-       (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
-} while (0)
-
-#define TAILQ_REMOVE(head, elm, field) do {                            \
-       if (((elm)->field.tqe_next) != NULL)                            \
-               (elm)->field.tqe_next->field.tqe_prev =                 \
-                   (elm)->field.tqe_prev;                              \
-       else                                                            \
-               (head)->tqh_last = (elm)->field.tqe_prev;               \
-       *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
-       _Q_INVALIDATE((elm)->field.tqe_prev);                           \
-       _Q_INVALIDATE((elm)->field.tqe_next);                           \
-} while (0)
-
-#define TAILQ_REPLACE(head, elm, elm2, field) do {                     \
-       if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)   \
-               (elm2)->field.tqe_next->field.tqe_prev =                \
-                   &(elm2)->field.tqe_next;                            \
-       else                                                            \
-               (head)->tqh_last = &(elm2)->field.tqe_next;             \
-       (elm2)->field.tqe_prev = (elm)->field.tqe_prev;                 \
-       *(elm2)->field.tqe_prev = (elm2);                               \
-       _Q_INVALIDATE((elm)->field.tqe_prev);                           \
-       _Q_INVALIDATE((elm)->field.tqe_next);                           \
-} while (0)
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type)                                       \
-struct name {                                                          \
-       struct type *cqh_first;         /* first element */             \
-       struct type *cqh_last;          /* last element */              \
-}
-
-#define CIRCLEQ_HEAD_INITIALIZER(head)                                 \
-       { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
-
-#define CIRCLEQ_ENTRY(type)                                            \
-struct {                                                               \
-       struct type *cqe_next;          /* next element */              \
-       struct type *cqe_prev;          /* previous element */          \
-}
-
-/*
- * Circular queue access methods
- */
-#define        CIRCLEQ_FIRST(head)             ((head)->cqh_first)
-#define        CIRCLEQ_LAST(head)              ((head)->cqh_last)
-#define        CIRCLEQ_END(head)               ((void *)(head))
-#define        CIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
-#define        CIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
-#define        CIRCLEQ_EMPTY(head)                                             \
-       (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
-
-#define CIRCLEQ_FOREACH(var, head, field)                              \
-       for((var) = CIRCLEQ_FIRST(head);                                \
-           (var) != CIRCLEQ_END(head);                                 \
-           (var) = CIRCLEQ_NEXT(var, field))
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field)                      \
-       for((var) = CIRCLEQ_LAST(head);                                 \
-           (var) != CIRCLEQ_END(head);                                 \
-           (var) = CIRCLEQ_PREV(var, field))
-
-/*
- * Circular queue functions.
- */
-#define        CIRCLEQ_INIT(head) do {                                         \
-       (head)->cqh_first = CIRCLEQ_END(head);                          \
-       (head)->cqh_last = CIRCLEQ_END(head);                           \
-} while (0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {           \
-       (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
-       (elm)->field.cqe_prev = (listelm);                              \
-       if ((listelm)->field.cqe_next == CIRCLEQ_END(head))             \
-               (head)->cqh_last = (elm);                               \
-       else                                                            \
-               (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
-       (listelm)->field.cqe_next = (elm);                              \
-} while (0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {          \
-       (elm)->field.cqe_next = (listelm);                              \
-       (elm)->field.cqe_prev = (listelm)->field.cqe_prev;              \
-       if ((listelm)->field.cqe_prev == CIRCLEQ_END(head))             \
-               (head)->cqh_first = (elm);                              \
-       else                                                            \
-               (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
-       (listelm)->field.cqe_prev = (elm);                              \
-} while (0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {                     \
-       (elm)->field.cqe_next = (head)->cqh_first;                      \
-       (elm)->field.cqe_prev = CIRCLEQ_END(head);                      \
-       if ((head)->cqh_last == CIRCLEQ_END(head))                      \
-               (head)->cqh_last = (elm);                               \
-       else                                                            \
-               (head)->cqh_first->field.cqe_prev = (elm);              \
-       (head)->cqh_first = (elm);                                      \
-} while (0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {                     \
-       (elm)->field.cqe_next = CIRCLEQ_END(head);                      \
-       (elm)->field.cqe_prev = (head)->cqh_last;                       \
-       if ((head)->cqh_first == CIRCLEQ_END(head))                     \
-               (head)->cqh_first = (elm);                              \
-       else                                                            \
-               (head)->cqh_last->field.cqe_next = (elm);               \
-       (head)->cqh_last = (elm);                                       \
-} while (0)
-
-#define        CIRCLEQ_REMOVE(head, elm, field) do {                           \
-       if ((elm)->field.cqe_next == CIRCLEQ_END(head))                 \
-               (head)->cqh_last = (elm)->field.cqe_prev;               \
-       else                                                            \
-               (elm)->field.cqe_next->field.cqe_prev =                 \
-                   (elm)->field.cqe_prev;                              \
-       if ((elm)->field.cqe_prev == CIRCLEQ_END(head))                 \
-               (head)->cqh_first = (elm)->field.cqe_next;              \
-       else                                                            \
-               (elm)->field.cqe_prev->field.cqe_next =                 \
-                   (elm)->field.cqe_next;                              \
-       _Q_INVALIDATE((elm)->field.cqe_prev);                           \
-       _Q_INVALIDATE((elm)->field.cqe_next);                           \
-} while (0)
-
-#define CIRCLEQ_REPLACE(head, elm, elm2, field) do {                   \
-       if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==         \
-           CIRCLEQ_END(head))                                          \
-               (head).cqh_last = (elm2);                               \
-       else                                                            \
-               (elm2)->field.cqe_next->field.cqe_prev = (elm2);        \
-       if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==         \
-           CIRCLEQ_END(head))                                          \
-               (head).cqh_first = (elm2);                              \
-       else                                                            \
-               (elm2)->field.cqe_prev->field.cqe_next = (elm2);        \
-       _Q_INVALIDATE((elm)->field.cqe_prev);                           \
-       _Q_INVALIDATE((elm)->field.cqe_next);                           \
-} while (0)
-
-#endif /* !_SYS_QUEUE_H_ */
diff --git a/third-party/miniupnp/codelength.h b/third-party/miniupnp/codelength.h
deleted file mode 100644 (file)
index d342bd1..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $Id: codelength.h,v 1.4 2012/09/27 15:40:29 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas BERNARD
- * copyright (c) 2005-2011 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#ifndef CODELENGTH_H_INCLUDED
-#define CODELENGTH_H_INCLUDED
-
-/* Encode length by using 7bit per Byte :
- * Most significant bit of each byte specifies that the
- * following byte is part of the code */
-#define DECODELENGTH(n, p) n = 0; \
-                           do { n = (n << 7) | (*p & 0x7f); } \
-                           while((*(p++)&0x80) && (n<(1<<25)));
-
-#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \
-       n = 0; \
-       do { \
-               if((p) >= (p_limit)) break; \
-               n = (n << 7) | (*(p) & 0x7f); \
-       } while((*((p)++)&0x80) && (n<(1<<25)));
-
-#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
-                         if(n>=2097152) *(p++) = (n >> 21) | 0x80; \
-                         if(n>=16384) *(p++) = (n >> 14) | 0x80; \
-                         if(n>=128) *(p++) = (n >> 7) | 0x80; \
-                         *(p++) = n & 0x7f;
-
-#endif
-
diff --git a/third-party/miniupnp/connecthostport.c b/third-party/miniupnp/connecthostport.c
deleted file mode 100644 (file)
index d66ae31..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/* $Id: connecthostport.c,v 1.13 2014/03/31 12:36:36 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2010-2014 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-/* use getaddrinfo() or gethostbyname()
- * uncomment the following line in order to use gethostbyname() */
-#ifdef NO_GETADDRINFO
-#define USE_GETHOSTBYNAME
-#endif
-
-#include <string.h>
-#include <stdio.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#define MAXHOSTNAMELEN 64
-#define snprintf _snprintf
-#define herror
-#define socklen_t int
-#else /* #ifdef _WIN32 */
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/select.h>
-#include <errno.h>
-#define closesocket close
-#include <netdb.h>
-#include <netinet/in.h>
-/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
- * during the connect() call */
-#define MINIUPNPC_IGNORE_EINTR
-#ifndef USE_GETHOSTBYNAME
-#include <sys/types.h>
-#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());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#if defined(__amigaos__) || defined(__amigaos4__)
-#define herror(A) printf("%s\n", A)
-#endif
-
-#include "connecthostport.h"
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-/* connecthostport()
- * return a socket connected (TCP) to the host and port
- * or -1 in case of error */
-int connecthostport(const char * host, unsigned short port,
-                    unsigned int scope_id)
-{
-       int s, n;
-#ifdef USE_GETHOSTBYNAME
-       struct sockaddr_in dest;
-       struct hostent *hp;
-#else /* #ifdef USE_GETHOSTBYNAME */
-       char tmp_host[MAXHOSTNAMELEN+1];
-       char port_str[8];
-       struct addrinfo *ai, *p;
-       struct addrinfo hints;
-#endif /* #ifdef USE_GETHOSTBYNAME */
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-       struct timeval timeout;
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-
-#ifdef USE_GETHOSTBYNAME
-       hp = gethostbyname(host);
-       if(hp == NULL)
-       {
-               herror(host);
-               return -1;
-       }
-       memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
-       memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
-       s = socket(PF_INET, SOCK_STREAM, 0);
-       if(s < 0)
-       {
-               PRINT_SOCKET_ERROR("socket");
-               return -1;
-       }
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-       /* setting a 3 seconds timeout for the connect() call */
-       timeout.tv_sec = 3;
-       timeout.tv_usec = 0;
-       if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
-       {
-               PRINT_SOCKET_ERROR("setsockopt");
-       }
-       timeout.tv_sec = 3;
-       timeout.tv_usec = 0;
-       if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
-       {
-               PRINT_SOCKET_ERROR("setsockopt");
-       }
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-       dest.sin_family = AF_INET;
-       dest.sin_port = htons(port);
-       n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
-#ifdef MINIUPNPC_IGNORE_EINTR
-       /* EINTR The system call was interrupted by a signal that was caught
-        * EINPROGRESS The socket is nonblocking and the connection cannot
-        *             be completed immediately. */
-       while(n < 0 && (errno == EINTR || errno = EINPROGRESS))
-       {
-               socklen_t len;
-               fd_set wset;
-               int err;
-               FD_ZERO(&wset);
-               FD_SET(s, &wset);
-               if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
-                       continue;
-               /*len = 0;*/
-               /*n = getpeername(s, NULL, &len);*/
-               len = sizeof(err);
-               if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
-                       PRINT_SOCKET_ERROR("getsockopt");
-                       closesocket(s);
-                       return -1;
-               }
-               if(err != 0) {
-                       errno = err;
-                       n = -1;
-               }
-       }
-#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
-       if(n<0)
-       {
-               PRINT_SOCKET_ERROR("connect");
-               closesocket(s);
-               return -1;
-       }
-#else /* #ifdef USE_GETHOSTBYNAME */
-       /* use getaddrinfo() instead of gethostbyname() */
-       memset(&hints, 0, sizeof(hints));
-       /* hints.ai_flags = AI_ADDRCONFIG; */
-#ifdef AI_NUMERICSERV
-       hints.ai_flags = AI_NUMERICSERV;
-#endif
-       hints.ai_socktype = SOCK_STREAM;
-       hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
-       /* hints.ai_protocol = IPPROTO_TCP; */
-       snprintf(port_str, sizeof(port_str), "%hu", port);
-       if(host[0] == '[')
-       {
-               /* literal ip v6 address */
-               int i, j;
-               for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
-               {
-                       tmp_host[i] = host[j];
-                       if(0 == memcmp(host+j, "%25", 3))       /* %25 is just url encoding for '%' */
-                               j+=2;                                                   /* skip "25" */
-               }
-               tmp_host[i] = '\0';
-       }
-       else
-       {
-               strncpy(tmp_host, host, MAXHOSTNAMELEN);
-       }
-       tmp_host[MAXHOSTNAMELEN] = '\0';
-       n = getaddrinfo(tmp_host, port_str, &hints, &ai);
-       if(n != 0)
-       {
-#ifdef _WIN32
-               fprintf(stderr, "getaddrinfo() error : %d\n", n);
-#else
-               fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
-#endif
-               return -1;
-       }
-       s = -1;
-       for(p = ai; p; p = p->ai_next)
-       {
-               s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
-               if(s < 0)
-                       continue;
-               if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) {
-                       struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr;
-                       addr6->sin6_scope_id = scope_id;
-               }
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-               /* setting a 3 seconds timeout for the connect() call */
-               timeout.tv_sec = 3;
-               timeout.tv_usec = 0;
-               if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
-               {
-                       PRINT_SOCKET_ERROR("setsockopt");
-               }
-               timeout.tv_sec = 3;
-               timeout.tv_usec = 0;
-               if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
-               {
-                       PRINT_SOCKET_ERROR("setsockopt");
-               }
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-               n = connect(s, p->ai_addr, p->ai_addrlen);
-#ifdef MINIUPNPC_IGNORE_EINTR
-               /* EINTR The system call was interrupted by a signal that was caught
-                * EINPROGRESS The socket is nonblocking and the connection cannot
-                *             be completed immediately. */
-               while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
-               {
-                       socklen_t len;
-                       fd_set wset;
-                       int err;
-                       FD_ZERO(&wset);
-                       FD_SET(s, &wset);
-                       if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
-                               continue;
-                       /*len = 0;*/
-                       /*n = getpeername(s, NULL, &len);*/
-                       len = sizeof(err);
-                       if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
-                               PRINT_SOCKET_ERROR("getsockopt");
-                               closesocket(s);
-                               freeaddrinfo(ai);
-                               return -1;
-                       }
-                       if(err != 0) {
-                               errno = err;
-                               n = -1;
-                       }
-               }
-#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
-               if(n < 0)
-               {
-                       closesocket(s);
-                       continue;
-               }
-               else
-               {
-                       break;
-               }
-       }
-       freeaddrinfo(ai);
-       if(s < 0)
-       {
-               PRINT_SOCKET_ERROR("socket");
-               return -1;
-       }
-       if(n < 0)
-       {
-               PRINT_SOCKET_ERROR("connect");
-               return -1;
-       }
-#endif /* #ifdef USE_GETHOSTBYNAME */
-       return s;
-}
-
diff --git a/third-party/miniupnp/connecthostport.h b/third-party/miniupnp/connecthostport.h
deleted file mode 100644 (file)
index 56941d6..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* $Id: connecthostport.h,v 1.3 2012/09/27 15:42:10 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/
- * Author: Thomas Bernard
- * Copyright (c) 2010-2012 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef CONNECTHOSTPORT_H_INCLUDED
-#define CONNECTHOSTPORT_H_INCLUDED
-
-/* connecthostport()
- * return a socket connected (TCP) to the host and port
- * or -1 in case of error */
-int connecthostport(const char * host, unsigned short port,
-                    unsigned int scope_id);
-
-#endif
-
diff --git a/third-party/miniupnp/declspec.h b/third-party/miniupnp/declspec.h
deleted file mode 100644 (file)
index 7729969..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef DECLSPEC_H_INCLUDED
-#define DECLSPEC_H_INCLUDED
-
-#if defined(_WIN32) && !defined(STATICLIB)
-       /* for windows dll */
-       #ifdef MINIUPNP_EXPORTS
-               #define LIBSPEC __declspec(dllexport)
-       #else
-               #define LIBSPEC __declspec(dllimport)
-       #endif
-#else
-       #if defined(__GNUC__) && __GNUC__ >= 4
-               /* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */
-               #define LIBSPEC __attribute__ ((visibility ("default")))
-       #else
-               #define LIBSPEC
-       #endif
-#endif
-
-#endif
-
diff --git a/third-party/miniupnp/igd_desc_parse.c b/third-party/miniupnp/igd_desc_parse.c
deleted file mode 100644 (file)
index 6c3e656..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/* $Id: igd_desc_parse.c,v 1.14 2011/04/11 09:19:24 nanard Exp $ */
-/* Project : miniupnp
- * http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2010 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include "igd_desc_parse.h"
-#include <stdio.h>
-#include <string.h>
-
-/* Start element handler :
- * update nesting level counter and copy element name */
-void IGDstartelt(void * d, const char * name, int l)
-{
-       struct IGDdatas * datas = (struct IGDdatas *)d;
-       memcpy( datas->cureltname, name, l);
-       datas->cureltname[l] = '\0';
-       datas->level++;
-       if( (l==7) && !memcmp(name, "service", l) ) {
-               datas->tmp.controlurl[0] = '\0';
-               datas->tmp.eventsuburl[0] = '\0';
-               datas->tmp.scpdurl[0] = '\0';
-               datas->tmp.servicetype[0] = '\0';
-       }
-}
-
-/* End element handler :
- * update nesting level counter and update parser state if
- * service element is parsed */
-void IGDendelt(void * d, const char * name, int l)
-{
-       struct IGDdatas * datas = (struct IGDdatas *)d;
-       datas->level--;
-       /*printf("endelt %2d %.*s\n", datas->level, l, name);*/
-       if( (l==7) && !memcmp(name, "service", l) )
-       {
-               /*
-               if( datas->state < 1
-                       && !strcmp(datas->servicetype,
-                               //      "urn:schemas-upnp-org:service:WANIPConnection:1") )
-                               "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
-                       datas->state ++;
-               */
-               if(0==strcmp(datas->tmp.servicetype,
-                               "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1")) {
-                       memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
-               } else if(0==strcmp(datas->tmp.servicetype,
-                               "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1")) {
-                       memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service));
-               } else if(0==strcmp(datas->tmp.servicetype,
-                               "urn:schemas-upnp-org:service:WANIPConnection:1")
-                                || 0==strcmp(datas->tmp.servicetype,
-                               "urn:schemas-upnp-org:service:WANPPPConnection:1") ) {
-                       if(datas->first.servicetype[0] == '\0') {
-                               memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service));
-                       } else {
-                               memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service));
-                       }
-               }
-       }
-}
-
-/* Data handler :
- * copy data depending on the current element name and state */
-void IGDdata(void * d, const char * data, int l)
-{
-       struct IGDdatas * datas = (struct IGDdatas *)d;
-       char * dstmember = 0;
-       /*printf("%2d %s : %.*s\n",
-           datas->level, datas->cureltname, l, data);  */
-       if( !strcmp(datas->cureltname, "URLBase") )
-               dstmember = datas->urlbase;
-       else if( !strcmp(datas->cureltname, "presentationURL") )
-               dstmember = datas->presentationurl;
-       else if( !strcmp(datas->cureltname, "serviceType") )
-               dstmember = datas->tmp.servicetype;
-       else if( !strcmp(datas->cureltname, "controlURL") )
-               dstmember = datas->tmp.controlurl;
-       else if( !strcmp(datas->cureltname, "eventSubURL") )
-               dstmember = datas->tmp.eventsuburl;
-       else if( !strcmp(datas->cureltname, "SCPDURL") )
-               dstmember = datas->tmp.scpdurl;
-/*     else if( !strcmp(datas->cureltname, "deviceType") )
-               dstmember = datas->devicetype_tmp;*/
-       if(dstmember)
-       {
-               if(l>=MINIUPNPC_URL_MAXSIZE)
-                       l = MINIUPNPC_URL_MAXSIZE-1;
-               memcpy(dstmember, data, l);
-               dstmember[l] = '\0';
-       }
-}
-
-void printIGD(struct IGDdatas * d)
-{
-       printf("urlbase = '%s'\n", d->urlbase);
-       printf("WAN Device (Common interface config) :\n");
-       /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/
-       printf(" serviceType = '%s'\n", d->CIF.servicetype);
-       printf(" controlURL = '%s'\n", d->CIF.controlurl);
-       printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
-       printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
-       printf("primary WAN Connection Device (IP or PPP Connection):\n");
-       /*printf(" deviceType = '%s'\n", d->first.devicetype);*/
-       printf(" servicetype = '%s'\n", d->first.servicetype);
-       printf(" controlURL = '%s'\n", d->first.controlurl);
-       printf(" eventSubURL = '%s'\n", d->first.eventsuburl);
-       printf(" SCPDURL = '%s'\n", d->first.scpdurl);
-       printf("secondary WAN Connection Device (IP or PPP Connection):\n");
-       /*printf(" deviceType = '%s'\n", d->second.devicetype);*/
-       printf(" servicetype = '%s'\n", d->second.servicetype);
-       printf(" controlURL = '%s'\n", d->second.controlurl);
-       printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
-       printf(" SCPDURL = '%s'\n", d->second.scpdurl);
-       printf("WAN IPv6 Firewall Control :\n");
-       /*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/
-       printf(" servicetype = '%s'\n", d->IPv6FC.servicetype);
-       printf(" controlURL = '%s'\n", d->IPv6FC.controlurl);
-       printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl);
-       printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl);
-}
-
-
diff --git a/third-party/miniupnp/igd_desc_parse.h b/third-party/miniupnp/igd_desc_parse.h
deleted file mode 100644 (file)
index 0a49b01..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $Id: igd_desc_parse.h,v 1.11 2012/10/16 16:49:02 nanard Exp $ */
-/* Project : miniupnp
- * http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2010 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#ifndef IGD_DESC_PARSE_H_INCLUDED
-#define IGD_DESC_PARSE_H_INCLUDED
-
-/* Structure to store the result of the parsing of UPnP
- * descriptions of Internet Gateway Devices */
-#define MINIUPNPC_URL_MAXSIZE (128)
-struct IGDdatas_service {
-       char controlurl[MINIUPNPC_URL_MAXSIZE];
-       char eventsuburl[MINIUPNPC_URL_MAXSIZE];
-       char scpdurl[MINIUPNPC_URL_MAXSIZE];
-       char servicetype[MINIUPNPC_URL_MAXSIZE];
-       /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
-};
-
-struct IGDdatas {
-       char cureltname[MINIUPNPC_URL_MAXSIZE];
-       char urlbase[MINIUPNPC_URL_MAXSIZE];
-       char presentationurl[MINIUPNPC_URL_MAXSIZE];
-       int level;
-       /*int state;*/
-       /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
-       struct IGDdatas_service CIF;
-       /* "urn:schemas-upnp-org:service:WANIPConnection:1"
-        * "urn:schemas-upnp-org:service:WANPPPConnection:1" */
-       struct IGDdatas_service first;
-       /* if both WANIPConnection and WANPPPConnection are present */
-       struct IGDdatas_service second;
-       /* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
-       struct IGDdatas_service IPv6FC;
-       /* tmp */
-       struct IGDdatas_service tmp;
-};
-
-void IGDstartelt(void *, const char *, int);
-void IGDendelt(void *, const char *, int);
-void IGDdata(void *, const char *, int);
-void printIGD(struct IGDdatas *);
-
-#endif
-
diff --git a/third-party/miniupnp/minisoap.c b/third-party/miniupnp/minisoap.c
deleted file mode 100644 (file)
index e45a481..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $Id: minisoap.c,v 1.22 2012/01/21 13:30:31 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2012 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- *
- * Minimal SOAP implementation for UPnP protocol.
- */
-#include <stdio.h>
-#include <string.h>
-#ifdef _WIN32
-#include <io.h>
-#include <winsock2.h>
-#define snprintf _snprintf
-#else
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#endif
-#include "minisoap.h"
-#include "miniupnpcstrings.h"
-
-/* only for malloc */
-#include <stdlib.h>
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x)    printf("Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-/* httpWrite sends the headers and the body to the socket
- * and returns the number of bytes sent */
-static int
-httpWrite(int fd, const char * body, int bodysize,
-          const char * headers, int headerssize)
-{
-       int n = 0;
-       /*n = write(fd, headers, headerssize);*/
-       /*if(bodysize>0)
-               n += write(fd, body, bodysize);*/
-       /* Note : my old linksys router only took into account
-        * soap request that are sent into only one packet */
-       char * p;
-       /* TODO: AVOID MALLOC */
-       p = malloc(headerssize+bodysize);
-       if(!p)
-         return 0;
-       memcpy(p, headers, headerssize);
-       memcpy(p+headerssize, body, bodysize);
-       /*n = write(fd, p, headerssize+bodysize);*/
-       n = send(fd, p, headerssize+bodysize, 0);
-       if(n<0) {
-         PRINT_SOCKET_ERROR("send");
-       }
-       /* disable send on the socket */
-       /* draytek routers dont seems to like that... */
-#if 0
-#ifdef _WIN32
-       if(shutdown(fd, SD_SEND)<0) {
-#else
-       if(shutdown(fd, SHUT_WR)<0)     { /*SD_SEND*/
-#endif
-               PRINT_SOCKET_ERROR("shutdown");
-       }
-#endif
-       free(p);
-       return n;
-}
-
-/* self explanatory  */
-int soapPostSubmit(int fd,
-                   const char * url,
-                                  const char * host,
-                                  unsigned short port,
-                                  const char * action,
-                                  const char * body,
-                                  const char * httpversion)
-{
-       int bodysize;
-       char headerbuf[512];
-       int headerssize;
-       char portstr[8];
-       bodysize = (int)strlen(body);
-       /* We are not using keep-alive HTTP connections.
-        * HTTP/1.1 needs the header Connection: close to do that.
-        * This is the default with HTTP/1.0
-        * Using HTTP/1.1 means we need to support chunked transfer-encoding :
-        * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked
-        * transfer encoding. */
-    /* Connection: Close is normally there only in HTTP/1.1 but who knows */
-       portstr[0] = '\0';
-       if(port != 80)
-               snprintf(portstr, sizeof(portstr), ":%hu", port);
-       headerssize = snprintf(headerbuf, sizeof(headerbuf),
-                       "POST %s HTTP/%s\r\n"
-                          "Host: %s%s\r\n"
-                                          "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
-                          "Content-Length: %d\r\n"
-                                          "Content-Type: text/xml\r\n"
-                                          "SOAPAction: \"%s\"\r\n"
-                                          "Connection: Close\r\n"
-                                          "Cache-Control: no-cache\r\n"        /* ??? */
-                                          "Pragma: no-cache\r\n"
-                                          "\r\n",
-                                          url, httpversion, host, portstr, bodysize, action);
-#ifdef DEBUG
-       /*printf("SOAP request : headersize=%d bodysize=%d\n",
-              headerssize, bodysize);
-       */
-       printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n",
-               url, httpversion, host, portstr);
-       printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
-       printf("Headers :\n%s", headerbuf);
-       printf("Body :\n%s\n", body);
-#endif
-       return httpWrite(fd, body, bodysize, headerbuf, headerssize);
-}
-
-
diff --git a/third-party/miniupnp/minisoap.h b/third-party/miniupnp/minisoap.h
deleted file mode 100644 (file)
index 14c859d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: minisoap.h,v 1.5 2012/09/27 15:42:10 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-#ifndef MINISOAP_H_INCLUDED
-#define MINISOAP_H_INCLUDED
-
-/*int httpWrite(int, const char *, int, const char *);*/
-int soapPostSubmit(int, const char *, const char *, unsigned short,
-                  const char *, const char *, const char *);
-
-#endif
-
diff --git a/third-party/miniupnp/minissdpc.c b/third-party/miniupnp/minissdpc.c
deleted file mode 100644 (file)
index c4913fb..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* $Id: minissdpc.c,v 1.16 2012/03/05 19:42:46 nanard Exp $ */
-/* Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2012 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-/*#include <syslog.h>*/
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include <winsock.h>
-#include <stdint.h>
-#endif
-#if defined(__amigaos__) || defined(__amigaos4__)
-#include <sys/socket.h>
-#endif
-#if defined(__amigaos__)
-#define uint16_t unsigned short
-#endif
-/* Hack */
-#define UNIX_PATH_LEN   108
-struct sockaddr_un {
-  uint16_t sun_family;
-  char     sun_path[UNIX_PATH_LEN];
-};
-#else
-#include <sys/socket.h>
-#include <sys/un.h>
-#endif
-
-#include "minissdpc.h"
-#include "miniupnpc.h"
-
-#include "codelength.h"
-
-struct UPNPDev *
-getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
-{
-       struct UPNPDev * tmp;
-       struct UPNPDev * devlist = NULL;
-       unsigned char buffer[2048];
-       ssize_t n;
-       unsigned char * p;
-       unsigned char * url;
-       unsigned int i;
-       unsigned int urlsize, stsize, usnsize, l;
-       int s;
-       struct sockaddr_un addr;
-
-       s = socket(AF_UNIX, SOCK_STREAM, 0);
-       if(s < 0)
-       {
-               /*syslog(LOG_ERR, "socket(unix): %m");*/
-               perror("socket(unix)");
-               return NULL;
-       }
-       addr.sun_family = AF_UNIX;
-       strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
-       /* TODO : check if we need to handle the EINTR */
-       if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
-       {
-               /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
-               close(s);
-               return NULL;
-       }
-       stsize = strlen(devtype);
-       buffer[0] = 1; /* request type 1 : request devices/services by type */
-       p = buffer + 1;
-       l = stsize;     CODELENGTH(l, p);
-       if(p + stsize > buffer + sizeof(buffer))
-       {
-               /* devtype is too long ! */
-               close(s);
-               return NULL;
-       }
-       memcpy(p, devtype, stsize);
-       p += stsize;
-       if(write(s, buffer, p - buffer) < 0)
-       {
-               /*syslog(LOG_ERR, "write(): %m");*/
-               perror("minissdpc.c: write()");
-               close(s);
-               return NULL;
-       }
-       n = read(s, buffer, sizeof(buffer));
-       if(n<=0)
-       {
-               perror("minissdpc.c: read()");
-               close(s);
-               return NULL;
-       }
-       p = buffer + 1;
-       for(i = 0; i < buffer[0]; i++)
-       {
-               if(p+2>=buffer+sizeof(buffer))
-                       break;
-               DECODELENGTH(urlsize, p);
-               if(p+urlsize+2>=buffer+sizeof(buffer))
-                       break;
-               url = p;
-               p += urlsize;
-               DECODELENGTH(stsize, p);
-               if(p+stsize+2>=buffer+sizeof(buffer))
-                       break;
-               tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
-               tmp->pNext = devlist;
-               tmp->descURL = tmp->buffer;
-               tmp->st = tmp->buffer + 1 + urlsize;
-               memcpy(tmp->buffer, url, urlsize);
-               tmp->buffer[urlsize] = '\0';
-               memcpy(tmp->buffer + urlsize + 1, p, stsize);
-               p += stsize;
-               tmp->buffer[urlsize+1+stsize] = '\0';
-               devlist = tmp;
-               /* added for compatibility with recent versions of MiniSSDPd
-                * >= 2007/12/19 */
-               DECODELENGTH(usnsize, p);
-               p += usnsize;
-               if(p>buffer + sizeof(buffer))
-                       break;
-       }
-       close(s);
-       return devlist;
-}
-
diff --git a/third-party/miniupnp/minissdpc.h b/third-party/miniupnp/minissdpc.h
deleted file mode 100644 (file)
index 915b002..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: minissdpc.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2007 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINISSDPC_H_INCLUDED
-#define MINISSDPC_H_INCLUDED
-
-struct UPNPDev *
-getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath);
-
-#endif
-
diff --git a/third-party/miniupnp/miniupnpc.c b/third-party/miniupnp/miniupnpc.c
deleted file mode 100644 (file)
index 82e7535..0000000
+++ /dev/null
@@ -1,1046 +0,0 @@
-/* $Id: miniupnpc.c,v 1.117 2014/01/31 14:19:13 nanard Exp $ */
-/* Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2014 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENSE file. */
-#define __EXTENSIONS__ 1
-#if !defined(__APPLE__) && !defined(__sun)
-#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__)
-#ifndef __cplusplus
-#define _XOPEN_SOURCE 600
-#endif
-#endif
-#ifndef __BSD_VISIBLE
-#define __BSD_VISIBLE 1
-#endif
-#endif
-
-#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun)
-#define HAS_IP_MREQN
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef _WIN32
-/* Win32 Specific includes and defines */
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include <iphlpapi.h>
-#define snprintf _snprintf
-#define strdup _strdup
-#ifndef strncasecmp
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define strncasecmp _memicmp
-#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#define strncasecmp memicmp
-#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#endif /* #ifndef strncasecmp */
-#define MAXHOSTNAMELEN 64
-#else /* #ifdef _WIN32 */
-/* Standard POSIX includes */
-#include <unistd.h>
-#if defined(__amigaos__) && !defined(__amigaos4__)
-/* Amiga OS 3 specific stuff */
-#define socklen_t int
-#else
-#include <sys/select.h>
-#endif
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <net/if.h>
-#if !defined(__amigaos__) && !defined(__amigaos4__)
-#include <poll.h>
-#endif
-#include <strings.h>
-#include <errno.h>
-#define closesocket close
-#endif /* #else _WIN32 */
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-#include <sys/time.h>
-#endif
-#if defined(__amigaos__) || defined(__amigaos4__)
-/* Amiga OS specific stuff */
-#define TIMEVAL struct timeval
-#endif
-
-
-#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN)
-/* Several versions of glibc don't define this structure, define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */
-struct ip_mreqn
-{
-       struct in_addr  imr_multiaddr;          /* IP multicast address of group */
-       struct in_addr  imr_address;            /* local IP address of interface */
-       int             imr_ifindex;            /* Interface index */
-};
-#endif
-
-#include "miniupnpc.h"
-#include "minissdpc.h"
-#include "miniwget.h"
-#include "minisoap.h"
-#include "minixml.h"
-#include "upnpcommands.h"
-#include "connecthostport.h"
-#include "receivedata.h"
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x)    printf("Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#define SOAPPREFIX "s"
-#define SERVICEPREFIX "u"
-#define SERVICEPREFIX2 'u'
-
-/* root description parsing */
-LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
-{
-       struct xmlparser parser;
-       /* xmlparser object */
-       parser.xmlstart = buffer;
-       parser.xmlsize = bufsize;
-       parser.data = data;
-       parser.starteltfunc = IGDstartelt;
-       parser.endeltfunc = IGDendelt;
-       parser.datafunc = IGDdata;
-       parser.attfunc = 0;
-       parsexml(&parser);
-#ifdef DEBUG
-       printIGD(data);
-#endif
-}
-
-/* simpleUPnPcommand2 :
- * not so simple !
- * return values :
- *   pointer - OK
- *   NULL - error */
-static char * simpleUPnPcommand2(int s, const char * url, const char * service,
-                                 const char * action, struct UPNParg * args,
-                                 int * bufsize, const char * httpversion)
-{
-       char hostname[MAXHOSTNAMELEN+1];
-       unsigned short port = 0;
-       char * path;
-       char soapact[128];
-       char soapbody[2048];
-       char * buf;
-    int n;
-
-       *bufsize = 0;
-       snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
-       if(args==NULL)
-       {
-               /*soapbodylen = */snprintf(soapbody, sizeof(soapbody),
-                                               "<?xml version=\"1.0\"?>\r\n"
-                             "<" SOAPPREFIX ":Envelope "
-                                                 "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-                                                 SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
-                                                 "<" SOAPPREFIX ":Body>"
-                                                 "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">"
-                                                 "</" SERVICEPREFIX ":%s>"
-                                                 "</" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>"
-                                                 "\r\n", action, service, action);
-       }
-       else
-       {
-               char * p;
-               const char * pe, * pv;
-               int soapbodylen;
-               soapbodylen = snprintf(soapbody, sizeof(soapbody),
-                                               "<?xml version=\"1.0\"?>\r\n"
-                           "<" SOAPPREFIX ":Envelope "
-                                               "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-                                               SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
-                                               "<" SOAPPREFIX ":Body>"
-                                               "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">",
-                                               action, service);
-               p = soapbody + soapbodylen;
-               while(args->elt)
-               {
-                       /* check that we are never overflowing the string... */
-                       if(soapbody + sizeof(soapbody) <= p + 100)
-                       {
-                               /* we keep a margin of at least 100 bytes */
-                               return NULL;
-                       }
-                       *(p++) = '<';
-                       pe = args->elt;
-                       while(*pe)
-                               *(p++) = *(pe++);
-                       *(p++) = '>';
-                       if((pv = args->val))
-                       {
-                               while(*pv)
-                                       *(p++) = *(pv++);
-                       }
-                       *(p++) = '<';
-                       *(p++) = '/';
-                       pe = args->elt;
-                       while(*pe)
-                               *(p++) = *(pe++);
-                       *(p++) = '>';
-                       args++;
-               }
-               *(p++) = '<';
-               *(p++) = '/';
-               *(p++) = SERVICEPREFIX2;
-               *(p++) = ':';
-               pe = action;
-               while(*pe)
-                       *(p++) = *(pe++);
-               strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
-                       soapbody + sizeof(soapbody) - p);
-       }
-       if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
-       if(s < 0) {
-               s = connecthostport(hostname, port, 0);
-               if(s < 0) {
-                       /* failed to connect */
-                       return NULL;
-               }
-       }
-
-       n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion);
-       if(n<=0) {
-#ifdef DEBUG
-               printf("Error sending SOAP request\n");
-#endif
-               closesocket(s);
-               return NULL;
-       }
-
-       buf = getHTTPResponse(s, bufsize);
-#ifdef DEBUG
-       if(*bufsize > 0 && buf)
-       {
-               printf("SOAP Response :\n%.*s\n", *bufsize, buf);
-       }
-#endif
-       closesocket(s);
-       return buf;
-}
-
-/* simpleUPnPcommand :
- * not so simple !
- * return values :
- *   pointer - OK
- *   NULL    - error */
-char * simpleUPnPcommand(int s, const char * url, const char * service,
-                      const char * action, struct UPNParg * args,
-                      int * bufsize)
-{
-       char * buf;
-
-#if 1
-       buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
-#else
-       buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
-       if (!buf || *bufsize == 0)
-       {
-#if DEBUG
-           printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
-#endif
-               buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
-       }
-#endif
-       return buf;
-}
-
-/* parseMSEARCHReply()
- * the last 4 arguments are filled during the parsing :
- *    - location/locationsize : "location:" field of the SSDP reply packet
- *    - st/stsize : "st:" field of the SSDP reply packet.
- * The strings are NOT null terminated */
-static void
-parseMSEARCHReply(const char * reply, int size,
-                  const char * * location, int * locationsize,
-                             const char * * st, int * stsize)
-{
-       int a, b, i;
-       i = 0;
-       a = i;  /* start of the line */
-       b = 0;  /* end of the "header" (position of the colon) */
-       while(i<size)
-       {
-               switch(reply[i])
-               {
-               case ':':
-                               if(b==0)
-                               {
-                                       b = i; /* end of the "header" */
-                                       /*for(j=a; j<b; j++)
-                                       {
-                                               putchar(reply[j]);
-                                       }
-                                       */
-                               }
-                               break;
-               case '\x0a':
-               case '\x0d':
-                               if(b!=0)
-                               {
-                                       /*for(j=b+1; j<i; j++)
-                                       {
-                                               putchar(reply[j]);
-                                       }
-                                       putchar('\n');*/
-                                       /* skip the colon and white spaces */
-                                       do { b++; } while(reply[b]==' ');
-                                       if(0==strncasecmp(reply+a, "location", 8))
-                                       {
-                                               *location = reply+b;
-                                               *locationsize = i-b;
-                                       }
-                                       else if(0==strncasecmp(reply+a, "st", 2))
-                                       {
-                                               *st = reply+b;
-                                               *stsize = i-b;
-                                       }
-                                       b = 0;
-                               }
-                               a = i+1;
-                               break;
-               default:
-                               break;
-               }
-               i++;
-       }
-}
-
-/* port upnp discover : SSDP protocol */
-#define PORT 1900
-#define XSTR(s) STR(s)
-#define STR(s) #s
-#define UPNP_MCAST_ADDR "239.255.255.250"
-/* for IPv6 */
-#define UPNP_MCAST_LL_ADDR "FF02::C" /* link-local */
-#define UPNP_MCAST_SL_ADDR "FF05::C" /* site-local */
-
-/* upnpDiscover() :
- * return a chained list of all devices found or NULL if
- * no devices was found.
- * It is up to the caller to free the chained list
- * delay is in millisecond (poll) */
-LIBSPEC struct UPNPDev *
-upnpDiscover(int delay, const char * multicastif,
-             const char * minissdpdsock, int sameport,
-             int ipv6,
-             int * error)
-{
-       struct UPNPDev * tmp;
-       struct UPNPDev * devlist = 0;
-       unsigned int scope_id = 0;
-       int opt = 1;
-       static const char MSearchMsgFmt[] =
-       "M-SEARCH * HTTP/1.1\r\n"
-       "HOST: %s:" XSTR(PORT) "\r\n"
-       "ST: %s\r\n"
-       "MAN: \"ssdp:discover\"\r\n"
-       "MX: %u\r\n"
-       "\r\n";
-       static const char * const deviceList[] = {
-#if 0
-               "urn:schemas-upnp-org:device:InternetGatewayDevice:2",
-               "urn:schemas-upnp-org:service:WANIPConnection:2",
-#endif
-               "urn:schemas-upnp-org:device:InternetGatewayDevice:1",
-               "urn:schemas-upnp-org:service:WANIPConnection:1",
-               "urn:schemas-upnp-org:service:WANPPPConnection:1",
-               "upnp:rootdevice",
-               0
-       };
-       int deviceIndex = 0;
-       char bufr[1536];        /* reception and emission buffer */
-       int sudp;
-       int n;
-       struct sockaddr_storage sockudp_r;
-       unsigned int mx;
-#ifdef NO_GETADDRINFO
-       struct sockaddr_storage sockudp_w;
-#else
-       int rv;
-       struct addrinfo hints, *servinfo, *p;
-#endif
-#ifdef _WIN32
-       MIB_IPFORWARDROW ip_forward;
-#endif
-       int linklocal = 1;
-
-       if(error)
-               *error = UPNPDISCOVER_UNKNOWN_ERROR;
-#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
-       /* first try to get infos from minissdpd ! */
-       if(!minissdpdsock)
-               minissdpdsock = "/var/run/minissdpd.sock";
-       while(!devlist && deviceList[deviceIndex]) {
-               devlist = getDevicesFromMiniSSDPD(deviceList[deviceIndex],
-                                                 minissdpdsock);
-               /* We return what we have found if it was not only a rootdevice */
-               if(devlist && !strstr(deviceList[deviceIndex], "rootdevice")) {
-                       if(error)
-                               *error = UPNPDISCOVER_SUCCESS;
-                       return devlist;
-               }
-               deviceIndex++;
-       }
-       deviceIndex = 0;
-#endif
-       /* fallback to direct discovery */
-#ifdef _WIN32
-       sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-#else
-       sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
-#endif
-       if(sudp < 0)
-       {
-               if(error)
-                       *error = UPNPDISCOVER_SOCKET_ERROR;
-               PRINT_SOCKET_ERROR("socket");
-               return NULL;
-       }
-       /* reception */
-       memset(&sockudp_r, 0, sizeof(struct sockaddr_storage));
-       if(ipv6) {
-               struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
-               p->sin6_family = AF_INET6;
-               if(sameport)
-                       p->sin6_port = htons(PORT);
-               p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */
-       } else {
-               struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
-               p->sin_family = AF_INET;
-               if(sameport)
-                       p->sin_port = htons(PORT);
-               p->sin_addr.s_addr = INADDR_ANY;
-       }
-#ifdef _WIN32
-/* This code could help us to use the right Network interface for
- * SSDP multicast traffic */
-/* Get IP associated with the index given in the ip_forward struct
- * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
-       if(!ipv6
-          && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) {
-               DWORD dwRetVal = 0;
-               PMIB_IPADDRTABLE pIPAddrTable;
-               DWORD dwSize = 0;
-#ifdef DEBUG
-               IN_ADDR IPAddr;
-#endif
-               int i;
-#ifdef DEBUG
-               printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop);
-#endif
-               pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE));
-               if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
-                       free(pIPAddrTable);
-                       pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize);
-               }
-               if(pIPAddrTable) {
-                       dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
-#ifdef DEBUG
-                       printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries);
-#endif
-                       for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) {
-#ifdef DEBUG
-                               printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex);
-                               IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr;
-                               printf("\tIP Address[%d]:     \t%s\n", i, inet_ntoa(IPAddr) );
-                               IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask;
-                               printf("\tSubnet Mask[%d]:    \t%s\n", i, inet_ntoa(IPAddr) );
-                               IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr;
-                               printf("\tBroadCast[%d]:      \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr);
-                               printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize);
-                               printf("\tType and State[%d]:", i);
-                               printf("\n");
-#endif
-                               if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) {
-                                       /* Set the address of this interface to be used */
-                                       struct in_addr mc_if;
-                                       memset(&mc_if, 0, sizeof(mc_if));
-                                       mc_if.s_addr = pIPAddrTable->table[i].dwAddr;
-                                       if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) {
-                                               PRINT_SOCKET_ERROR("setsockopt");
-                                       }
-                                       ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr;
-#ifndef DEBUG
-                                       break;
-#endif
-                               }
-                       }
-                       free(pIPAddrTable);
-                       pIPAddrTable = NULL;
-               }
-       }
-#endif
-
-#ifdef _WIN32
-       if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
-#else
-       if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
-#endif
-       {
-               if(error)
-                       *error = UPNPDISCOVER_SOCKET_ERROR;
-               PRINT_SOCKET_ERROR("setsockopt");
-               return NULL;
-       }
-
-       if(multicastif)
-       {
-               if(ipv6) {
-#if !defined(_WIN32)
-                       /* according to MSDN, if_nametoindex() is supported since
-                        * MS Windows Vista and MS Windows Server 2008.
-                        * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
-                       unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */
-                       if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(&ifindex)) < 0)
-                       {
-                               PRINT_SOCKET_ERROR("setsockopt");
-                       }
-#else
-#ifdef DEBUG
-                       printf("Setting of multicast interface not supported in IPv6 under Windows.\n");
-#endif
-#endif
-               } else {
-                       struct in_addr mc_if;
-                       mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
-                       if(mc_if.s_addr != INADDR_NONE)
-                       {
-                               ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
-                               if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
-                               {
-                                       PRINT_SOCKET_ERROR("setsockopt");
-                               }
-                       } else {
-#ifdef HAS_IP_MREQN
-                               /* was not an ip address, try with an interface name */
-                               struct ip_mreqn reqn;   /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */
-                               memset(&reqn, 0, sizeof(struct ip_mreqn));
-                               reqn.imr_ifindex = if_nametoindex(multicastif);
-                               if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0)
-                               {
-                                       PRINT_SOCKET_ERROR("setsockopt");
-                               }
-#else
-#ifdef DEBUG
-                               printf("Setting of multicast interface not supported with interface name.\n");
-#endif
-#endif
-                       }
-               }
-       }
-
-       /* Before sending the packed, we first "bind" in order to be able
-        * to receive the response */
-    if (bind(sudp, (const struct sockaddr *)&sockudp_r,
-                ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0)
-       {
-               if(error)
-                       *error = UPNPDISCOVER_SOCKET_ERROR;
-        PRINT_SOCKET_ERROR("bind");
-               closesocket(sudp);
-               return NULL;
-    }
-
-       if(error)
-               *error = UPNPDISCOVER_SUCCESS;
-       /* Calculating maximum response time in seconds */
-       mx = ((unsigned int)delay) / 1000u;
-       if(mx == 0) {
-               mx = 1;
-               delay = 1000;
-       }
-       /* receiving SSDP response packet */
-       for(n = 0; deviceList[deviceIndex]; deviceIndex++)
-       {
-       if(n == 0)
-       {
-               /* sending the SSDP M-SEARCH packet */
-               n = snprintf(bufr, sizeof(bufr),
-                            MSearchMsgFmt,
-                            ipv6 ?
-                            (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" :  "[" UPNP_MCAST_SL_ADDR "]")
-                            : UPNP_MCAST_ADDR,
-                            deviceList[deviceIndex], mx);
-#ifdef DEBUG
-               printf("Sending %s", bufr);
-#endif
-#ifdef NO_GETADDRINFO
-               /* the following code is not using getaddrinfo */
-               /* emission */
-               memset(&sockudp_w, 0, sizeof(struct sockaddr_storage));
-               if(ipv6) {
-                       struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w;
-                       p->sin6_family = AF_INET6;
-                       p->sin6_port = htons(PORT);
-                       inet_pton(AF_INET6,
-                                 linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR,
-                                 &(p->sin6_addr));
-               } else {
-                       struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w;
-                       p->sin_family = AF_INET;
-                       p->sin_port = htons(PORT);
-                       p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
-               }
-               n = sendto(sudp, bufr, n, 0,
-                          &sockudp_w,
-                          ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
-               if (n < 0) {
-                       if(error)
-                               *error = UPNPDISCOVER_SOCKET_ERROR;
-                       PRINT_SOCKET_ERROR("sendto");
-                       break;
-               }
-#else /* #ifdef NO_GETADDRINFO */
-               memset(&hints, 0, sizeof(hints));
-               hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */
-               hints.ai_socktype = SOCK_DGRAM;
-               /*hints.ai_flags = */
-               if ((rv = getaddrinfo(ipv6
-                                     ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR)
-                                     : UPNP_MCAST_ADDR,
-                                     XSTR(PORT), &hints, &servinfo)) != 0) {
-                       if(error)
-                               *error = UPNPDISCOVER_SOCKET_ERROR;
-#ifdef _WIN32
-                   fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
-#else
-                   fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
-#endif
-                       break;
-               }
-               for(p = servinfo; p; p = p->ai_next) {
-                       n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
-                       if (n < 0) {
-#ifdef DEBUG
-                               char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
-                               if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
-                                               sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
-                                       fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf);
-                               }
-#endif
-                               PRINT_SOCKET_ERROR("sendto");
-                               continue;
-                       }
-               }
-               freeaddrinfo(servinfo);
-               if(n < 0) {
-                       if(error)
-                               *error = UPNPDISCOVER_SOCKET_ERROR;
-                       break;
-               }
-#endif /* #ifdef NO_GETADDRINFO */
-       }
-       /* Waiting for SSDP REPLY packet to M-SEARCH */
-       n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
-       if (n < 0) {
-               /* error */
-               if(error)
-                       *error = UPNPDISCOVER_SOCKET_ERROR;
-               break;
-       } else if (n == 0) {
-               /* no data or Time Out */
-               if (devlist) {
-                       /* no more device type to look for... */
-                       if(error)
-                               *error = UPNPDISCOVER_SUCCESS;
-                       break;
-               }
-               if(ipv6) {
-                       if(linklocal) {
-                               linklocal = 0;
-                               --deviceIndex;
-                       } else {
-                               linklocal = 1;
-                       }
-               }
-       } else {
-               const char * descURL=NULL;
-               int urlsize=0;
-               const char * st=NULL;
-               int stsize=0;
-        /*printf("%d byte(s) :\n%s\n", n, bufr);*/ /* affichage du message */
-               parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize);
-               if(st&&descURL)
-               {
-#ifdef DEBUG
-                       printf("M-SEARCH Reply:\nST: %.*s\nLocation: %.*s\n",
-                              stsize, st, urlsize, descURL);
-#endif
-                       for(tmp=devlist; tmp; tmp = tmp->pNext) {
-                               if(memcmp(tmp->descURL, descURL, urlsize) == 0 &&
-                                  tmp->descURL[urlsize] == '\0' &&
-                                  memcmp(tmp->st, st, stsize) == 0 &&
-                                  tmp->st[stsize] == '\0')
-                                       break;
-                       }
-                       /* at the exit of the loop above, tmp is null if
-                        * no duplicate device was found */
-                       if(tmp)
-                               continue;
-                       tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
-                       if(!tmp) {
-                               /* memory allocation error */
-                               if(error)
-                                       *error = UPNPDISCOVER_MEMORY_ERROR;
-                               break;
-                       }
-                       tmp->pNext = devlist;
-                       tmp->descURL = tmp->buffer;
-                       tmp->st = tmp->buffer + 1 + urlsize;
-                       memcpy(tmp->buffer, descURL, urlsize);
-                       tmp->buffer[urlsize] = '\0';
-                       memcpy(tmp->buffer + urlsize + 1, st, stsize);
-                       tmp->buffer[urlsize+1+stsize] = '\0';
-                       tmp->scope_id = scope_id;
-                       devlist = tmp;
-               }
-       }
-       }
-       closesocket(sudp);
-       return devlist;
-}
-
-/* freeUPNPDevlist() should be used to
- * free the chained list returned by upnpDiscover() */
-LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist)
-{
-       struct UPNPDev * next;
-       while(devlist)
-       {
-               next = devlist->pNext;
-               free(devlist);
-               devlist = next;
-       }
-}
-
-static void
-url_cpy_or_cat(char * dst, const char * src, int n)
-{
-       if(  (src[0] == 'h')
-          &&(src[1] == 't')
-          &&(src[2] == 't')
-          &&(src[3] == 'p')
-          &&(src[4] == ':')
-          &&(src[5] == '/')
-          &&(src[6] == '/'))
-       {
-               strncpy(dst, src, n);
-       }
-       else
-       {
-               int l = strlen(dst);
-               if(src[0] != '/')
-                       dst[l++] = '/';
-               if(l<=n)
-                       strncpy(dst + l, src, n - l);
-       }
-}
-
-/* Prepare the Urls for usage...
- */
-LIBSPEC void
-GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
-            const char * descURL, unsigned int scope_id)
-{
-       char * p;
-       int n1, n2, n3, n4;
-#ifdef IF_NAMESIZE
-       char ifname[IF_NAMESIZE];
-#else
-       char scope_str[8];
-#endif
-
-       n1 = strlen(data->urlbase);
-       if(n1==0)
-               n1 = strlen(descURL);
-       if(scope_id != 0) {
-#ifdef IF_NAMESIZE
-               if(if_indextoname(scope_id, ifname)) {
-                       n1 += 3 + strlen(ifname);       /* 3 == strlen(%25) */
-               }
-#else
-       /* under windows, scope is numerical */
-       snprintf(scope_str, sizeof(scope_str), "%u", scope_id);
-#endif
-       }
-       n1 += 2;        /* 1 byte more for Null terminator, 1 byte for '/' if needed */
-       n2 = n1; n3 = n1; n4 = n1;
-       n1 += strlen(data->first.scpdurl);
-       n2 += strlen(data->first.controlurl);
-       n3 += strlen(data->CIF.controlurl);
-       n4 += strlen(data->IPv6FC.controlurl);
-
-       /* allocate memory to store URLs */
-       urls->ipcondescURL = (char *)malloc(n1);
-       urls->controlURL = (char *)malloc(n2);
-       urls->controlURL_CIF = (char *)malloc(n3);
-       urls->controlURL_6FC = (char *)malloc(n4);
-
-       /* strdup descURL */
-       urls->rootdescURL = strdup(descURL);
-
-       /* get description of WANIPConnection */
-       if(data->urlbase[0] != '\0')
-               strncpy(urls->ipcondescURL, data->urlbase, n1);
-       else
-               strncpy(urls->ipcondescURL, descURL, n1);
-       p = strchr(urls->ipcondescURL+7, '/');
-       if(p) p[0] = '\0';
-       if(scope_id != 0) {
-               if(0 == memcmp(urls->ipcondescURL, "http://[fe80:", 13)) {
-                       /* this is a linklocal IPv6 address */
-                       p = strchr(urls->ipcondescURL, ']');
-                       if(p) {
-                               /* insert %25<scope> into URL */
-#ifdef IF_NAMESIZE
-                               memmove(p + 3 + strlen(ifname), p, strlen(p) + 1);
-                               memcpy(p, "%25", 3);
-                               memcpy(p + 3, ifname, strlen(ifname));
-#else
-                               memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1);
-                               memcpy(p, "%25", 3);
-                               memcpy(p + 3, scope_str, strlen(scope_str));
-#endif
-                       }
-               }
-       }
-       strncpy(urls->controlURL, urls->ipcondescURL, n2);
-       strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
-       strncpy(urls->controlURL_6FC, urls->ipcondescURL, n4);
-
-       url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
-
-       url_cpy_or_cat(urls->controlURL, data->first.controlurl, n2);
-
-       url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
-
-       url_cpy_or_cat(urls->controlURL_6FC, data->IPv6FC.controlurl, n4);
-
-#ifdef DEBUG
-       printf("urls->ipcondescURL='%s' %u n1=%d\n", urls->ipcondescURL,
-              (unsigned)strlen(urls->ipcondescURL), n1);
-       printf("urls->controlURL='%s' %u n2=%d\n", urls->controlURL,
-              (unsigned)strlen(urls->controlURL), n2);
-       printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
-              (unsigned)strlen(urls->controlURL_CIF), n3);
-       printf("urls->controlURL_6FC='%s' %u n4=%d\n", urls->controlURL_6FC,
-              (unsigned)strlen(urls->controlURL_6FC), n4);
-#endif
-}
-
-LIBSPEC void
-FreeUPNPUrls(struct UPNPUrls * urls)
-{
-       if(!urls)
-               return;
-       free(urls->controlURL);
-       urls->controlURL = 0;
-       free(urls->ipcondescURL);
-       urls->ipcondescURL = 0;
-       free(urls->controlURL_CIF);
-       urls->controlURL_CIF = 0;
-       free(urls->controlURL_6FC);
-       urls->controlURL_6FC = 0;
-       free(urls->rootdescURL);
-       urls->rootdescURL = 0;
-}
-
-int
-UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
-{
-       char status[64];
-       unsigned int uptime;
-       status[0] = '\0';
-       UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
-                          status, &uptime, NULL);
-       if(0 == strcmp("Connected", status))
-       {
-               return 1;
-       }
-       else
-               return 0;
-}
-
-
-/* UPNP_GetValidIGD() :
- * return values :
- *    -1 = Internal error
- *     0 = NO IGD found
- *     1 = A valid connected IGD has been found
- *     2 = A valid IGD has been found but it reported as
- *         not connected
- *     3 = an UPnP device has been found but was not recognized as an IGD
- *
- * In any positive non zero return case, the urls and data structures
- * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
- * free allocated memory.
- */
-LIBSPEC int
-UPNP_GetValidIGD(struct UPNPDev * devlist,
-                 struct UPNPUrls * urls,
-                                struct IGDdatas * data,
-                                char * lanaddr, int lanaddrlen)
-{
-       struct xml_desc {
-               char * xml;
-               int size;
-               int is_igd;
-       } * desc = NULL;
-       struct UPNPDev * dev;
-       int ndev = 0;
-       int i;
-       int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
-       int n_igd = 0;
-       char extIpAddr[16];
-       if(!devlist)
-       {
-#ifdef DEBUG
-               printf("Empty devlist\n");
-#endif
-               return 0;
-       }
-       /* counting total number of devices in the list */
-       for(dev = devlist; dev; dev = dev->pNext)
-               ndev++;
-       if(ndev > 0)
-       {
-               desc = calloc(ndev, sizeof(struct xml_desc));
-               if(!desc)
-                       return -1; /* memory allocation error */
-       }
-       /* Step 1 : downloading descriptions and testing type */
-       for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
-       {
-               /* we should choose an internet gateway device.
-                * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
-               desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
-                                              lanaddr, lanaddrlen,
-                                              dev->scope_id);
-#ifdef DEBUG
-               if(!desc[i].xml)
-               {
-                       printf("error getting XML description %s\n", dev->descURL);
-               }
-#endif
-               if(desc[i].xml)
-               {
-                       memset(data, 0, sizeof(struct IGDdatas));
-                       memset(urls, 0, sizeof(struct UPNPUrls));
-                       parserootdesc(desc[i].xml, desc[i].size, data);
-                       if(0==strcmp(data->CIF.servicetype,
-                          "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"))
-                       {
-                               desc[i].is_igd = 1;
-                               n_igd++;
-                       }
-               }
-       }
-       /* iterate the list to find a device depending on state */
-       for(state = 1; state <= 3; state++)
-       {
-               for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
-               {
-                       if(desc[i].xml)
-                       {
-                               memset(data, 0, sizeof(struct IGDdatas));
-                               memset(urls, 0, sizeof(struct UPNPUrls));
-                               parserootdesc(desc[i].xml, desc[i].size, data);
-                               if(desc[i].is_igd || state >= 3 )
-                               {
-                                 GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
-
-                                 /* in state 2 and 3 we dont test if device is connected ! */
-                                 if(state >= 2)
-                                   goto free_and_return;
-#ifdef DEBUG
-                                 printf("UPNPIGD_IsConnected(%s) = %d\n",
-                                    urls->controlURL,
-                                UPNPIGD_IsConnected(urls, data));
-#endif
-                                 /* checks that status is connected AND there is a external IP address assigned */
-                                 if(UPNPIGD_IsConnected(urls, data)
-                                    && (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0))
-                                       goto free_and_return;
-                                 FreeUPNPUrls(urls);
-                                 if(data->second.servicetype[0] != '\0') {
-#ifdef DEBUG
-                                   printf("We tried %s, now we try %s !\n",
-                                          data->first.servicetype, data->second.servicetype);
-#endif
-                                   /* swaping WANPPPConnection and WANIPConnection ! */
-                                   memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
-                                   memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
-                                   memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
-                                   GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
-#ifdef DEBUG
-                                   printf("UPNPIGD_IsConnected(%s) = %d\n",
-                                      urls->controlURL,
-                                  UPNPIGD_IsConnected(urls, data));
-#endif
-                                   if(UPNPIGD_IsConnected(urls, data)
-                                      && (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0))
-                                         goto free_and_return;
-                                   FreeUPNPUrls(urls);
-                                 }
-                               }
-                               memset(data, 0, sizeof(struct IGDdatas));
-                       }
-               }
-       }
-       state = 0;
-free_and_return:
-       if(desc) {
-               for(i = 0; i < ndev; i++) {
-                       if(desc[i].xml) {
-                               free(desc[i].xml);
-                       }
-               }
-               free(desc);
-       }
-       return state;
-}
-
-/* UPNP_GetIGDFromUrl()
- * Used when skipping the discovery process.
- * return value :
- *   0 - Not ok
- *   1 - OK */
-int
-UPNP_GetIGDFromUrl(const char * rootdescurl,
-                   struct UPNPUrls * urls,
-                   struct IGDdatas * data,
-                   char * lanaddr, int lanaddrlen)
-{
-       char * descXML;
-       int descXMLsize = 0;
-       descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
-                                      lanaddr, lanaddrlen, 0);
-       if(descXML) {
-               memset(data, 0, sizeof(struct IGDdatas));
-               memset(urls, 0, sizeof(struct UPNPUrls));
-               parserootdesc(descXML, descXMLsize, data);
-               free(descXML);
-               descXML = NULL;
-               GetUPNPUrls(urls, data, rootdescurl, 0);
-               return 1;
-       } else {
-               return 0;
-       }
-}
-
diff --git a/third-party/miniupnp/miniupnpc.h b/third-party/miniupnp/miniupnpc.h
deleted file mode 100644 (file)
index 3af109c..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* $Id: miniupnpc.h,v 1.35 2014/01/31 13:26:34 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2012 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINIUPNPC_H_INCLUDED
-#define MINIUPNPC_H_INCLUDED
-
-#include "declspec.h"
-#include "igd_desc_parse.h"
-
-/* error codes : */
-#define UPNPDISCOVER_SUCCESS (0)
-#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
-#define UPNPDISCOVER_SOCKET_ERROR (-101)
-#define UPNPDISCOVER_MEMORY_ERROR (-102)
-
-/* versions : */
-#define MINIUPNPC_VERSION      "1.9.20140401"
-#define MINIUPNPC_API_VERSION  10
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Structures definitions : */
-struct UPNParg { const char * elt; const char * val; };
-
-char *
-simpleUPnPcommand(int, const char *, const char *,
-                  const char *, struct UPNParg *,
-                  int *);
-
-struct UPNPDev {
-       struct UPNPDev * pNext;
-       char * descURL;
-       char * st;
-       unsigned int scope_id;
-       char buffer[2];
-};
-
-/* upnpDiscover()
- * discover UPnP devices on the network.
- * The discovered devices are returned as a chained list.
- * It is up to the caller to free the list with freeUPNPDevlist().
- * delay (in millisecond) is the maximum time for waiting any device
- * response.
- * If available, device list will be obtained from MiniSSDPd.
- * Default path for minissdpd socket will be used if minissdpdsock argument
- * is NULL.
- * If multicastif is not NULL, it will be used instead of the default
- * multicast interface for sending SSDP discover packets.
- * If sameport is not null, SSDP packets will be sent from the source port
- * 1900 (same as destination port) otherwise system assign a source port. */
-LIBSPEC struct UPNPDev *
-upnpDiscover(int delay, const char * multicastif,
-             const char * minissdpdsock, int sameport,
-             int ipv6,
-             int * error);
-/* freeUPNPDevlist()
- * free list returned by upnpDiscover() */
-LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
-
-/* parserootdesc() :
- * parse root XML description of a UPnP device and fill the IGDdatas
- * structure. */
-LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
-
-/* structure used to get fast access to urls
- * controlURL: controlURL of the WANIPConnection
- * ipcondescURL: url of the description of the WANIPConnection
- * controlURL_CIF: controlURL of the WANCommonInterfaceConfig
- * controlURL_6FC: controlURL of the WANIPv6FirewallControl
- */
-struct UPNPUrls {
-       char * controlURL;
-       char * ipcondescURL;
-       char * controlURL_CIF;
-       char * controlURL_6FC;
-       char * rootdescURL;
-};
-
-/* UPNP_GetValidIGD() :
- * return values :
- *     0 = NO IGD found
- *     1 = A valid connected IGD has been found
- *     2 = A valid IGD has been found but it reported as
- *         not connected
- *     3 = an UPnP device has been found but was not recognized as an IGD
- *
- * In any non zero return case, the urls and data structures
- * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
- * free allocated memory.
- */
-LIBSPEC int
-UPNP_GetValidIGD(struct UPNPDev * devlist,
-                 struct UPNPUrls * urls,
-                                struct IGDdatas * data,
-                                char * lanaddr, int lanaddrlen);
-
-/* UPNP_GetIGDFromUrl()
- * Used when skipping the discovery process.
- * return value :
- *   0 - Not ok
- *   1 - OK */
-LIBSPEC int
-UPNP_GetIGDFromUrl(const char * rootdescurl,
-                   struct UPNPUrls * urls,
-                   struct IGDdatas * data,
-                   char * lanaddr, int lanaddrlen);
-
-LIBSPEC void
-GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
-            const char *, unsigned int);
-
-LIBSPEC void
-FreeUPNPUrls(struct UPNPUrls *);
-
-/* return 0 or 1 */
-LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/third-party/miniupnp/miniupnpcstrings.h.in b/third-party/miniupnp/miniupnpcstrings.h.in
deleted file mode 100644 (file)
index c32e3a1..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* $Id: miniupnpcstrings.h.in,v 1.5 2012/10/16 16:48:26 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2011 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINIUPNPCSTRINGS_H_INCLUDED
-#define MINIUPNPCSTRINGS_H_INCLUDED
-
-#define OS_STRING "OS/version"
-#define MINIUPNPC_VERSION_STRING "version"
-
-#endif
-
diff --git a/third-party/miniupnp/miniupnpctypes.h b/third-party/miniupnp/miniupnpctypes.h
deleted file mode 100644 (file)
index 591c32f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id: miniupnpctypes.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */
-/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org
- * Author : Thomas Bernard
- * Copyright (c) 2011 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided within this distribution */
-#ifndef MINIUPNPCTYPES_H_INCLUDED
-#define MINIUPNPCTYPES_H_INCLUDED
-
-#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
-#define UNSIGNED_INTEGER unsigned long long
-#define STRTOUI        strtoull
-#else
-#define UNSIGNED_INTEGER unsigned int
-#define STRTOUI        strtoul
-#endif
-
-#endif
-
diff --git a/third-party/miniupnp/miniwget.c b/third-party/miniupnp/miniwget.c
deleted file mode 100644 (file)
index 813db93..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-/* $Id: miniwget.c,v 1.61 2014/02/05 17:27:48 nanard Exp $ */
-/* Project : miniupnp
- * Website : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2014 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#define MAXHOSTNAMELEN 64
-#define MIN(x,y) (((x)<(y))?(x):(y))
-#define snprintf _snprintf
-#define socklen_t int
-#ifndef strncasecmp
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define strncasecmp _memicmp
-#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#define strncasecmp memicmp
-#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#endif /* #ifndef strncasecmp */
-#else /* #ifdef _WIN32 */
-#include <unistd.h>
-#include <sys/param.h>
-#if defined(__amigaos__) && !defined(__amigaos4__)
-#define socklen_t int
-#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/select.h>
-#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <netdb.h>
-#define closesocket close
-#endif /* #else _WIN32 */
-#if defined(__sun) || defined(sun)
-#define MIN(x,y) (((x)<(y))?(x):(y))
-#endif
-
-#include "miniupnpcstrings.h"
-#include "miniwget.h"
-#include "connecthostport.h"
-#include "receivedata.h"
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-/*
- * Read a HTTP response from a socket.
- * Process Content-Length and Transfer-encoding headers.
- * return a pointer to the content buffer, which length is saved
- * to the length parameter.
- */
-void *
-getHTTPResponse(int s, int * size)
-{
-       char buf[2048];
-       int n;
-       int endofheaders = 0;
-       int chunked = 0;
-       int content_length = -1;
-       unsigned int chunksize = 0;
-       unsigned int bytestocopy = 0;
-       /* buffers : */
-       char * header_buf;
-       unsigned int header_buf_len = 2048;
-       unsigned int header_buf_used = 0;
-       char * content_buf;
-       unsigned int content_buf_len = 2048;
-       unsigned int content_buf_used = 0;
-       char chunksize_buf[32];
-       unsigned int chunksize_buf_index;
-
-       header_buf = malloc(header_buf_len);
-       content_buf = malloc(content_buf_len);
-       chunksize_buf[0] = '\0';
-       chunksize_buf_index = 0;
-
-       while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0)
-       {
-               if(endofheaders == 0)
-               {
-                       int i;
-                       int linestart=0;
-                       int colon=0;
-                       int valuestart=0;
-                       if(header_buf_used + n > header_buf_len) {
-                               header_buf = realloc(header_buf, header_buf_used + n);
-                               header_buf_len = header_buf_used + n;
-                       }
-                       memcpy(header_buf + header_buf_used, buf, n);
-                       header_buf_used += n;
-                       /* search for CR LF CR LF (end of headers)
-                        * recognize also LF LF */
-                       i = 0;
-                       while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
-                               if(header_buf[i] == '\r') {
-                                       i++;
-                                       if(header_buf[i] == '\n') {
-                                               i++;
-                                               if(i < (int)header_buf_used && header_buf[i] == '\r') {
-                                                       i++;
-                                                       if(i < (int)header_buf_used && header_buf[i] == '\n') {
-                                                               endofheaders = i+1;
-                                                       }
-                                               }
-                                       }
-                               } else if(header_buf[i] == '\n') {
-                                       i++;
-                                       if(header_buf[i] == '\n') {
-                                               endofheaders = i+1;
-                                       }
-                               }
-                               i++;
-                       }
-                       if(endofheaders == 0)
-                               continue;
-                       /* parse header lines */
-                       for(i = 0; i < endofheaders - 1; i++) {
-                               if(colon <= linestart && header_buf[i]==':')
-                               {
-                                       colon = i;
-                                       while(i < (endofheaders-1)
-                                             && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
-                                               i++;
-                                       valuestart = i + 1;
-                               }
-                               /* detecting end of line */
-                               else if(header_buf[i]=='\r' || header_buf[i]=='\n')
-                               {
-                                       if(colon > linestart && valuestart > colon)
-                                       {
-#ifdef DEBUG
-                                               printf("header='%.*s', value='%.*s'\n",
-                                                      colon-linestart, header_buf+linestart,
-                                                      i-valuestart, header_buf+valuestart);
-#endif
-                                               if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart))
-                                               {
-                                                       content_length = atoi(header_buf+valuestart);
-#ifdef DEBUG
-                                                       printf("Content-Length: %d\n", content_length);
-#endif
-                                               }
-                                               else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
-                                                  && 0==strncasecmp(header_buf+valuestart, "chunked", 7))
-                                               {
-#ifdef DEBUG
-                                                       printf("chunked transfer-encoding!\n");
-#endif
-                                                       chunked = 1;
-                                               }
-                                       }
-                                       while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
-                                               i++;
-                                       linestart = i;
-                                       colon = linestart;
-                                       valuestart = 0;
-                               }
-                       }
-                       /* copy the remaining of the received data back to buf */
-                       n = header_buf_used - endofheaders;
-                       memcpy(buf, header_buf + endofheaders, n);
-                       /* if(headers) */
-               }
-               if(endofheaders)
-               {
-                       /* content */
-                       if(chunked)
-                       {
-                               int i = 0;
-                               while(i < n)
-                               {
-                                       if(chunksize == 0)
-                                       {
-                                               /* reading chunk size */
-                                               if(chunksize_buf_index == 0) {
-                                                       /* skipping any leading CR LF */
-                                                       if(i<n && buf[i] == '\r') i++;
-                                                       if(i<n && buf[i] == '\n') i++;
-                                               }
-                                               while(i<n && isxdigit(buf[i])
-                                                    && chunksize_buf_index < (sizeof(chunksize_buf)-1))
-                                               {
-                                                       chunksize_buf[chunksize_buf_index++] = buf[i];
-                                                       chunksize_buf[chunksize_buf_index] = '\0';
-                                                       i++;
-                                               }
-                                               while(i<n && buf[i] != '\r' && buf[i] != '\n')
-                                                       i++; /* discarding chunk-extension */
-                                               if(i<n && buf[i] == '\r') i++;
-                                               if(i<n && buf[i] == '\n') {
-                                                       unsigned int j;
-                                                       for(j = 0; j < chunksize_buf_index; j++) {
-                                                       if(chunksize_buf[j] >= '0'
-                                                          && chunksize_buf[j] <= '9')
-                                                               chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
-                                                       else
-                                                               chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
-                                                       }
-                                                       chunksize_buf[0] = '\0';
-                                                       chunksize_buf_index = 0;
-                                                       i++;
-                                               } else {
-                                                       /* not finished to get chunksize */
-                                                       continue;
-                                               }
-#ifdef DEBUG
-                                               printf("chunksize = %u (%x)\n", chunksize, chunksize);
-#endif
-                                               if(chunksize == 0)
-                                               {
-#ifdef DEBUG
-                                                       printf("end of HTTP content - %d %d\n", i, n);
-                                                       /*printf("'%.*s'\n", n-i, buf+i);*/
-#endif
-                                                       goto end_of_stream;
-                                               }
-                                       }
-                                       bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
-                                       if((content_buf_used + bytestocopy) > content_buf_len)
-                                       {
-                                               if(content_length >= (int)(content_buf_used + bytestocopy)) {
-                                                       content_buf_len = content_length;
-                                               } else {
-                                                       content_buf_len = content_buf_used + bytestocopy;
-                                               }
-                                               content_buf = (char *)realloc((void *)content_buf,
-                                                                             content_buf_len);
-                                       }
-                                       memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
-                                       content_buf_used += bytestocopy;
-                                       i += bytestocopy;
-                                       chunksize -= bytestocopy;
-                               }
-                       }
-                       else
-                       {
-                               /* not chunked */
-                               if(content_length > 0
-                                  && (int)(content_buf_used + n) > content_length) {
-                                       /* skipping additional bytes */
-                                       n = content_length - content_buf_used;
-                               }
-                               if(content_buf_used + n > content_buf_len)
-                               {
-                                       if(content_length >= (int)(content_buf_used + n)) {
-                                               content_buf_len = content_length;
-                                       } else {
-                                               content_buf_len = content_buf_used + n;
-                                       }
-                                       content_buf = (char *)realloc((void *)content_buf,
-                                                                     content_buf_len);
-                               }
-                               memcpy(content_buf + content_buf_used, buf, n);
-                               content_buf_used += n;
-                       }
-               }
-               /* use the Content-Length header value if available */
-               if(content_length > 0 && (int)content_buf_used >= content_length)
-               {
-#ifdef DEBUG
-                       printf("End of HTTP content\n");
-#endif
-                       break;
-               }
-       }
-end_of_stream:
-       free(header_buf); header_buf = NULL;
-       *size = content_buf_used;
-       if(content_buf_used == 0)
-       {
-               free(content_buf);
-               content_buf = NULL;
-       }
-       return content_buf;
-}
-
-/* miniwget3() :
- * do all the work.
- * Return NULL if something failed. */
-static void *
-miniwget3(const char * host,
-          unsigned short port, const char * path,
-          int * size, char * addr_str, int addr_str_len,
-          const char * httpversion, unsigned int scope_id)
-{
-       char buf[2048];
-    int s;
-       int n;
-       int len;
-       int sent;
-       void * content;
-
-       *size = 0;
-       s = connecthostport(host, port, scope_id);
-       if(s < 0)
-               return NULL;
-
-       /* get address for caller ! */
-       if(addr_str)
-       {
-               struct sockaddr_storage saddr;
-               socklen_t saddrlen;
-
-               saddrlen = sizeof(saddr);
-               if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
-               {
-                       perror("getsockname");
-               }
-               else
-               {
-#if defined(__amigaos__) && !defined(__amigaos4__)
-       /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
-     * But his function make a string with the port :  nn.nn.nn.nn:port */
-/*             if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
-                            NULL, addr_str, (DWORD *)&addr_str_len))
-               {
-                   printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
-               }*/
-                       /* the following code is only compatible with ip v4 addresses */
-                       strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
-#else
-#if 0
-                       if(saddr.sa_family == AF_INET6) {
-                               inet_ntop(AF_INET6,
-                                         &(((struct sockaddr_in6 *)&saddr)->sin6_addr),
-                                         addr_str, addr_str_len);
-                       } else {
-                               inet_ntop(AF_INET,
-                                         &(((struct sockaddr_in *)&saddr)->sin_addr),
-                                         addr_str, addr_str_len);
-                       }
-#endif
-                       /* getnameinfo return ip v6 address with the scope identifier
-                        * such as : 2a01:e35:8b2b:7330::%4281128194 */
-                       n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
-                                       addr_str, addr_str_len,
-                                       NULL, 0,
-                                       NI_NUMERICHOST | NI_NUMERICSERV);
-                       if(n != 0) {
-#ifdef _WIN32
-                               fprintf(stderr, "getnameinfo() failed : %d\n", n);
-#else
-                               fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
-#endif
-                       }
-#endif
-               }
-#ifdef DEBUG
-               printf("address miniwget : %s\n", addr_str);
-#endif
-       }
-
-       len = snprintf(buf, sizeof(buf),
-                 "GET %s HTTP/%s\r\n"
-                            "Host: %s:%d\r\n"
-                                "Connection: Close\r\n"
-                                "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
-
-                                "\r\n",
-                          path, httpversion, host, port);
-       sent = 0;
-       /* sending the HTTP request */
-       while(sent < len)
-       {
-               n = send(s, buf+sent, len-sent, 0);
-               if(n < 0)
-               {
-                       perror("send");
-                       closesocket(s);
-                       return NULL;
-               }
-               else
-               {
-                       sent += n;
-               }
-       }
-       content = getHTTPResponse(s, size);
-       closesocket(s);
-       return content;
-}
-
-/* miniwget2() :
- * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
-static void *
-miniwget2(const char * host,
-                 unsigned short port, const char * path,
-                 int * size, char * addr_str, int addr_str_len,
-          unsigned int scope_id)
-{
-       char * respbuffer;
-
-#if 1
-       respbuffer = miniwget3(host, port, path, size,
-                              addr_str, addr_str_len, "1.1", scope_id);
-#else
-       respbuffer = miniwget3(host, port, path, size,
-                              addr_str, addr_str_len, "1.0", scope_id);
-       if (*size == 0)
-       {
-#ifdef DEBUG
-               printf("Retrying with HTTP/1.1\n");
-#endif
-               free(respbuffer);
-               respbuffer = miniwget3(host, port, path, size,
-                                      addr_str, addr_str_len, "1.1", scope_id);
-       }
-#endif
-       return respbuffer;
-}
-
-
-
-
-/* parseURL()
- * arguments :
- *   url :             source string not modified
- *   hostname :        hostname destination string (size of MAXHOSTNAMELEN+1)
- *   port :            port (destination)
- *   path :            pointer to the path part of the URL
- *
- * Return values :
- *    0 - Failure
- *    1 - Success         */
-int
-parseURL(const char * url,
-         char * hostname, unsigned short * port,
-         char * * path, unsigned int * scope_id)
-{
-       char * p1, *p2, *p3;
-       if(!url)
-               return 0;
-       p1 = strstr(url, "://");
-       if(!p1)
-               return 0;
-       p1 += 3;
-       if(  (url[0]!='h') || (url[1]!='t')
-          ||(url[2]!='t') || (url[3]!='p'))
-               return 0;
-       memset(hostname, 0, MAXHOSTNAMELEN + 1);
-       if(*p1 == '[')
-       {
-               /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
-               char * scope;
-               scope = strchr(p1, '%');
-               p2 = strchr(p1, ']');
-               if(p2 && scope && scope < p2 && scope_id) {
-                       /* parse scope */
-#ifdef IF_NAMESIZE
-                       char tmp[IF_NAMESIZE];
-                       int l;
-                       scope++;
-                       /* "%25" is just '%' in URL encoding */
-                       if(scope[0] == '2' && scope[1] == '5')
-                               scope += 2;     /* skip "25" */
-                       l = p2 - scope;
-                       if(l >= IF_NAMESIZE)
-                               l = IF_NAMESIZE - 1;
-                       memcpy(tmp, scope, l);
-                       tmp[l] = '\0';
-                       *scope_id = if_nametoindex(tmp);
-                       if(*scope_id == 0) {
-                               *scope_id = (unsigned int)strtoul(tmp, NULL, 10);
-                       }
-#else
-                       /* under windows, scope is numerical */
-                       char tmp[8];
-                       int l;
-                       scope++;
-                       /* "%25" is just '%' in URL encoding */
-                       if(scope[0] == '2' && scope[1] == '5')
-                               scope += 2;     /* skip "25" */
-                       l = p2 - scope;
-                       if(l >= sizeof(tmp))
-                               l = sizeof(tmp) - 1;
-                       memcpy(tmp, scope, l);
-                       tmp[l] = '\0';
-                       *scope_id = (unsigned int)strtoul(tmp, NULL, 10);
-#endif
-               }
-               p3 = strchr(p1, '/');
-               if(p2 && p3)
-               {
-                       p2++;
-                       strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
-                       if(*p2 == ':')
-                       {
-                               *port = 0;
-                               p2++;
-                               while( (*p2 >= '0') && (*p2 <= '9'))
-                               {
-                                       *port *= 10;
-                                       *port += (unsigned short)(*p2 - '0');
-                                       p2++;
-                               }
-                       }
-                       else
-                       {
-                               *port = 80;
-                       }
-                       *path = p3;
-                       return 1;
-               }
-       }
-       p2 = strchr(p1, ':');
-       p3 = strchr(p1, '/');
-       if(!p3)
-               return 0;
-       if(!p2 || (p2>p3))
-       {
-               strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
-               *port = 80;
-       }
-       else
-       {
-               strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
-               *port = 0;
-               p2++;
-               while( (*p2 >= '0') && (*p2 <= '9'))
-               {
-                       *port *= 10;
-                       *port += (unsigned short)(*p2 - '0');
-                       p2++;
-               }
-       }
-       *path = p3;
-       return 1;
-}
-
-void *
-miniwget(const char * url, int * size, unsigned int scope_id)
-{
-       unsigned short port;
-       char * path;
-       /* protocol://host:port/chemin */
-       char hostname[MAXHOSTNAMELEN+1];
-       *size = 0;
-       if(!parseURL(url, hostname, &port, &path, &scope_id))
-               return NULL;
-#ifdef DEBUG
-       printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
-              hostname, port, path, scope_id);
-#endif
-       return miniwget2(hostname, port, path, size, 0, 0, scope_id);
-}
-
-void *
-miniwget_getaddr(const char * url, int * size,
-                 char * addr, int addrlen, unsigned int scope_id)
-{
-       unsigned short port;
-       char * path;
-       /* protocol://host:port/path */
-       char hostname[MAXHOSTNAMELEN+1];
-       *size = 0;
-       if(addr)
-               addr[0] = '\0';
-       if(!parseURL(url, hostname, &port, &path, &scope_id))
-               return NULL;
-#ifdef DEBUG
-       printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
-              hostname, port, path, scope_id);
-#endif
-       return miniwget2(hostname, port, path, size, addr, addrlen, scope_id);
-}
-
diff --git a/third-party/miniupnp/miniwget.h b/third-party/miniupnp/miniwget.h
deleted file mode 100644 (file)
index 31bcea3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* $Id: miniwget.h,v 1.8 2012/09/27 15:42:10 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2012 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#ifndef MINIWGET_H_INCLUDED
-#define MINIWGET_H_INCLUDED
-
-#include "declspec.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBSPEC void * getHTTPResponse(int s, int * size);
-
-LIBSPEC void * miniwget(const char *, int *, unsigned int);
-
-LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int);
-
-int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/third-party/miniupnp/minixml.c b/third-party/miniupnp/minixml.c
deleted file mode 100644 (file)
index 3e201ec..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-/* $Id: minixml.c,v 1.11 2014/02/03 15:54:12 nanard Exp $ */
-/* minixml.c : the minimum size a xml parser can be ! */
-/* Project : miniupnp
- * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author : Thomas Bernard
-
-Copyright (c) 2005-2014, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <string.h>
-#include "minixml.h"
-
-/* parseatt : used to parse the argument list
- * return 0 (false) in case of success and -1 (true) if the end
- * of the xmlbuffer is reached. */
-static int parseatt(struct xmlparser * p)
-{
-       const char * attname;
-       int attnamelen;
-       const char * attvalue;
-       int attvaluelen;
-       while(p->xml < p->xmlend)
-       {
-               if(*p->xml=='/' || *p->xml=='>')
-                       return 0;
-               if( !IS_WHITE_SPACE(*p->xml) )
-               {
-                       char sep;
-                       attname = p->xml;
-                       attnamelen = 0;
-                       while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
-                       {
-                               attnamelen++; p->xml++;
-                               if(p->xml >= p->xmlend)
-                                       return -1;
-                       }
-                       while(*(p->xml++) != '=')
-                       {
-                               if(p->xml >= p->xmlend)
-                                       return -1;
-                       }
-                       while(IS_WHITE_SPACE(*p->xml))
-                       {
-                               p->xml++;
-                               if(p->xml >= p->xmlend)
-                                       return -1;
-                       }
-                       sep = *p->xml;
-                       if(sep=='\'' || sep=='\"')
-                       {
-                               p->xml++;
-                               if(p->xml >= p->xmlend)
-                                       return -1;
-                               attvalue = p->xml;
-                               attvaluelen = 0;
-                               while(*p->xml != sep)
-                               {
-                                       attvaluelen++; p->xml++;
-                                       if(p->xml >= p->xmlend)
-                                               return -1;
-                               }
-                       }
-                       else
-                       {
-                               attvalue = p->xml;
-                               attvaluelen = 0;
-                               while(   !IS_WHITE_SPACE(*p->xml)
-                                         && *p->xml != '>' && *p->xml != '/')
-                               {
-                                       attvaluelen++; p->xml++;
-                                       if(p->xml >= p->xmlend)
-                                               return -1;
-                               }
-                       }
-                       /*printf("%.*s='%.*s'\n",
-                              attnamelen, attname, attvaluelen, attvalue);*/
-                       if(p->attfunc)
-                               p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
-               }
-               p->xml++;
-       }
-       return -1;
-}
-
-/* parseelt parse the xml stream and
- * call the callback functions when needed... */
-static void parseelt(struct xmlparser * p)
-{
-       int i;
-       const char * elementname;
-       while(p->xml < (p->xmlend - 1))
-       {
-               if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "<!--", 4)))
-               {
-                       p->xml += 3;
-                       /* ignore comments */
-                       do
-                       {
-                               p->xml++;
-                               if ((p->xml + 3) >= p->xmlend)
-                                       return;
-                       }
-                       while(memcmp(p->xml, "-->", 3) != 0);
-                       p->xml += 3;
-               }
-               else if((p->xml)[0]=='<' && (p->xml)[1]!='?')
-               {
-                       i = 0; elementname = ++p->xml;
-                       while( !IS_WHITE_SPACE(*p->xml)
-                                 && (*p->xml!='>') && (*p->xml!='/')
-                                )
-                       {
-                               i++; p->xml++;
-                               if (p->xml >= p->xmlend)
-                                       return;
-                               /* to ignore namespace : */
-                               if(*p->xml==':')
-                               {
-                                       i = 0;
-                                       elementname = ++p->xml;
-                               }
-                       }
-                       if(i>0)
-                       {
-                               if(p->starteltfunc)
-                                       p->starteltfunc(p->data, elementname, i);
-                               if(parseatt(p))
-                                       return;
-                               if(*p->xml!='/')
-                               {
-                                       const char * data;
-                                       i = 0; data = ++p->xml;
-                                       if (p->xml >= p->xmlend)
-                                               return;
-                                       while( IS_WHITE_SPACE(*p->xml) )
-                                       {
-                                               i++; p->xml++;
-                                               if (p->xml >= p->xmlend)
-                                                       return;
-                                       }
-                                       if(memcmp(p->xml, "<![CDATA[", 9) == 0)
-                                       {
-                                               /* CDATA handling */
-                                               p->xml += 9;
-                                               data = p->xml;
-                                               i = 0;
-                                               while(memcmp(p->xml, "]]>", 3) != 0)
-                                               {
-                                                       i++; p->xml++;
-                                                       if ((p->xml + 3) >= p->xmlend)
-                                                               return;
-                                               }
-                                               if(i>0 && p->datafunc)
-                                                       p->datafunc(p->data, data, i);
-                                               while(*p->xml!='<')
-                                               {
-                                                       p->xml++;
-                                                       if (p->xml >= p->xmlend)
-                                                               return;
-                                               }
-                                       }
-                                       else
-                                       {
-                                               while(*p->xml!='<')
-                                               {
-                                                       i++; p->xml++;
-                                                       if ((p->xml + 1) >= p->xmlend)
-                                                               return;
-                                               }
-                                               if(i>0 && p->datafunc && *(p->xml + 1) == '/')
-                                                       p->datafunc(p->data, data, i);
-                                       }
-                               }
-                       }
-                       else if(*p->xml == '/')
-                       {
-                               i = 0; elementname = ++p->xml;
-                               if (p->xml >= p->xmlend)
-                                       return;
-                               while((*p->xml != '>'))
-                               {
-                                       i++; p->xml++;
-                                       if (p->xml >= p->xmlend)
-                                               return;
-                               }
-                               if(p->endeltfunc)
-                                       p->endeltfunc(p->data, elementname, i);
-                               p->xml++;
-                       }
-               }
-               else
-               {
-                       p->xml++;
-               }
-       }
-}
-
-/* the parser must be initialized before calling this function */
-void parsexml(struct xmlparser * parser)
-{
-       parser->xml = parser->xmlstart;
-       parser->xmlend = parser->xmlstart + parser->xmlsize;
-       parseelt(parser);
-}
-
-
diff --git a/third-party/miniupnp/minixml.h b/third-party/miniupnp/minixml.h
deleted file mode 100644 (file)
index 9f43aa4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* $Id: minixml.h,v 1.7 2012/09/27 15:42:10 nanard Exp $ */
-/* minimal xml parser
- *
- * Project : miniupnp
- * Website : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#ifndef MINIXML_H_INCLUDED
-#define MINIXML_H_INCLUDED
-#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n'))
-
-/* if a callback function pointer is set to NULL,
- * the function is not called */
-struct xmlparser {
-       const char *xmlstart;
-       const char *xmlend;
-       const char *xml;        /* pointer to current character */
-       int xmlsize;
-       void * data;
-       void (*starteltfunc) (void *, const char *, int);
-       void (*endeltfunc) (void *, const char *, int);
-       void (*datafunc) (void *, const char *, int);
-       void (*attfunc) (void *, const char *, int, const char *, int);
-};
-
-/* parsexml()
- * the xmlparser structure must be initialized before the call
- * the following structure members have to be initialized :
- * xmlstart, xmlsize, data, *func
- * xml is for internal usage, xmlend is computed automatically */
-void parsexml(struct xmlparser *);
-
-#endif
-
diff --git a/third-party/miniupnp/portlistingparse.c b/third-party/miniupnp/portlistingparse.c
deleted file mode 100644 (file)
index 19e3054..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/* $Id: portlistingparse.c,v 1.6 2012/05/29 10:26:51 nanard Exp $ */
-/* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2011 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-#include <string.h>
-#include <stdlib.h>
-#include "portlistingparse.h"
-#include "minixml.h"
-
-/* list of the elements */
-static const struct {
-       const portMappingElt code;
-       const char * const str;
-} elements[] = {
-       { PortMappingEntry, "PortMappingEntry"},
-       { NewRemoteHost, "NewRemoteHost"},
-       { NewExternalPort, "NewExternalPort"},
-       { NewProtocol, "NewProtocol"},
-       { NewInternalPort, "NewInternalPort"},
-       { NewInternalClient, "NewInternalClient"},
-       { NewEnabled, "NewEnabled"},
-       { NewDescription, "NewDescription"},
-       { NewLeaseTime, "NewLeaseTime"},
-       { PortMappingEltNone, NULL}
-};
-
-/* Helper function */
-static UNSIGNED_INTEGER
-atoui(const char * p, int l)
-{
-       UNSIGNED_INTEGER r = 0;
-       while(l > 0 && *p)
-       {
-               if(*p >= '0' && *p <= '9')
-                       r = r*10 + (*p - '0');
-               else
-                       break;
-               p++;
-               l--;
-       }
-       return r;
-}
-
-/* Start element handler */
-static void
-startelt(void * d, const char * name, int l)
-{
-       int i;
-       struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
-       pdata->curelt = PortMappingEltNone;
-       for(i = 0; elements[i].str; i++)
-       {
-               if(memcmp(name, elements[i].str, l) == 0)
-               {
-                       pdata->curelt = elements[i].code;
-                       break;
-               }
-       }
-       if(pdata->curelt == PortMappingEntry)
-       {
-               struct PortMapping * pm;
-               pm = calloc(1, sizeof(struct PortMapping));
-               LIST_INSERT_HEAD( &(pdata->head), pm, entries);
-       }
-}
-
-/* End element handler */
-static void
-endelt(void * d, const char * name, int l)
-{
-       struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
-       (void)name;
-       (void)l;
-       pdata->curelt = PortMappingEltNone;
-}
-
-/* Data handler */
-static void
-data(void * d, const char * data, int l)
-{
-       struct PortMapping * pm;
-       struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
-       pm = pdata->head.lh_first;
-       if(!pm)
-               return;
-       if(l > 63)
-               l = 63;
-       switch(pdata->curelt)
-       {
-       case NewRemoteHost:
-               memcpy(pm->remoteHost, data, l);
-               pm->remoteHost[l] = '\0';
-               break;
-       case NewExternalPort:
-               pm->externalPort = (unsigned short)atoui(data, l);
-               break;
-       case NewProtocol:
-               if(l > 3)
-                       l = 3;
-               memcpy(pm->protocol, data, l);
-               pm->protocol[l] = '\0';
-               break;
-       case NewInternalPort:
-               pm->internalPort = (unsigned short)atoui(data, l);
-               break;
-       case NewInternalClient:
-               memcpy(pm->internalClient, data, l);
-               pm->internalClient[l] = '\0';
-               break;
-       case NewEnabled:
-               pm->enabled = (unsigned char)atoui(data, l);
-               break;
-       case NewDescription:
-               memcpy(pm->description, data, l);
-               pm->description[l] = '\0';
-               break;
-       case NewLeaseTime:
-               pm->leaseTime = atoui(data, l);
-               break;
-       default:
-               break;
-       }
-}
-
-
-/* Parse the PortMappingList XML document for IGD version 2
- */
-void
-ParsePortListing(const char * buffer, int bufsize,
-                 struct PortMappingParserData * pdata)
-{
-       struct xmlparser parser;
-
-       memset(pdata, 0, sizeof(struct PortMappingParserData));
-       LIST_INIT(&(pdata->head));
-       /* init xmlparser */
-       parser.xmlstart = buffer;
-       parser.xmlsize = bufsize;
-       parser.data = pdata;
-       parser.starteltfunc = startelt;
-       parser.endeltfunc = endelt;
-       parser.datafunc = data;
-       parser.attfunc = 0;
-       parsexml(&parser);
-}
-
-void
-FreePortListing(struct PortMappingParserData * pdata)
-{
-       struct PortMapping * pm;
-       while((pm = pdata->head.lh_first) != NULL)
-       {
-               LIST_REMOVE(pm, entries);
-               free(pm);
-       }
-}
-
diff --git a/third-party/miniupnp/portlistingparse.h b/third-party/miniupnp/portlistingparse.h
deleted file mode 100644 (file)
index bafa2a4..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $Id: portlistingparse.h,v 1.7 2012/09/27 15:42:10 nanard Exp $ */
-/* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2011-2012 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-#ifndef PORTLISTINGPARSE_H_INCLUDED
-#define PORTLISTINGPARSE_H_INCLUDED
-
-#include "declspec.h"
-/* for the definition of UNSIGNED_INTEGER */
-#include "miniupnpctypes.h"
-
-#if defined(NO_SYS_QUEUE_H) || defined(_WIN32) || defined(__HAIKU__)
-#include "bsdqueue.h"
-#else
-#include <sys/queue.h>
-#endif
-
-#ifdef __cplusplus
-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>
- */
-typedef enum { PortMappingEltNone,
-       PortMappingEntry, NewRemoteHost,
-       NewExternalPort, NewProtocol,
-       NewInternalPort, NewInternalClient,
-       NewEnabled, NewDescription,
-       NewLeaseTime } portMappingElt;
-
-struct PortMapping {
-       LIST_ENTRY(PortMapping) entries;
-       UNSIGNED_INTEGER leaseTime;
-       unsigned short externalPort;
-       unsigned short internalPort;
-       char remoteHost[64];
-       char internalClient[64];
-       char description[64];
-       char protocol[4];
-       unsigned char enabled;
-};
-
-struct PortMappingParserData {
-       LIST_HEAD(portmappinglisthead, PortMapping) head;
-       portMappingElt curelt;
-};
-
-LIBSPEC void
-ParsePortListing(const char * buffer, int bufsize,
-                 struct PortMappingParserData * pdata);
-
-LIBSPEC void
-FreePortListing(struct PortMappingParserData * pdata);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/third-party/miniupnp/receivedata.c b/third-party/miniupnp/receivedata.c
deleted file mode 100644 (file)
index 9599556..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* $Id: receivedata.c,v 1.5 2013/10/07 09:48:36 nanard Exp $ */
-/* Project : miniupnp
- * Website : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2011-2012 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include <stdio.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <unistd.h>
-#if defined(__amigaos__) && !defined(__amigaos4__)
-#define socklen_t int
-#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/select.h>
-#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#if !defined(__amigaos__) && !defined(__amigaos4__)
-#include <poll.h>
-#endif
-#include <errno.h>
-#define MINIUPNPC_IGNORE_EINTR
-#endif
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x)    printf("Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#include "receivedata.h"
-
-int
-receivedata(int socket,
-            char * data, int length,
-            int timeout, unsigned int * scope_id)
-{
-#ifdef MINIUPNPC_GET_SRC_ADDR
-#ifdef DEBUG
-       /* to shut up valgrind about uninit value */
-       struct sockaddr_storage src_addr = {0};
-#else
-       struct sockaddr_storage src_addr;
-#endif
-       socklen_t src_addr_len = sizeof(src_addr);
-#endif
-    int n;
-#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
-       /* using poll */
-    struct pollfd fds[1]; /* for the poll */
-#ifdef MINIUPNPC_IGNORE_EINTR
-    do {
-#endif
-        fds[0].fd = socket;
-        fds[0].events = POLLIN;
-        n = poll(fds, 1, timeout);
-#ifdef MINIUPNPC_IGNORE_EINTR
-    } while(n < 0 && errno == EINTR);
-#endif
-    if(n < 0) {
-        PRINT_SOCKET_ERROR("poll");
-        return -1;
-    } else if(n == 0) {
-               /* timeout */
-        return 0;
-    }
-#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
-       /* using select under _WIN32 and amigaos */
-    fd_set socketSet;
-    TIMEVAL timeval;
-    FD_ZERO(&socketSet);
-    FD_SET(socket, &socketSet);
-    timeval.tv_sec = timeout / 1000;
-    timeval.tv_usec = (timeout % 1000) * 1000;
-    n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
-    if(n < 0) {
-        PRINT_SOCKET_ERROR("select");
-        return -1;
-    } else if(n == 0) {
-        return 0;
-    }
-#endif
-#ifdef MINIUPNPC_GET_SRC_ADDR
-       n = recvfrom(socket, data, length, 0,
-                    (struct sockaddr *)&src_addr, &src_addr_len);
-#else
-       n = recv(socket, data, length, 0);
-#endif
-       if(n<0) {
-               PRINT_SOCKET_ERROR("recv");
-       }
-#ifdef MINIUPNPC_GET_SRC_ADDR
-       if (src_addr.ss_family == AF_INET6) {
-               const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr;
-#ifdef DEBUG
-               printf("scope_id=%u\n", src_addr6->sin6_scope_id);
-#endif
-               if(scope_id)
-                       *scope_id = src_addr6->sin6_scope_id;
-       }
-#endif
-       return n;
-}
-
-
diff --git a/third-party/miniupnp/receivedata.h b/third-party/miniupnp/receivedata.h
deleted file mode 100644 (file)
index 0520a11..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id: receivedata.h,v 1.4 2012/09/27 15:42:10 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2011-2012 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef RECEIVEDATA_H_INCLUDED
-#define RECEIVEDATA_H_INCLUDED
-
-/* Reads data from the specified socket.
- * Returns the number of bytes read if successful, zero if no bytes were
- * read or if we timed out. Returns negative if there was an error. */
-int receivedata(int socket,
-                char * data, int length,
-                int timeout, unsigned int * scope_id);
-
-#endif
-
diff --git a/third-party/miniupnp/updateminiupnpcstrings.sh b/third-party/miniupnp/updateminiupnpcstrings.sh
deleted file mode 100755 (executable)
index 0639da6..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#! /bin/sh
-# $Id: updateminiupnpcstrings.sh,v 1.7 2011/01/04 11:41:53 nanard Exp $
-# project miniupnp : http://miniupnp.free.fr/
-# (c) 2009 Thomas Bernard
-
-VERSION_FILE="$1"
-TEMPLATE_FILE="$2"
-FILE="$3"
-TMPFILE="$3.tmp"
-
-# detecting the OS name and version
-OS_NAME=`uname -s`
-OS_VERSION=`uname -r`
-if [ -f /etc/debian_version ]; then
-       OS_NAME=Debian
-       OS_VERSION=`cat /etc/debian_version`
-fi
-# use lsb_release (Linux Standard Base) when available
-LSB_RELEASE=`which lsb_release`
-if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then
-       OS_NAME=`${LSB_RELEASE} -i -s`
-       OS_VERSION=`${LSB_RELEASE} -r -s`
-       case $OS_NAME in
-               Debian)
-                       #OS_VERSION=`${LSB_RELEASE} -c -s`
-                       ;;
-               Ubuntu)
-                       #OS_VERSION=`${LSB_RELEASE} -c -s`
-                       ;;
-       esac
-fi
-
-# on AmigaOS 3, uname -r returns "unknown", so we use uname -v
-if [ "$OS_NAME" = "AmigaOS" ]; then
-       if [ "$OS_VERSION" = "unknown" ]; then
-               OS_VERSION=`uname -v`
-       fi
-fi
-
-echo "Detected OS [$OS_NAME] version [$OS_VERSION]"
-MINIUPNPC_VERSION=`cat "${VERSION_FILE}"`
-echo "MiniUPnPc version [${MINIUPNPC_VERSION}]"
-
-EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|"
-#echo $EXPR
-test -f "${FILE}.in"
-echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE."
-sed -e "$EXPR" < "$TEMPLATE_FILE" > "$TMPFILE"
-
-EXPR="s|MINIUPNPC_VERSION_STRING \".*\"|MINIUPNPC_VERSION_STRING \"${MINIUPNPC_VERSION}\"|"
-echo "setting MINIUPNPC_VERSION_STRING macro value to ${MINIUPNPC_VERSION} in $FILE."
-sed -e "$EXPR" < "$TMPFILE" > "$FILE"
-rm "$TMPFILE"
-
diff --git a/third-party/miniupnp/upnpcommands.c b/third-party/miniupnp/upnpcommands.c
deleted file mode 100644 (file)
index ad69781..0000000
+++ /dev/null
@@ -1,1098 +0,0 @@
-/* $Id: upnpcommands.c,v 1.42 2014/01/31 13:18:25 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2012 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "upnpcommands.h"
-#include "miniupnpc.h"
-#include "portlistingparse.h"
-
-static UNSIGNED_INTEGER
-my_atoui(const char * s)
-{
-       return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
-}
-
-/*
- * */
-LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesSent(const char * controlURL,
-                                       const char * servicetype)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       unsigned int r = 0;
-       char * p;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetTotalBytesSent", 0, &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       /*DisplayNameValueList(buffer, bufsize);*/
-       free(buffer); buffer = NULL;
-       p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
-       r = my_atoui(p);
-       ClearNameValueList(&pdata);
-       return r;
-}
-
-/*
- * */
-LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesReceived(const char * controlURL,
-                                               const char * servicetype)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       unsigned int r = 0;
-       char * p;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetTotalBytesReceived", 0, &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       /*DisplayNameValueList(buffer, bufsize);*/
-       free(buffer); buffer = NULL;
-       p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
-       r = my_atoui(p);
-       ClearNameValueList(&pdata);
-       return r;
-}
-
-/*
- * */
-LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalPacketsSent(const char * controlURL,
-                                               const char * servicetype)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       unsigned int r = 0;
-       char * p;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetTotalPacketsSent", 0, &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       /*DisplayNameValueList(buffer, bufsize);*/
-       free(buffer); buffer = NULL;
-       p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
-       r = my_atoui(p);
-       ClearNameValueList(&pdata);
-       return r;
-}
-
-/*
- * */
-LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalPacketsReceived(const char * controlURL,
-                                               const char * servicetype)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       unsigned int r = 0;
-       char * p;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetTotalPacketsReceived", 0, &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       /*DisplayNameValueList(buffer, bufsize);*/
-       free(buffer); buffer = NULL;
-       p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
-       r = my_atoui(p);
-       ClearNameValueList(&pdata);
-       return r;
-}
-
-/* UPNP_GetStatusInfo() call the corresponding UPNP method
- * returns the current status and uptime */
-LIBSPEC int
-UPNP_GetStatusInfo(const char * controlURL,
-                               const char * servicetype,
-                               char * status,
-                               unsigned int * uptime,
-                               char * lastconnerror)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       char * p;
-       char * up;
-       char * err;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!status && !uptime)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetStatusInfo", 0, &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       /*DisplayNameValueList(buffer, bufsize);*/
-       free(buffer); buffer = NULL;
-       up = GetValueFromNameValueList(&pdata, "NewUptime");
-       p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
-       err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
-       if(p && up)
-         ret = UPNPCOMMAND_SUCCESS;
-
-       if(status) {
-               if(p){
-                       strncpy(status, p, 64 );
-                       status[63] = '\0';
-               }else
-                       status[0]= '\0';
-       }
-
-       if(uptime) {
-               if(up)
-                       sscanf(up,"%u",uptime);
-               else
-                       uptime = 0;
-       }
-
-       if(lastconnerror) {
-               if(err) {
-                       strncpy(lastconnerror, err, 64 );
-                       lastconnerror[63] = '\0';
-               } else
-                       lastconnerror[0] = '\0';
-       }
-
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-       ClearNameValueList(&pdata);
-       return ret;
-}
-
-/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
- * returns the connection type */
-LIBSPEC int
-UPNP_GetConnectionTypeInfo(const char * controlURL,
-                           const char * servicetype,
-                           char * connectionType)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       char * p;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!connectionType)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetConnectionTypeInfo", 0, &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       p = GetValueFromNameValueList(&pdata, "NewConnectionType");
-       /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
-       /* PossibleConnectionTypes will have several values.... */
-       if(p) {
-               strncpy(connectionType, p, 64 );
-               connectionType[63] = '\0';
-               ret = UPNPCOMMAND_SUCCESS;
-       } else
-               connectionType[0] = '\0';
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-       ClearNameValueList(&pdata);
-       return ret;
-}
-
-/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
- * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
- * One of the values can be null
- * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
- * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
-LIBSPEC int
-UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
-                             const char * servicetype,
-                             unsigned int * bitrateDown,
-                             unsigned int * bitrateUp)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-       char * down;
-       char * up;
-       char * p;
-
-       if(!bitrateDown && !bitrateUp)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       /* shouldn't we use GetCommonLinkProperties ? */
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetCommonLinkProperties", 0, &bufsize))) {
-                                     /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       /*DisplayNameValueList(buffer, bufsize);*/
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
-       /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
-       down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
-       up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
-       /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
-       /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
-       if(down && up)
-               ret = UPNPCOMMAND_SUCCESS;
-
-       if(bitrateDown) {
-               if(down)
-                       sscanf(down,"%u",bitrateDown);
-               else
-                       *bitrateDown = 0;
-       }
-
-       if(bitrateUp) {
-               if(up)
-                       sscanf(up,"%u",bitrateUp);
-               else
-                       *bitrateUp = 0;
-       }
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-       ClearNameValueList(&pdata);
-       return ret;
-}
-
-
-/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
- * if the third arg is not null the value is copied to it.
- * at least 16 bytes must be available
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR Either an UPnP error code or an unknown error.
- *
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- */
-LIBSPEC int
-UPNP_GetExternalIPAddress(const char * controlURL,
-                          const char * servicetype,
-                          char * extIpAdd)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       char * p;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!extIpAdd || !controlURL || !servicetype)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetExternalIPAddress", 0, &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       /*DisplayNameValueList(buffer, bufsize);*/
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
-       p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
-       if(p) {
-               strncpy(extIpAdd, p, 16 );
-               extIpAdd[15] = '\0';
-               ret = UPNPCOMMAND_SUCCESS;
-       } else
-               extIpAdd[0] = '\0';
-
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-
-       ClearNameValueList(&pdata);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
-                    const char * extPort,
-                                       const char * inPort,
-                                       const char * inClient,
-                                       const char * desc,
-                                       const char * proto,
-                    const char * remoteHost,
-                    const char * leaseDuration)
-{
-       struct UPNParg * AddPortMappingArgs;
-       char * buffer;
-       int bufsize;
-       struct NameValueParserData pdata;
-       const char * resVal;
-       int ret;
-
-       if(!inPort || !inClient || !proto || !extPort)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
-       AddPortMappingArgs[0].elt = "NewRemoteHost";
-       AddPortMappingArgs[0].val = remoteHost;
-       AddPortMappingArgs[1].elt = "NewExternalPort";
-       AddPortMappingArgs[1].val = extPort;
-       AddPortMappingArgs[2].elt = "NewProtocol";
-       AddPortMappingArgs[2].val = proto;
-       AddPortMappingArgs[3].elt = "NewInternalPort";
-       AddPortMappingArgs[3].val = inPort;
-       AddPortMappingArgs[4].elt = "NewInternalClient";
-       AddPortMappingArgs[4].val = inClient;
-       AddPortMappingArgs[5].elt = "NewEnabled";
-       AddPortMappingArgs[5].val = "1";
-       AddPortMappingArgs[6].elt = "NewPortMappingDescription";
-       AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
-       AddPortMappingArgs[7].elt = "NewLeaseDuration";
-       AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "AddPortMapping", AddPortMappingArgs,
-                                       &bufsize))) {
-               free(AddPortMappingArgs);
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       /*DisplayNameValueList(buffer, bufsize);*/
-       /*buffer[bufsize] = '\0';*/
-       /*puts(buffer);*/
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       resVal = GetValueFromNameValueList(&pdata, "errorCode");
-       if(resVal) {
-               /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(resVal, "%d", &ret);
-       } else {
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-       ClearNameValueList(&pdata);
-       free(AddPortMappingArgs);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
-                       const char * extPort, const char * proto,
-                       const char * remoteHost)
-{
-       /*struct NameValueParserData pdata;*/
-       struct UPNParg * DeletePortMappingArgs;
-       char * buffer;
-       int bufsize;
-       struct NameValueParserData pdata;
-       const char * resVal;
-       int ret;
-
-       if(!extPort || !proto)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
-       DeletePortMappingArgs[0].elt = "NewRemoteHost";
-       DeletePortMappingArgs[0].val = remoteHost;
-       DeletePortMappingArgs[1].elt = "NewExternalPort";
-       DeletePortMappingArgs[1].val = extPort;
-       DeletePortMappingArgs[2].elt = "NewProtocol";
-       DeletePortMappingArgs[2].val = proto;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                      "DeletePortMapping",
-                                      DeletePortMappingArgs, &bufsize))) {
-               free(DeletePortMappingArgs);
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       /*DisplayNameValueList(buffer, bufsize);*/
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       resVal = GetValueFromNameValueList(&pdata, "errorCode");
-       if(resVal) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(resVal, "%d", &ret);
-       } else {
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-       ClearNameValueList(&pdata);
-       free(DeletePortMappingArgs);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_GetGenericPortMappingEntry(const char * controlURL,
-                                const char * servicetype,
-                                                        const char * index,
-                                                        char * extPort,
-                                                        char * intClient,
-                                                        char * intPort,
-                                                        char * protocol,
-                                                        char * desc,
-                                                        char * enabled,
-                                                        char * rHost,
-                                                        char * duration)
-{
-       struct NameValueParserData pdata;
-       struct UPNParg * GetPortMappingArgs;
-       char * buffer;
-       int bufsize;
-       char * p;
-       int r = UPNPCOMMAND_UNKNOWN_ERROR;
-       if(!index)
-               return UPNPCOMMAND_INVALID_ARGS;
-       intClient[0] = '\0';
-       intPort[0] = '\0';
-       GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
-       GetPortMappingArgs[0].elt = "NewPortMappingIndex";
-       GetPortMappingArgs[0].val = index;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                      "GetGenericPortMappingEntry",
-                                      GetPortMappingArgs, &bufsize))) {
-               free(GetPortMappingArgs);
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-
-       p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
-       if(p && rHost)
-       {
-               strncpy(rHost, p, 64);
-               rHost[63] = '\0';
-       }
-       p = GetValueFromNameValueList(&pdata, "NewExternalPort");
-       if(p && extPort)
-       {
-               strncpy(extPort, p, 6);
-               extPort[5] = '\0';
-               r = UPNPCOMMAND_SUCCESS;
-       }
-       p = GetValueFromNameValueList(&pdata, "NewProtocol");
-       if(p && protocol)
-       {
-               strncpy(protocol, p, 4);
-               protocol[3] = '\0';
-       }
-       p = GetValueFromNameValueList(&pdata, "NewInternalClient");
-       if(p && intClient)
-       {
-               strncpy(intClient, p, 16);
-               intClient[15] = '\0';
-               r = 0;
-       }
-       p = GetValueFromNameValueList(&pdata, "NewInternalPort");
-       if(p && intPort)
-       {
-               strncpy(intPort, p, 6);
-               intPort[5] = '\0';
-       }
-       p = GetValueFromNameValueList(&pdata, "NewEnabled");
-       if(p && enabled)
-       {
-               strncpy(enabled, p, 4);
-               enabled[3] = '\0';
-       }
-       p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
-       if(p && desc)
-       {
-               strncpy(desc, p, 80);
-               desc[79] = '\0';
-       }
-       p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
-       if(p && duration)
-       {
-               strncpy(duration, p, 16);
-               duration[15] = '\0';
-       }
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               r = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &r);
-       }
-       ClearNameValueList(&pdata);
-       free(GetPortMappingArgs);
-       return r;
-}
-
-LIBSPEC int
-UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
-                                   const char * servicetype,
-                                   unsigned int * numEntries)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       char* p;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetPortMappingNumberOfEntries", 0,
-                                       &bufsize))) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-#ifdef DEBUG
-       DisplayNameValueList(buffer, bufsize);
-#endif
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-
-       p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
-       if(numEntries && p) {
-               *numEntries = 0;
-               sscanf(p, "%u", numEntries);
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-
-       ClearNameValueList(&pdata);
-       return ret;
-}
-
-/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
- * the result is returned in the intClient and intPort strings
- * please provide 16 and 6 bytes of data */
-LIBSPEC int
-UPNP_GetSpecificPortMappingEntry(const char * controlURL,
-                                 const char * servicetype,
-                                 const char * extPort,
-                                 const char * proto,
-                                 const char * remoteHost,
-                                 char * intClient,
-                                 char * intPort,
-                                 char * desc,
-                                 char * enabled,
-                                 char * leaseDuration)
-{
-       struct NameValueParserData pdata;
-       struct UPNParg * GetPortMappingArgs;
-       char * buffer;
-       int bufsize;
-       char * p;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!intPort || !intClient || !extPort || !proto)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
-       GetPortMappingArgs[0].elt = "NewRemoteHost";
-       GetPortMappingArgs[0].val = remoteHost;
-       GetPortMappingArgs[1].elt = "NewExternalPort";
-       GetPortMappingArgs[1].val = extPort;
-       GetPortMappingArgs[2].elt = "NewProtocol";
-       GetPortMappingArgs[2].val = proto;
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetSpecificPortMappingEntry",
-                                       GetPortMappingArgs, &bufsize))) {
-               free(GetPortMappingArgs);
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       /*DisplayNameValueList(buffer, bufsize);*/
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-
-       p = GetValueFromNameValueList(&pdata, "NewInternalClient");
-       if(p) {
-               strncpy(intClient, p, 16);
-               intClient[15] = '\0';
-               ret = UPNPCOMMAND_SUCCESS;
-       } else
-               intClient[0] = '\0';
-
-       p = GetValueFromNameValueList(&pdata, "NewInternalPort");
-       if(p) {
-               strncpy(intPort, p, 6);
-               intPort[5] = '\0';
-       } else
-               intPort[0] = '\0';
-
-       p = GetValueFromNameValueList(&pdata, "NewEnabled");
-       if(p && enabled) {
-               strncpy(enabled, p, 4);
-               enabled[3] = '\0';
-       }
-
-       p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
-       if(p && desc) {
-               strncpy(desc, p, 80);
-               desc[79] = '\0';
-       }
-
-       p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
-       if(p && leaseDuration)
-       {
-               strncpy(leaseDuration, p, 16);
-               leaseDuration[15] = '\0';
-       }
-
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-
-       ClearNameValueList(&pdata);
-       free(GetPortMappingArgs);
-       return ret;
-}
-
-/* UPNP_GetListOfPortMappings()
- *
- * Possible UPNP Error codes :
- * 606 Action not Authorized
- * 730 PortMappingNotFound - no port mapping is found in the specified range.
- * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
- *                              consistent.
- */
-LIBSPEC int
-UPNP_GetListOfPortMappings(const char * controlURL,
-                           const char * servicetype,
-                           const char * startPort,
-                           const char * endPort,
-                           const char * protocol,
-                           const char * numberOfPorts,
-                           struct PortMappingParserData * data)
-{
-       struct NameValueParserData pdata;
-       struct UPNParg * GetListOfPortMappingsArgs;
-       const char * p;
-       char * buffer;
-       int bufsize;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!startPort || !endPort || !protocol)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
-       GetListOfPortMappingsArgs[0].elt = "NewStartPort";
-       GetListOfPortMappingsArgs[0].val = startPort;
-       GetListOfPortMappingsArgs[1].elt = "NewEndPort";
-       GetListOfPortMappingsArgs[1].val = endPort;
-       GetListOfPortMappingsArgs[2].elt = "NewProtocol";
-       GetListOfPortMappingsArgs[2].val = protocol;
-       GetListOfPortMappingsArgs[3].elt = "NewManage";
-       GetListOfPortMappingsArgs[3].val = "1";
-       GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
-       GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
-
-       if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                       "GetListOfPortMappings",
-                                       GetListOfPortMappingsArgs, &bufsize))) {
-               free(GetListOfPortMappingsArgs);
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       free(GetListOfPortMappingsArgs);
-
-       /*DisplayNameValueList(buffer, bufsize);*/
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-
-       /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
-       /*if(p) {
-               printf("NewPortListing : %s\n", p);
-       }*/
-       /*printf("NewPortListing(%d chars) : %s\n",
-              pdata.portListingLength, pdata.portListing);*/
-       if(pdata.portListing)
-       {
-               /*struct PortMapping * pm;
-               int i = 0;*/
-               ParsePortListing(pdata.portListing, pdata.portListingLength,
-                                data);
-               ret = UPNPCOMMAND_SUCCESS;
-               /*
-               for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
-               {
-                       printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
-                              i, pm->protocol, pm->externalPort, pm->internalClient,
-                              pm->internalPort,
-                              pm->description, pm->remoteHost);
-                       i++;
-               }
-               */
-               /*FreePortListing(&data);*/
-       }
-
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p) {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-       ClearNameValueList(&pdata);
-
-       /*printf("%.*s", bufsize, buffer);*/
-
-       return ret;
-}
-
-/* IGD:2, functions for service WANIPv6FirewallControl:1 */
-LIBSPEC int
-UPNP_GetFirewallStatus(const char * controlURL,
-                               const char * servicetype,
-                               int * firewallEnabled,
-                               int * inboundPinholeAllowed)
-{
-       struct NameValueParserData pdata;
-       char * buffer;
-       int bufsize;
-       char * fe, *ipa, *p;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!firewallEnabled || !inboundPinholeAllowed)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                  "GetFirewallStatus", 0, &bufsize);
-       if(!buffer) {
-               return UPNPCOMMAND_HTTP_ERROR;
-       }
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
-       ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
-       if(ipa && fe)
-               ret = UPNPCOMMAND_SUCCESS;
-       if(fe)
-               *firewallEnabled = my_atoui(fe);
-       /*else
-               *firewallEnabled = 0;*/
-       if(ipa)
-               *inboundPinholeAllowed = my_atoui(ipa);
-       /*else
-               *inboundPinholeAllowed = 0;*/
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p)
-       {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-       ClearNameValueList(&pdata);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    int * opTimeout)
-{
-       struct UPNParg * GetOutboundPinholeTimeoutArgs;
-       char * buffer;
-       int bufsize;
-       struct NameValueParserData pdata;
-       const char * resVal;
-       char * p;
-       int ret;
-
-       if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
-       GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
-       GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
-       GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
-       GetOutboundPinholeTimeoutArgs[1].val = remotePort;
-       GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
-       GetOutboundPinholeTimeoutArgs[2].val = proto;
-       GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
-       GetOutboundPinholeTimeoutArgs[3].val = intPort;
-       GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
-       GetOutboundPinholeTimeoutArgs[4].val = intClient;
-       buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                  "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
-       if(!buffer)
-               return UPNPCOMMAND_HTTP_ERROR;
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       resVal = GetValueFromNameValueList(&pdata, "errorCode");
-       if(resVal)
-       {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(resVal, "%d", &ret);
-       }
-       else
-       {
-               ret = UPNPCOMMAND_SUCCESS;
-               p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
-               if(p)
-                       *opTimeout = my_atoui(p);
-       }
-       ClearNameValueList(&pdata);
-       free(GetOutboundPinholeTimeoutArgs);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_AddPinhole(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    const char * leaseTime,
-                    char * uniqueID)
-{
-       struct UPNParg * AddPinholeArgs;
-       char * buffer;
-       int bufsize;
-       struct NameValueParserData pdata;
-       const char * resVal;
-       char * p;
-       int ret;
-
-       if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
-       /* RemoteHost can be wilcarded */
-       if(strncmp(remoteHost, "empty", 5)==0)
-       {
-               AddPinholeArgs[0].elt = "RemoteHost";
-               AddPinholeArgs[0].val = "";
-       }
-       else
-       {
-               AddPinholeArgs[0].elt = "RemoteHost";
-               AddPinholeArgs[0].val = remoteHost;
-       }
-       AddPinholeArgs[1].elt = "RemotePort";
-       AddPinholeArgs[1].val = remotePort;
-       AddPinholeArgs[2].elt = "Protocol";
-       AddPinholeArgs[2].val = proto;
-       AddPinholeArgs[3].elt = "InternalPort";
-       AddPinholeArgs[3].val = intPort;
-       if(strncmp(intClient, "empty", 5)==0)
-       {
-               AddPinholeArgs[4].elt = "InternalClient";
-               AddPinholeArgs[4].val = "";
-       }
-       else
-       {
-               AddPinholeArgs[4].elt = "InternalClient";
-               AddPinholeArgs[4].val = intClient;
-       }
-       AddPinholeArgs[5].elt = "LeaseTime";
-       AddPinholeArgs[5].val = leaseTime;
-       buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                  "AddPinhole", AddPinholeArgs, &bufsize);
-       if(!buffer)
-               return UPNPCOMMAND_HTTP_ERROR;
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       p = GetValueFromNameValueList(&pdata, "UniqueID");
-       if(p)
-       {
-               strncpy(uniqueID, p, 8);
-               uniqueID[7] = '\0';
-       }
-       resVal = GetValueFromNameValueList(&pdata, "errorCode");
-       if(resVal)
-       {
-               /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(resVal, "%d", &ret);
-       }
-       else
-       {
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-       ClearNameValueList(&pdata);
-       free(AddPinholeArgs);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
-                    const char * uniqueID,
-                    const char * leaseTime)
-{
-       struct UPNParg * UpdatePinholeArgs;
-       char * buffer;
-       int bufsize;
-       struct NameValueParserData pdata;
-       const char * resVal;
-       int ret;
-
-       if(!uniqueID || !leaseTime)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
-       UpdatePinholeArgs[0].elt = "UniqueID";
-       UpdatePinholeArgs[0].val = uniqueID;
-       UpdatePinholeArgs[1].elt = "NewLeaseTime";
-       UpdatePinholeArgs[1].val = leaseTime;
-       buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                  "UpdatePinhole", UpdatePinholeArgs, &bufsize);
-       if(!buffer)
-               return UPNPCOMMAND_HTTP_ERROR;
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       resVal = GetValueFromNameValueList(&pdata, "errorCode");
-       if(resVal)
-       {
-               /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(resVal, "%d", &ret);
-       }
-       else
-       {
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-       ClearNameValueList(&pdata);
-       free(UpdatePinholeArgs);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
-{
-       /*struct NameValueParserData pdata;*/
-       struct UPNParg * DeletePinholeArgs;
-       char * buffer;
-       int bufsize;
-       struct NameValueParserData pdata;
-       const char * resVal;
-       int ret;
-
-       if(!uniqueID)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
-       DeletePinholeArgs[0].elt = "UniqueID";
-       DeletePinholeArgs[0].val = uniqueID;
-       buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                  "DeletePinhole", DeletePinholeArgs, &bufsize);
-       if(!buffer)
-               return UPNPCOMMAND_HTTP_ERROR;
-       /*DisplayNameValueList(buffer, bufsize);*/
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-       resVal = GetValueFromNameValueList(&pdata, "errorCode");
-       if(resVal)
-       {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(resVal, "%d", &ret);
-       }
-       else
-       {
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-       ClearNameValueList(&pdata);
-       free(DeletePinholeArgs);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * isWorking)
-{
-       struct NameValueParserData pdata;
-       struct UPNParg * CheckPinholeWorkingArgs;
-       char * buffer;
-       int bufsize;
-       char * p;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!uniqueID)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
-       CheckPinholeWorkingArgs[0].elt = "UniqueID";
-       CheckPinholeWorkingArgs[0].val = uniqueID;
-       buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                  "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
-       if(!buffer)
-               return UPNPCOMMAND_HTTP_ERROR;
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-
-       p = GetValueFromNameValueList(&pdata, "IsWorking");
-       if(p)
-       {
-               *isWorking=my_atoui(p);
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-       else
-               *isWorking = 0;
-
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p)
-       {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-
-       ClearNameValueList(&pdata);
-       free(CheckPinholeWorkingArgs);
-       return ret;
-}
-
-LIBSPEC int
-UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * packets)
-{
-       struct NameValueParserData pdata;
-       struct UPNParg * GetPinholePacketsArgs;
-       char * buffer;
-       int bufsize;
-       char * p;
-       int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-       if(!uniqueID)
-               return UPNPCOMMAND_INVALID_ARGS;
-
-       GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
-       GetPinholePacketsArgs[0].elt = "UniqueID";
-       GetPinholePacketsArgs[0].val = uniqueID;
-       buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-                                  "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
-       if(!buffer)
-               return UPNPCOMMAND_HTTP_ERROR;
-       ParseNameValue(buffer, bufsize, &pdata);
-       free(buffer); buffer = NULL;
-
-       p = GetValueFromNameValueList(&pdata, "PinholePackets");
-       if(p)
-       {
-               *packets=my_atoui(p);
-               ret = UPNPCOMMAND_SUCCESS;
-       }
-
-       p = GetValueFromNameValueList(&pdata, "errorCode");
-       if(p)
-       {
-               ret = UPNPCOMMAND_UNKNOWN_ERROR;
-               sscanf(p, "%d", &ret);
-       }
-
-       ClearNameValueList(&pdata);
-       free(GetPinholePacketsArgs);
-       return ret;
-}
-
-
diff --git a/third-party/miniupnp/upnpcommands.h b/third-party/miniupnp/upnpcommands.h
deleted file mode 100644 (file)
index 93d9f3d..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/* $Id: upnpcommands.h,v 1.27 2014/02/17 15:38:26 nanard Exp $ */
-/* Miniupnp project : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2014 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided within this distribution */
-#ifndef UPNPCOMMANDS_H_INCLUDED
-#define UPNPCOMMANDS_H_INCLUDED
-
-#include "upnpreplyparse.h"
-#include "portlistingparse.h"
-#include "declspec.h"
-#include "miniupnpctypes.h"
-
-/* MiniUPnPc return codes : */
-#define UPNPCOMMAND_SUCCESS (0)
-#define UPNPCOMMAND_UNKNOWN_ERROR (-1)
-#define UPNPCOMMAND_INVALID_ARGS (-2)
-#define UPNPCOMMAND_HTTP_ERROR (-3)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesSent(const char * controlURL,
-                                       const char * servicetype);
-
-LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesReceived(const char * controlURL,
-                                               const char * servicetype);
-
-LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalPacketsSent(const char * controlURL,
-                                       const char * servicetype);
-
-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 */
-LIBSPEC int
-UPNP_GetStatusInfo(const char * controlURL,
-                              const char * servicetype,
-                                  char * status,
-                                  unsigned int * uptime,
-                   char * lastconnerror);
-
-/* UPNP_GetConnectionTypeInfo()
- * argument connectionType is a 64 character buffer
- * Return Values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error code */
-LIBSPEC int
-UPNP_GetConnectionTypeInfo(const char * controlURL,
-                           const char * servicetype,
-                                                  char * connectionType);
-
-/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
- * if the third arg is not null the value is copied to it.
- * at least 16 bytes must be available
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR Either an UPnP error code or an unknown error.
- *
- * possible UPnP Errors :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control. */
-LIBSPEC int
-UPNP_GetExternalIPAddress(const char * controlURL,
-                          const char * servicetype,
-                          char * extIpAdd);
-
-/* UPNP_GetLinkLayerMaxBitRates()
- * call WANCommonInterfaceConfig:1#GetCommonLinkProperties
- *
- * return values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code. */
-LIBSPEC int
-UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
-                                                       const char* servicetype,
-                                                       unsigned int * bitrateDown,
-                                                       unsigned int * bitrateUp);
-
-/* UPNP_AddPortMapping()
- * if desc is NULL, it will be defaulted to "libminiupnpc"
- * remoteHost is usually NULL because IGD don't support it.
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR. Either an UPnP error code or an unknown error.
- *
- * List of possible UPnP errors for AddPortMapping :
- * errorCode errorDescription (short) - Description (long)
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization and
- *                             the sender was not authorized.
- * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
- *                                   wild-carded
- * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
- * 718 ConflictInMappingEntry - The port mapping entry specified conflicts
- *                     with a mapping assigned previously to another client
- * 724 SamePortValuesRequired - Internal and External port values
- *                              must be the same
- * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
- *                  permanent lease times on port mappings
- * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
- *                             and cannot be a specific IP address or DNS name
- * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and
- *                                        cannot be a specific port value
- * 728 NoPortMapsAvailable - There are not enough free ports available to
- *                           complete port mapping.
- * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
- *                                   due to conflict with other mechanisms.
- * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
- */
-LIBSPEC int
-UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
-                    const char * extPort,
-                                   const char * inPort,
-                                       const char * inClient,
-                                       const char * desc,
-                    const char * proto,
-                    const char * remoteHost,
-                    const char * leaseDuration);
-
-/* UPNP_DeletePortMapping()
- * Use same argument values as what was used for AddPortMapping().
- * remoteHost is usually NULL because IGD don't support it.
- * Return Values :
- * 0 : SUCCESS
- * NON ZERO : error. Either an UPnP error code or an undefined error.
- *
- * List of possible UPnP errors for DeletePortMapping :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 714 NoSuchEntryInArray - The specified value does not exist in the array */
-LIBSPEC int
-UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
-                       const char * extPort, const char * proto,
-                       const char * remoteHost);
-
-/* UPNP_GetPortMappingNumberOfEntries()
- * not supported by all routers */
-LIBSPEC int
-UPNP_GetPortMappingNumberOfEntries(const char* controlURL,
-                                   const char* servicetype,
-                                   unsigned int * num);
-
-/* UPNP_GetSpecificPortMappingEntry()
- *    retrieves an existing port mapping
- * params :
- *  in   extPort
- *  in   proto
- *  in   remoteHost
- *  out  intClient (16 bytes)
- *  out  intPort (6 bytes)
- *  out  desc (80 bytes)
- *  out  enabled (4 bytes)
- *  out  leaseDuration (16 bytes)
- *
- * return value :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code.
- *
- * List of possible UPnP errors for _GetSpecificPortMappingEntry :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 714 NoSuchEntryInArray - The specified value does not exist in the array.
- */
-LIBSPEC int
-UPNP_GetSpecificPortMappingEntry(const char * controlURL,
-                                 const char * servicetype,
-                                 const char * extPort,
-                                 const char * proto,
-                                 const char * remoteHost,
-                                 char * intClient,
-                                 char * intPort,
-                                 char * desc,
-                                 char * enabled,
-                                 char * leaseDuration);
-
-/* UPNP_GetGenericPortMappingEntry()
- * params :
- *  in   index
- *  out  extPort (6 bytes)
- *  out  intClient (16 bytes)
- *  out  intPort (6 bytes)
- *  out  protocol (4 bytes)
- *  out  desc (80 bytes)
- *  out  enabled (4 bytes)
- *  out  rHost (64 bytes)
- *  out  duration (16 bytes)
- *
- * return value :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code.
- *
- * Possible UPNP Error codes :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds
- */
-LIBSPEC int
-UPNP_GetGenericPortMappingEntry(const char * controlURL,
-                                const char * servicetype,
-                                                               const char * index,
-                                                               char * extPort,
-                                                               char * intClient,
-                                                               char * intPort,
-                                                               char * protocol,
-                                                               char * desc,
-                                                               char * enabled,
-                                                               char * rHost,
-                                                               char * duration);
-
-/* UPNP_GetListOfPortMappings()      Available in IGD v2
- *
- *
- * Possible UPNP Error codes :
- * 606 Action not Authorized
- * 730 PortMappingNotFound - no port mapping is found in the specified range.
- * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
- *                              consistent.
- */
-LIBSPEC int
-UPNP_GetListOfPortMappings(const char * controlURL,
-                           const char * servicetype,
-                           const char * startPort,
-                           const char * endPort,
-                           const char * protocol,
-                           const char * numberOfPorts,
-                           struct PortMappingParserData * data);
-
-/* IGD:2, functions for service WANIPv6FirewallControl:1 */
-LIBSPEC int
-UPNP_GetFirewallStatus(const char * controlURL,
-                               const char * servicetype,
-                               int * firewallEnabled,
-                               int * inboundPinholeAllowed);
-
-LIBSPEC int
-UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    int * opTimeout);
-
-LIBSPEC int
-UPNP_AddPinhole(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    const char * leaseTime,
-                    char * uniqueID);
-
-LIBSPEC int
-UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
-                    const char * uniqueID,
-                    const char * leaseTime);
-
-LIBSPEC int
-UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID);
-
-LIBSPEC int
-UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * isWorking);
-
-LIBSPEC int
-UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * packets);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/third-party/miniupnp/upnpreplyparse.c b/third-party/miniupnp/upnpreplyparse.c
deleted file mode 100644 (file)
index dafa263..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* $Id: upnpreplyparse.c,v 1.15 2013/06/06 21:36:40 nanard Exp $ */
-/* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2006-2013 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "upnpreplyparse.h"
-#include "minixml.h"
-
-static void
-NameValueParserStartElt(void * d, const char * name, int l)
-{
-       struct NameValueParserData * data = (struct NameValueParserData *)d;
-       data->topelt = 1;
-    if(l>63)
-        l = 63;
-    memcpy(data->curelt, name, l);
-    data->curelt[l] = '\0';
-       data->cdata = NULL;
-       data->cdatalen = 0;
-}
-
-static void
-NameValueParserEndElt(void * d, const char * name, int l)
-{
-    struct NameValueParserData * data = (struct NameValueParserData *)d;
-    struct NameValue * nv;
-       (void)name;
-       (void)l;
-       if(!data->topelt)
-               return;
-       if(strcmp(data->curelt, "NewPortListing") != 0)
-       {
-               int l;
-               /* standard case. Limited to n chars strings */
-               l = data->cdatalen;
-           nv = malloc(sizeof(struct NameValue));
-           if(l>=(int)sizeof(nv->value))
-               l = sizeof(nv->value) - 1;
-           strncpy(nv->name, data->curelt, 64);
-               nv->name[63] = '\0';
-               if(data->cdata != NULL)
-               {
-                       memcpy(nv->value, data->cdata, l);
-                       nv->value[l] = '\0';
-               }
-               else
-               {
-                       nv->value[0] = '\0';
-               }
-           LIST_INSERT_HEAD( &(data->head), nv, entries);
-       }
-       data->cdata = NULL;
-       data->cdatalen = 0;
-       data->topelt = 0;
-}
-
-static void
-NameValueParserGetData(void * d, const char * datas, int l)
-{
-    struct NameValueParserData * data = (struct NameValueParserData *)d;
-       if(strcmp(data->curelt, "NewPortListing") == 0)
-       {
-               /* specific case for NewPortListing which is a XML Document */
-               data->portListing = malloc(l + 1);
-               if(!data->portListing)
-               {
-                       /* malloc error */
-                       return;
-               }
-               memcpy(data->portListing, datas, l);
-               data->portListing[l] = '\0';
-               data->portListingLength = l;
-       }
-       else
-       {
-               /* standard case. */
-               data->cdata = datas;
-               data->cdatalen = l;
-       }
-}
-
-void
-ParseNameValue(const char * buffer, int bufsize,
-               struct NameValueParserData * data)
-{
-    struct xmlparser parser;
-    LIST_INIT(&(data->head));
-       data->portListing = NULL;
-       data->portListingLength = 0;
-    /* init xmlparser object */
-    parser.xmlstart = buffer;
-    parser.xmlsize = bufsize;
-    parser.data = data;
-    parser.starteltfunc = NameValueParserStartElt;
-    parser.endeltfunc = NameValueParserEndElt;
-    parser.datafunc = NameValueParserGetData;
-       parser.attfunc = 0;
-    parsexml(&parser);
-}
-
-void
-ClearNameValueList(struct NameValueParserData * pdata)
-{
-    struct NameValue * nv;
-       if(pdata->portListing)
-       {
-               free(pdata->portListing);
-               pdata->portListing = NULL;
-               pdata->portListingLength = 0;
-       }
-    while((nv = pdata->head.lh_first) != NULL)
-    {
-        LIST_REMOVE(nv, entries);
-        free(nv);
-    }
-}
-
-char *
-GetValueFromNameValueList(struct NameValueParserData * pdata,
-                          const char * Name)
-{
-    struct NameValue * nv;
-    char * p = NULL;
-    for(nv = pdata->head.lh_first;
-        (nv != NULL) && (p == NULL);
-        nv = nv->entries.le_next)
-    {
-        if(strcmp(nv->name, Name) == 0)
-            p = nv->value;
-    }
-    return p;
-}
-
-#if 0
-/* useless now that minixml ignores namespaces by itself */
-char *
-GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
-                                  const char * Name)
-{
-       struct NameValue * nv;
-       char * p = NULL;
-       char * pname;
-       for(nv = pdata->head.lh_first;
-           (nv != NULL) && (p == NULL);
-               nv = nv->entries.le_next)
-       {
-               pname = strrchr(nv->name, ':');
-               if(pname)
-                       pname++;
-               else
-                       pname = nv->name;
-               if(strcmp(pname, Name)==0)
-                       p = nv->value;
-       }
-       return p;
-}
-#endif
-
-/* debug all-in-one function
- * do parsing then display to stdout */
-#ifdef DEBUG
-void
-DisplayNameValueList(char * buffer, int bufsize)
-{
-    struct NameValueParserData pdata;
-    struct NameValue * nv;
-    ParseNameValue(buffer, bufsize, &pdata);
-    for(nv = pdata.head.lh_first;
-        nv != NULL;
-        nv = nv->entries.le_next)
-    {
-        printf("%s = %s\n", nv->name, nv->value);
-    }
-    ClearNameValueList(&pdata);
-}
-#endif
-
diff --git a/third-party/miniupnp/upnpreplyparse.h b/third-party/miniupnp/upnpreplyparse.h
deleted file mode 100644 (file)
index d4e3757..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* $Id: upnpreplyparse.h,v 1.17 2013/06/06 21:36:40 nanard Exp $ */
-/* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2006-2013 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-
-#ifndef UPNPREPLYPARSE_H_INCLUDED
-#define UPNPREPLYPARSE_H_INCLUDED
-
-#if defined(NO_SYS_QUEUE_H) || defined(_WIN32) || defined(__HAIKU__)
-#include "bsdqueue.h"
-#else
-#include <sys/queue.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct NameValue {
-    LIST_ENTRY(NameValue) entries;
-    char name[64];
-    char value[128];
-};
-
-struct NameValueParserData {
-    LIST_HEAD(listhead, NameValue) head;
-    char curelt[64];
-       char * portListing;
-       int portListingLength;
-       int topelt;
-       const char * cdata;
-       int cdatalen;
-};
-
-/* ParseNameValue() */
-void
-ParseNameValue(const char * buffer, int bufsize,
-               struct NameValueParserData * data);
-
-/* ClearNameValueList() */
-void
-ClearNameValueList(struct NameValueParserData * pdata);
-
-/* GetValueFromNameValueList() */
-char *
-GetValueFromNameValueList(struct NameValueParserData * pdata,
-                          const char * Name);
-
-#if 0
-/* GetValueFromNameValueListIgnoreNS() */
-char *
-GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
-                                  const char * Name);
-#endif
-
-/* DisplayNameValueList() */
-#ifdef DEBUG
-void
-DisplayNameValueList(char * buffer, int bufsize);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-