Integrate miniupnpc.

This should bring it up to about the state of the patches and comments in
ticket #1073, without the threaded device detection. Timeout is 500ms, that
should be enough to detect a LAN device, and doesn't delay startup too much.

Port r8447 plus the fixes for it in r8449, r8453, r8455 and r8456 to trunk.

git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@8460 4a71c877-e1ca-e34f-864e-861f7616d084
master
Christian Ohm 2009-11-21 19:04:16 +00:00 committed by Git SVN Gateway
parent 03607b0fb8
commit a7ae06572d
14 changed files with 316 additions and 28 deletions

View File

@ -383,6 +383,7 @@ AC_CONFIG_FILES([Makefile
lib/ivis_opengl/Makefile lib/ivis_opengl/Makefile
lib/ivis_common/Makefile lib/ivis_common/Makefile
lib/netplay/Makefile lib/netplay/Makefile
lib/netplay/miniupnpc/Makefile
lib/script/Makefile lib/script/Makefile
lib/sequence/Makefile lib/sequence/Makefile
lib/sound/Makefile lib/sound/Makefile

View File

@ -1,3 +1,5 @@
SUBDIRS = miniupnpc
AM_CPPFLAGS = $(SDL_CFLAGS) $(WZ_CPPFLAGS) AM_CPPFLAGS = $(SDL_CFLAGS) $(WZ_CPPFLAGS)
AM_CFLAGS = $(WZ_CFLAGS) AM_CFLAGS = $(WZ_CFLAGS)
@ -13,4 +15,4 @@ libnetplay_a_SOURCES = \
netplay.c \ netplay.c \
nettypes.c nettypes.c
libnetplay_a_LIBADD = $(top_builddir)/lib/framework/libframework.a libnetplay_a_LIBADD = $(top_builddir)/lib/framework/libframework.a $(top_builddir)/lib/netplay/miniupnpc/libminiupnpc.a

View File

@ -0,0 +1,28 @@
AM_CPPFLAGS = -DSTATICLIB $(SDL_CFLAGS) $(WZ_CPPFLAGS)
AM_CFLAGS = -DSTATICLIB $(WZ_CFLAGS)
noinst_LIBRARIES = libminiupnpc.a
noinst_HEADERS = \
miniupnpc.h \
miniupnpcstrings.h \
miniwget.h \
minixml.h \
minisoap.h \
minissdpc.h \
codelength.h \
upnpcommands.h \
igd_desc_parse.h \
upnpreplyparse.h \
upnperrors.h \
declspec.h
libminiupnpc_a_SOURCES = \
miniwget.c \
minixml.c \
igd_desc_parse.c \
minisoap.c \
miniupnpc.c \
upnpreplyparse.c \
upnpcommands.c \
minissdpc.c \
upnperrors.c

View File

@ -5,7 +5,9 @@
#ifdef MINIUPNP_EXPORTS #ifdef MINIUPNP_EXPORTS
#define LIBSPEC __declspec(dllexport) #define LIBSPEC __declspec(dllexport)
#else #else
#define LIBSPEC __declspec(dllimport) // NOTE: with the cross compiler, even if we have -DSTATICLIB, for some odd reason it still does this
// #define LIBSPEC __declspec(dllimport) which is not what we want. So we hack the line like so.
#define LIBSPEC
#endif #endif
#else #else
#define LIBSPEC #define LIBSPEC

View File

@ -21,6 +21,8 @@
#include "minisoap.h" #include "minisoap.h"
#include "miniupnpcstrings.h" #include "miniupnpcstrings.h"
#undef DEBUG
/* only for malloc */ /* only for malloc */
#include <stdlib.h> #include <stdlib.h>

View File

@ -8,12 +8,15 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef WIN32 #ifdef WIN32
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <io.h> #include <io.h>
// Warzone additions
#include "lib/framework/types.h"
typedef SSIZE_T ssize_t;
// end WZ
/* Hack */ /* Hack */
#define UNIX_PATH_LEN 108 #define UNIX_PATH_LEN 108
struct sockaddr_un { struct sockaddr_un {
@ -23,6 +26,7 @@ struct sockaddr_un {
#else #else
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h>
#endif #endif
#include "minissdpc.h" #include "minissdpc.h"

View File

@ -11,6 +11,8 @@
#include "declspec.h" #include "declspec.h"
#include "igd_desc_parse.h" #include "igd_desc_parse.h"
#undef DEBUG
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -0,0 +1,26 @@
/* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2005-2009 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef __MINIUPNPCSTRINGS_H__
#define __MINIUPNPCSTRINGS_H__
#include "lib/framework/wzglobal.h"
#if defined(WZ_OS_WIN32)
#define OS_STRING "Windows"
#elif defined (WZ_OS_MAC)
#define OS_STRING "Mac OS"
#elif defined(WZ_OS_LINUX)
#define OS_STRING "Linux"
#else
#define OS_STRING "Other/unknown"
#endif
#define MINIUPNPC_VERSION_STRING "1.4"
#endif

View File

@ -35,6 +35,10 @@
#include "netplay.h" #include "netplay.h"
#include "netlog.h" #include "netlog.h"
#include "miniupnpc/miniwget.h"
#include "miniupnpc/miniupnpc.h"
#include "miniupnpc/upnpcommands.h"
#if defined(WZ_OS_UNIX) #if defined(WZ_OS_UNIX)
# include <arpa/inet.h> # include <arpa/inet.h>
# include <errno.h> # include <errno.h>
@ -223,6 +227,15 @@ static NETBUFSOCKET* bsocket = NULL; //buffered socket (holds tcp_socket) (clie
static NETBUFSOCKET* connected_bsocket[MAX_CONNECTED_PLAYERS] = { NULL }; static NETBUFSOCKET* connected_bsocket[MAX_CONNECTED_PLAYERS] = { NULL };
static SocketSet* socket_set = NULL; static SocketSet* socket_set = NULL;
// UPnP
static int upnp = false;
static struct UPNPUrls urls;
static struct IGDdatas data;
// local ip address
static char lanaddr[16];
/** /**
* Used for connections with clients. * Used for connections with clients.
*/ */
@ -1793,6 +1806,104 @@ static bool NETrecvGAMESTRUCT(GAMESTRUCT* game)
return true; return true;
} }
static int upnp_init(void *asdf)
{
struct UPNPDev *devlist;
struct UPNPDev *dev;
char *descXML;
int descXMLsize = 0;
memset(&urls, 0, sizeof(struct UPNPUrls));
memset(&data, 0, sizeof(struct IGDdatas));
debug(LOG_NET, "Searching for UPnP devices for automatic port forwarding...");
devlist = upnpDiscover(500, NULL, NULL, 0);
debug(LOG_NET, "UPnP device search finished.");
if (devlist)
{
dev = devlist;
while (dev)
{
if (strstr(dev->st, "InternetGatewayDevice"))
break;
dev = dev->pNext;
}
if (!dev)
{
dev = devlist; /* defaulting to first device */
}
debug(LOG_NET, "UPnP device found: %s %s\n", dev->descURL, dev->st);
descXML = miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, sizeof(lanaddr));
debug(LOG_NET, "LAN address: %s", lanaddr);
if (descXML)
{
parserootdesc (descXML, descXMLsize, &data);
free (descXML); descXML = 0;
GetUPNPUrls (&urls, &data, dev->descURL);
}
freeUPNPDevlist(devlist);
if (urls.controlURL[0] == '\0')
{
return false;
}
return true;
}
debug(LOG_NET, "No UPnP devices found.");
return false;
}
static bool upnp_add_redirect(int port)
{
char externalIP[16];
char port_str[16];
int r;
debug(LOG_NET, "upnp_add_redir(%d)\n", port);
UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP);
sprintf(port_str, "%d", port);
r = UPNP_AddPortMapping(urls.controlURL, data.servicetype,
port_str, port_str, lanaddr, "Warzone 2100", "TCP", 0);
if (r != UPNPCOMMAND_SUCCESS)
{
debug(LOG_NET, "AddPortMapping(%s, %s, %s) failed\n", port_str, port_str, lanaddr);
return false;
}
return true;
}
static void upnp_rem_redirect(int port)
{
char port_str[16];
debug(LOG_NET, "upnp_rem_redir(%d)", port);
sprintf(port_str, "%d", port);
UPNP_DeletePortMapping(urls.controlURL, data.servicetype, port_str, "TCP", 0);
}
void NETaddRedirects(void)
{
debug(LOG_NET, "%s\n", __FUNCTION__);
if (upnp) {
upnp_add_redirect(2100);
upnp_add_redirect(9990);
}
}
void NETremRedirects(void)
{
debug(LOG_NET, "%s\n", __FUNCTION__);
if (upnp)
{
upnp_rem_redirect(2100);
upnp_rem_redirect(9990);
}
}
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
// setup stuff // setup stuff
int NETinit(BOOL bFirstCall) int NETinit(BOOL bFirstCall)
@ -1805,6 +1916,30 @@ int NETinit(BOOL bFirstCall)
{ {
debug(LOG_NET, "NETPLAY: Init called, MORNIN'"); debug(LOG_NET, "NETPLAY: Init called, MORNIN'");
#if defined(WZ_OS_WIN)
{
static WSADATA stuff;
WORD ver_required = (2 << 8) + 2;
if (WSAStartup(ver_required, &stuff) != 0)
{
debug(LOG_ERROR, "Failed to initialize Winsock: %s", strSockError(getSockErr()));
return -1;
}
}
winsock2_dll = LoadLibraryA("ws2_32.dll");
if (winsock2_dll)
{
getaddrinfo_dll_func = GetProcAddress(winsock2_dll, "getaddrinfo");
freeaddrinfo_dll_func = GetProcAddress(winsock2_dll, "freeaddrinfo");
}
// Determine major Windows version
major_windows_version = LOBYTE(LOWORD(GetVersion()));
#endif
upnp = upnp_init(NULL);
for(i = 0; i < MAX_PLAYERS; i++) for(i = 0; i < MAX_PLAYERS; i++)
{ {
memset(&NetPlay.games[i], 0, sizeof(NetPlay.games[i])); memset(&NetPlay.games[i], 0, sizeof(NetPlay.games[i]));
@ -1818,28 +1953,6 @@ int NETinit(BOOL bFirstCall)
NETstartLogging(); NETstartLogging();
} }
#if defined(WZ_OS_WIN)
{
static WSADATA stuff;
WORD ver_required = (2 << 8) + 2;
if (WSAStartup(ver_required, &stuff) != 0)
{
debug(LOG_ERROR, "Failed to initialize Winsock: %s", strSockError(getSockErr()));
return -1;
}
}
winsock2_dll = LoadLibraryA("ws2_32.dll");
if (winsock2_dll)
{
getaddrinfo_dll_func = GetProcAddress(winsock2_dll, "getaddrinfo");
freeaddrinfo_dll_func = GetProcAddress(winsock2_dll, "freeaddrinfo");
}
// Determine major Windows version
major_windows_version = LOBYTE(LOWORD(GetVersion()));
#endif
NetPlay.ShowedMOTD = false; NetPlay.ShowedMOTD = false;
NetPlay.GamePassworded = false; NetPlay.GamePassworded = false;
@ -1867,6 +1980,8 @@ int NETshutdown(void)
} }
#endif #endif
NETremRedirects();
return 0; return 0;
} }
@ -3074,6 +3189,7 @@ BOOL NEThostGame(const char* SessionName, const char* PlayerName,
debug(LOG_NET, "NEThostGame(%s, %s, %d, %d, %d, %d, %u)", SessionName, PlayerName, debug(LOG_NET, "NEThostGame(%s, %s, %d, %d, %d, %d, %u)", SessionName, PlayerName,
one, two, three, four, plyrs); one, two, three, four, plyrs);
NETaddRedirects();
NET_InitPlayers(); NET_InitPlayers();
NetPlay.maxPlayers = MAX_PLAYERS; NetPlay.maxPlayers = MAX_PLAYERS;
if(!NetPlay.bComms) if(!NetPlay.bComms)

View File

@ -238,6 +238,9 @@ extern UBYTE NETrecvFile(void); // recv file chunk
extern int NETclose(void); // close current game extern int NETclose(void); // close current game
extern int NETshutdown(void); // leave the game in play. extern int NETshutdown(void); // leave the game in play.
extern void NETaddRedirects(void);
extern void NETremRedirects(void);
extern UDWORD NETgetBytesSent(void); // return bytes sent/recv. call regularly for good results extern UDWORD NETgetBytesSent(void); // return bytes sent/recv. call regularly for good results
extern UDWORD NETgetPacketsSent(void); // return packets sent/recv. call regularly for good results extern UDWORD NETgetPacketsSent(void); // return packets sent/recv. call regularly for good results
extern UDWORD NETgetBytesRecvd(void); // return bytes sent/recv. call regularly for good results extern UDWORD NETgetBytesRecvd(void); // return bytes sent/recv. call regularly for good results

View File

@ -6,7 +6,6 @@
ProjectGUID="{C7698ECE-9255-4A60-8091-A9A76E8BE911}" ProjectGUID="{C7698ECE-9255-4A60-8091-A9A76E8BE911}"
RootNamespace="netplay" RootNamespace="netplay"
Keyword="Win32Proj" Keyword="Win32Proj"
TargetFrameworkVersion="131072"
> >
<Platforms> <Platforms>
<Platform <Platform
@ -42,7 +41,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="&quot;$(SolutionDir)\..&quot;;&quot;$(SolutionDir)\..\devpkg\include&quot;;&quot;$(SolutionDir)\..\devpkg\include\SDL&quot;" AdditionalIncludeDirectories="&quot;$(SolutionDir)\..&quot;;&quot;$(SolutionDir)\..\devpkg\include&quot;;&quot;$(SolutionDir)\..\devpkg\include\SDL&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;STATICLIB"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="3" RuntimeLibrary="3"
@ -105,7 +104,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(SolutionDir)\..&quot;;&quot;$(SolutionDir)\..\devpkg\include&quot;;&quot;$(SolutionDir)\..\devpkg\include\SDL&quot;" AdditionalIncludeDirectories="&quot;$(SolutionDir)\..&quot;;&quot;$(SolutionDir)\..\devpkg\include&quot;;&quot;$(SolutionDir)\..\devpkg\include\SDL&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;STATICLIB"
RuntimeLibrary="2" RuntimeLibrary="2"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="3" WarningLevel="3"
@ -165,6 +164,106 @@
RelativePath=".\nettypes.c" RelativePath=".\nettypes.c"
> >
</File> </File>
<Filter
Name="miniUPnP"
>
<Filter
Name="src files"
>
<File
RelativePath=".\miniupnpc\igd_desc_parse.c"
>
</File>
<File
RelativePath=".\miniupnpc\minisoap.c"
>
</File>
<File
RelativePath=".\miniupnpc\minissdpc.c"
>
</File>
<File
RelativePath=".\miniupnpc\miniupnpc.c"
>
</File>
<File
RelativePath=".\miniupnpc\miniwget.c"
>
</File>
<File
RelativePath=".\miniupnpc\minixml.c"
>
</File>
<File
RelativePath=".\miniupnpc\upnpcommands.c"
>
</File>
<File
RelativePath=".\miniupnpc\upnperrors.c"
>
</File>
<File
RelativePath=".\miniupnpc\upnpreplyparse.c"
>
</File>
</Filter>
<Filter
Name="header files"
>
<File
RelativePath=".\miniupnpc\bsdqueue.h"
>
</File>
<File
RelativePath=".\miniupnpc\codelength.h"
>
</File>
<File
RelativePath=".\miniupnpc\declspec.h"
>
</File>
<File
RelativePath=".\miniupnpc\igd_desc_parse.h"
>
</File>
<File
RelativePath=".\miniupnpc\minisoap.h"
>
</File>
<File
RelativePath=".\miniupnpc\minissdpc.h"
>
</File>
<File
RelativePath=".\miniupnpc\miniupnpc.h"
>
</File>
<File
RelativePath=".\miniupnpc\miniupnpcstrings.h"
>
</File>
<File
RelativePath=".\miniupnpc\miniwget.h"
>
</File>
<File
RelativePath=".\miniupnpc\minixml.h"
>
</File>
<File
RelativePath=".\miniupnpc\upnpcommands.h"
>
</File>
<File
RelativePath=".\miniupnpc\upnperrors.h"
>
</File>
<File
RelativePath=".\miniupnpc\upnpreplyparse.h"
>
</File>
</Filter>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"

View File

@ -289,6 +289,7 @@ warzone2100_LDADD = \
$(top_builddir)/lib/sound/libsound.a \ $(top_builddir)/lib/sound/libsound.a \
$(top_builddir)/lib/script/libscript.a \ $(top_builddir)/lib/script/libscript.a \
$(top_builddir)/lib/netplay/libnetplay.a \ $(top_builddir)/lib/netplay/libnetplay.a \
$(top_builddir)/lib/netplay/miniupnpc/libminiupnpc.a \
$(top_builddir)/lib/ivis_opengl/libivis_opengl.a \ $(top_builddir)/lib/ivis_opengl/libivis_opengl.a \
$(top_builddir)/lib/ivis_common/libivis_common.a \ $(top_builddir)/lib/ivis_common/libivis_common.a \
$(top_builddir)/lib/gamelib/libgamelib.a \ $(top_builddir)/lib/gamelib/libgamelib.a \

View File

@ -2101,6 +2101,7 @@ static void stopJoining(void)
widgDelete(psWScreen,FRONTEND_BACKDROP); // refresh options screen. widgDelete(psWScreen,FRONTEND_BACKDROP); // refresh options screen.
startMultiOptions(true); startMultiOptions(true);
ingame.localJoiningInProgress = false; ingame.localJoiningInProgress = false;
NETremRedirects();
return; return;
} }
else if(ingame.localJoiningInProgress) // cancel a joined game. else if(ingame.localJoiningInProgress) // cancel a joined game.

View File

@ -720,6 +720,7 @@ BOOL multiGameShutdown(void)
// close game // close game
NETclose(); NETclose();
NETremRedirects();
if (ingame.numStructureLimits) if (ingame.numStructureLimits)
{ {