Let MS_Connect use -bindaddr

And so now you really can host from multiple IP addresses.

(cherry picked from commit e56bf12537700af7b7fcd0d3b0e8586e41edddd1)
This commit is contained in:
James R 2019-08-03 13:27:57 -07:00
parent 223edd8ee0
commit af2d3cfd16
1 changed files with 67 additions and 27 deletions

View File

@ -323,7 +323,7 @@ static INT32 GetServersList(void)
//
// MS_Connect()
//
static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async)
static INT32 MS_SubConnect(const char *ip_addr, const char *str_port, INT32 async, struct sockaddr *bindaddr, socklen_t bindaddrlen)
{
#ifdef NONET
(void)ip_addr;
@ -356,44 +356,48 @@ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async)
socket_fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
if (socket_fd != (SOCKET_TYPE)ERRSOCKET)
{
if (async) // do asynchronous connection
if (!bindaddr || bind(socket_fd, bindaddr, bindaddrlen) == 0)
{
if (async) // do asynchronous connection
{
#ifdef FIONBIO
#ifdef WATTCP
char res = 1;
char res = 1;
#else
unsigned long res = 1;
unsigned long res = 1;
#endif
ioctl(socket_fd, FIONBIO, &res);
ioctl(socket_fd, FIONBIO, &res);
#endif
if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) == ERRSOCKET)
{
#ifdef _WIN32 // humm, on win32/win64 it doesn't work with EINPROGRESS (stupid windows)
if (WSAGetLastError() != WSAEWOULDBLOCK)
#else
if (errno != EINPROGRESS)
#endif
if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) == ERRSOCKET)
{
con_state = MSCS_FAILED;
CloseConnection();
I_freeaddrinfo(ai);
return MS_CONNECT_ERROR;
#ifdef _WIN32 // humm, on win32/win64 it doesn't work with EINPROGRESS (stupid windows)
if (WSAGetLastError() != WSAEWOULDBLOCK)
#else
if (errno != EINPROGRESS)
#endif
{
con_state = MSCS_FAILED;
CloseConnection();
I_freeaddrinfo(ai);
return MS_CONNECT_ERROR;
}
}
con_state = MSCS_WAITING;
FD_ZERO(&wset);
FD_SET(socket_fd, &wset);
select_timeout.tv_sec = 0, select_timeout.tv_usec = 0;
I_freeaddrinfo(ai);
return 0;
}
else if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) != ERRSOCKET)
{
I_freeaddrinfo(ai);
return 0;
}
con_state = MSCS_WAITING;
FD_ZERO(&wset);
FD_SET(socket_fd, &wset);
select_timeout.tv_sec = 0, select_timeout.tv_usec = 0;
I_freeaddrinfo(ai);
return 0;
}
else if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) != ERRSOCKET)
{
I_freeaddrinfo(ai);
return 0;
}
close(socket_fd);
}
runp = runp->ai_next;
}
@ -402,6 +406,42 @@ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async)
return MS_CONNECT_ERROR;
}
static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async)
{
const char *lhost;
struct my_addrinfo hints;
struct my_addrinfo *ai, *aip;
int c;
if (M_CheckParm("-bindaddr") && ( lhost = M_GetNextParm() ))
{
memset (&hints, 0x00, sizeof(hints));
#ifdef AI_ADDRCONFIG
hints.ai_flags = AI_ADDRCONFIG;
#endif
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (( c = I_getaddrinfo(lhost, 0, &hints, &ai) ) != 0)
{
CONS_Printf(
"mserv.c: bind to %s: %s\n",
lhost,
gai_strerror(c));
return MS_GETHOSTBYNAME_ERROR;
}
for (aip = ai; aip; aip = aip->ai_next)
{
c = MS_SubConnect(ip_addr, str_port, async, aip->ai_addr, aip->ai_addrlen);
if (c == 0)
return 0;
}
I_freeaddrinfo(ai);
return c;
}
else
return MS_SubConnect(ip_addr, str_port, async, 0, 0);
}
#define NUM_LIST_SERVER MAXSERVERLIST
const msg_server_t *GetShortServersList(INT32 room)
{