Use RFC2732 notation for IPv6 addresses

This fixes keepbody and the connect command (also
'-connect' parameter).

connect ::1
connect [::1]:5029
This commit is contained in:
James R 2021-08-31 19:54:27 -07:00
parent f8a749be09
commit 0422870df8
4 changed files with 53 additions and 24 deletions

View file

@ -1171,9 +1171,9 @@ static boolean CL_SendJoin(void)
static INT32 FindRejoinerNum(SINT8 node) static INT32 FindRejoinerNum(SINT8 node)
{ {
char strippednodeaddress[64]; char addressbuffer[64];
const char *nodeaddress; const char *nodeaddress;
char *port; const char *strippednodeaddress;
INT32 i; INT32 i;
// Make sure there is no dead dress before proceeding to the stripping // Make sure there is no dead dress before proceeding to the stripping
@ -1184,10 +1184,8 @@ static INT32 FindRejoinerNum(SINT8 node)
return -1; return -1;
// Strip the address of its port // Strip the address of its port
strcpy(strippednodeaddress, nodeaddress); strcpy(addressbuffer, nodeaddress);
port = strchr(strippednodeaddress, ':'); strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL);
if (port)
*port = '\0';
// Check if any player matches the stripped address // Check if any player matches the stripped address
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
@ -3426,14 +3424,13 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (server && I_GetNodeAddress) if (server && I_GetNodeAddress)
{ {
char addressbuffer[64];
const char *address = I_GetNodeAddress(node); const char *address = I_GetNodeAddress(node);
char *port = NULL;
if (address) // MI: fix msvcrt.dll!_mbscat crash? if (address) // MI: fix msvcrt.dll!_mbscat crash?
{ {
strcpy(playeraddress[newplayernum], address); strcpy(addressbuffer, address);
port = strchr(playeraddress[newplayernum], ':'); strcpy(playeraddress[newplayernum],
if (port) I_NetSplitAddress(addressbuffer, NULL));
*port = '\0';
} }
} }
} }

View file

@ -1200,26 +1200,34 @@ static void Internal_FreeNodenum(INT32 nodenum)
(void)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 I_NetMakeNode(const char *hostname)
{ {
SINT8 newnode = -1; SINT8 newnode = -1;
if (I_NetMakeNodewPort) if (I_NetMakeNodewPort)
{ {
char *localhostname = strdup(hostname); char *localhostname = strdup(hostname);
char *t = localhostname; char *port;
const char *port;
if (!localhostname) if (!localhostname)
return newnode; return newnode;
// retrieve portnum from address! // retrieve portnum from address!
strtok(localhostname, ":"); hostname = I_NetSplitAddress(localhostname, &port);
port = strtok(NULL, ":");
// remove the port in the hostname as we've it already CONS_Printf("%s %s\n", hostname, port);
while ((*t != ':') && (*t != '\0'))
t++;
*t = '\0';
newnode = I_NetMakeNodewPort(localhostname, port); newnode = I_NetMakeNodewPort(hostname, port);
free(localhostname); free(localhostname);
} }
return newnode; return newnode;

View file

@ -109,6 +109,17 @@ extern boolean (*I_NetCanSend)(void);
*/ */
extern void (*I_NetFreeNodenum)(INT32 nodenum); 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 /** \brief open a connection with specified address
\param address address to connect to \param address address to connect to

View file

@ -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 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_NTOP
#ifdef HAVE_IPV6
int v6 = (sk->any.sa_family == AF_INET6);
#else
int v6 = 0;
#endif
void *addr; void *addr;
if(sk->any.sa_family == AF_INET) if(sk->any.sa_family == AF_INET)
@ -355,14 +361,21 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
if(addr == NULL) if(addr == NULL)
sprintf(s, "No address"); 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); sprintf(s, "Unknown family type, error #%u", errno);
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0) else if(sk->any.sa_family == AF_INET6)
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port))); {
s[0] = '[';
strcat(s, "]");
if (sk->ip6.sin6_port != 0)
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
}
#endif #endif
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0) else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
strcat(s, va(":%d", ntohs(sk->ip4.sin_port))); strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
#else #else
if (sk->any.sa_family == AF_INET) if (sk->any.sa_family == AF_INET)
{ {