Fetch server list from multiple masters to improve redundancy

This commit is contained in:
smallmodel 2025-04-27 00:07:41 +02:00
parent 007c680b45
commit 8aa1ebef5f
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
6 changed files with 180 additions and 71 deletions

View file

@ -25,12 +25,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_gamespy.h" #include "cl_gamespy.h"
#include "q_gamespy.h" #include "q_gamespy.h"
const char *ServerListGetHost() unsigned int ServerListGetNumMasters() {
{ return Com_GetNumMasterEntries();
return Com_GetMasterHost();
} }
int ServerListGetMsPort() const char *ServerListGetHost(int index)
{ {
return Com_GetMasterQueryPort(); return Com_GetMasterEntry(index)->host;
}
int ServerListGetMsPort(int index)
{
return Com_GetMasterEntry(index)->queryport;
} }

View file

@ -19,6 +19,23 @@ Fax(714)549-0757
for this SDK. It also has a change history for the SDK. for this SDK. It also has a change history for the SDK.
******/ ******/
/**
* The following modifications were made:
*
* 1) Non-blocking server list sockets. List requests are asynchronous and will not block the game. The only blocking request could be due to DNS resolution.
* 2) Parallel server list requests.
* 2.1) A pool of sockets is initially created
* 2.2) The server list, initially in the `sl_idle` state, will connect those sockets to available masters.
* 2.3) When at least one master replies, the server list transitions to sl_listxfer state.
* 2.4) The server list receives from multiple masters
* 2.5) When finished fetchign from 1 master, the server list transitions to sl_querying
* 2.6) At this point all received servers get queried. Masters that haven't finished sending the list are still being processed
* 2.7) When all received servers have been queried, the server list restarts from 2.4 with next masters to query
*
* NOTE: The idea here is mostly to ensure the redundancy of the server list between multiple masters
* even if the results are combined.
*/
#include "goaceng.h" #include "goaceng.h"
#include "gserver.h" #include "gserver.h"
#if defined(applec) || defined(THINK_C) || defined(__MWERKS__) && !defined(__KATANA__) #if defined(applec) || defined(THINK_C) || defined(__MWERKS__) && !defined(__KATANA__)
@ -53,11 +70,12 @@ Fax(714)549-0757
* *
* @return const char* The master host * @return const char* The master host
*/ */
extern const char *ServerListGetHost(); extern unsigned int ServerListGetNumMasters();
extern int ServerListGetMsPort(); extern const char *ServerListGetHost(int index);
extern int ServerListGetMsPort(int index);
#define MSHOST ServerListGetHost() //#define MSHOST ServerListGetHost(0)
#define MSPORT ServerListGetMsPort() //#define MSPORT ServerListGetMsPort(0)
#define SERVER_GROWBY 64 #define SERVER_GROWBY 64
#define LAN_SEARCH_TIME 3000 //3 sec #define LAN_SEARCH_TIME 3000 //3 sec
#define LIST_NUMKEYBUCKETS 500 #define LIST_NUMKEYBUCKETS 500
@ -80,6 +98,13 @@ typedef struct
typedef enum { pi_fieldcount, pi_fields, pi_servers } GParseInfoState; typedef enum { pi_fieldcount, pi_fields, pi_servers } GParseInfoState;
typedef enum { ls_connecting, ls_connected, ls_finished } GListSocketState; typedef enum { ls_connecting, ls_connected, ls_finished } GListSocketState;
typedef struct GServerListSocketImplementation
{
SOCKET s;
GListSocketState socketstate;
char data[2048];
} *GServerListSocket;
struct GServerListImplementation struct GServerListImplementation
{ {
GServerListState state; GServerListState state;
@ -96,9 +121,9 @@ struct GServerListImplementation
void *instance; void *instance;
char *sortkey; char *sortkey;
gbool sortascending; gbool sortascending;
GListSocketState socketstate; GServerListSocket slsockets;
SOCKET slsocket; int numslsockets;
//SOCKET slsockets; int startslindex;
unsigned long lanstarttime; unsigned long lanstarttime;
GQueryType querytype; GQueryType querytype;
HashTable keylist; HashTable keylist;
@ -154,6 +179,10 @@ GServerList ServerListNew(const char *gamename, const char *enginename, const ch
// Added in OPM // Added in OPM
list->encryptdata = 1; list->encryptdata = 1;
list->slsockets = (GServerListSocket)malloc(sizeof(struct GServerListSocketImplementation));
list->numslsockets = 1;
list->startslindex = 0;
SocketStartUp(); SocketStartUp();
return list; return list;
} }
@ -166,6 +195,7 @@ void ServerListFree(GServerList serverlist)
ArrayFree(serverlist->servers); ArrayFree(serverlist->servers);
TableFree(serverlist->keylist); TableFree(serverlist->keylist);
free(serverlist->updatelist); free(serverlist->updatelist);
free(serverlist->slsockets);
free(serverlist); free(serverlist);
SocketShutDown(); SocketShutDown();
@ -208,53 +238,79 @@ static GError FreeUpdateList(GServerList serverlist)
} }
//create and connect a server list socket //create and connect a server list socket
static GError CreateServerListSocket(GServerList serverlist, gbool async) static GError CreateServerListSocket(GServerList serverlist, GServerListSocket slsocket, gbool async)
{ {
struct sockaddr_in saddr; struct sockaddr_in saddr;
struct hostent *hent; struct hostent *hent;
int lasterr; int lasterr;
int i;
int port;
const char *host;
if (serverlist->startslindex >= ServerListGetNumMasters()) {
return GE_NODNS;
}
port = ServerListGetMsPort(serverlist->startslindex);
host = ServerListGetHost(serverlist->startslindex);
saddr.sin_family = AF_INET; saddr.sin_family = AF_INET;
saddr.sin_port = htons(MSPORT); saddr.sin_port = htons(port);
saddr.sin_addr.s_addr = inet_addr(MSHOST); saddr.sin_addr.s_addr = inet_addr(host);
if (saddr.sin_addr.s_addr == INADDR_NONE) if (saddr.sin_addr.s_addr == INADDR_NONE)
{ {
hent = gethostbyname(MSHOST); hent = gethostbyname(host);
if (!hent) if (!hent)
return GE_NODNS; return GE_NODNS;
saddr.sin_addr.s_addr = *(u_long *)hent->h_addr_list[0]; saddr.sin_addr.s_addr = *(u_long *)hent->h_addr_list[0];
} }
serverlist->slsocket = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); slsocket->s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (serverlist->slsocket == INVALID_SOCKET) if (slsocket->s == INVALID_SOCKET)
return GE_NOSOCKET; return GE_NOSOCKET;
if (async) { if (async) {
SetSockBlocking(serverlist->slsocket, 0); SetSockBlocking(slsocket->s, 0);
} }
if (connect ( serverlist->slsocket, (struct sockaddr *) &saddr, sizeof saddr ) != 0 if (connect ( slsocket->s, (struct sockaddr *) &saddr, sizeof saddr ) != 0
&& (lasterr = GOAGetLastError(serverlist->slsocket), lasterr != WSAEWOULDBLOCK && lasterr != WSAEINPROGRESS)) && (lasterr = GOAGetLastError(slsocket->slsocket), lasterr != WSAEWOULDBLOCK && lasterr != WSAEINPROGRESS))
{ {
closesocket(serverlist->slsocket); closesocket(slsocket->s);
return GE_NOCONNECT; return GE_NOCONNECT;
} }
slsocket->socketstate = ls_connecting;
serverlist->startslindex++;
//else we are connected //else we are connected
return 0; return 0;
} }
//create and connect a server list sockets
static GError CreateServerListSockets(GServerList serverlist, gbool async)
{
int i;
for(i = 0; i < serverlist->numslsockets; i++) {
CreateServerListSocket(serverlist, &serverlist->slsockets[i], async);
}
return 0;
}
//create and connect a server list socket //create and connect a server list socket
static GError CreateServerListLANSocket(GServerList serverlist) static GError CreateServerListLANSocket(GServerList serverlist)
{ {
int optval = 1; int optval = 1;
GServerListSocket slsocket = &serverlist->slsockets[0];
serverlist->slsocket = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); slsocket->s = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if (serverlist->slsocket == INVALID_SOCKET) if (slsocket->s == INVALID_SOCKET)
return GE_NOSOCKET; return GE_NOSOCKET;
if (setsockopt(serverlist->slsocket, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0) if (setsockopt(slsocket->s, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
return GE_NOSOCKET; return GE_NOSOCKET;
//else we are ready to broadcast //else we are ready to broadcast
@ -274,14 +330,14 @@ static void ServerListModeChange(GServerList serverlist, GServerListState newsta
// validate us to the master and send a list request // validate us to the master and send a list request
#define SECURE "\\secure\\" #define SECURE "\\secure\\"
static GError SendListRequest(GServerList serverlist, char *filter) static GError SendListRequest(GServerList serverlist, GServerListSocket slsocket, char *filter)
{ {
char data[256], *ptr, result[64]; char data[256], *ptr, result[64];
int len; int len;
int i; int i;
char *modifier; char *modifier;
len = recv(serverlist->slsocket, data, sizeof(data) - 1, 0); len = recv(slsocket->s, data, sizeof(data) - 1, 0);
if (gsiSocketIsError(len)) { if (gsiSocketIsError(len)) {
return GE_NOCONNECT; return GE_NOCONNECT;
} }
@ -312,7 +368,7 @@ static GError SendListRequest(GServerList serverlist, char *filter)
serverlist->enginename, ENGINE_VERSION, result); //validate us serverlist->enginename, ENGINE_VERSION, result); //validate us
} }
len = send ( serverlist->slsocket, data, strlen(data), 0 ); len = send ( slsocket->s, data, strlen(data), 0 );
if (gsiSocketIsError(len) || len == 0) if (gsiSocketIsError(len) || len == 0)
return GE_NOCONNECT; return GE_NOCONNECT;
@ -333,7 +389,7 @@ static GError SendListRequest(GServerList serverlist, char *filter)
sprintf(data, "\\list\\%s\\gamename\\%s\\where\\%s\\final\\", modifier, serverlist->gamename, filter); sprintf(data, "\\list\\%s\\gamename\\%s\\where\\%s\\final\\", modifier, serverlist->gamename, filter);
else else
sprintf(data, "\\list\\%s\\gamename\\%s\\final\\", modifier, serverlist->gamename); sprintf(data, "\\list\\%s\\gamename\\%s\\final\\", modifier, serverlist->gamename);
len = send ( serverlist->slsocket, data, strlen(data), 0 ); len = send ( slsocket->s, data, strlen(data), 0 );
if (gsiSocketIsError(len) || len == 0) if (gsiSocketIsError(len) || len == 0)
return GE_NOCONNECT; return GE_NOCONNECT;
@ -352,7 +408,7 @@ static GError SendBroadcastRequest(GServerList serverlist, int startport, int en
for (i = startport ; i <= endport ; i += delta) for (i = startport ; i <= endport ; i += delta)
{ {
saddr.sin_port = htons(i); saddr.sin_port = htons(i);
sendto(serverlist->slsocket, "\\status\\",8,0,(struct sockaddr *)&saddr,sizeof(saddr)); sendto(serverlist->slsockets[0].s, "\\status\\",8,0,(struct sockaddr *)&saddr,sizeof(saddr));
} }
ServerListModeChange(serverlist, sl_lanlist); ServerListModeChange(serverlist, sl_lanlist);
serverlist->lanstarttime = current_time(); serverlist->lanstarttime = current_time();
@ -385,17 +441,17 @@ GError ServerListUpdate(GServerList serverlist, gbool async)
/* ServerListStartQuery /* ServerListStartQuery
------------------------- -------------------------
Start querying a GServerList. */ Start querying a GServerList. */
GError ServerListStartQuery(GServerList serverlist, gbool async) GError ServerListStartQuery(GServerList serverlist, GServerListSocket slsocket, gbool async)
{ {
GError error; GError error;
if (serverlist->socketstate != ls_connecting) { if (slsocket->socketstate != ls_connecting) {
return GE_BUSY; return GE_BUSY;
} }
if (serverlist->abortupdate) { if (serverlist->abortupdate) {
closesocket(serverlist->slsocket); closesocket(slsocket->s);
serverlist->slsocket = INVALID_SOCKET; slsocket->s = INVALID_SOCKET;
ServerListModeChange(serverlist, sl_idle); ServerListModeChange(serverlist, sl_idle);
return GE_NOCONNECT; return GE_NOCONNECT;
} }
@ -404,23 +460,23 @@ GError ServerListStartQuery(GServerList serverlist, gbool async)
// Abort if the socket is in error // Abort if the socket is in error
int so_error; int so_error;
int len = sizeof(so_error); int len = sizeof(so_error);
getsockopt(serverlist->slsocket, SOL_SOCKET, SO_ERROR, &so_error, &len); getsockopt(slsocket->s, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error) { if (so_error) {
serverlist->socketstate = ls_connected; slsocket->socketstate = ls_finished;
return GE_NOCONNECT; return GE_NOCONNECT;
} }
// Check for pending data // Check for pending data
char buf; char buf;
if (recv(serverlist->slsocket, &buf, 1, MSG_PEEK) == -1) { if (recv(slsocket->s, &buf, 1, MSG_PEEK) == -1) {
return GE_BUSY; return GE_BUSY;
} }
} }
serverlist->socketstate = ls_connected; slsocket->socketstate = ls_connected;
error = SendListRequest(serverlist, serverlist->filter); error = SendListRequest(serverlist, slsocket, serverlist->filter);
if (error) return error; if (error) return error;
if (serverlist->querytype != qt_grouprooms && serverlist->querytype != qt_masterinfo) { if (serverlist->querytype != qt_grouprooms && serverlist->querytype != qt_masterinfo) {
error = InitUpdateList(serverlist); error = InitUpdateList(serverlist);
@ -439,13 +495,14 @@ Start updating a GServerList. */
GError ServerListUpdate2(GServerList serverlist, gbool async, char *filter, GQueryType querytype) GError ServerListUpdate2(GServerList serverlist, gbool async, char *filter, GQueryType querytype)
{ {
GError error; GError error;
int i;
if (serverlist->state != sl_idle) if (serverlist->state != sl_idle)
return GE_BUSY; return GE_BUSY;
serverlist->querytype = querytype; serverlist->querytype = querytype;
error = CreateServerListSocket(serverlist, async); error = CreateServerListSockets(serverlist, async);
if (error) return error; //if (error) return error;
serverlist->nextupdate = 0; serverlist->nextupdate = 0;
serverlist->abortupdate = 0; serverlist->abortupdate = 0;
@ -455,13 +512,13 @@ GError ServerListUpdate2(GServerList serverlist, gbool async, char *filter, GQue
serverlist->cryptinfo.offset = -1; serverlist->cryptinfo.offset = -1;
strncpy(serverlist->filter, filter, sizeof(serverlist->filter)); strncpy(serverlist->filter, filter, sizeof(serverlist->filter));
serverlist->socketstate = ls_connecting;
if (async) { if (async) {
return 0; return 0;
} }
ServerListStartQuery(serverlist, async); for(i = 0; i < serverlist->numslsockets; i++) {
ServerListStartQuery(serverlist, &serverlist->slsockets[i], async);
}
return 0; return 0;
} }
@ -650,7 +707,7 @@ GError ServerListAuxUpdate(GServerList serverlist, const char *ip, int port, gbo
return 0; return 0;
} }
static GError ServerListLANList(GServerList serverlist) static GError ServerListLANList(GServerList serverlist, GServerListSocket slsocket)
{ {
struct timeval timeout = {0,0}; struct timeval timeout = {0,0};
fd_set set; fd_set set;
@ -662,11 +719,11 @@ static GError ServerListLANList(GServerList serverlist)
while (1) //we break if the select fails while (1) //we break if the select fails
{ {
FD_ZERO(&set); FD_ZERO(&set);
FD_SET( serverlist->slsocket, &set); FD_SET( slsocket->s, &set);
error = select(FD_SETSIZE, &set, NULL, NULL, &timeout); error = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
if (gsiSocketIsError(error) || 0 == error) //no data if (gsiSocketIsError(error) || 0 == error) //no data
break; break;
error = recvfrom(serverlist->slsocket, indata, sizeof(indata) - 1, 0, (struct sockaddr *)&saddr, &saddrlen ); error = recvfrom(slsocket->s, indata, sizeof(indata) - 1, 0, (struct sockaddr *)&saddr, &saddrlen );
if (gsiSocketIsError(error)) if (gsiSocketIsError(error))
continue; continue;
//we got data, add the server to the list to update //we got data, add the server to the list to update
@ -675,8 +732,8 @@ static GError ServerListLANList(GServerList serverlist)
} }
if (current_time() - serverlist->lanstarttime > LAN_SEARCH_TIME) //done waiting for replies if (current_time() - serverlist->lanstarttime > LAN_SEARCH_TIME) //done waiting for replies
{ {
closesocket(serverlist->slsocket); closesocket(slsocket->s);
serverlist->slsocket = INVALID_SOCKET; slsocket->s = INVALID_SOCKET;
ServerListModeChange(serverlist, sl_querying); ServerListModeChange(serverlist, sl_querying);
} }
return 0; return 0;
@ -772,7 +829,7 @@ static int ServerListParseInfoList(GServerList serverlist, char *data, int len)
} }
//reads the server list from the socket and parses it //reads the server list from the socket and parses it
static GError ServerListReadList(GServerList serverlist) static GError ServerListReadList(GServerList serverlist, GServerListSocket slsocket)
{ {
static char data[2048]; //static input buffer static char data[2048]; //static input buffer
static int oldlen = 0; static int oldlen = 0;
@ -784,7 +841,7 @@ static GError ServerListReadList(GServerList serverlist)
unsigned short port; unsigned short port;
FD_ZERO(&set); FD_ZERO(&set);
FD_SET(serverlist->slsocket, &set); FD_SET(slsocket->s, &set);
#ifndef KGTRN_ACCESS #ifndef KGTRN_ACCESS
i = select( FD_SETSIZE, &set, NULL, NULL, &timeout ); i = select( FD_SETSIZE, &set, NULL, NULL, &timeout );
if (i <= 0) if (i <= 0)
@ -792,11 +849,11 @@ static GError ServerListReadList(GServerList serverlist)
#endif #endif
//append to data //append to data
len = recv(serverlist->slsocket, data + oldlen, sizeof(data) - oldlen - 1, 0); len = recv(slsocket->s, data + oldlen, sizeof(data) - oldlen - 1, 0);
if (gsiSocketIsError(len) || len == 0) if (gsiSocketIsError(len) || len == 0)
{ {
closesocket(serverlist->slsocket); closesocket(slsocket->s);
serverlist->slsocket = INVALID_SOCKET; slsocket->s = INVALID_SOCKET;
oldlen = 0; //clear data so it can be used again oldlen = 0; //clear data so it can be used again
ServerListHalt(serverlist); ServerListHalt(serverlist);
ServerListModeChange(serverlist, sl_querying); ServerListModeChange(serverlist, sl_querying);
@ -835,8 +892,8 @@ static GError ServerListReadList(GServerList serverlist)
{ {
if (strncmp(p,"\\final\\",7) == 0 || serverlist->abortupdate) if (strncmp(p,"\\final\\",7) == 0 || serverlist->abortupdate)
{ {
closesocket(serverlist->slsocket); closesocket(slsocket->s);
serverlist->slsocket = INVALID_SOCKET; slsocket->s = INVALID_SOCKET;
oldlen = 0; //clear data so it can be used again oldlen = 0; //clear data so it can be used again
if (serverlist->querytype == qt_grouprooms || serverlist->querytype == qt_masterinfo) { if (serverlist->querytype == qt_grouprooms || serverlist->querytype == qt_masterinfo) {
ServerListModeChange(serverlist, sl_idle); ServerListModeChange(serverlist, sl_idle);
@ -971,16 +1028,16 @@ static GError ServerListQueryLoop(GServerList serverlist)
return 0; return 0;
} }
/* ServerListThink /* ServerListThinkSocket
------------------ ------------------
For use with Async Updates. This needs to be called every ~10ms for list processing and For use with Async Updates. This needs to be called every ~10ms for list processing and
updating to occur during async server list updates */ updating to occur during async server list updates */
GError ServerListThink(GServerList serverlist) GError ServerListThinkSocket(GServerList serverlist, GServerListSocket slsocket)
{ {
switch(serverlist->socketstate) switch(slsocket->socketstate)
{ {
case ls_connecting: case ls_connecting:
ServerListStartQuery(serverlist, 1); ServerListStartQuery(serverlist, slsocket, 1);
break; break;
default: default:
break; break;
@ -991,16 +1048,30 @@ GError ServerListThink(GServerList serverlist)
case sl_idle: return 0; case sl_idle: return 0;
case sl_listxfer: case sl_listxfer:
//read the data //read the data
return ServerListReadList(serverlist); return ServerListReadList(serverlist, slsocket);
break; break;
case sl_lanlist: case sl_lanlist:
return ServerListLANList(serverlist); return ServerListLANList(serverlist, slsocket);
case sl_querying: case sl_querying:
//do some queries //do some queries
return ServerListQueryLoop(serverlist); return ServerListQueryLoop(serverlist);
break; break;
} }
return 0;
}
/* ServerListThink
------------------
For use with Async Updates. This needs to be called every ~10ms for list processing and
updating to occur during async server list updates */
GError ServerListThink(GServerList serverlist)
{
int i;
for(i = 0; i < serverlist->numslsockets; i++) {
ServerListThinkSocket(serverlist, &serverlist->slsockets[i]);
}
return 0; return 0;
} }

View file

@ -23,22 +23,43 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#pragma once #pragma once
#include "q_gamespy.h" #include "q_gamespy.h"
#include "q_shared.h"
master_entry_t entries[16] =
{
{ "master.333networks.com", 28900, 27900 },
{ "master.errorist.eu", 28900, 27900 }
};
int num_entries = 1;
void Com_InitGameSpy() void Com_InitGameSpy()
{ {
} }
unsigned int Com_GetNumMasterEntries() {
return num_entries;
}
const master_entry_t *Com_GetMasterEntry(int index) {
if (index >= num_entries) {
return NULL;
}
return &entries[index];
}
const char *Com_GetMasterHost() const char *Com_GetMasterHost()
{ {
return "master.333networks.com"; return entries[0].host;
} }
int Com_GetMasterQueryPort() int Com_GetMasterQueryPort()
{ {
return 28900; return entries[0].queryport;
} }
int Com_GetMasterHeartbeatPort() int Com_GetMasterHeartbeatPort()
{ {
return 27900; return entries[0].hbport;
} }

View file

@ -24,8 +24,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#pragma once #pragma once
typedef struct {
char host[128];
int queryport;
int hbport;
} master_entry_t;
void Com_InitGameSpy(); void Com_InitGameSpy();
unsigned int Com_GetNumMasterEntries();
const master_entry_t *Com_GetMasterEntry(int index);
const char *Com_GetMasterHost(); const char *Com_GetMasterHost();
int Com_GetMasterQueryPort(); int Com_GetMasterQueryPort();
int Com_GetMasterHeartbeatPort(); int Com_GetMasterHeartbeatPort();

View file

@ -503,12 +503,17 @@ void SV_GamespyAuthorize(netadr_t from, const char *response)
} }
} }
const char *qr_get_master_host() unsigned int qr_get_num_masters()
{ {
return Com_GetMasterHost(); return Com_GetNumMasterEntries();
} }
int qr_get_master_port() const char *qr_get_master_host(int index)
{ {
return Com_GetMasterHeartbeatPort(); return Com_GetMasterEntry(index)->host;
}
int qr_get_master_port(int index)
{
return Com_GetMasterEntry(index)->hbport;
} }

View file

@ -65,9 +65,9 @@ as the base port. Generally there is no reason to modify this value.
/******** /********
DEFINES DEFINES
********/ ********/
#define MASTER_PORT qr_get_master_port() #define MASTER_PORT qr_get_master_port(0)
//#define MASTER_ADDR "master." GSI_DOMAIN_NAME //#define MASTER_ADDR "master." GSI_DOMAIN_NAME
#define MASTER_ADDR qr_get_master_host() #define MASTER_ADDR qr_get_master_host(0)
#define FIRST_HB_TIME 30000 /* 30 sec */ #define FIRST_HB_TIME 30000 /* 30 sec */
#define HB_TIME 300000 /* 5 minutes */ #define HB_TIME 300000 /* 5 minutes */
#define MAX_FIRST_COUNT 10 /* 10 tries = 5 minutes */ #define MAX_FIRST_COUNT 10 /* 10 tries = 5 minutes */