Use the best network interface to route an ip instead of the first interface in getLocalInterfaces on Windows.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6469 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2013-07-01 15:12:06 +00:00
parent 81874da2cc
commit af5c31a4f5
4 changed files with 57 additions and 16 deletions

View File

@ -905,7 +905,7 @@ bool p3NetMgrIMPL::checkNetAddress()
struct in_addr prefAddr;
struct sockaddr_in oldAddr;
validAddr = getPreferredInterface(prefAddr);
validAddr = getPreferredInterface(mLocalAddr.sin_addr, prefAddr);
/* if we don't have a valid address - reset */
if (!validAddr)

View File

@ -147,7 +147,7 @@ std::string socket_errorType(int err)
#include <net/if.h>
#include <sys/ioctl.h>
bool getLocalInterfaces(std::list<struct in_addr> &addrs)
bool getLocalInterfaces(struct in_addr &/*routeAddr*/, std::list<struct in_addr> &addrs)
{
int sock = 0;
struct ifreq ifreq;
@ -328,18 +328,23 @@ std::string socket_errorType(int err)
// A function to determine the interfaces on your computer....
// No idea of how to do this in windows....
// see if it compiles.
bool getLocalInterfaces(std::list<struct in_addr> &addrs)
bool getLocalInterfaces(struct in_addr &routeAddr, std::list<struct in_addr> &addrs)
{
// Get the best interface for transport to routeAddr
// This interface should be first in list!
DWORD bestInterface;
if (GetBestInterface((IPAddr) routeAddr.s_addr, &bestInterface) != NO_ERROR)
{
bestInterface = 0;
}
/* USE MIB IPADDR Interface */
PMIB_IPADDRTABLE iptable = NULL;
DWORD dwSize = 0;
if (GetIpAddrTable(iptable, &dwSize, 0) !=
ERROR_INSUFFICIENT_BUFFER)
if (GetIpAddrTable(iptable, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER)
{
pqioutput(PQL_ALERT, pqinetzone,
"Cannot Find Windoze Interfaces!");
pqioutput(PQL_ALERT, pqinetzone, "Cannot Find Windoze Interfaces!");
exit(0);
}
@ -348,15 +353,38 @@ bool getLocalInterfaces(std::list<struct in_addr> &addrs)
struct in_addr addr;
for(unsigned int i = 0; i < iptable -> dwNumEntries; i++)
for (unsigned int i = 0; i < iptable -> dwNumEntries; i++)
{
MIB_IPADDRROW &ipaddr = iptable->table[i];
std::string out;
addr.s_addr = iptable->table[i].dwAddr;
rs_sprintf(out, "Iface(%ld) => %s\n", iptable->table[i].dwIndex, rs_inet_ntoa(addr).c_str());
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
addr.s_addr = ipaddr.dwAddr;
rs_sprintf(out, "Iface(%ld) => %s\n", ipaddr.dwIndex, rs_inet_ntoa(addr).c_str());
addrs.push_back(addr);
unsigned short wType = ipaddr.unused2; // should be wType
if (wType & MIB_IPADDR_DISCONNECTED)
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface disconnected, " + out);
continue;
}
if (wType & MIB_IPADDR_DELETED)
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface deleted, " + out);
continue;
}
if (ipaddr.dwIndex == bestInterface)
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Best address, " + out);
addrs.push_front(addr);
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out);
addrs.push_back(addr);
}
}
free (iptable);
@ -529,7 +557,7 @@ int inaddr_cmp(struct sockaddr_in addr1, unsigned long addr2)
}
bool getPreferredInterface(struct in_addr &prefAddr) // returns best addr.
bool getPreferredInterface(in_addr &routeAddr, struct in_addr &prefAddr) // returns best addr.
{
std::list<struct in_addr> addrs;
std::list<struct in_addr>::iterator it;
@ -544,7 +572,7 @@ bool getPreferredInterface(struct in_addr &prefAddr) // returns best addr.
bool found_priv = false;
bool found_ext = false;
if (!getLocalInterfaces(addrs))
if (!getLocalInterfaces(routeAddr, addrs))
{
return false;
}

View File

@ -101,8 +101,8 @@ int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 );
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 );
int inaddr_cmp(struct sockaddr_in addr1, unsigned long);
bool getPreferredInterface(struct in_addr &prefAddr); // returns best addr.
bool getLocalInterfaces(std::list<struct in_addr> &addrs); // returns all possible addrs.
bool getPreferredInterface(struct in_addr &routeAddr, struct in_addr &prefAddr); // returns best addr.
bool getLocalInterfaces(in_addr &routeAddr, std::list<struct in_addr> &addrs); // returns all possible addrs.
// checks (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2);

View File

@ -45,6 +45,19 @@
// For win32 systems (tested on MingW+Ubuntu)
#define stat64 _stati64
// Should be in Iphlpapi.h, but mingw doesn't seem to have these
// Values copied directly from:
// http://msdn.microsoft.com/en-us/library/aa366845(v=vs.85).aspx
// (Title: MIB_IPADDRROW structure)
#ifndef MIB_IPADDR_DISCONNECTED
#define MIB_IPADDR_DISCONNECTED 0x0008 // Address is on disconnected interface
#endif
#ifndef MIB_IPADDR_DELETED
#define MIB_IPADDR_DELETED 0x0040 // Address is being deleted
#endif
#endif // WINDOWS_SYS
#endif // RSWIN_H_