* Bind socket to interface and port *
*************************************************/
-/* This function binds a socket to a local interface address and port. For a
-wildcard IPv6 bind, the address is ":".
-
-Arguments:
- sock the socket
- af AF_INET or AF_INET6 - the socket type
- address the IP address, in text form
- port the IP port (host order)
-
-Returns: the result of bind()
-*/
-
int
-ip_bind(int sock, int af, uschar *address, int port)
+ip_addr(void * sin_, int af, const uschar * address, int port)
{
-int s_len;
-union sockaddr_46 sin;
-memset(&sin, 0, sizeof(sin));
+union sockaddr_46 * sin = sin_;
+memset(sin, 0, sizeof(*sin));
/* Setup code when using an IPv6 socket. The wildcard address is ":", to
ensure an IPv6 socket is used. */
{
if (address[0] == ':' && address[1] == 0)
{
- sin.v6.sin6_family = AF_INET6;
- sin.v6.sin6_addr = in6addr_any;
+ sin->v6.sin6_family = AF_INET6;
+ sin->v6.sin6_addr = in6addr_any;
}
else
- {
- ip_addrinfo(address, &sin.v6); /* Panic-dies on error */
- }
- sin.v6.sin6_port = htons(port);
- s_len = sizeof(sin.v6);
+ ip_addrinfo(address, &sin->v6); /* Panic-dies on error */
+ sin->v6.sin6_port = htons(port);
+ return sizeof(sin->v6);
}
else
#else /* HAVE_IPv6 */
/* Setup code when using IPv4 socket. The wildcard address is "". */
{
- sin.v4.sin_family = AF_INET;
- sin.v4.sin_port = htons(port);
- s_len = sizeof(sin.v4);
- if (address[0] == 0)
- sin.v4.sin_addr.s_addr = (S_ADDR_TYPE)INADDR_ANY;
- else
- sin.v4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(CS address);
+ sin->v4.sin_family = AF_INET;
+ sin->v4.sin_port = htons(port);
+ sin->v4.sin_addr.s_addr = address[0] == 0
+ ? (S_ADDR_TYPE)INADDR_ANY
+ : (S_ADDR_TYPE)inet_addr(CS address);
+ return sizeof(sin->v4);
}
+}
+
+
+
+/* This function binds a socket to a local interface address and port. For a
+wildcard IPv6 bind, the address is ":".
+
+Arguments:
+ sock the socket
+ af AF_INET or AF_INET6 - the socket type
+ address the IP address, in text form
+ port the IP port (host order)
-/* Now we can call the bind() function */
+Returns: the result of bind()
+*/
+int
+ip_bind(int sock, int af, uschar *address, int port)
+{
+union sockaddr_46 sin;
+int s_len = ip_addr(&sin, af, address, port);
return bind(sock, (struct sockaddr *)&sin, s_len);
}
can't think of any other way of doing this. It converts a connection refused
into a timeout if the timeout is set to 999999. */
-if (running_in_test_harness)
+if (running_in_test_harness && save_errno == ECONNREFUSED && timeout == 999999)
{
- if (save_errno == ECONNREFUSED && timeout == 999999)
- {
- rc = -1;
- save_errno = EINTR;
- sigalrm_seen = TRUE;
- }
+ rc = -1;
+ save_errno = EINTR;
+ sigalrm_seen = TRUE;
}
/* Success */
/* A failure whose error code is "Interrupted system call" is in fact
an externally applied timeout if the signal handler has been run. */
-errno = (save_errno == EINTR && sigalrm_seen)? ETIMEDOUT : save_errno;
+errno = save_errno == EINTR && sigalrm_seen ? ETIMEDOUT : save_errno;
return -1;
}
{
if (fd != fd6) close(fd6);
if (fd != fd4) close(fd4);
- if (connhost) {
+ if (connhost)
+ {
h->port = port;
*connhost = *h;
connhost->next = NULL;
int
ip_tcpsocket(const uschar * hostport, uschar ** errstr, int tmo)
{
- int scan;
- uschar hostname[256];
- unsigned int portlow, porthigh;
-
- /* extract host and port part */
- scan = sscanf(CS hostport, "%255s %u-%u", hostname, &portlow, &porthigh);
- if ( scan != 3 ) {
- if ( scan != 2 ) {
- *errstr = string_sprintf("invalid socket '%s'", hostport);
- return -1;
+int scan;
+uschar hostname[256];
+unsigned int portlow, porthigh;
+
+/* extract host and port part */
+scan = sscanf(CS hostport, "%255s %u-%u", hostname, &portlow, &porthigh);
+if (scan != 3)
+ {
+ if (scan != 2)
+ {
+ *errstr = string_sprintf("invalid socket '%s'", hostport);
+ return -1;
}
- porthigh = portlow;
+ porthigh = portlow;
}
- return ip_connectedsocket(SOCK_STREAM, hostname, portlow, porthigh,
- tmo, NULL, errstr);
+return ip_connectedsocket(SOCK_STREAM, hostname, portlow, porthigh,
+ tmo, NULL, errstr);
}
int
ip_unixsocket(const uschar * path, uschar ** errstr)
{
- int sock;
- struct sockaddr_un server;
+int sock;
+struct sockaddr_un server;
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- *errstr = US"can't open UNIX socket.";
- return -1;
+if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ *errstr = US"can't open UNIX socket.";
+ return -1;
}
- server.sun_family = AF_UNIX;
- Ustrncpy(server.sun_path, path, sizeof(server.sun_path)-1);
- server.sun_path[sizeof(server.sun_path)-1] = '\0';
- if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
- int err = errno;
- (void)close(sock);
- *errstr = string_sprintf("unable to connect to UNIX socket (%s): %s",
- path, strerror(err));
- return -1;
- }
- return sock;
+server.sun_family = AF_UNIX;
+Ustrncpy(server.sun_path, path, sizeof(server.sun_path)-1);
+server.sun_path[sizeof(server.sun_path)-1] = '\0';
+if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
+ {
+ int err = errno;
+ (void)close(sock);
+ *errstr = string_sprintf("unable to connect to UNIX socket (%s): %s",
+ path, strerror(err));
+ return -1;
+ }
+return sock;
}
int
ip_streamsocket(const uschar * spec, uschar ** errstr, int tmo)
{
- return *spec == '/'
- ? ip_unixsocket(spec, errstr) : ip_tcpsocket(spec, errstr, tmo);
+return *spec == '/'
+ ? ip_unixsocket(spec, errstr) : ip_tcpsocket(spec, errstr, tmo);
}
/*************************************************
*/
void
-ip_keepalive(int sock, uschar *address, BOOL torf)
+ip_keepalive(int sock, const uschar *address, BOOL torf)
{
int fodder = 1;
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
}
/* Wait until the socket is ready */
-for (;;)
+do
{
FD_ZERO (&select_inset);
FD_SET (fd, &select_inset);
}
/* If the socket is ready, break out of the loop. */
-
- if (FD_ISSET(fd, &select_inset)) break;
}
+while (!FD_ISSET(fd, &select_inset));
return TRUE;
}
return TRUE;
}
else if (c > 0)
- {
first = middle + 1;
- }
else
- {
last = middle;
- }
}
return FALSE;
}
/* End of ip.c */
+/* vi: aw ai sw=2
+*/