106
107
int bindresvport(int sd, struct sockaddr_in *sin);
111
* Returns the max number of possible file descriptors (as
112
* per the OS limits).
116
int get_max_num_descriptors(void)
118
static int max_num_descriptors = 0;
120
if (max_num_descriptors <= 0)
121
max_num_descriptors = getdtablesize();
123
return(max_num_descriptors);
124
} /* END get_num_max_descriptors() */
127
* Returns the number of bytes needed to allocate
128
* a fd_set array that can hold all of the possible
129
* socket descriptors.
132
int get_fdset_size(void)
134
unsigned int MaxNumDescriptors = 0;
135
int NumFDSetsNeeded = 0;
136
int NumBytesInFDSet = 0;
139
MaxNumDescriptors = get_max_num_descriptors();
141
NumBytesInFDSet = sizeof(fd_set);
142
NumFDSetsNeeded = MaxNumDescriptors / FD_SETSIZE;
144
if (MaxNumDescriptors < FD_SETSIZE)
146
/* the default size already provides sufficient space */
148
Result = NumBytesInFDSet;
150
else if ((MaxNumDescriptors % FD_SETSIZE) > 0)
152
/* we need to allocate more memory to cover extra
153
* bits--add an extra FDSet worth of memory to the size */
155
Result = (NumFDSetsNeeded + 1) * NumBytesInFDSet;
159
/* division was exact--we know exactly how many bytes we need */
161
Result = NumFDSetsNeeded * NumBytesInFDSet;
165
} /* END get_fdset_size() */
110
169
** wait for connect to complete. We use non-blocking sockets,
111
170
** so have to wait for completion this way.
114
173
static int await_connect(
175
long timeout, /* I */
117
176
int sockd) /* I */
181
int MaxNumDescriptors = 0;
183
fd_set *BigFDSet = NULL;
123
185
struct timeval tv;
125
187
torque_socklen_t len;
133
if ((n = select(sockd + 1, 0, &fs, 0, &tv)) != 1)
190
* some operating systems (like FreeBSD) cannot have a value for tv.tv_usec
191
* larger than 1,000,000 so we need to split up the timeout duration between
192
* seconds and microseconds
195
tv.tv_sec = timeout / 1000000;
196
tv.tv_usec = timeout % 1000000;
198
/* calculate needed size for fd_set in select() */
200
MaxNumDescriptors = get_max_num_descriptors();
202
BigFDSet = (fd_set *)calloc(1,sizeof(char) * get_fdset_size());
204
FD_SET(sockd, BigFDSet);
206
if ((n = select(sockd+1,0,BigFDSet,0,&tv)) != 1)
135
208
/* FAILURE: socket not ready for write */
153
228
/* FAILURE: socket error detected */
156
232
} /* END await_connect() */
161
#define TORQUE_MAXCONNECTTIMEOUT 5
238
long MaxConnectTimeout = 5000000; /* in microseconds */
164
241
* client_to_svr - connect to a server
175
252
* hosts with the same port. Let the caller keep the addresses around
176
253
* rather than look it up each time.
178
* NOTE: will wait up to TORQUE_MAXCONNECTTIMEOUT seconds for transient network failures
255
* NOTE: will wait up to MaxConnectTimeout microseconds for transient network failures
181
258
/* NOTE: create new connection on reserved port to validate root/trusted authority */
183
260
int client_to_svr(
185
pbs_net_t hostaddr, /* I - internet addr of host */
186
unsigned int port, /* I - port to which to connect */
187
int local_port, /* I - BOOLEAN: not 0 to use local reserved port */
188
char *EMsg) /* O (optional,minsize=1024) */
262
pbs_net_t hostaddr, /* I - internet addr of host */
263
unsigned int port, /* I - port to which to connect */
264
int local_port, /* I - BOOLEAN: not 0 to use local reserved port */
265
char *EMsg) /* O (optional,minsize=1024) */
191
268
const char id[] = "client_to_svr";
287
memset(&local, 0, sizeof(local));
288
memset(&remote, 0, sizeof(remote));
208
290
local.sin_family = AF_INET;
210
292
local.sin_addr.s_addr = 0;
401
485
case EINPROGRESS:
403
if (await_connect(TORQUE_MAXCONNECTTIMEOUT, sock) == 0)
487
if (await_connect(MaxConnectTimeout, sock) == 0)
405
/* socket not ready for writing after TORQUE_MAXCONNECTTIMEOUT second timeout */
489
/* socket not ready for writing after MaxConnectTimeout microseconds timeout */
406
490
/* no network failures detected */