~ubuntu-branches/ubuntu/precise/torque/precise-updates

« back to all changes in this revision

Viewing changes to src/lib/Libnet/net_client.c

  • Committer: Bazaar Package Importer
  • Author(s): Dominique Belhachemi
  • Date: 2010-05-17 20:56:46 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100517205646-yjsoqs5r1s9xpnu9
Tags: upstream-2.4.8+dfsg
ImportĀ upstreamĀ versionĀ 2.4.8+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
#include <errno.h>
87
87
#include <netdb.h>
88
88
#include <string.h>
 
89
#include <stdlib.h>
89
90
#include "portability.h"
90
91
#include "server_limits.h"
91
92
#include "net_connect.h"
106
107
int bindresvport(int sd, struct sockaddr_in *sin);
107
108
#endif
108
109
 
 
110
/**
 
111
 * Returns the max number of possible file descriptors (as
 
112
 * per the OS limits).
 
113
 *
 
114
 */
 
115
 
 
116
int get_max_num_descriptors(void)
 
117
  {
 
118
  static int max_num_descriptors = 0;
 
119
 
 
120
  if (max_num_descriptors <= 0)
 
121
    max_num_descriptors = getdtablesize();
 
122
 
 
123
  return(max_num_descriptors);
 
124
  }  /* END get_num_max_descriptors() */
 
125
 
 
126
/**
 
127
 * Returns the number of bytes needed to allocate
 
128
 * a fd_set array that can hold all of the possible
 
129
 * socket descriptors.
 
130
 */
 
131
 
 
132
int get_fdset_size(void)
 
133
  {
 
134
  unsigned int MaxNumDescriptors = 0;
 
135
  int NumFDSetsNeeded = 0;
 
136
  int NumBytesInFDSet = 0;
 
137
  int Result = 0;
 
138
 
 
139
  MaxNumDescriptors = get_max_num_descriptors();
 
140
 
 
141
  NumBytesInFDSet = sizeof(fd_set);
 
142
  NumFDSetsNeeded = MaxNumDescriptors / FD_SETSIZE;
 
143
 
 
144
  if (MaxNumDescriptors < FD_SETSIZE)
 
145
    {
 
146
    /* the default size already provides sufficient space */
 
147
 
 
148
    Result = NumBytesInFDSet;
 
149
    }
 
150
  else if ((MaxNumDescriptors % FD_SETSIZE) > 0)
 
151
    {
 
152
    /* we need to allocate more memory to cover extra
 
153
     * bits--add an extra FDSet worth of memory to the size */
 
154
 
 
155
    Result = (NumFDSetsNeeded + 1) * NumBytesInFDSet;
 
156
    }
 
157
  else
 
158
    {
 
159
    /* division was exact--we know exactly how many bytes we need */
 
160
 
 
161
    Result = NumFDSetsNeeded * NumBytesInFDSet;
 
162
    }
 
163
 
 
164
  return(Result);
 
165
  }  /* END get_fdset_size() */
 
166
 
 
167
 
109
168
/*
110
169
** wait for connect to complete.  We use non-blocking sockets,
111
170
** so have to wait for completion this way.
113
172
 
114
173
static int await_connect(
115
174
 
116
 
  int timeout,   /* I */
 
175
  long timeout,   /* I */
117
176
  int sockd)     /* I */
118
177
 
119
178
  {
120
 
  fd_set fs;
121
179
  int n, val, rc;
122
180
 
 
181
  int MaxNumDescriptors = 0;
 
182
 
 
183
  fd_set *BigFDSet = NULL;
 
184
 
123
185
  struct timeval tv;
124
186
 
125
187
  torque_socklen_t len;
126
188
 
127
 
  tv.tv_sec = timeout;
128
 
  tv.tv_usec = 0;
129
 
 
130
 
  FD_ZERO(&fs);
131
 
  FD_SET(sockd, &fs);
132
 
 
133
 
  if ((n = select(sockd + 1, 0, &fs, 0, &tv)) != 1)
 
189
  /* 
 
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
 
193
   */
 
194
 
 
195
  tv.tv_sec = timeout / 1000000;
 
196
  tv.tv_usec = timeout % 1000000;
 
197
 
 
198
  /* calculate needed size for fd_set in select() */
 
199
 
 
200
  MaxNumDescriptors = get_max_num_descriptors();
 
201
 
 
202
  BigFDSet = (fd_set *)calloc(1,sizeof(char) * get_fdset_size());
 
203
 
 
204
  FD_SET(sockd, BigFDSet);
 
205
 
 
206
  if ((n = select(sockd+1,0,BigFDSet,0,&tv)) != 1)
134
207
    {
135
208
    /* FAILURE:  socket not ready for write */
136
209
 
 
210
    free(BigFDSet);
137
211
    return(-1);
138
212
    }
139
213
 
145
219
    {
146
220
    /* SUCCESS:  no failures detected */
147
221
 
 
222
    free(BigFDSet);
148
223
    return(0);
149
224
    }
150
225
 
152
227
 
153
228
  /* FAILURE:  socket error detected */
154
229
 
 
230
  free(BigFDSet);
155
231
  return(-1);
156
232
  }  /* END await_connect() */
157
233
 
158
234
 
159
235
 
160
236
 
161
 
#define TORQUE_MAXCONNECTTIMEOUT  5
 
237
/* global */
 
238
long MaxConnectTimeout = 5000000; /* in microseconds */
162
239
 
163
240
/*
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.
177
254
 *
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
179
256
 */
180
257
 
181
258
/* NOTE:  create new connection on reserved port to validate root/trusted authority */
182
259
 
183
260
int client_to_svr(
184
261
 
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) */
189
266
 
190
267
  {
191
268
  const char id[] = "client_to_svr";
195
272
  struct sockaddr_in remote;
196
273
  int                sock;
197
274
  unsigned short     tryport;
 
275
#ifndef NOPRIVPORTS
198
276
  int                flags;
 
277
#endif /* !NOPRIVPORTS */
199
278
  int                one = 1;
200
279
 
201
280
  int                trycount;
205
284
 
206
285
  errno = 0;
207
286
 
 
287
  memset(&local, 0, sizeof(local));
 
288
  memset(&remote, 0, sizeof(remote));
 
289
 
208
290
  local.sin_family      = AF_INET;
209
291
 
210
292
  local.sin_addr.s_addr = 0;
213
295
 
214
296
  tryport = IPPORT_RESERVED - 1;
215
297
 
 
298
#ifndef NOPRIVPORTS
216
299
retry:  /* retry goto added (rentec) */
 
300
#endif /* !NOPRIVPORTS */
217
301
 
218
302
  /* get socket */
219
303
 
400
484
 
401
485
    case EINPROGRESS:
402
486
 
403
 
      if (await_connect(TORQUE_MAXCONNECTTIMEOUT, sock) == 0)
 
487
      if (await_connect(MaxConnectTimeout, sock) == 0)
404
488
        {
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 */
407
491
 
408
492
        break;
413
497
    case ECONNREFUSED:
414
498
 
415
499
      if (EMsg != NULL)
416
 
        sprintf(EMsg, "cannot bind to port %d in %s - connection refused",
 
500
        sprintf(EMsg, "cannot connect to port %d in %s - connection refused",
417
501
                tryport,
418
502
                id);
419
503
 
428
512
    default:
429
513
 
430
514
      if (EMsg != NULL)
431
 
        sprintf(EMsg, "cannot bind to port %d in %s - errno:%d %s",
 
515
        sprintf(EMsg, "cannot connect to port %d in %s - errno:%d %s",
432
516
                tryport,
433
517
                id,
434
518
                errno,