mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Merge branch 'ipv6' into 'next'
Fix IPv6 See merge request STJr/SRB2!1612
This commit is contained in:
commit
c2c27bf356
7 changed files with 122 additions and 65 deletions
|
@ -1318,9 +1318,9 @@ static boolean CL_SendJoin(void)
|
|||
|
||||
static INT32 FindRejoinerNum(SINT8 node)
|
||||
{
|
||||
char strippednodeaddress[64];
|
||||
char addressbuffer[64];
|
||||
const char *nodeaddress;
|
||||
char *port;
|
||||
const char *strippednodeaddress;
|
||||
INT32 i;
|
||||
|
||||
// Make sure there is no dead dress before proceeding to the stripping
|
||||
|
@ -1331,10 +1331,8 @@ static INT32 FindRejoinerNum(SINT8 node)
|
|||
return -1;
|
||||
|
||||
// Strip the address of its port
|
||||
strcpy(strippednodeaddress, nodeaddress);
|
||||
port = strchr(strippednodeaddress, ':');
|
||||
if (port)
|
||||
*port = '\0';
|
||||
strcpy(addressbuffer, nodeaddress);
|
||||
strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL);
|
||||
|
||||
// Check if any player matches the stripped address
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -3771,14 +3769,13 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
|
||||
if (server && I_GetNodeAddress)
|
||||
{
|
||||
char addressbuffer[64];
|
||||
const char *address = I_GetNodeAddress(node);
|
||||
char *port = NULL;
|
||||
if (address) // MI: fix msvcrt.dll!_mbscat crash?
|
||||
{
|
||||
strcpy(playeraddress[newplayernum], address);
|
||||
port = strchr(playeraddress[newplayernum], ':');
|
||||
if (port)
|
||||
*port = '\0';
|
||||
strcpy(addressbuffer, address);
|
||||
strcpy(playeraddress[newplayernum],
|
||||
I_NetSplitAddress(addressbuffer, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
26
src/d_net.c
26
src/d_net.c
|
@ -1207,26 +1207,32 @@ static void Internal_FreeNodenum(INT32 nodenum)
|
|||
(void)nodenum;
|
||||
}
|
||||
|
||||
char *I_NetSplitAddress(char *host, char **port)
|
||||
{
|
||||
boolean v4 = (strchr(host, '.') != NULL);
|
||||
|
||||
host = strtok(host, v4 ? ":" : "[]");
|
||||
|
||||
if (port)
|
||||
*port = strtok(NULL, ":");
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
SINT8 I_NetMakeNode(const char *hostname)
|
||||
{
|
||||
SINT8 newnode = -1;
|
||||
if (I_NetMakeNodewPort)
|
||||
{
|
||||
char *localhostname = strdup(hostname);
|
||||
char *t = localhostname;
|
||||
const char *port;
|
||||
char *port;
|
||||
if (!localhostname)
|
||||
return newnode;
|
||||
|
||||
// retrieve portnum from address!
|
||||
strtok(localhostname, ":");
|
||||
port = strtok(NULL, ":");
|
||||
hostname = I_NetSplitAddress(localhostname, &port);
|
||||
|
||||
// remove the port in the hostname as we've it already
|
||||
while ((*t != ':') && (*t != '\0'))
|
||||
t++;
|
||||
*t = '\0';
|
||||
|
||||
newnode = I_NetMakeNodewPort(localhostname, port);
|
||||
newnode = I_NetMakeNodewPort(hostname, port);
|
||||
free(localhostname);
|
||||
}
|
||||
return newnode;
|
||||
|
|
|
@ -216,7 +216,11 @@ HMS_connect (const char *format, ...)
|
|||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
|
||||
#ifndef NO_IPV6
|
||||
if (M_CheckParm("-noipv6"))
|
||||
#endif
|
||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
|
||||
|
|
11
src/i_net.h
11
src/i_net.h
|
@ -109,6 +109,17 @@ extern boolean (*I_NetCanSend)(void);
|
|||
*/
|
||||
extern void (*I_NetFreeNodenum)(INT32 nodenum);
|
||||
|
||||
/**
|
||||
\brief split a string into address and port
|
||||
|
||||
\param address string to split
|
||||
|
||||
\param port double pointer to hold port component (optional)
|
||||
|
||||
\return address component
|
||||
*/
|
||||
extern char *I_NetSplitAddress(char *address, char **port);
|
||||
|
||||
/** \brief open a connection with specified address
|
||||
|
||||
\param address address to connect to
|
||||
|
|
71
src/i_tcp.c
71
src/i_tcp.c
|
@ -340,8 +340,14 @@ static inline void I_UPnP_rem(const char *port, const char * servicetype)
|
|||
|
||||
static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||
{
|
||||
static char s[64]; // 255.255.255.255:65535 or IPv6:65535
|
||||
static char s[64]; // 255.255.255.255:65535 or
|
||||
// [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
|
||||
#ifdef HAVE_NTOP
|
||||
#ifdef HAVE_IPV6
|
||||
int v6 = (sk->any.sa_family == AF_INET6);
|
||||
#else
|
||||
int v6 = 0;
|
||||
#endif
|
||||
void *addr;
|
||||
|
||||
if(sk->any.sa_family == AF_INET)
|
||||
|
@ -355,14 +361,21 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
|||
|
||||
if(addr == NULL)
|
||||
sprintf(s, "No address");
|
||||
else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL)
|
||||
else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
|
||||
sprintf(s, "Unknown family type, error #%u", errno);
|
||||
#ifdef HAVE_IPV6
|
||||
else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
||||
else if(sk->any.sa_family == AF_INET6)
|
||||
{
|
||||
s[0] = '[';
|
||||
strcat(s, "]");
|
||||
|
||||
if (sk->ip6.sin6_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
||||
}
|
||||
#endif
|
||||
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
|
||||
strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
|
||||
|
||||
#else
|
||||
if (sk->any.sa_family == AF_INET)
|
||||
{
|
||||
|
@ -427,7 +440,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
|||
&& (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port));
|
||||
#ifdef HAVE_IPV6
|
||||
else if (b->any.sa_family == AF_INET6)
|
||||
return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
|
||||
return !memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
|
||||
&& (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port));
|
||||
#endif
|
||||
else
|
||||
|
@ -735,8 +748,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
unsigned long trueval = true;
|
||||
#endif
|
||||
mysockaddr_t straddr;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
socklen_t len = sizeof(straddr);
|
||||
|
||||
if (s == (SOCKET_TYPE)ERRSOCKET)
|
||||
return (SOCKET_TYPE)ERRSOCKET;
|
||||
|
@ -754,14 +766,12 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
}
|
||||
#endif
|
||||
|
||||
straddr.any = *addr;
|
||||
memcpy(&straddr, addr, addrlen);
|
||||
I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr));
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
mysockaddr_t tmpaddr;
|
||||
tmpaddr.any = *addr ;
|
||||
if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
||||
if (straddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
||||
{
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
|
@ -778,7 +788,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
||||
if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
||||
{
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
|
@ -788,7 +798,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
// make it IPv6 ony
|
||||
opt = true;
|
||||
opts = (socklen_t)sizeof(opt);
|
||||
if (setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts))
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore
|
||||
}
|
||||
|
@ -830,10 +840,17 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
|||
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
||||
}
|
||||
|
||||
if (getsockname(s, (struct sockaddr *)&sin, &len) == -1)
|
||||
if (getsockname(s, &straddr.any, &len) == -1)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
||||
else
|
||||
current_port = (UINT16)ntohs(sin.sin_port);
|
||||
{
|
||||
if (family == AF_INET)
|
||||
current_port = (UINT16)ntohs(straddr.ip4.sin_port);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
current_port = (UINT16)ntohs(straddr.ip6.sin6_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -844,7 +861,7 @@ static boolean UDP_Socket(void)
|
|||
struct my_addrinfo *ai, *runp, hints;
|
||||
int gaie;
|
||||
#ifdef HAVE_IPV6
|
||||
const INT32 b_ipv6 = M_CheckParm("-ipv6");
|
||||
const INT32 b_ipv6 = !M_CheckParm("-noipv6");
|
||||
#endif
|
||||
const char *serv;
|
||||
|
||||
|
@ -1156,6 +1173,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
SINT8 newnode = -1;
|
||||
struct my_addrinfo *ai = NULL, *runp, hints;
|
||||
int gaie;
|
||||
size_t i;
|
||||
|
||||
if (!port || !port[0])
|
||||
port = DEFAULTPORT;
|
||||
|
@ -1183,13 +1201,24 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
|
||||
while (runp != NULL)
|
||||
{
|
||||
// find ip of the server
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
// test ip address of server
|
||||
for (i = 0; i < mysocketses; ++i)
|
||||
{
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
break;
|
||||
/* sendto tests that there is a network to this
|
||||
address */
|
||||
if (runp->ai_addr->sa_family == myfamily[i] &&
|
||||
sendto(mysockets[i], NULL, 0, 0,
|
||||
runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
{
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
|
||||
if (i < mysocketses)
|
||||
runp = runp->ai_next;
|
||||
else
|
||||
break;
|
||||
}
|
||||
I_freeaddrinfo(ai);
|
||||
return newnode;
|
||||
|
|
52
src/m_menu.c
52
src/m_menu.c
|
@ -975,7 +975,7 @@ static menuitem_t MP_MainMenu[] =
|
|||
{
|
||||
{IT_HEADER, NULL, "Join a game", NULL, 0},
|
||||
{IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenuModChecks, 12},
|
||||
{IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 22},
|
||||
{IT_STRING|IT_KEYHANDLER, NULL, "Specify server address:", M_HandleConnectIP, 22},
|
||||
{IT_HEADER, NULL, "Host a game", NULL, 54},
|
||||
{IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 66},
|
||||
{IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 76},
|
||||
|
@ -11738,35 +11738,19 @@ static void M_StartServerMenu(INT32 choice)
|
|||
|
||||
#define CONNIP_LEN 128
|
||||
static char setupm_ip[CONNIP_LEN];
|
||||
|
||||
#define DOTS "... "
|
||||
|
||||
// Draw the funky Connect IP menu. Tails 11-19-2002
|
||||
// So much work for such a little thing!
|
||||
static void M_DrawMPMainMenu(void)
|
||||
static void M_DrawConnectIP(void)
|
||||
{
|
||||
INT32 x = currentMenu->x;
|
||||
INT32 y = currentMenu->y;
|
||||
INT32 y = currentMenu->y + 22;
|
||||
|
||||
const INT32 boxwidth = /*16*8 + 6*/ (BASEVIDWIDTH - 2*(x+5));
|
||||
const INT32 maxstrwidth = boxwidth - 5;
|
||||
char *drawnstr = malloc(sizeof(setupm_ip));
|
||||
char *drawnstr_orig = drawnstr;
|
||||
boolean drawthin, shorten = false;
|
||||
|
||||
// use generic drawer for cursor, items and title
|
||||
M_DrawGenericMenu();
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+66,
|
||||
((itemOn == 4) ? V_YELLOWMAP : 0), va("(2-%d players)", MAXPLAYERS));
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+76,
|
||||
((itemOn == 5) ? V_YELLOWMAP : 0), "(2 players)");
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+116,
|
||||
((itemOn == 8) ? V_YELLOWMAP : 0), "(splitscreen)");
|
||||
|
||||
y += 22;
|
||||
|
||||
V_DrawFill(x+5, y+4+5, boxwidth, 8+6, 159);
|
||||
|
||||
strcpy(drawnstr, setupm_ip);
|
||||
|
@ -11814,6 +11798,28 @@ static void M_DrawMPMainMenu(void)
|
|||
free(drawnstr_orig);
|
||||
}
|
||||
|
||||
// Draw the funky Connect IP menu. Tails 11-19-2002
|
||||
// So much work for such a little thing!
|
||||
static void M_DrawMPMainMenu(void)
|
||||
{
|
||||
INT32 x = currentMenu->x;
|
||||
INT32 y = currentMenu->y;
|
||||
|
||||
// use generic drawer for cursor, items and title
|
||||
M_DrawGenericMenu();
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+66,
|
||||
((itemOn == 4) ? V_YELLOWMAP : 0), va("(2-%d players)", MAXPLAYERS));
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+76,
|
||||
((itemOn == 5) ? V_YELLOWMAP : 0), "(2 players)");
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-x, y+116,
|
||||
((itemOn == 8) ? V_YELLOWMAP : 0), "(splitscreen)");
|
||||
|
||||
M_DrawConnectIP();
|
||||
}
|
||||
|
||||
#undef DOTS
|
||||
|
||||
// Tails 11-19-2002
|
||||
|
@ -11951,7 +11957,11 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
break;
|
||||
|
||||
// Rudimentary number and period enforcing - also allows letters so hostnames can be used instead
|
||||
if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z'))
|
||||
// and square brackets for RFC 2732 IPv6 addresses
|
||||
if ((choice >= '-' && choice <= ':') ||
|
||||
(choice == '[' || choice == ']') ||
|
||||
(choice >= 'A' && choice <= 'Z') ||
|
||||
(choice >= 'a' && choice <= 'z'))
|
||||
{
|
||||
S_StartSound(NULL,sfx_menu1); // Tails
|
||||
setupm_ip[l] = (char)choice;
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef union
|
|||
typedef struct
|
||||
{
|
||||
msg_header_t header;
|
||||
char ip[16];
|
||||
char ip[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
|
||||
char port[8];
|
||||
char name[32];
|
||||
INT32 room;
|
||||
|
|
Loading…
Reference in a new issue