mirror of
https://github.com/glest/glest-source.git
synced 2025-08-17 21:51:17 +02:00
Bugfix for LAN autofind servers. Needed to change the way we broadcast UDP so that we do it individually for each NIC's broadcast address. (see: http://stackoverflow.com/questions/683624/udp-broadcast-on-all-interfaces)
This commit is contained in:
@@ -28,6 +28,23 @@
|
|||||||
#include "platform_util.h"
|
#include "platform_util.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
# include <winsock.h>
|
||||||
|
# include <iphlpapi.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <sys/socket.h>
|
||||||
|
# include <netdb.h>
|
||||||
|
# include <netinet/in.h>
|
||||||
|
# include <net/if.h>
|
||||||
|
# include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Shared::Util;
|
using namespace Shared::Util;
|
||||||
|
|
||||||
@@ -75,6 +92,316 @@ string Ip::getString() const{
|
|||||||
// class Socket
|
// class Socket
|
||||||
// ===============================================
|
// ===============================================
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__)
|
||||||
|
# define USE_GETIFADDRS 1
|
||||||
|
# include <ifaddrs.h>
|
||||||
|
static uint32 SockAddrToUint32(struct sockaddr * a)
|
||||||
|
{
|
||||||
|
return ((a)&&(a->sa_family == AF_INET)) ? ntohl(((struct sockaddr_in *)a)->sin_addr.s_addr) : 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// convert a numeric IP address into its string representation
|
||||||
|
static void Inet_NtoA(uint32 addr, char * ipbuf)
|
||||||
|
{
|
||||||
|
sprintf(ipbuf, "%d.%d.%d.%d", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert a string represenation of an IP address into its numeric equivalent
|
||||||
|
static uint32 Inet_AtoN(const char * buf)
|
||||||
|
{
|
||||||
|
// net_server inexplicably doesn't have this function; so I'll just fake it
|
||||||
|
uint32 ret = 0;
|
||||||
|
int shift = 24; // fill out the MSB first
|
||||||
|
bool startQuad = true;
|
||||||
|
while((shift >= 0)&&(*buf))
|
||||||
|
{
|
||||||
|
if (startQuad)
|
||||||
|
{
|
||||||
|
unsigned char quad = (unsigned char) atoi(buf);
|
||||||
|
ret |= (((uint32)quad) << shift);
|
||||||
|
shift -= 8;
|
||||||
|
}
|
||||||
|
startQuad = (*buf == '.');
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static void PrintNetworkInterfaceInfos()
|
||||||
|
{
|
||||||
|
#if defined(USE_GETIFADDRS)
|
||||||
|
// BSD-style implementation
|
||||||
|
struct ifaddrs * ifap;
|
||||||
|
if (getifaddrs(&ifap) == 0)
|
||||||
|
{
|
||||||
|
struct ifaddrs * p = ifap;
|
||||||
|
while(p)
|
||||||
|
{
|
||||||
|
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
|
||||||
|
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
|
||||||
|
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
|
||||||
|
if (ifaAddr > 0)
|
||||||
|
{
|
||||||
|
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
|
||||||
|
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
|
||||||
|
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
|
||||||
|
printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
|
||||||
|
}
|
||||||
|
p = p->ifa_next;
|
||||||
|
}
|
||||||
|
freeifaddrs(ifap);
|
||||||
|
}
|
||||||
|
#elif defined(WIN32)
|
||||||
|
// Windows XP style implementation
|
||||||
|
|
||||||
|
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
|
||||||
|
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
|
||||||
|
// multiple times in order to deal with potential race conditions properly.
|
||||||
|
MIB_IPADDRTABLE * ipTable = NULL;
|
||||||
|
{
|
||||||
|
ULONG bufLen = 0;
|
||||||
|
for (int i=0; i<5; i++)
|
||||||
|
{
|
||||||
|
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
|
||||||
|
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
free(ipTable); // in case we had previously allocated it
|
||||||
|
ipTable = (MIB_IPADDRTABLE *) malloc(bufLen);
|
||||||
|
}
|
||||||
|
else if (ipRet == NO_ERROR) break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(ipTable);
|
||||||
|
ipTable = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipTable)
|
||||||
|
{
|
||||||
|
// Try to get the Adapters-info table, so we can given useful names to the IP
|
||||||
|
// addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle
|
||||||
|
// the potential race condition between the size-query call and the get-data call.
|
||||||
|
// I love a well-designed API :^P
|
||||||
|
IP_ADAPTER_INFO * pAdapterInfo = NULL;
|
||||||
|
{
|
||||||
|
ULONG bufLen = 0;
|
||||||
|
for (int i=0; i<5; i++)
|
||||||
|
{
|
||||||
|
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
|
||||||
|
if (apRet == ERROR_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
free(pAdapterInfo); // in case we had previously allocated it
|
||||||
|
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen);
|
||||||
|
}
|
||||||
|
else if (apRet == ERROR_SUCCESS) break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(pAdapterInfo);
|
||||||
|
pAdapterInfo = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD i=0; i<ipTable->dwNumEntries; i++)
|
||||||
|
{
|
||||||
|
const MIB_IPADDRROW & row = ipTable->table[i];
|
||||||
|
|
||||||
|
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
|
||||||
|
const char * name = NULL;
|
||||||
|
const char * desc = NULL;
|
||||||
|
if (pAdapterInfo)
|
||||||
|
{
|
||||||
|
IP_ADAPTER_INFO * next = pAdapterInfo;
|
||||||
|
while((next)&&(name==NULL))
|
||||||
|
{
|
||||||
|
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
|
||||||
|
while(ipAddr)
|
||||||
|
{
|
||||||
|
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
|
||||||
|
{
|
||||||
|
name = next->AdapterName;
|
||||||
|
desc = next->Description;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ipAddr = ipAddr->Next;
|
||||||
|
}
|
||||||
|
next = next->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char buf[128];
|
||||||
|
if (name == NULL)
|
||||||
|
{
|
||||||
|
sprintf(buf, "unnamed-%i", i);
|
||||||
|
name = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 ipAddr = ntohl(row.dwAddr);
|
||||||
|
uint32 netmask = ntohl(row.dwMask);
|
||||||
|
uint32 baddr = ipAddr & netmask;
|
||||||
|
if (row.dwBCastAddr) baddr |= ~netmask;
|
||||||
|
|
||||||
|
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
|
||||||
|
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
|
||||||
|
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
|
||||||
|
printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pAdapterInfo);
|
||||||
|
free(ipTable);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Dunno what we're running on here!
|
||||||
|
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
string getNetworkInterfaceBroadcastAddress(string ipAddress)
|
||||||
|
{
|
||||||
|
string broadCastAddress = "";
|
||||||
|
|
||||||
|
#if defined(USE_GETIFADDRS)
|
||||||
|
// BSD-style implementation
|
||||||
|
struct ifaddrs * ifap;
|
||||||
|
if (getifaddrs(&ifap) == 0)
|
||||||
|
{
|
||||||
|
struct ifaddrs * p = ifap;
|
||||||
|
while(p)
|
||||||
|
{
|
||||||
|
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
|
||||||
|
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
|
||||||
|
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
|
||||||
|
if (ifaAddr > 0)
|
||||||
|
{
|
||||||
|
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
|
||||||
|
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
|
||||||
|
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
|
||||||
|
//printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
|
||||||
|
if(strcmp(ifaAddrStr,ipAddress.c_str()) == 0) {
|
||||||
|
broadCastAddress = dstAddrStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = p->ifa_next;
|
||||||
|
}
|
||||||
|
freeifaddrs(ifap);
|
||||||
|
}
|
||||||
|
#elif defined(WIN32)
|
||||||
|
// Windows XP style implementation
|
||||||
|
|
||||||
|
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
|
||||||
|
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
|
||||||
|
// multiple times in order to deal with potential race conditions properly.
|
||||||
|
MIB_IPADDRTABLE * ipTable = NULL;
|
||||||
|
{
|
||||||
|
ULONG bufLen = 0;
|
||||||
|
for (int i=0; i<5; i++)
|
||||||
|
{
|
||||||
|
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
|
||||||
|
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
|
free(ipTable); // in case we had previously allocated it
|
||||||
|
ipTable = (MIB_IPADDRTABLE *) malloc(bufLen);
|
||||||
|
}
|
||||||
|
else if (ipRet == NO_ERROR) break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(ipTable);
|
||||||
|
ipTable = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipTable)
|
||||||
|
{
|
||||||
|
// Try to get the Adapters-info table, so we can given useful names to the IP
|
||||||
|
// addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle
|
||||||
|
// the potential race condition between the size-query call and the get-data call.
|
||||||
|
// I love a well-designed API :^P
|
||||||
|
IP_ADAPTER_INFO * pAdapterInfo = NULL;
|
||||||
|
{
|
||||||
|
ULONG bufLen = 0;
|
||||||
|
for (int i=0; i<5; i++)
|
||||||
|
{
|
||||||
|
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
|
||||||
|
if (apRet == ERROR_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
free(pAdapterInfo); // in case we had previously allocated it
|
||||||
|
pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen);
|
||||||
|
}
|
||||||
|
else if (apRet == ERROR_SUCCESS) break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(pAdapterInfo);
|
||||||
|
pAdapterInfo = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD i=0; i<ipTable->dwNumEntries; i++)
|
||||||
|
{
|
||||||
|
const MIB_IPADDRROW & row = ipTable->table[i];
|
||||||
|
|
||||||
|
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
|
||||||
|
const char * name = NULL;
|
||||||
|
const char * desc = NULL;
|
||||||
|
if (pAdapterInfo)
|
||||||
|
{
|
||||||
|
IP_ADAPTER_INFO * next = pAdapterInfo;
|
||||||
|
while((next)&&(name==NULL))
|
||||||
|
{
|
||||||
|
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
|
||||||
|
while(ipAddr)
|
||||||
|
{
|
||||||
|
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
|
||||||
|
{
|
||||||
|
name = next->AdapterName;
|
||||||
|
desc = next->Description;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ipAddr = ipAddr->Next;
|
||||||
|
}
|
||||||
|
next = next->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char buf[128];
|
||||||
|
if (name == NULL)
|
||||||
|
{
|
||||||
|
//sprintf(buf, "unnamed-%i", i);
|
||||||
|
name = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 ipAddr = ntohl(row.dwAddr);
|
||||||
|
uint32 netmask = ntohl(row.dwMask);
|
||||||
|
uint32 baddr = ipAddr & netmask;
|
||||||
|
if (row.dwBCastAddr) baddr |= ~netmask;
|
||||||
|
|
||||||
|
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
|
||||||
|
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
|
||||||
|
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
|
||||||
|
//printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
|
||||||
|
if(strcmp(ifaAddrStr,ipAddress.c_str()) == 0) {
|
||||||
|
broadCastAddress = dstAddrStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pAdapterInfo);
|
||||||
|
free(ipTable);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Dunno what we're running on here!
|
||||||
|
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return broadCastAddress;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> Socket::getLocalIPAddressList() {
|
std::vector<std::string> Socket::getLocalIPAddressList() {
|
||||||
std::vector<std::string> ipList;
|
std::vector<std::string> ipList;
|
||||||
|
|
||||||
@@ -1073,16 +1400,18 @@ void BroadCastSocketThread::execute() {
|
|||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
unsigned int tbcaddr; // The broadcast address.
|
const int MAX_NIC_COUNT = 10;
|
||||||
|
//unsigned int tbcaddr; // The broadcast address.
|
||||||
short port; // The port for the broadcast.
|
short port; // The port for the broadcast.
|
||||||
struct sockaddr_in bcLocal; // local socket address for the broadcast.
|
struct sockaddr_in bcLocal[MAX_NIC_COUNT]; // local socket address for the broadcast.
|
||||||
struct sockaddr_in bcaddr; // The broadcast address for the receiver.
|
//struct sockaddr_in bcaddr; // The broadcast address for the receiver.
|
||||||
int bcfd; // The socket used for the broadcast.
|
int bcfd[MAX_NIC_COUNT]; // The socket used for the broadcast.
|
||||||
bool one = true; // Parameter for "setscokopt".
|
bool one = true; // Parameter for "setscokopt".
|
||||||
int pn; // The number of the packet broadcasted.
|
int pn; // The number of the packet broadcasted.
|
||||||
char buff[1024]; // Buffers the data to be broadcasted.
|
char buff[1024]; // Buffers the data to be broadcasted.
|
||||||
char myhostname[100]; // hostname of local machine
|
char myhostname[100]; // hostname of local machine
|
||||||
struct in_addr myaddr; // My host address in net format
|
char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to
|
||||||
|
//struct in_addr myaddr; // My host address in net format
|
||||||
struct hostent* myhostent;
|
struct hostent* myhostent;
|
||||||
char * ptr; // some transient vars
|
char * ptr; // some transient vars
|
||||||
int len,i;
|
int len,i;
|
||||||
@@ -1091,87 +1420,102 @@ void BroadCastSocketThread::execute() {
|
|||||||
gethostname(myhostname,100);
|
gethostname(myhostname,100);
|
||||||
myhostent = gethostbyname(myhostname);
|
myhostent = gethostbyname(myhostname);
|
||||||
|
|
||||||
// get only the first host IP address
|
// get all host IP addresses
|
||||||
std::vector<std::string> ipList = Socket::getLocalIPAddressList();
|
std::vector<std::string> ipList = Socket::getLocalIPAddressList();
|
||||||
|
|
||||||
|
for(unsigned int idx = 0; idx < ipList.size() && idx < MAX_NIC_COUNT; idx++) {
|
||||||
|
string broadCastAddress = getNetworkInterfaceBroadcastAddress(ipList[idx]);
|
||||||
|
strcpy(subnetmask[idx], broadCastAddress.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
port = htons( Socket::getBroadCastPort() );
|
port = htons( Socket::getBroadCastPort() );
|
||||||
|
|
||||||
// Create the broadcast socket
|
for(unsigned int idx = 0; idx < ipList.size() && idx < MAX_NIC_COUNT; idx++) {
|
||||||
memset( &bcLocal, 0, sizeof( struct sockaddr_in));
|
// Create the broadcast socket
|
||||||
bcLocal.sin_family = AF_INET;
|
memset( &bcLocal[idx], 0, sizeof( struct sockaddr_in));
|
||||||
bcLocal.sin_addr.s_addr = htonl( INADDR_BROADCAST );
|
bcLocal[idx].sin_family = AF_INET;
|
||||||
bcLocal.sin_port = port; // We are letting the OS fill in the port number for the local machine.
|
bcLocal[idx].sin_addr.s_addr = inet_addr(subnetmask[idx]); //htonl( INADDR_BROADCAST );
|
||||||
bcfd = socket( AF_INET, SOCK_DGRAM, 0 );
|
bcLocal[idx].sin_port = port; // We are letting the OS fill in the port number for the local machine.
|
||||||
|
bcfd[idx] = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
|
if( bcfd[idx] <= 0 ) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket [%s]: %d\n", subnetmask[idx], errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
// Mark the socket for broadcast.
|
||||||
|
else if( setsockopt( bcfd[idx], SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast [%s]: %d\n", subnetmask[idx], errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
// If there is an error, report it and terminate.
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] setting up broadcast on address [%s]\n",__FILE__,__FUNCTION__,__LINE__,subnetmask[idx]);
|
||||||
if( bcfd <= 0 ) {
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket.: %d\n", errno);
|
|
||||||
//exit(-1);
|
|
||||||
}
|
}
|
||||||
// Mark the socket for broadcast.
|
|
||||||
else if( setsockopt( bcfd, SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) {
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast.: %d\n", errno);
|
|
||||||
//exit(-1);
|
|
||||||
}
|
|
||||||
// Bind the address to the broadcast socket.
|
|
||||||
else {
|
|
||||||
|
|
||||||
// Record the broadcast address of the receiver.
|
setRunningStatus(true);
|
||||||
bcaddr.sin_family = AF_INET;
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");
|
||||||
bcaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);//tbcaddr;
|
|
||||||
bcaddr.sin_port = port;
|
|
||||||
|
|
||||||
setRunningStatus(true);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Server thread is running\n");
|
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
time_t elapsed = 0;
|
||||||
|
for( pn = 1; ; pn++ )
|
||||||
try {
|
{
|
||||||
// Send this machine's host name and address in hostname:n.n.n.n format
|
for(unsigned int idx = 0; idx < ipList.size() && idx < MAX_NIC_COUNT; idx++) {
|
||||||
sprintf(buff,"%s",myhostname);
|
if( bcfd[idx] > 0 ) {
|
||||||
for(int idx = 0; idx < ipList.size(); idx++) {
|
try {
|
||||||
sprintf(buff,"%s:%s",buff,ipList[idx].c_str());
|
// Send this machine's host name and address in hostname:n.n.n.n format
|
||||||
}
|
sprintf(buff,"%s",myhostname);
|
||||||
|
for(unsigned int idx1 = 0; idx1 < ipList.size(); idx1++) {
|
||||||
time_t elapsed = 0;
|
sprintf(buff,"%s:%s",buff,ipList[idx1].c_str());
|
||||||
for( pn = 1; ; pn++ )
|
|
||||||
{
|
|
||||||
if(difftime(time(NULL),elapsed) >= 1) {
|
|
||||||
elapsed = time(NULL);
|
|
||||||
// Broadcast the packet to the subnet
|
|
||||||
if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %d\n", errno);
|
|
||||||
//exit(-1);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting to [%s] the message: [%s]\n",subnetmask,buff);
|
if(difftime(time(NULL),elapsed) >= 1) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff);
|
elapsed = time(NULL);
|
||||||
|
// Broadcast the packet to the subnet
|
||||||
|
//if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
||||||
|
if( sendto( bcfd[idx], buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcLocal[idx], sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
||||||
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %d\n", errno);
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting to [%s] the message: [%s]\n",subnetmask,buff);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(getQuitStatus() == true) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep( 100 ); // send out broadcast every 1 seconds
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
if(getQuitStatus() == true) {
|
catch(const exception &ex) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
break;
|
setRunningStatus(false);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
setRunningStatus(false);
|
||||||
}
|
}
|
||||||
sleep( 100 ); // send out broadcast every 1 seconds
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(getQuitStatus() == true) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(getQuitStatus() == true) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
catch(const exception &ex) {
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
|
||||||
setRunningStatus(false);
|
|
||||||
}
|
|
||||||
catch(...) {
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
|
|
||||||
setRunningStatus(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
setRunningStatus(false);
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is exiting\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setRunningStatus(false);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is exiting\n");
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user