update miniupnp to 20100405

This commit is contained in:
Mitchell Livingston 2010-04-05 22:44:14 +00:00
parent 861f2b1f85
commit 62ceb344f6
7 changed files with 355 additions and 165 deletions

View File

@ -109,6 +109,8 @@
A2265F420B5EF5F40093DDA5 /* FileNameCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A2265F400B5EF5F40093DDA5 /* FileNameCell.m */; };
A226FDAC0D0CDF20005A7F71 /* libnatpmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C7A118D0D0B2EB800B5701F /* libnatpmp.a */; };
A22A8D560AEEAFA5007E9CB9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A22A8D540AEEAFA5007E9CB9 /* Localizable.strings */; };
A22B00B2116A9E9F003315FC /* connecthostport.h in Headers */ = {isa = PBXBuildFile; fileRef = A22B00AF116A9E90003315FC /* connecthostport.h */; };
A22B00B3116A9EA4003315FC /* connecthostport.c in Sources */ = {isa = PBXBuildFile; fileRef = A22B00AE116A9E90003315FC /* connecthostport.c */; };
A22CFB820FB66EF30009BD3E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A22CFB810FB66EF30009BD3E /* Carbon.framework */; };
A22CFCA80FC24ED80009BD3E /* tr-dht.c in Sources */ = {isa = PBXBuildFile; fileRef = A22CFCA60FC24ED80009BD3E /* tr-dht.c */; };
A22CFCA90FC24ED80009BD3E /* tr-dht.h in Headers */ = {isa = PBXBuildFile; fileRef = A22CFCA70FC24ED80009BD3E /* tr-dht.h */; };
@ -551,6 +553,8 @@
A223AA830D220CEB00840069 /* nl */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = nl; path = macosx/nl.lproj/PrefsWindow.xib; sourceTree = "<group>"; };
A2265F3F0B5EF5F40093DDA5 /* FileNameCell.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FileNameCell.h; path = macosx/FileNameCell.h; sourceTree = "<group>"; };
A2265F400B5EF5F40093DDA5 /* FileNameCell.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = FileNameCell.m; path = macosx/FileNameCell.m; sourceTree = "<group>"; };
A22B00AE116A9E90003315FC /* connecthostport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = connecthostport.c; path = "third-party/miniupnp/connecthostport.c"; sourceTree = "<group>"; };
A22B00AF116A9E90003315FC /* connecthostport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = connecthostport.h; path = "third-party/miniupnp/connecthostport.h"; sourceTree = "<group>"; };
A22CF7AC0FA3505F0009BD3E /* it */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = it; path = macosx/it.lproj/GroupRules.xib; sourceTree = "<group>"; };
A22CF7B20FA3517E0009BD3E /* zh_TW */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = zh_TW; path = macosx/zh_TW.lproj/GroupRules.xib; sourceTree = "<group>"; };
A22CF7B90FA352740009BD3E /* fr */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = fr; path = macosx/fr.lproj/GroupRules.xib; sourceTree = "<group>"; };
@ -1352,6 +1356,7 @@
BE1183410CE15DF00002D0F3 /* libminiupnp */ = {
isa = PBXGroup;
children = (
A22B00AE116A9E90003315FC /* connecthostport.c */,
BE1183610CE160D50002D0F3 /* igd_desc_parse.c */,
BE1183620CE160D50002D0F3 /* minixml.c */,
BE1183630CE160D50002D0F3 /* miniwget.c */,
@ -1361,6 +1366,7 @@
BE1183670CE160D50002D0F3 /* upnpcommands.c */,
BE1183680CE160D50002D0F3 /* miniupnpc.c */,
BE11834D0CE160C50002D0F3 /* bsdqueue.h */,
A22B00AF116A9E90003315FC /* connecthostport.h */,
BE11834E0CE160C50002D0F3 /* declspec.h */,
BE11834F0CE160C50002D0F3 /* igd_desc_parse.h */,
BE1183500CE160C50002D0F3 /* minixml.h */,
@ -1576,6 +1582,7 @@
BE1183600CE160C50002D0F3 /* minissdpc.h in Headers */,
A254853C0EB66CD4004539DA /* codelength.h in Headers */,
A2F8CD430F3D0F4A00DB356A /* miniupnpcstrings.h in Headers */,
A22B00B2116A9E9F003315FC /* connecthostport.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2115,6 +2122,7 @@
BE11836E0CE160D50002D0F3 /* upnpreplyparse.c in Sources */,
BE11836F0CE160D50002D0F3 /* upnpcommands.c in Sources */,
BE1183700CE160D50002D0F3 /* miniupnpc.c in Sources */,
A22B00B3116A9EA4003315FC /* connecthostport.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -1,8 +1,18 @@
$Id: Changelog.txt,v 1.105 2010/01/06 10:03:53 nanard Exp $
$Id: Changelog.txt,v 1.110 2010/04/05 12:09:51 nanard Exp $
miniUPnP client Changelog.
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.
2010/04/04:
Use getaddrinfo() instead of gethostbyname() in miniwget.
2010/01/06:
#define _DARWIN_C_SOURCE for macosx
#define _DARWIN_C_SOURCE for Mac OS X
2009/12/19:
Improve MinGW32 build

View File

@ -3,6 +3,7 @@ noinst_LIBRARIES = libminiupnp.a
AM_CFLAGS = @PTHREAD_CFLAGS@ -DNDEBUG
libminiupnp_a_SOURCES = \
connecthostport.c \
igd_desc_parse.c \
minisoap.c \
minissdpc.c \
@ -15,6 +16,7 @@ libminiupnp_a_SOURCES = \
noinst_HEADERS = \
bsdqueue.h \
codelength.h \
connecthostport.h \
declspec.h \
igd_desc_parse.h \
minisoap.h \

221
third-party/miniupnp/connecthostport.c vendored Normal file
View File

@ -0,0 +1,221 @@
/* $Id: connecthostport.c,v 1.2 2010/04/05 00:08:15 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2010 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() */
/* #define USE_GETHOSTBYNAME */
#include <string.h>
#include <stdio.h>
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#define snprintf _snprintf
#define herror
#define socklen_t int
#else /* #ifdef WIN32 */
#include <unistd.h>
#include <errno.h>
#define closesocket close
#include <netdb.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>
#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"
/* 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)
{
int s, n;
#ifdef USE_GETHOSTBYNAME
struct sockaddr_in dest;
struct hostent *hp;
#else /* #ifdef USE_GETHOSTBYNAME */
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
while(n < 0 && errno == EINTR)
{
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);
n = getaddrinfo(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;
#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
while(n < 0 && errno == EINTR)
{
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;
}

17
third-party/miniupnp/connecthostport.h vendored Normal file
View File

@ -0,0 +1,17 @@
/* $Id: connecthostport.h,v 1.1 2010/04/04 23:21:03 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
* Copyright (c) 2010 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __CONNECTHOSTPORT_H__
#define __CONNECTHOSTPORT_H__
/* 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);
#endif

View File

@ -1,4 +1,4 @@
/* $Id: miniupnpc.c,v 1.74 2010/01/09 23:54:40 nanard Exp $ */
/* $Id: miniupnpc.c,v 1.77 2010/04/05 12:34:05 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2005-2010 Thomas Bernard
@ -50,10 +50,10 @@
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#if !defined(__amigaos__) && !defined(__amigaos4__)
#include <poll.h>
#endif
#include <netdb.h>
#include <strings.h>
#include <errno.h>
#define closesocket close
@ -73,6 +73,7 @@
#include "minisoap.h"
#include "minixml.h"
#include "upnpcommands.h"
#include "connecthostport.h"
#ifdef WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
@ -180,7 +181,6 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
const char * action, struct UPNParg * args,
char * buffer, int * bufsize)
{
struct sockaddr_in dest;
char hostname[MAXHOSTNAMELEN+1];
unsigned short port = 0;
char * path;
@ -190,9 +190,7 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
int buffree;
int n;
int contentlen, headerlen; /* for the response */
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
struct timeval timeout;
#endif
snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
if(args==NULL)
{
@ -261,62 +259,9 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
if(!parseURL(url, hostname, &port, &path)) return -1;
if(s<0)
{
s = socket(PF_INET, SOCK_STREAM, 0);
if(s<0)
s = connecthostport(hostname, port);
if(s < 0)
{
PRINT_SOCKET_ERROR("socket");
*bufsize = 0;
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
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
dest.sin_addr.s_addr = inet_addr(hostname);
n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr));
#ifdef MINIUPNPC_IGNORE_EINTR
while(n < 0 && errno == EINTR)
{
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;
} else {
n = 0;
}
}
#endif
if(n < 0)
{
PRINT_SOCKET_ERROR("connect");
closesocket(s);
*bufsize = 0;
return -1;
}
@ -450,8 +395,10 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
char bufr[1536]; /* reception and emission buffer */
int sudp;
int n;
struct sockaddr_in sockudp_r, sockudp_w;
struct sockaddr sockudp_r;
unsigned int mx;
int rv;
struct addrinfo hints, *servinfo, *p;
#ifdef WIN32
/*MIB_IPFORWARDROW ip_forward;*/
#endif
@ -481,17 +428,28 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
PRINT_SOCKET_ERROR("socket");
return NULL;
}
/* reception */
memset(&sockudp_r, 0, sizeof(struct sockaddr_in));
sockudp_r.sin_family = AF_INET;
if(sameport)
sockudp_r.sin_port = htons(PORT);
sockudp_r.sin_addr.s_addr = INADDR_ANY;
/* emission */
memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
sockudp_w.sin_family = AF_INET;
sockudp_w.sin_port = htons(PORT);
sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
/* reception */
memset(&sockudp_r, 0, sizeof(struct sockaddr));
if(0/*ipv6*/) {
struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
p->sin6_family = AF_INET6;
if(sameport)
p->sin6_port = htons(PORT);
p->sin6_addr = in6addr_any;//IN6ADDR_ANY_INIT;/*INADDR_ANY;*/
} else {
struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
p->sin_family = AF_INET;
if(sameport)
p->sin_port = htons(PORT);
p->sin_addr.s_addr = INADDR_ANY;
}
#if 0
/* emission */
memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
sockudp_w.sin_family = AF_INET;
sockudp_w.sin_port = htons(PORT);
sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
#endif
#ifdef WIN32
/* This code could help us to use the right Network interface for
* SSDP multicast traffic */
@ -546,7 +504,10 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
{
struct in_addr mc_if;
mc_if.s_addr = inet_addr(multicastif);
sockudp_r.sin_addr.s_addr = mc_if.s_addr;
if(0/*ipv6*/) {
} else {
((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
}
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt");
@ -554,7 +515,7 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
}
/* Avant d'envoyer le paquet on bind pour recevoir la reponse */
if (bind(sudp, (struct sockaddr *)&sockudp_r, sizeof(struct sockaddr_in)) != 0)
if (bind(sudp, &sockudp_r, 0/*ipv6*/?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) != 0)
{
PRINT_SOCKET_ERROR("bind");
closesocket(sudp);
@ -572,6 +533,7 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
n = snprintf(bufr, sizeof(bufr),
MSearchMsgFmt, deviceList[deviceIndex++], mx);
/*printf("Sending %s", bufr);*/
#if 0
n = sendto(sudp, bufr, n, 0,
(struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in));
if (n < 0) {
@ -579,6 +541,31 @@ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
closesocket(sudp);
return devlist;
}
#endif
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // AF_INET6 or AF_INET
hints.ai_socktype = SOCK_DGRAM;
/*hints.ai_flags = */
if ((rv = getaddrinfo(UPNP_MCAST_ADDR, XSTR(PORT), &hints, &servinfo)) != 0) {
#ifdef WIN32
fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
#else
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
#endif
return devlist;
}
for(p = servinfo; p; p = p->ai_next) {
n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
if (n < 0) {
PRINT_SOCKET_ERROR("sendto");
continue;
}
}
freeaddrinfo(servinfo);
if(n < 0) {
closesocket(sudp);
return devlist;
}
}
/* Waiting for SSDP REPLY packet to M-SEARCH */
n = ReceiveData(sudp, bufr, sizeof(bufr), delay);

View File

@ -1,51 +1,49 @@
/* $Id: miniwget.c,v 1.31 2009/12/04 11:29:19 nanard Exp $ */
/* $Id: miniwget.c,v 1.36 2010/04/05 12:34:05 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005-2009 Thomas Bernard
* Copyright (c) 2005-2010 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
* LICENCE file provided in this distribution. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "miniupnpc.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 herror
#define socklen_t int
#else
#else /* #ifdef WIN32 */
#include <unistd.h>
#include <sys/param.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
#define socklen_t int
#else
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/select.h>
#endif
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <time.h>
#include <netdb.h>
#define closesocket close
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
* during the connect() call */
#define MINIUPNPC_IGNORE_EINTR
#endif
#endif /* #else WIN32 */
#if defined(__sun) || defined(sun)
#define MIN(x,y) (((x)<(y))?(x):(y))
#endif
#if defined(__amigaos__) || defined(__amigaos4__)
#define herror(A) printf("%s\n", A)
#endif
#include "miniupnpcstrings.h"
#include "miniwget.h"
#include "connecthostport.h"
/* miniwget2() :
* */
* do all the work.
* Return NULL if something failed. */
static void *
miniwget2(const char * url, const char * host,
unsigned short port, const char * path,
@ -53,93 +51,29 @@ miniwget2(const char * url, const char * host,
{
char buf[2048];
int s;
struct sockaddr_in dest;
struct hostent *hp;
int n;
int len;
int sent;
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
struct timeval timeout;
#endif
*size = 0;
hp = gethostbyname(host);
if(hp==NULL)
{
herror(host);
return NULL;
}
/* memcpy((char *)&dest.sin_addr, hp->h_addr, hp->h_length); */
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);
s = connecthostport(host, port);
if(s < 0)
{
perror("socket");
return NULL;
}
#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)
{
perror("setsockopt");
}
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
{
perror("setsockopt");
}
#endif
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
#ifdef MINIUPNPC_IGNORE_EINTR
while(n < 0 && errno == EINTR)
{
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) {
perror("getsockopt");
closesocket(s);
return NULL;
}
if(err != 0) {
errno = err;
n = -1;
}
}
#endif
if(n<0)
{
perror("connect");
closesocket(s);
return NULL;
}
/* get address for caller ! */
if(addr_str)
{
struct sockaddr_in saddr;
struct sockaddr saddr;
socklen_t saddrlen;
saddrlen = sizeof(saddr);
if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
if(getsockname(s, &saddr, &saddrlen) < 0)
{
perror("getsockname");
}
else
{
#if defined(WIN32) || (defined(__amigaos__) && !defined(__amigaos4__))
#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),
@ -147,9 +81,20 @@ miniwget2(const char * url, const char * host,
{
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
}*/
strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len);
strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
#else
inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);
/*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
n = getnameinfo(&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