}
-/*
+/* Create a socket and connect to host (name or number, ipv6 ok)
+ at one of port-range.
Arguments:
type SOCK_DGRAM or SOCK_STREAM
af AF_INET6 or AF_INET for the socket type
address the remote address, in text form
portlo,porthi the remote port range
timeout a timeout
+ connhost if not NULL, host_item filled in with connection details
errstr pointer for allocated string on error
Return:
*/
int
ip_connectedsocket(int type, const uschar * hostname, int portlo, int porthi,
- int timeout, uschar ** errstr)
+ int timeout, host_item * connhost, uschar ** errstr)
{
int namelen, port;
host_item shost;
host_item *h;
-int fd, fd4 = -1, fd6 = -1;
+int af, fd, fd4 = -1, fd6 = -1;
shost.next = NULL;
shost.address = NULL;
-shost.port = port;
+shost.port = portlo;
shost.mx = -1;
namelen = Ustrlen(hostname);
/* Otherwise check for an unadorned IP address */
else if (string_is_ip_address(hostname, NULL) != 0)
- shost.name = shost.address = hostname;
+ shost.name = shost.address = string_copy(hostname);
/* Otherwise lookup IP address(es) from the name */
else
{
- shost.name = hostname;
+ shost.name = string_copy(hostname);
if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
FALSE) != HOST_FOUND)
{
for (h = &shost; h != NULL; h = h->next)
{
fd = (Ustrchr(h->address, ':') != 0)
- ? (fd6 < 0) ? (fd6 = ip_socket(SOCK_STREAM, AF_INET6)) : fd6
- : (fd4 < 0) ? (fd4 = ip_socket(SOCK_STREAM, AF_INET )) : fd4;
+ ? (fd6 < 0) ? (fd6 = ip_socket(SOCK_STREAM, af = AF_INET6)) : fd6
+ : (fd4 < 0) ? (fd4 = ip_socket(SOCK_STREAM, af = AF_INET )) : fd4;
if (fd < 0)
{
goto bad;
}
- for(port = portlo, port <= porthi; port++)
+ for(port = portlo; port <= porthi; port++)
if (ip_connect(fd, af, h->address, port, timeout) == 0)
{
if (fd != fd6) close(fd6);
if (fd != fd4) close(fd4);
+ if (connhost) {
+ h->port = port;
+ *connhost = *h;
+ connhost->next = NULL;
+ }
return fd;
}
}