Announcement

Collapse
No announcement yet.

Engine Code: "DSL" Fix 3.0

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Engine Code: "DSL" Fix 3.0

    Using the base Quake source as an example:

    Open net_wins.c:

    Step 1: Above "void WINS_GetLocalAddress()", add this:

    Code:
    int WINS_iptype(unsigned long ipaddr) {
    	// Baker: 3.99e - workaround for mostly DSL/dialup
    
    	// Return 1 if unresolvable/invalid
    	// Return 2 if private network (router, LAN, whatever)
    	// Return 3 if internet ip
    
    	// TCP/IP addresses reserved for 'private' networks are:
    	//10.0.0.0       to     10.255.255.255
    	//172.16.0.0     to     172.31.255.255
    	//192.168.0.0    to     192.168.255.255
    	//
    	//and as of July 2001
    	//
    	//169.254.0.0    to     169.254.255.255 rfc
    
    	if (((ipaddr >> 24) & 0xff) == 0)
    		return 1;  // Invalid ip
    
    	if (((ipaddr >> 24) & 0xff) == 169 && ((ipaddr >> 16) & 0xff) == 254)
    		return 1;  // Unresolvable private ip
    
    	if (((ipaddr >> 24) & 0xff) == 10)
    		return 2;  // Private ip
    
    	if (((ipaddr >> 24) & 0xff) == 172 && ((ipaddr >> 16) & 0xff) >= 16 && ((ipaddr >> 16) & 0xff) <= 31)
    		return 2;  // Private ip
    
    	if (((ipaddr >> 24) & 0xff) == 192 && ((ipaddr >> 16) & 0xff) == 168)
    		return 2;  // Private ip
    
    	return 3;
    
    }
    Step #2: Find the "void WINS_GetLocalAddress()" procedure and replace the full procedure with the following:

    Code:
    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_DoubleTime();
    	WSASetBlockingHook(BlockingHook);
    	local = pgethostbyname(buff);
    	WSAUnhookBlockingHook();
    	if (local == NULL)
    		return;
    
    	if (COM_CheckParm("-oldnet") || isDedicated) {
    		// Baker: screens for unresolvable ips like 169.254.x.x (dsl modem at best, unresponsive device at worst)
    
    		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 (WINS_iptype(addr) == 1) {
    			// Unresolvable private IP or invalid ip
    			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 exists, 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);
    			}
    		}
    
    		return;
    	}
    
    	// Baker 3.99e: New: use internet ip over private network ip over unresolvable/invalid ip
    
    	{
    		unsigned long	addr0, addr1, addr2;
    		int				choice = 0, addrtype0 = 0, addrtype1 = 0, addrtype2 = 0;
    		char			tcpip0[NET_NAMELEN];
    		char			tcpip1[NET_NAMELEN];
    		char			tcpip2[NET_NAMELEN];
    
    		// Baker: get ip addresses
    
    		myAddr = *(int *)local->h_addr_list[0];
    		addr0 = ntohl(myAddr);
    
    		addrtype0 = WINS_iptype(addr0);
    		sprintf(tcpip0, "%d.%d.%d.%d", (addr0 >> 24) & 0xff, (addr0 >> 16) & 0xff, (addr0 >> 8) & 0xff, addr0 & 0xff);
    
    		if (local->h_addr_list[1]) {
    
    			Con_Printf("\nMultiple IPs found\n%s", Con_Quakebar(36));
    			Con_Printf("ip #0: %s %s\n", ((addrtype0 == 3) ? "internet     " : ((addrtype0 == 2) ? "local network" : ((addrtype0 == 1) ? "unresolvable " : "no device    "))), tcpip0);
    
    			myAddr = *(int *)local->h_addr_list[1];
    			addr1 = ntohl(myAddr);
    			addrtype1 = WINS_iptype(addr1);
    			sprintf(tcpip1, "%d.%d.%d.%d", (addr1 >> 24) & 0xff, (addr1 >> 16) & 0xff, (addr1 >> 8) & 0xff, addr1 & 0xff);
    			Con_Printf("ip #1: %s %s\n", ((addrtype1 == 3) ? "internet     " : ((addrtype1 == 2) ? "local network" : ((addrtype1 == 1) ? "unresolvable " : "no device    "))), tcpip1);
    
    			if (addrtype1 >= addrtype0)
    				choice = 1;
    
    			if (local->h_addr_list[2]) {
    
    				myAddr = *(int *)local->h_addr_list[2];
    				addr2 = ntohl(myAddr);
    				addrtype2 = WINS_iptype(addr2);
    				sprintf(tcpip2, "%d.%d.%d.%d", (addr2 >> 24) & 0xff, (addr2 >> 16) & 0xff, (addr2 >> 8) & 0xff, addr2 & 0xff);
    				Con_Printf("ip #2: %s %s\n", ((addrtype2 == 3) ? "internet     " : ((addrtype2 == 2) ? "local network" : ((addrtype2 == 1) ? "unresolvable " : "no device    "))), tcpip2);
    
    				if (addrtype2 >= (choice == 0 ? addrtype0 : addrtype1))
    					choice = 2; // else the above stands
    			}
    
    			myAddr = *(int *)local->h_addr_list[choice];
    			addr = ntohl(myAddr);
    			sprintf(my_tcpip_address, "%d.%d.%d.%d", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
    			Con_Printf("%s", Con_Quakebar(36));
    			Con_Printf("Using ip %s\n", my_tcpip_address);
    			Con_Printf("%s\n", Con_Quakebar(36));
    		} else {
    			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);
    		}
    	}
    
    }

    FAQ about the above:

    #1 What is the difference between the previous DSL fix and this?

    It was missing an important "else" condition.

    #2 What is the "DSL" fix?

    There are a number of situations where Quake can't use the internet because it tries to use the wrong IP address. This is particularly a problem for DSL without a router and for DSL when the router isn't doing the PPPOE authentication itself. It can also affect dialup + LAN or even in rare circumstances cable with some network setups.

    The result is that with this fix, Quake will figure out which IP address represents the current internet connection.
    Quakeone.com - Being exactly one-half good and one-half evil has advantages. When a portal opens to the antimatter universe, my opposite is just me with a goatee.

    So while you guys all have to fight your anti-matter counterparts, me and my evil twin will be drinking a beer laughing at you guys ...
Working...
X