252
252
/*************************************************
253
* Create connected socket to remote host *
254
*************************************************/
256
/* Create a socket and connect to host (name or number, ipv6 ok)
257
at one of port-range.
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
265
connhost if not NULL, host_item filled in with connection details
266
errstr pointer for allocated string on error
269
socket fd, or -1 on failure (having allocated an error string)
272
ip_connectedsocket(int type, const uschar * hostname, int portlo, int porthi,
273
int timeout, host_item * connhost, uschar ** errstr)
278
int af = 0, fd, fd4 = -1, fd6 = -1;
281
shost.address = NULL;
285
namelen = Ustrlen(hostname);
287
/* Anything enclosed in [] must be an IP address. */
289
if (hostname[0] == '[' &&
290
hostname[namelen - 1] == ']')
292
uschar * host = string_copy(hostname);
293
host[namelen - 1] = 0;
295
if (string_is_ip_address(host, NULL) == 0)
297
*errstr = string_sprintf("malformed IP address \"%s\"", hostname);
300
shost.name = shost.address = host;
303
/* Otherwise check for an unadorned IP address */
305
else if (string_is_ip_address(hostname, NULL) != 0)
306
shost.name = shost.address = string_copy(hostname);
308
/* Otherwise lookup IP address(es) from the name */
312
shost.name = string_copy(hostname);
313
if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
314
FALSE) != HOST_FOUND)
316
*errstr = string_sprintf("no IP address found for host %s", shost.name);
321
/* Try to connect to the server - test each IP till one works */
323
for (h = &shost; h != NULL; h = h->next)
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;
331
*errstr = string_sprintf("failed to create socket: %s", strerror(errno));
335
for(port = portlo; port <= porthi; port++)
336
if (ip_connect(fd, af, h->address, port, timeout) == 0)
338
if (fd != fd6) close(fd6);
339
if (fd != fd4) close(fd4);
343
connhost->next = NULL;
349
*errstr = string_sprintf("failed to connect to %s: "
350
"couldn't connect to any host: %s", hostname, strerror(errno));
353
close(fd4); close(fd6); return -1;
357
/*************************************************
253
358
* Set keepalive on a socket *
254
359
*************************************************/