mirror of
https://github.com/transmission/transmission
synced 2025-03-03 10:15:45 +00:00
add libnatpmp by Thomas Bernard
This commit is contained in:
parent
b17d8c34f8
commit
42a0ab727c
7 changed files with 585 additions and 0 deletions
14
third-party/libnatpmp/LICENSE
vendored
Normal file
14
third-party/libnatpmp/LICENSE
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
libnatpmp
|
||||||
|
Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
13
third-party/libnatpmp/Makefile.am
vendored
Normal file
13
third-party/libnatpmp/Makefile.am
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
noinst_LIBRARIES = libnatpmp.a
|
||||||
|
|
||||||
|
libnatpmp_a_SOURCES = \
|
||||||
|
getgateway.c \
|
||||||
|
natpmp.c
|
||||||
|
|
||||||
|
noinst_HEADERS = \
|
||||||
|
getgateway.h \
|
||||||
|
natpmp.h
|
||||||
|
|
||||||
|
extra_DIST = \
|
||||||
|
README \
|
||||||
|
LICENSE
|
4
third-party/libnatpmp/README
vendored
Normal file
4
third-party/libnatpmp/README
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
libnatpmp is written by Thomas Bernard.
|
||||||
|
Its homepage is http://miniupnp.tuxfamily.org/libnatpmp.html
|
||||||
|
This code is from the libnatpmp-20071202 snapshot
|
||||||
|
|
111
third-party/libnatpmp/getgateway.c
vendored
Normal file
111
third-party/libnatpmp/getgateway.c
vendored
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/* $Id: getgateway.c,v 1.4 2007/11/22 18:01:37 nanard Exp $ */
|
||||||
|
/* libnatpmp
|
||||||
|
* Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#ifdef BSD
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
#endif
|
||||||
|
#include "getgateway.h"
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
int getdefaultgateway(in_addr_t * addr)
|
||||||
|
{
|
||||||
|
long d, g;
|
||||||
|
char buf[256];
|
||||||
|
int line = 0;
|
||||||
|
FILE * f;
|
||||||
|
char * p;
|
||||||
|
f = fopen("/proc/net/route", "r");
|
||||||
|
if(!f)
|
||||||
|
return -1;
|
||||||
|
while(fgets(buf, sizeof(buf), f)) {
|
||||||
|
if(line > 0) {
|
||||||
|
p = buf;
|
||||||
|
while(*p && !isspace(*p))
|
||||||
|
p++;
|
||||||
|
while(*p && isspace(*p))
|
||||||
|
p++;
|
||||||
|
if(sscanf(p, "%lx%lx", &d, &g)==2) {
|
||||||
|
if(d == 0) { /* default */
|
||||||
|
*addr = g;
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
/* not found ! */
|
||||||
|
if(f)
|
||||||
|
fclose(f);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BSD
|
||||||
|
|
||||||
|
#define ROUNDUP(a) \
|
||||||
|
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||||
|
|
||||||
|
int getdefaultgateway(in_addr_t * addr)
|
||||||
|
{
|
||||||
|
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
|
||||||
|
NET_RT_DUMP, 0, 0/*tableid*/};
|
||||||
|
size_t l;
|
||||||
|
char * buf, * p;
|
||||||
|
struct rt_msghdr * rt;
|
||||||
|
struct sockaddr * sa;
|
||||||
|
struct sockaddr * sa_tab[RTAX_MAX];
|
||||||
|
int i;
|
||||||
|
int r = -1;
|
||||||
|
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(l>0) {
|
||||||
|
buf = malloc(l);
|
||||||
|
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif
|
25
third-party/libnatpmp/getgateway.h
vendored
Normal file
25
third-party/libnatpmp/getgateway.h
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/* $Id: getgateway.h,v 1.2 2007/11/22 18:01:37 nanard Exp $ */
|
||||||
|
/* libnatpmp
|
||||||
|
* Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||||
|
#ifndef __GETGATEWAY_H__
|
||||||
|
#define __GETGATEWAY_H__
|
||||||
|
|
||||||
|
/* getdefaultgateway() :
|
||||||
|
* return value :
|
||||||
|
* 0 : success
|
||||||
|
* -1 : failure */
|
||||||
|
int getdefaultgateway(in_addr_t * addr);
|
||||||
|
|
||||||
|
#endif
|
249
third-party/libnatpmp/natpmp.c
vendored
Normal file
249
third-party/libnatpmp/natpmp.c
vendored
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
/* $Id: natpmp.c,v 1.4 2007/12/02 00:12:47 nanard Exp $ */
|
||||||
|
/* libnatpmp
|
||||||
|
* Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include "natpmp.h"
|
||||||
|
#include "getgateway.h"
|
||||||
|
|
||||||
|
int initnatpmp(natpmp_t * p)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int closenatpmp(natpmp_t * p)
|
||||||
|
{
|
||||||
|
if(!p)
|
||||||
|
return NATPMP_ERR_INVALIDARGS;
|
||||||
|
if(close(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
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->publicaddress.addr.s_addr = *((uint32_t *)(buf + 8));
|
||||||
|
else {
|
||||||
|
response->newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8)));
|
||||||
|
response->newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10)));
|
||||||
|
response->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;
|
||||||
|
}
|
||||||
|
|
169
third-party/libnatpmp/natpmp.h
vendored
Normal file
169
third-party/libnatpmp/natpmp.h
vendored
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/* $Id: natpmp.h,v 1.3 2007/12/02 00:12:47 nanard Exp $ */
|
||||||
|
/* libnatpmp
|
||||||
|
* Copyright (c) 2007, Thomas BERNARD <miniupnp@free.fr>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||||
|
#ifndef __NATPMP_H__
|
||||||
|
#define __NATPMP_H__
|
||||||
|
|
||||||
|
/* NAT-PMP Port as defined by the NAT-PMP draft */
|
||||||
|
#define NATPMP_PORT (5351)
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int s; /* socket */
|
||||||
|
in_addr_t gateway; /* default gateway (IPv4) */
|
||||||
|
int has_pending_request;
|
||||||
|
unsigned char pending_request[12];
|
||||||
|
int pending_request_len;
|
||||||
|
int try_number;
|
||||||
|
struct timeval retry_time;
|
||||||
|
} natpmp_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t type; /* NATPMP_RESPTYPE_* */
|
||||||
|
uint16_t resultcode; /* NAT-PMP response code */
|
||||||
|
uint32_t epoch; /* Seconds since start of epoch */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
//in_addr_t addr;
|
||||||
|
struct in_addr addr;
|
||||||
|
} publicaddress;
|
||||||
|
struct {
|
||||||
|
uint16_t privateport;
|
||||||
|
uint16_t mappedpublicport;
|
||||||
|
uint32_t lifetime;
|
||||||
|
} newportmapping;
|
||||||
|
};
|
||||||
|
} natpmpresp_t;
|
||||||
|
|
||||||
|
/* possible values for type field of natpmpresp_t */
|
||||||
|
#define NATPMP_RESPTYPE_PUBLICADDRESS (0)
|
||||||
|
#define NATPMP_RESPTYPE_TCPPORTMAPPING (1)
|
||||||
|
#define NATPMP_RESPTYPE_UDPPORTMAPPING (2)
|
||||||
|
|
||||||
|
/* Values to pass to sendnewportmappingrequest() */
|
||||||
|
#define NATPMP_PROTOCOL_TCP (1)
|
||||||
|
#define NATPMP_PROTOCOL_UDP (2)
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
|
||||||
|
/* initnatpmp()
|
||||||
|
* initialize a natpmp_t object
|
||||||
|
* Return values :
|
||||||
|
* 0 = OK
|
||||||
|
* NATPMP_ERR_INVALIDARGS
|
||||||
|
* NATPMP_ERR_SOCKETERROR
|
||||||
|
* NATPMP_ERR_FCNTLERROR
|
||||||
|
* NATPMP_ERR_CANNOTGETGATEWAY
|
||||||
|
* NATPMP_ERR_CONNECTERR */
|
||||||
|
int initnatpmp(natpmp_t * p);
|
||||||
|
|
||||||
|
/* closenatpmp()
|
||||||
|
* close resources associated with a natpmp_t object
|
||||||
|
* Return values :
|
||||||
|
* 0 = OK
|
||||||
|
* NATPMP_ERR_INVALIDARGS
|
||||||
|
* NATPMP_ERR_CLOSEERR */
|
||||||
|
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 */
|
||||||
|
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.
|
||||||
|
* Return values :
|
||||||
|
* 12 = OK (size of the request)
|
||||||
|
* NATPMP_ERR_INVALIDARGS
|
||||||
|
* NATPMP_ERR_SENDERR */
|
||||||
|
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 */
|
||||||
|
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 */
|
||||||
|
int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue