mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
Remove third-party code stored in the repo directly
This commit is contained in:
133
third-party/dht/CHANGES
vendored
133
third-party/dht/CHANGES
vendored
@@ -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.
|
||||
19
third-party/dht/LICENCE
vendored
19
third-party/dht/LICENCE
vendored
@@ -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.
|
||||
6
third-party/dht/Makefile.am
vendored
6
third-party/dht/Makefile.am
vendored
@@ -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
|
||||
198
third-party/dht/README
vendored
198
third-party/dht/README
vendored
@@ -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>
|
||||
480
third-party/dht/dht-example.c
vendored
480
third-party/dht/dht-example.c
vendored
@@ -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;
|
||||
}
|
||||
2969
third-party/dht/dht.c
vendored
2969
third-party/dht/dht.c
vendored
File diff suppressed because it is too large
Load Diff
58
third-party/dht/dht.h
vendored
58
third-party/dht/dht.h
vendored
@@ -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);
|
||||
15
third-party/libb64/AUTHORS
vendored
15
third-party/libb64/AUTHORS
vendored
@@ -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
|
||||
|
||||
33
third-party/libb64/CHANGELOG
vendored
33
third-party/libb64/CHANGELOG
vendored
@@ -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.
|
||||
44
third-party/libb64/INSTALL
vendored
44
third-party/libb64/INSTALL
vendored
@@ -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
|
||||
29
third-party/libb64/LICENSE
vendored
29
third-party/libb64/LICENSE
vendored
@@ -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.
|
||||
4
third-party/libb64/Makefile.am
vendored
4
third-party/libb64/Makefile.am
vendored
@@ -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
|
||||
143
third-party/libb64/README
vendored
143
third-party/libb64/README
vendored
@@ -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.
|
||||
29
third-party/libb64/b64/cdecode.h
vendored
29
third-party/libb64/b64/cdecode.h
vendored
@@ -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 */
|
||||
|
||||
32
third-party/libb64/b64/cencode.h
vendored
32
third-party/libb64/b64/cencode.h
vendored
@@ -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 */
|
||||
|
||||
88
third-party/libb64/cdecode.c
vendored
88
third-party/libb64/cdecode.c
vendored
@@ -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;
|
||||
}
|
||||
|
||||
115
third-party/libb64/cencode.c
vendored
115
third-party/libb64/cencode.c
vendored
@@ -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;
|
||||
}
|
||||
|
||||
86
third-party/libnatpmp/Changelog.txt
vendored
86
third-party/libnatpmp/Changelog.txt
vendored
@@ -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
|
||||
|
||||
26
third-party/libnatpmp/LICENSE
vendored
26
third-party/libnatpmp/LICENSE
vendored
@@ -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.
|
||||
|
||||
18
third-party/libnatpmp/Makefile.am
vendored
18
third-party/libnatpmp/Makefile.am
vendored
@@ -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
|
||||
7
third-party/libnatpmp/README
vendored
7
third-party/libnatpmp/README
vendored
@@ -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.
|
||||
|
||||
15
third-party/libnatpmp/declspec.h
vendored
15
third-party/libnatpmp/declspec.h
vendored
@@ -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
|
||||
|
||||
568
third-party/libnatpmp/getgateway.c
vendored
568
third-party/libnatpmp/getgateway.c
vendored
@@ -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 */
|
||||
|
||||
|
||||
49
third-party/libnatpmp/getgateway.h
vendored
49
third-party/libnatpmp/getgateway.h
vendored
@@ -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
|
||||
362
third-party/libnatpmp/natpmp.c
vendored
362
third-party/libnatpmp/natpmp.c
vendored
@@ -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
|
||||
|
||||
215
third-party/libnatpmp/natpmp.h
vendored
215
third-party/libnatpmp/natpmp.h
vendored
@@ -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
|
||||
60
third-party/libnatpmp/wingettimeofday.c
vendored
60
third-party/libnatpmp/wingettimeofday.c
vendored
@@ -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
|
||||
|
||||
39
third-party/libnatpmp/wingettimeofday.h
vendored
39
third-party/libnatpmp/wingettimeofday.h
vendored
@@ -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
|
||||
19
third-party/libutp/LICENSE
vendored
19
third-party/libutp/LICENSE
vendored
@@ -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.
|
||||
6
third-party/libutp/Makefile.am
vendored
6
third-party/libutp/Makefile.am
vendored
@@ -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
|
||||
66
third-party/libutp/README.md
vendored
66
third-party/libutp/README.md
vendored
@@ -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/
|
||||
11
third-party/libutp/StdAfx.h
vendored
11
third-party/libutp/StdAfx.h
vendored
@@ -1,11 +0,0 @@
|
||||
#if !defined(AFX_STDAFX_H__C1470942_E9DA_4913_BEF1_9BA7584E595B__INCLUDED_)
|
||||
#define AFX_STDAFX_H__C1470942_E9DA_4913_BEF1_9BA7584E595B__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
// I don't have anything to put here, but some projects use precompiled headers,
|
||||
// so I include StdAfx.h anyway, so they don't have to edit the files to compile normally.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__C1470942_E9DA_4913_BEF1_9BA7584E595B__INCLUDED_)
|
||||
186
third-party/libutp/templates.h
vendored
186
third-party/libutp/templates.h
vendored
@@ -1,186 +0,0 @@
|
||||
#ifndef __TEMPLATES_H__
|
||||
#define __TEMPLATES_H__
|
||||
|
||||
#include "utypes.h"
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(POSIX)
|
||||
/* Allow over-writing FORCEINLINE from makefile because gcc 3.4.4 for buffalo
|
||||
doesn't seem to support __attribute__((always_inline)) in -O0 build
|
||||
(strangely, it works in -Os build) */
|
||||
#ifndef FORCEINLINE
|
||||
// The always_inline attribute asks gcc to inline the function even if no optimization is being requested.
|
||||
// This macro should be used exclusive-or with the inline directive (use one or the other but not both)
|
||||
// since Microsoft uses __forceinline to also mean inline,
|
||||
// and this code is following a Microsoft compatibility model.
|
||||
// Just setting the attribute without also specifying the inline directive apparently won't inline the function,
|
||||
// as evidenced by multiply-defined symbols found at link time.
|
||||
#define FORCEINLINE inline __attribute__((always_inline))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
// Used for gcc tool chains accepting but not supporting pragma pack
|
||||
// See http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html
|
||||
#define PACKED_ATTRIBUTE __attribute__((__packed__))
|
||||
#else
|
||||
#define PACKED_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define ALIGNED_ATTRIBUTE(x) __attribute__((aligned (x)))
|
||||
#else
|
||||
#define ALIGNED_ATTRIBUTE(x)
|
||||
#endif
|
||||
|
||||
// Utility templates
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
template <typename T> static inline T min(T a, T b) { if (a < b) return a; return b; }
|
||||
template <typename T> static inline T max(T a, T b) { if (a > b) return a; return b; }
|
||||
|
||||
template <typename T> static inline T min(T a, T b, T c) { return min(min(a,b),c); }
|
||||
template <typename T> static inline T max(T a, T b, T c) { return max(max(a,b),c); }
|
||||
template <typename T> static inline T clamp(T v, T mi, T ma)
|
||||
{
|
||||
if (v > ma) v = ma;
|
||||
if (v < mi) v = mi;
|
||||
return v;
|
||||
}
|
||||
|
||||
#if (defined(__SVR4) && defined(__sun))
|
||||
#pragma pack(1)
|
||||
#else
|
||||
#pragma pack(push,1)
|
||||
#endif
|
||||
|
||||
namespace aux
|
||||
{
|
||||
FORCEINLINE uint16 host_to_network(uint16 i) { return htons(i); }
|
||||
FORCEINLINE uint32 host_to_network(uint32 i) { return htonl(i); }
|
||||
FORCEINLINE int32 host_to_network(int32 i) { return htonl(i); }
|
||||
FORCEINLINE uint16 network_to_host(uint16 i) { return ntohs(i); }
|
||||
FORCEINLINE uint32 network_to_host(uint32 i) { return ntohl(i); }
|
||||
FORCEINLINE int32 network_to_host(int32 i) { return ntohl(i); }
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct PACKED_ATTRIBUTE big_endian
|
||||
{
|
||||
T operator=(T i) { m_integer = aux::host_to_network(i); return i; }
|
||||
operator T() const { return aux::network_to_host(m_integer); }
|
||||
private:
|
||||
T m_integer;
|
||||
};
|
||||
|
||||
typedef big_endian<int32> int32_big;
|
||||
typedef big_endian<uint32> uint32_big;
|
||||
typedef big_endian<uint16> uint16_big;
|
||||
|
||||
#if (defined(__SVR4) && defined(__sun))
|
||||
#pragma pack(0)
|
||||
#else
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
template<typename T> static inline void zeromem(T *a, size_t count = 1) { memset(a, 0, count * sizeof(T)); }
|
||||
|
||||
typedef int SortCompareProc(const void *, const void *);
|
||||
|
||||
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); }
|
||||
|
||||
|
||||
// WARNING: The template parameter MUST be a POD type!
|
||||
template <typename T, size_t minsize = 16> class Array {
|
||||
protected:
|
||||
T *mem;
|
||||
size_t alloc,count;
|
||||
|
||||
public:
|
||||
Array(size_t init) { Init(init); }
|
||||
Array() { Init(); }
|
||||
~Array() { Free(); }
|
||||
|
||||
void inline Init() { mem = NULL; alloc = count = 0; }
|
||||
void inline Init(size_t init) { Init(); if (init) Resize(init); }
|
||||
size_t inline GetCount() const { return count; }
|
||||
size_t inline GetAlloc() const { return alloc; }
|
||||
void inline SetCount(size_t c) { count = c; }
|
||||
|
||||
inline T& operator[](size_t offset) { assert(offset ==0 || offset<alloc); return mem[offset]; }
|
||||
inline const T& operator[](size_t offset) const { assert(offset ==0 || offset<alloc); return mem[offset]; }
|
||||
|
||||
void inline Resize(size_t a) {
|
||||
if (a == 0) { free(mem); Init(); }
|
||||
else { mem = (T*)realloc(mem, (alloc=a) * sizeof(T)); }
|
||||
}
|
||||
|
||||
void Grow() { Resize(::max<size_t>(minsize, alloc * 2)); }
|
||||
|
||||
inline size_t Append(const T &t) {
|
||||
if (count >= alloc) Grow();
|
||||
size_t r=count++;
|
||||
mem[r] = t;
|
||||
return r;
|
||||
}
|
||||
|
||||
T inline &Append() {
|
||||
if (count >= alloc) Grow();
|
||||
return mem[count++];
|
||||
}
|
||||
|
||||
void inline Compact() {
|
||||
Resize(count);
|
||||
}
|
||||
|
||||
void inline Free() {
|
||||
free(mem);
|
||||
Init();
|
||||
}
|
||||
|
||||
void inline Clear() {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
bool inline MoveUpLast(size_t index) {
|
||||
assert(index < count);
|
||||
size_t c = --count;
|
||||
if (index != c) {
|
||||
mem[index] = mem[c];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool inline MoveUpLastExist(const T &v) {
|
||||
return MoveUpLast(LookupElementExist(v));
|
||||
}
|
||||
|
||||
size_t inline LookupElement(const T &v) const {
|
||||
for(size_t i = 0; i != count; i++)
|
||||
if (mem[i] == v)
|
||||
return i;
|
||||
return (size_t) -1;
|
||||
}
|
||||
|
||||
bool inline HasElement(const T &v) const {
|
||||
return LookupElement(v) != -1;
|
||||
}
|
||||
|
||||
typedef int SortCompareProc(const T *a, const T *b);
|
||||
|
||||
void Sort(SortCompareProc* proc, size_t start, size_t end) {
|
||||
QuickSortT(&mem[start], end - start, proc);
|
||||
}
|
||||
|
||||
void Sort(SortCompareProc* proc, size_t start) {
|
||||
Sort(proc, start, count);
|
||||
}
|
||||
|
||||
void Sort(SortCompareProc* proc) {
|
||||
Sort(proc, 0, count);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //__TEMPLATES_H__
|
||||
2867
third-party/libutp/utp.cpp
vendored
2867
third-party/libutp/utp.cpp
vendored
File diff suppressed because it is too large
Load Diff
165
third-party/libutp/utp.h
vendored
165
third-party/libutp/utp.h
vendored
@@ -1,165 +0,0 @@
|
||||
#ifndef __UTP_H__
|
||||
#define __UTP_H__
|
||||
|
||||
#include "utypes.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib,"ws2_32.lib")
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct UTPSocket;
|
||||
|
||||
// Used to set sockopt on a uTP socket to set the version of uTP
|
||||
// to use for outgoing connections. This can only be called before
|
||||
// the uTP socket is connected
|
||||
#define SO_UTPVERSION 99
|
||||
|
||||
enum {
|
||||
// socket has reveived syn-ack (notification only for outgoing connection completion)
|
||||
// this implies writability
|
||||
UTP_STATE_CONNECT = 1,
|
||||
|
||||
// socket is able to send more data
|
||||
UTP_STATE_WRITABLE = 2,
|
||||
|
||||
// connection closed
|
||||
UTP_STATE_EOF = 3,
|
||||
|
||||
// socket is being destroyed, meaning all data has been sent if possible.
|
||||
// it is not valid to refer to the socket after this state change occurs
|
||||
UTP_STATE_DESTROYING = 4,
|
||||
};
|
||||
|
||||
// Callbacks called by a uTP socket (register with UTP_SetCallbacks)
|
||||
|
||||
// The uTP socket layer calls this when bytes have been received from the network.
|
||||
typedef void UTPOnReadProc(void *userdata, const byte *bytes, size_t count);
|
||||
|
||||
// The uTP socket layer calls this to fill the outgoing buffer with bytes.
|
||||
// The uTP layer takes responsibility that those bytes will be delivered.
|
||||
typedef void UTPOnWriteProc(void *userdata, byte *bytes, size_t count);
|
||||
|
||||
// The uTP socket layer calls this to retrieve number of bytes currently in read buffer
|
||||
typedef size_t UTPGetRBSize(void *userdata);
|
||||
|
||||
// The uTP socket layer calls this whenever the socket becomes writable.
|
||||
typedef void UTPOnStateChangeProc(void *userdata, int state);
|
||||
|
||||
// The uTP socket layer calls this when an error occurs on the socket.
|
||||
// These errors currently include ECONNREFUSED, ECONNRESET and ETIMEDOUT, but
|
||||
// could eventually include any BSD socket error.
|
||||
typedef void UTPOnErrorProc(void *userdata, int errcode);
|
||||
|
||||
// The uTP socket layer calls this to report overhead statistics
|
||||
typedef void UTPOnOverheadProc(void *userdata, bool send, size_t count, int type);
|
||||
|
||||
struct UTPFunctionTable {
|
||||
UTPOnReadProc *on_read;
|
||||
UTPOnWriteProc *on_write;
|
||||
UTPGetRBSize *get_rb_size;
|
||||
UTPOnStateChangeProc *on_state;
|
||||
UTPOnErrorProc *on_error;
|
||||
UTPOnOverheadProc *on_overhead;
|
||||
};
|
||||
|
||||
|
||||
// The uTP socket layer calls this when a new incoming uTP connection is established
|
||||
// this implies writability
|
||||
typedef void UTPGotIncomingConnection(void *userdata, struct UTPSocket* s);
|
||||
|
||||
// The uTP socket layer calls this to send UDP packets
|
||||
typedef void SendToProc(void *userdata, const byte *p, size_t len, const struct sockaddr *to, socklen_t tolen);
|
||||
|
||||
|
||||
// Functions which can be called with a uTP socket
|
||||
|
||||
// Create a uTP socket
|
||||
struct UTPSocket *UTP_Create(SendToProc *send_to_proc, void *send_to_userdata,
|
||||
const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
||||
// Setup the callbacks - must be done before connect or on incoming connection
|
||||
void UTP_SetCallbacks(struct UTPSocket *socket, struct UTPFunctionTable *func, void *userdata);
|
||||
|
||||
// Valid options include SO_SNDBUF, SO_RCVBUF and SO_UTPVERSION
|
||||
bool UTP_SetSockopt(struct UTPSocket *socket, int opt, int val);
|
||||
|
||||
// Try to connect to a specified host.
|
||||
void UTP_Connect(struct UTPSocket *socket);
|
||||
|
||||
// Process a UDP packet from the network. This will process a packet for an existing connection,
|
||||
// or create a new connection and call incoming_proc. Returns true if the packet was processed
|
||||
// in some way, false if the packet did not appear to be uTP.
|
||||
bool UTP_IsIncomingUTP(UTPGotIncomingConnection *incoming_proc,
|
||||
SendToProc *send_to_proc, void *send_to_userdata,
|
||||
const byte *buffer, size_t len, const struct sockaddr *to, socklen_t tolen);
|
||||
|
||||
// Process an ICMP received UDP packet.
|
||||
bool UTP_HandleICMP(const byte* buffer, size_t len, const struct sockaddr *to, socklen_t tolen);
|
||||
|
||||
// Write bytes to the uTP socket.
|
||||
// Returns true if the socket is still writable.
|
||||
bool UTP_Write(struct UTPSocket *socket, size_t count);
|
||||
|
||||
// Notify the uTP socket of buffer drain
|
||||
void UTP_RBDrained(struct UTPSocket *socket);
|
||||
|
||||
// Call periodically to process timeouts and other periodic events
|
||||
void UTP_CheckTimeouts(void);
|
||||
|
||||
// Retrieves the peer address of the specified socket, stores this address in the
|
||||
// sockaddr structure pointed to by the addr argument, and stores the length of this
|
||||
// address in the object pointed to by the addrlen argument.
|
||||
void UTP_GetPeerName(struct UTPSocket *socket, struct sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
void UTP_GetDelays(struct UTPSocket *socket, int32 *ours, int32 *theirs, uint32 *age);
|
||||
|
||||
size_t UTP_GetPacketSize(struct UTPSocket *socket);
|
||||
|
||||
#ifdef _DEBUG
|
||||
struct UTPStats {
|
||||
uint64 _nbytes_recv; // total bytes received
|
||||
uint64 _nbytes_xmit; // total bytes transmitted
|
||||
uint32 _rexmit; // retransmit counter
|
||||
uint32 _fastrexmit; // fast retransmit counter
|
||||
uint32 _nxmit; // transmit counter
|
||||
uint32 _nrecv; // receive counter (total)
|
||||
uint32 _nduprecv; // duplicate receive counter
|
||||
};
|
||||
|
||||
// Get stats for UTP socket
|
||||
void UTP_GetStats(struct UTPSocket *socket, UTPStats *stats);
|
||||
#endif
|
||||
|
||||
// Close the UTP socket.
|
||||
// It is not valid to issue commands for this socket after it is closed.
|
||||
// This does not actually destroy the socket until outstanding data is sent, at which
|
||||
// point the socket will change to the UTP_STATE_DESTROYING state.
|
||||
void UTP_Close(struct UTPSocket *socket);
|
||||
|
||||
struct UTPGlobalStats {
|
||||
uint32 _nraw_recv[5]; // total packets recieved less than 300/600/1200/MTU bytes fpr all connections (global)
|
||||
uint32 _nraw_send[5]; // total packets sent less than 300/600/1200/MTU bytes for all connections (global)
|
||||
};
|
||||
|
||||
void UTP_GetGlobalStats(struct UTPGlobalStats *stats);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__UTP_H__
|
||||
39
third-party/libutp/utp_config.h
vendored
39
third-party/libutp/utp_config.h
vendored
@@ -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);
|
||||
*/
|
||||
};
|
||||
26
third-party/libutp/utp_config_example.h
vendored
26
third-party/libutp/utp_config_example.h
vendored
@@ -1,26 +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
|
||||
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, ...);
|
||||
210
third-party/libutp/utp_utils.cpp
vendored
210
third-party/libutp/utp_utils.cpp
vendored
@@ -1,210 +0,0 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "utypes.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);
|
||||
static GetTickCount64Proc *pt2GetTickCount64;
|
||||
static GetTickCount64Proc *pt2RealGetTickCount;
|
||||
|
||||
static uint64 startPerformanceCounter;
|
||||
static uint64 startGetTickCount;
|
||||
// MSVC 6 standard doesn't like division with uint64s
|
||||
static double counterPerMicrosecond;
|
||||
|
||||
uint64 UTGetTickCount64()
|
||||
{
|
||||
if (pt2GetTickCount64) {
|
||||
return pt2GetTickCount64();
|
||||
}
|
||||
if (pt2RealGetTickCount) {
|
||||
uint64 v = pt2RealGetTickCount();
|
||||
// fix return value from GetTickCount
|
||||
return (DWORD)v | ((v >> 0x18) & 0xFFFFFFFF00000000);
|
||||
}
|
||||
return (uint64)GetTickCount();
|
||||
}
|
||||
|
||||
void Time_Initialize()
|
||||
{
|
||||
HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
|
||||
pt2GetTickCount64 = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount64");
|
||||
// not a typo. GetTickCount actually returns 64 bits
|
||||
pt2RealGetTickCount = (GetTickCount64Proc*)GetProcAddress(kernel32, "GetTickCount");
|
||||
|
||||
uint64 frequency;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&startPerformanceCounter);
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
|
||||
counterPerMicrosecond = (double)frequency / 1000000.0f;
|
||||
startGetTickCount = UTGetTickCount64();
|
||||
}
|
||||
|
||||
int64 abs64(int64 x) { return x < 0 ? -x : x; }
|
||||
|
||||
static uint64 GetMicroseconds()
|
||||
{
|
||||
static bool time_init = false;
|
||||
if (!time_init) {
|
||||
time_init = true;
|
||||
Time_Initialize();
|
||||
}
|
||||
|
||||
uint64 counter;
|
||||
uint64 tick;
|
||||
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &counter);
|
||||
tick = UTGetTickCount64();
|
||||
|
||||
// unfortunately, QueryPerformanceCounter is not guaranteed
|
||||
// to be monotonic. Make it so.
|
||||
int64 ret = (int64)(((int64)counter - (int64)startPerformanceCounter) / counterPerMicrosecond);
|
||||
// if the QPC clock leaps more than one second off GetTickCount64()
|
||||
// something is seriously fishy. Adjust QPC to stay monotonic
|
||||
int64 tick_diff = tick - startGetTickCount;
|
||||
if (abs64(ret / 100000 - tick_diff / 100) > 10) {
|
||||
startPerformanceCounter -= (uint64)((int64)(tick_diff * 1000 - ret) * counterPerMicrosecond);
|
||||
ret = (int64)((counter - startPerformanceCounter) / counterPerMicrosecond);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else //!WIN32
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h> // Linux needs both time.h and sys/time.h
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
static uint64 GetMicroseconds()
|
||||
{
|
||||
// http://developer.apple.com/mac/library/qa/qa2004/qa1398.html
|
||||
// http://www.macresearch.org/tutorial_performance_and_time
|
||||
static mach_timebase_info_data_t sTimebaseInfo;
|
||||
static uint64_t start_tick = 0;
|
||||
uint64_t tick;
|
||||
// Returns a counter in some fraction of a nanoseconds
|
||||
tick = mach_absolute_time();
|
||||
if (sTimebaseInfo.denom == 0) {
|
||||
// Get the timer ratio to convert mach_absolute_time to nanoseconds
|
||||
mach_timebase_info(&sTimebaseInfo);
|
||||
start_tick = tick;
|
||||
}
|
||||
// Calculate the elapsed time, convert it to microseconds and return it.
|
||||
return ((tick - start_tick) * sTimebaseInfo.numer) / (sTimebaseInfo.denom * 1000);
|
||||
}
|
||||
|
||||
#else //!__APPLE__
|
||||
|
||||
/* Unfortunately, #ifdef CLOCK_MONOTONIC is not enough to make sure that
|
||||
POSIX clocks work -- we could be running a recent libc with an ancient
|
||||
kernel (think OpenWRT). -- jch */
|
||||
|
||||
static uint64_t GetMicroseconds()
|
||||
{
|
||||
static int have_posix_clocks = -1;
|
||||
int rc;
|
||||
|
||||
#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(CLOCK_MONOTONIC)
|
||||
if (have_posix_clocks < 0) {
|
||||
struct timespec ts;
|
||||
rc = clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
if (rc < 0) {
|
||||
have_posix_clocks = 0;
|
||||
} else {
|
||||
have_posix_clocks = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_posix_clocks) {
|
||||
struct timespec ts;
|
||||
rc = clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return uint64(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
struct timeval tv;
|
||||
rc = gettimeofday(&tv, NULL);
|
||||
return uint64(tv.tv_sec) * 1000000 + tv.tv_usec;
|
||||
}
|
||||
}
|
||||
#endif //!__APPLE__
|
||||
|
||||
#endif //!WIN32
|
||||
|
||||
uint64 UTP_GetMicroseconds()
|
||||
{
|
||||
static uint64 offset = 0, previous = 0;
|
||||
|
||||
uint64 now = GetMicroseconds() + offset;
|
||||
if (previous > now) {
|
||||
/* Eek! */
|
||||
offset += previous - now;
|
||||
now = previous;
|
||||
}
|
||||
previous = now;
|
||||
return now;
|
||||
}
|
||||
|
||||
uint32 UTP_GetMilliseconds()
|
||||
{
|
||||
return UTP_GetMicroseconds() / 1000;
|
||||
}
|
||||
|
||||
|
||||
#define ETHERNET_MTU 1500
|
||||
#define IPV4_HEADER_SIZE 20
|
||||
#define IPV6_HEADER_SIZE 40
|
||||
#define UDP_HEADER_SIZE 8
|
||||
#define GRE_HEADER_SIZE 24
|
||||
#define PPPOE_HEADER_SIZE 8
|
||||
#define MPPE_HEADER_SIZE 2
|
||||
// packets have been observed in the wild that were fragmented
|
||||
// with a payload of 1416 for the first fragment
|
||||
// There are reports of routers that have MTU sizes as small as 1392
|
||||
#define FUDGE_HEADER_SIZE 36
|
||||
#define TEREDO_MTU 1280
|
||||
|
||||
#define UDP_IPV4_OVERHEAD (IPV4_HEADER_SIZE + UDP_HEADER_SIZE)
|
||||
#define UDP_IPV6_OVERHEAD (IPV6_HEADER_SIZE + UDP_HEADER_SIZE)
|
||||
#define UDP_TEREDO_OVERHEAD (UDP_IPV4_OVERHEAD + UDP_IPV6_OVERHEAD)
|
||||
|
||||
#define UDP_IPV4_MTU (ETHERNET_MTU - IPV4_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE - FUDGE_HEADER_SIZE)
|
||||
#define UDP_IPV6_MTU (ETHERNET_MTU - IPV6_HEADER_SIZE - UDP_HEADER_SIZE - GRE_HEADER_SIZE - PPPOE_HEADER_SIZE - MPPE_HEADER_SIZE - FUDGE_HEADER_SIZE)
|
||||
#define UDP_TEREDO_MTU (TEREDO_MTU - IPV6_HEADER_SIZE - UDP_HEADER_SIZE)
|
||||
|
||||
uint16 UTP_GetUDPMTU(const struct sockaddr *remote, socklen_t remotelen)
|
||||
{
|
||||
// Since we don't know the local address of the interface,
|
||||
// be conservative and assume all IPv6 connections are Teredo.
|
||||
return remote->sa_family == AF_INET6 ? UDP_TEREDO_MTU : UDP_IPV4_MTU;
|
||||
}
|
||||
|
||||
uint16 UTP_GetUDPOverhead(const struct sockaddr *remote, socklen_t remotelen)
|
||||
{
|
||||
// Since we don't know the local address of the interface,
|
||||
// be conservative and assume all IPv6 connections are Teredo.
|
||||
return remote->sa_family == AF_INET6 ? UDP_TEREDO_OVERHEAD : UDP_IPV4_OVERHEAD;
|
||||
}
|
||||
|
||||
uint32 UTP_Random()
|
||||
{
|
||||
return rand();
|
||||
}
|
||||
|
||||
void UTP_DelaySample(const struct sockaddr *remote, int sample_ms) {}
|
||||
size_t UTP_GetPacketSize(const struct sockaddr *remote) { return 1500; }
|
||||
|
||||
16
third-party/libutp/utp_utils.h
vendored
16
third-party/libutp/utp_utils.h
vendored
@@ -1,16 +0,0 @@
|
||||
// This should return the MTU to the destination
|
||||
uint16 UTP_GetUDPMTU(const struct sockaddr *remote, socklen_t remotelen);
|
||||
// This should return the number of bytes of UDP overhead for one packet to the
|
||||
// destination, for overhead calculation only
|
||||
uint16 UTP_GetUDPOverhead(const struct sockaddr *remote, socklen_t remotelen);
|
||||
// This should return monotonically increasing milliseconds, start point does not matter
|
||||
uint32 UTP_GetMilliseconds();
|
||||
// This should return monotonically increasing microseconds, start point does not matter
|
||||
uint64 UTP_GetMicroseconds();
|
||||
// This should return a random uint32
|
||||
uint32 UTP_Random();
|
||||
// This is called every time we have a delay sample is made
|
||||
void UTP_DelaySample(const struct sockaddr *remote, int sample_ms);
|
||||
// Should return the max packet size to use when sending to the given address
|
||||
size_t UTP_GetPacketSize(const struct sockaddr *remote);
|
||||
|
||||
42
third-party/libutp/utypes.h
vendored
42
third-party/libutp/utypes.h
vendored
@@ -1,42 +0,0 @@
|
||||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
// standard types
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef signed __int64 int64;
|
||||
#else
|
||||
typedef unsigned long long uint64;
|
||||
typedef long long int64;
|
||||
#endif
|
||||
|
||||
/* compile-time assert */
|
||||
#ifndef CASSERT
|
||||
#define CASSERT( exp, name ) typedef int is_not_##name [ (exp ) ? 1 : -1 ];
|
||||
#endif
|
||||
|
||||
CASSERT(8 == sizeof(uint64), sizeof_uint64_is_8)
|
||||
CASSERT(8 == sizeof(int64), sizeof_int64_is_8)
|
||||
|
||||
#ifndef INT64_MAX
|
||||
#define INT64_MAX 0x7fffffffffffffffLL
|
||||
#endif
|
||||
|
||||
// always ANSI
|
||||
typedef const char * cstr;
|
||||
typedef char * str;
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef uint8 bool;
|
||||
#endif
|
||||
|
||||
#endif //__UTYPES_H__
|
||||
585
third-party/miniupnp/Changelog.txt
vendored
585
third-party/miniupnp/Changelog.txt
vendored
@@ -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
|
||||
|
||||
27
third-party/miniupnp/LICENSE
vendored
27
third-party/miniupnp/LICENSE
vendored
@@ -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.
|
||||
|
||||
47
third-party/miniupnp/Makefile.am
vendored
47
third-party/miniupnp/Makefile.am
vendored
@@ -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
|
||||
66
third-party/miniupnp/README
vendored
66
third-party/miniupnp/README
vendored
@@ -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/
|
||||
|
||||
1
third-party/miniupnp/VERSION
vendored
1
third-party/miniupnp/VERSION
vendored
@@ -1 +0,0 @@
|
||||
1.7
|
||||
127
third-party/miniupnp/apiversions.txt
vendored
127
third-party/miniupnp/apiversions.txt
vendored
@@ -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);
|
||||
|
||||
531
third-party/miniupnp/bsdqueue.h
vendored
531
third-party/miniupnp/bsdqueue.h
vendored
@@ -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_ */
|
||||
31
third-party/miniupnp/codelength.h
vendored
31
third-party/miniupnp/codelength.h
vendored
@@ -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
|
||||
|
||||
261
third-party/miniupnp/connecthostport.c
vendored
261
third-party/miniupnp/connecthostport.c
vendored
@@ -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;
|
||||
}
|
||||
|
||||
18
third-party/miniupnp/connecthostport.h
vendored
18
third-party/miniupnp/connecthostport.h
vendored
@@ -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
|
||||
|
||||
21
third-party/miniupnp/declspec.h
vendored
21
third-party/miniupnp/declspec.h
vendored
@@ -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
|
||||
|
||||
125
third-party/miniupnp/igd_desc_parse.c
vendored
125
third-party/miniupnp/igd_desc_parse.c
vendored
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
48
third-party/miniupnp/igd_desc_parse.h
vendored
48
third-party/miniupnp/igd_desc_parse.h
vendored
@@ -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
|
||||
|
||||
121
third-party/miniupnp/minisoap.c
vendored
121
third-party/miniupnp/minisoap.c
vendored
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
15
third-party/miniupnp/minisoap.h
vendored
15
third-party/miniupnp/minisoap.h
vendored
@@ -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
|
||||
|
||||
133
third-party/miniupnp/minissdpc.c
vendored
133
third-party/miniupnp/minissdpc.c
vendored
@@ -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;
|
||||
}
|
||||
|
||||
15
third-party/miniupnp/minissdpc.h
vendored
15
third-party/miniupnp/minissdpc.h
vendored
@@ -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
|
||||
|
||||
1046
third-party/miniupnp/miniupnpc.c
vendored
1046
third-party/miniupnp/miniupnpc.c
vendored
File diff suppressed because it is too large
Load Diff
130
third-party/miniupnp/miniupnpc.h
vendored
130
third-party/miniupnp/miniupnpc.h
vendored
@@ -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
|
||||
|
||||
15
third-party/miniupnp/miniupnpcstrings.h.in
vendored
15
third-party/miniupnp/miniupnpcstrings.h.in
vendored
@@ -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
|
||||
|
||||
19
third-party/miniupnp/miniupnpctypes.h
vendored
19
third-party/miniupnp/miniupnpctypes.h
vendored
@@ -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
|
||||
|
||||
575
third-party/miniupnp/miniwget.c
vendored
575
third-party/miniupnp/miniwget.c
vendored
@@ -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);
|
||||
}
|
||||
|
||||
30
third-party/miniupnp/miniwget.h
vendored
30
third-party/miniupnp/miniwget.h
vendored
@@ -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
|
||||
|
||||
229
third-party/miniupnp/minixml.c
vendored
229
third-party/miniupnp/minixml.c
vendored
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
37
third-party/miniupnp/minixml.h
vendored
37
third-party/miniupnp/minixml.h
vendored
@@ -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
|
||||
|
||||
159
third-party/miniupnp/portlistingparse.c
vendored
159
third-party/miniupnp/portlistingparse.c
vendored
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
71
third-party/miniupnp/portlistingparse.h
vendored
71
third-party/miniupnp/portlistingparse.h
vendored
@@ -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
|
||||
109
third-party/miniupnp/receivedata.c
vendored
109
third-party/miniupnp/receivedata.c
vendored
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
19
third-party/miniupnp/receivedata.h
vendored
19
third-party/miniupnp/receivedata.h
vendored
@@ -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
|
||||
|
||||
54
third-party/miniupnp/updateminiupnpcstrings.sh
vendored
54
third-party/miniupnp/updateminiupnpcstrings.sh
vendored
@@ -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"
|
||||
|
||||
1098
third-party/miniupnp/upnpcommands.c
vendored
1098
third-party/miniupnp/upnpcommands.c
vendored
File diff suppressed because it is too large
Load Diff
293
third-party/miniupnp/upnpcommands.h
vendored
293
third-party/miniupnp/upnpcommands.h
vendored
@@ -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
|
||||
|
||||
183
third-party/miniupnp/upnpreplyparse.c
vendored
183
third-party/miniupnp/upnpreplyparse.c
vendored
@@ -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
|
||||
|
||||
69
third-party/miniupnp/upnpreplyparse.h
vendored
69
third-party/miniupnp/upnpreplyparse.h
vendored
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user