~ubuntu-branches/ubuntu/vivid/exim4/vivid

« back to all changes in this revision

Viewing changes to src/ip.c

  • Committer: Package Import Robot
  • Author(s): Corey Bryant
  • Date: 2014-08-04 11:48:39 UTC
  • mfrom: (56.1.2 utopic)
  • Revision ID: package-import@ubuntu.com-20140804114839-xoulpcx9nxi5m72u
Tags: 4.84~RC1-3ubuntu1
* Merge from Debian unstable (LP: #1351470). Remaining changes:
  - Show Ubuntu distribution on smtp:
    + debian/patches/fix_smtp_banner.patch: updated SMTP banner
      with Ubuntu distribution
    + debian/control: added lsb-release build dependency
  - Don't provide default-mta; in Ubuntu, we want postfix to be the
    default.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
*     Exim - an Internet mail transport agent    *
3
3
*************************************************/
4
4
 
5
 
/* Copyright (c) University of Cambridge 1995 - 2009 */
 
5
/* Copyright (c) University of Cambridge 1995 - 2014 */
6
6
/* See the file NOTICE for conditions of use and distribution. */
7
7
 
8
8
/* Functions for doing things with sockets. With the advent of IPv6 this has
172
172
  af          AF_INET6 or AF_INET for the socket type
173
173
  address     the remote address, in text form
174
174
  port        the remote port
175
 
  timeout     a timeout
 
175
  timeout     a timeout (zero for indefinite timeout)
176
176
 
177
177
Returns:      0 on success; -1 on failure, with errno set
178
178
*/
250
250
 
251
251
 
252
252
/*************************************************
 
253
*    Create connected socket to remote host      *
 
254
*************************************************/
 
255
 
 
256
/* Create a socket and connect to host (name or number, ipv6 ok)
 
257
   at one of port-range.
 
258
 
 
259
Arguments:
 
260
  type          SOCK_DGRAM or SOCK_STREAM
 
261
  af            AF_INET6 or AF_INET for the socket type
 
262
  address       the remote address, in text form
 
263
  portlo,porthi the remote port range
 
264
  timeout       a timeout
 
265
  connhost      if not NULL, host_item filled in with connection details
 
266
  errstr        pointer for allocated string on error
 
267
 
 
268
Return:
 
269
  socket fd, or -1 on failure (having allocated an error string)
 
270
*/
 
271
int
 
272
ip_connectedsocket(int type, const uschar * hostname, int portlo, int porthi,
 
273
        int timeout, host_item * connhost, uschar ** errstr)
 
274
{
 
275
int namelen, port;
 
276
host_item shost;
 
277
host_item *h;
 
278
int af = 0, fd, fd4 = -1, fd6 = -1;
 
279
 
 
280
shost.next = NULL;
 
281
shost.address = NULL;
 
282
shost.port = portlo;
 
283
shost.mx = -1;
 
284
 
 
285
namelen = Ustrlen(hostname);
 
286
 
 
287
/* Anything enclosed in [] must be an IP address. */
 
288
 
 
289
if (hostname[0] == '[' &&
 
290
    hostname[namelen - 1] == ']')
 
291
  {
 
292
  uschar * host = string_copy(hostname);
 
293
  host[namelen - 1] = 0;
 
294
  host++;
 
295
  if (string_is_ip_address(host, NULL) == 0)
 
296
    {
 
297
    *errstr = string_sprintf("malformed IP address \"%s\"", hostname);
 
298
    return -1;
 
299
    }
 
300
  shost.name = shost.address = host;
 
301
  }
 
302
 
 
303
/* Otherwise check for an unadorned IP address */
 
304
 
 
305
else if (string_is_ip_address(hostname, NULL) != 0)
 
306
  shost.name = shost.address = string_copy(hostname);
 
307
 
 
308
/* Otherwise lookup IP address(es) from the name */
 
309
 
 
310
else
 
311
  {
 
312
  shost.name = string_copy(hostname);
 
313
  if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
 
314
      FALSE) != HOST_FOUND)
 
315
    {
 
316
    *errstr = string_sprintf("no IP address found for host %s", shost.name);
 
317
    return -1;
 
318
    }
 
319
  }
 
320
 
 
321
/* Try to connect to the server - test each IP till one works */
 
322
 
 
323
for (h = &shost; h != NULL; h = h->next)
 
324
  {
 
325
  fd = (Ustrchr(h->address, ':') != 0)
 
326
    ? (fd6 < 0) ? (fd6 = ip_socket(type, af = AF_INET6)) : fd6
 
327
    : (fd4 < 0) ? (fd4 = ip_socket(type, af = AF_INET )) : fd4;
 
328
 
 
329
  if (fd < 0)
 
330
    {
 
331
    *errstr = string_sprintf("failed to create socket: %s", strerror(errno));
 
332
    goto bad;
 
333
    }
 
334
 
 
335
  for(port = portlo; port <= porthi; port++)
 
336
    if (ip_connect(fd, af, h->address, port, timeout) == 0)
 
337
      {
 
338
      if (fd != fd6) close(fd6);
 
339
      if (fd != fd4) close(fd4);
 
340
      if (connhost) {
 
341
        h->port = port;
 
342
        *connhost = *h;
 
343
        connhost->next = NULL;
 
344
        }
 
345
      return fd;
 
346
      }
 
347
  }
 
348
 
 
349
*errstr = string_sprintf("failed to connect to %s: "
 
350
  "couldn't connect to any host: %s", hostname, strerror(errno));
 
351
 
 
352
bad:
 
353
  close(fd4); close(fd6); return -1;
 
354
}
 
355
 
 
356
 
 
357
/*************************************************
253
358
*         Set keepalive on a socket              *
254
359
*************************************************/
255
360
 
298
403
{
299
404
fd_set select_inset;
300
405
struct timeval tv;
301
 
int start_recv = time(NULL);
 
406
time_t start_recv = time(NULL);
302
407
int rc;
303
408
 
304
409
/* Wait until the socket is ready */