This is an easy to implement and solid improvement that will resolve a LARGE percentage of Quake connectivity difficulties for DSL users that aren't using a router. And it's automatic!
This isn't as good as the method DarkPlaces or Quakeworld use to establish connections, but it is very easy to implement.
This doesn't resolve trouble that dialup users with a LAN have or situations where someone has 2 network cards and so forth. But dialup users are rare and most people don't have a complicated setup. And this won't resolve issues where someone has setup DSL in a very strange way involving a router.
But this does fix 1 of the 4 situations requiring the -ip parameter with NQ, which is probably at least half of the situations where someone should be able to connect to a server, but can't.
Instructions:
1. Open net_wins.c
2. Find void WINS_GetLocalAddress()
3. Replace the above with this.
This change simply ignores ip #0 if the address is 169.254.x.x and checks to see if a 2nd ip address exists (ip #1) and if so, uses it.
You can read the comments I put into the code to understand it.
/quote blocks don't show tabs. The code be taken out of the ProQuake 3.99a source:
http://www.quakeone.com/proquake/pro...80116_2226.zip
(Thanks to tryno, looking at his idea he coded was very helpful in coming up with this idea. This can continue to be evolved further as well).
This isn't as good as the method DarkPlaces or Quakeworld use to establish connections, but it is very easy to implement.
This doesn't resolve trouble that dialup users with a LAN have or situations where someone has 2 network cards and so forth. But dialup users are rare and most people don't have a complicated setup. And this won't resolve issues where someone has setup DSL in a very strange way involving a router.
But this does fix 1 of the 4 situations requiring the -ip parameter with NQ, which is probably at least half of the situations where someone should be able to connect to a server, but can't.
Instructions:
1. Open net_wins.c
2. Find void WINS_GetLocalAddress()
Old way, to be replaced
void WINS_GetLocalAddress()
{
struct hostent *local = NULL;
char buff[MAXHOSTNAMELEN];
unsigned long addr;
if (myAddr != INADDR_ANY)
return;
if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR)
return;
blocktime = Sys_FloatTime();
WSASetBlockingHook(BlockingHook);
local = pgethostbyname(buff);
WSAUnhookBlockingHook();
if (local == NULL)
return;
myAddr = *(int *)local->h_addr_list[0];
addr = ntohl(myAddr);
sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16 ) & 0xff, (addr >> 8 ) & 0xff, addr & 0xff);
}
void WINS_GetLocalAddress()
{
struct hostent *local = NULL;
char buff[MAXHOSTNAMELEN];
unsigned long addr;
if (myAddr != INADDR_ANY)
return;
if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR)
return;
blocktime = Sys_FloatTime();
WSASetBlockingHook(BlockingHook);
local = pgethostbyname(buff);
WSAUnhookBlockingHook();
if (local == NULL)
return;
myAddr = *(int *)local->h_addr_list[0];
addr = ntohl(myAddr);
sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16 ) & 0xff, (addr >> 8 ) & 0xff, addr & 0xff);
}
New way, replaces the above code entirely with this
void WINS_GetLocalAddress()
{
struct hostent *local = NULL;
char buff[MAXHOSTNAMELEN];
unsigned long addr;
if (myAddr != INADDR_ANY)
return;
if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR)
return;
blocktime = Sys_FloatTime();
WSASetBlockingHook(BlockingHook);
local = pgethostbyname(buff);
WSAUnhookBlockingHook();
if (local == NULL)
return;
// Baker: Here is our DSL workaround. It works like this:
// ip addresses that begin 169.254.x.x are always invalid
// these are self-assigned APIPA addresses for DHCP
// for devices that fail.
//
// There are 2 reasons for failure:
// #1. plain DSL modem (with no router built-in)
// #2. DHCP failure of some sort
//
// If we find ip address #0 is 169.254.x.x then
// we will assume it is a DSL modem and check to see if
// there is a 2nd ip address available.
//
// Even if ip address #0 is 169.254.x.x and not a
// DSL modem, which can happen with situations like
// a defective router or improperly configured
// network adapter, it still isn't going to work
// so checking ip address #1 and using that if available
// is still desireable.
// Baker: get ip address #0
myAddr = *(int *)local->h_addr_list[0];
addr = ntohl(myAddr);
sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8 ) & 0xff, addr & 0xff);
// Baker: is ip address #0 = 169.254.x.x ?
if (((addr >> 24 ) & 0xff) == 169 && ((addr >> 16 ) & 0xff) == 254) {
// Ok, can't use ip address #0.
Con_DPrintf ("WINS_GetLocalAddress: ip address #0 (%s) is invalid, checking next ...\n", my_tcpip_address);
if (local->h_addr_list[1]) {
// ip address #1 is valid, use it.
myAddr = *(int *)local->h_addr_list[1];
addr = ntohl(myAddr);
sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16 ) & 0xff, (addr >> 8 ) & 0xff, addr & 0xff);
Con_DPrintf ("WINS_GetLocalAddress: ip address #1 (%s) found. Using.\n", my_tcpip_address);
} else {
Con_DPrintf("WINS_GetLocalAddress: ip address #1 does not exist\n");
Con_DPrintf("WINS_GetLocalAddress: Warning continuing with #0\n");
Con_Printf("Invalid IP (%s): Is internet/network connected?\n", my_tcpip_address);
}
}
}
void WINS_GetLocalAddress()
{
struct hostent *local = NULL;
char buff[MAXHOSTNAMELEN];
unsigned long addr;
if (myAddr != INADDR_ANY)
return;
if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR)
return;
blocktime = Sys_FloatTime();
WSASetBlockingHook(BlockingHook);
local = pgethostbyname(buff);
WSAUnhookBlockingHook();
if (local == NULL)
return;
// Baker: Here is our DSL workaround. It works like this:
// ip addresses that begin 169.254.x.x are always invalid
// these are self-assigned APIPA addresses for DHCP
// for devices that fail.
//
// There are 2 reasons for failure:
// #1. plain DSL modem (with no router built-in)
// #2. DHCP failure of some sort
//
// If we find ip address #0 is 169.254.x.x then
// we will assume it is a DSL modem and check to see if
// there is a 2nd ip address available.
//
// Even if ip address #0 is 169.254.x.x and not a
// DSL modem, which can happen with situations like
// a defective router or improperly configured
// network adapter, it still isn't going to work
// so checking ip address #1 and using that if available
// is still desireable.
// Baker: get ip address #0
myAddr = *(int *)local->h_addr_list[0];
addr = ntohl(myAddr);
sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8 ) & 0xff, addr & 0xff);
// Baker: is ip address #0 = 169.254.x.x ?
if (((addr >> 24 ) & 0xff) == 169 && ((addr >> 16 ) & 0xff) == 254) {
// Ok, can't use ip address #0.
Con_DPrintf ("WINS_GetLocalAddress: ip address #0 (%s) is invalid, checking next ...\n", my_tcpip_address);
if (local->h_addr_list[1]) {
// ip address #1 is valid, use it.
myAddr = *(int *)local->h_addr_list[1];
addr = ntohl(myAddr);
sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16 ) & 0xff, (addr >> 8 ) & 0xff, addr & 0xff);
Con_DPrintf ("WINS_GetLocalAddress: ip address #1 (%s) found. Using.\n", my_tcpip_address);
} else {
Con_DPrintf("WINS_GetLocalAddress: ip address #1 does not exist\n");
Con_DPrintf("WINS_GetLocalAddress: Warning continuing with #0\n");
Con_Printf("Invalid IP (%s): Is internet/network connected?\n", my_tcpip_address);
}
}
}
You can read the comments I put into the code to understand it.
/quote blocks don't show tabs. The code be taken out of the ProQuake 3.99a source:
http://www.quakeone.com/proquake/pro...80116_2226.zip
(Thanks to tryno, looking at his idea he coded was very helpful in coming up with this idea. This can continue to be evolved further as well).
Comment