Bug Tracker – Full Text Bug Listing

Bug 587

Summary: Allow binding to a certain IP Address.
Product: Odamex Reporter: GhostlyDeath <ghostlydeath>
Component: ServerAssignee: Odamex Bug Reporter <odamex-bug-reporter>
Status: REOPENED ---    
Severity: trivial CC: elykdav, mike, nescientia, Ralphis
Priority: P2    
Version: (old) 0.5.0 - 0.5.5   
Hardware: All   
OS: All   
Bug Depends on:    
Bug Blocks: 424    
Attachments: Patch that allows you to bind to an address
Newer patch
WinSock fixes
Probable fix for localhost connect issue

Description GhostlyDeath 2010-05-17 23:06:35 UTC
On some servers, you have multiple IP Addresses, and in that case the socket library may decide what it really wants to use.

Would basically be this in i_net.cpp in the function BindToLocalPort

***********************************************************

netadr_t na;

if -bind command line parameter exists
{
    NET_StringToAdr("<-bind address>", &na);
    NetadrToSockadr(&na, &address);
}
else  // Any address
    address.sin_addr.s_addr = INADDR_ANY;

***********************************************************
Comment 1 GhostlyDeath 2010-07-03 16:11:13 UTC
Created attachment 186 [details]
Patch that allows you to bind to an address

This patch does the following:

 * Allows you to bind to a certain IP address (for example if you have multiple IP addresses, INADDR_ANY just doesn't cut it).
 * Fixes NET_StringToAdr so that it works for any host (that is, I replaced badly written code).
 * You need to use "+set bindaddress <host/ip>", otherwise it will use the default (the cvar doesn't appear to get saved).

Note that when binding to an address:
 
 * You need to own the address (that is, if it doesn't appear in ifconfig then you can't use it). If errno states that you can't use the address (must be root or not an address you own) then it will revert to any address.
 * You can only join the game when connecting to that address, which is the point of this patch.
 * If you do choose a 127.*.*.* address then you can only play with yourself.
Comment 2 GhostlyDeath 2010-07-03 18:08:31 UTC
Created attachment 187 [details]
Newer patch

Changed CVAR name to sv_bindaddress.
Comment 3 Brandon Del Bel 2010-07-04 07:21:33 UTC
r1635:

make -f Makefile.win client server
...
i586-mingw32msvc-g++ -I/usr/i586-mingw32msvc/include/SDL -I/usr/i586-mingw32msvc/include/SDL -Os -D_WIN32 -DNOASM -Icommon -Itextscreen -I../client/sdl -Iclient/sdl -I../client/src -Iclient/src -c common/i_net.cpp -o obj/common/client_i_net.o
common/i_net.cpp: In function ‘void BindToLocalPort(SOCKET, u_short)’:
common/i_net.cpp:155: error: ‘EADDRNOTAVAIL’ was not declared in this scope
make: *** [obj/common/client_i_net.o] Error 1
Comment 4 GhostlyDeath 2010-07-04 17:22:24 UTC
#ifdef _WIN32
    #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
#endif

Also, errno could be errno or h_errno, depends.
Comment 5 GhostlyDeath 2010-07-04 17:35:37 UTC
(In reply to comment #4)
> #ifdef _WIN32
>     #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
> #endif
> 
> Also, errno could be errno or h_errno, depends.

No screw that
Comment 6 GhostlyDeath 2010-07-04 17:41:41 UTC
Created attachment 188 [details]
WinSock fixes

Misc Fixes for Win32 which uses WinSock which is practically 100% compatible but alot of stuff is renamed.
Comment 7 Ralph Vickers 2010-07-04 20:49:27 UTC
Resolved r1636
Comment 8 GhostlyDeath 2010-07-05 00:36:59 UTC
(In reply to comment #7)
> Resolved r1636

No
Comment 9 GhostlyDeath 2010-07-05 00:41:24 UTC
The code in 1636 is not correct:

errno is used in UNIX for BSD sockets but with WinSock it's not the case. Winsock requires WSAGetLastError() to obtain errno values. Also every errno for WinSocks is changed to WSAxxxx.

The latest patch uses WSAGetLastError() for windows but still uses errno for UNIX.

It also fixes places where strerror(errno) is used where errno is never set, which is the other portion of the code.
Comment 10 Ralph Vickers 2010-07-17 23:43:27 UTC
Can no longer connect to localhost/127.0.0.1 with the implementation of this patch. Is it possible to correct this?
Comment 11 Mike Lightner 2010-07-21 23:50:06 UTC
r1664 reverts this patch.  This was not thoroughly tested on Windows and has introduced undesirable behavior.

I think it is something that is implementable and worth keeping open.
Comment 12 Kyle 2011-01-15 03:00:12 UTC
Created attachment 237 [details]
Probable fix for localhost connect issue

This patch puts the problem-causing code inside an "#ifndef _WIN32", while this removes the ability to bind to a specific IP with the windows server, it keeps this (useful) functionality in for server hosts running *nix. As I do not run windows, this patch will need to be tested

(Patched against trunk r2046)
Comment 13 Mike Lightner 2011-01-17 15:39:55 UTC
Your "fix" is to hide it from one platform.  I do not think this constitutes a fix.  You remove the ability for one platform to do it, and in turn the platform(s) that still would be able to may then have problems binding to localhost.
Comment 14 Kyle 2011-01-19 01:51:03 UTC
(In reply to comment #13)
> Your "fix" is to hide it from one platform.  I do not think this constitutes a
> fix.  You remove the ability for one platform to do it, and in turn the
> platform(s) that still would be able to may then have problems binding to
> localhost.

Wrong, the platforms that the binding is left available for actually have some working implementation of the socket library, and therefore allow connecting to localhost *as long as* the sv_bindaddress cvar is left unset.

I'm asking for a compromise between compatibility and practicality, getting this feature working under windows is better off left until it's actually needed. Meanwhile there are servers running on Linux/BSD that need this feature.