Commit b0234c6f authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add VTCP_bind() and VTCP_listen() functions to replace the VSS_ditto

parent 1809f707
......@@ -48,7 +48,7 @@ int VTCP_nonblocking(int sock);
int VTCP_linger(int sock, int linger);
int VTCP_check_hup(int sock);
#ifdef SOL_SOCKET
// #ifdef SOL_SOCKET
void VTCP_name(const struct suckaddr *addr, char *abuf, unsigned alen,
char *pbuf, unsigned plen);
int VTCP_connected(int s);
......@@ -56,5 +56,7 @@ int VTCP_connect(const struct suckaddr *name, int msec);
int VTCP_open(const char *addr, const char *def_port, double timeout,
const char **err);
void VTCP_close(int *s);
int VTCP_bind(const struct suckaddr *addr, const char **errp);
int VTCP_listen(const struct suckaddr *addr, int depth, const char **errp);
void VTCP_set_read_timeout(int s, double seconds);
#endif
// #endif
......@@ -358,6 +358,93 @@ VTCP_open(const char *addr, const char *def_port, double timeout,
return (error);
}
/*--------------------------------------------------------------------
* Given a struct suckaddr, open a socket of the appropriate type, and bind
* it to the requested address.
*
* If the address is an IPv6 address, the IPV6_V6ONLY option is set to
* avoid conflicts between INADDR_ANY and IN6ADDR_ANY.
*/
int
VTCP_bind(const struct suckaddr *sa, const char **errp)
{
int sd, val, e;
socklen_t sl;
const struct sockaddr *so;
int proto;
if (errp != NULL)
*errp = NULL;
proto = VSA_Get_Proto(sa);
sd = socket(proto, SOCK_STREAM, 0);
if (sd < 0) {
if (errp != NULL)
*errp = "socket(2)";
return (-1);
}
val = 1;
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) != 0) {
if (errp != NULL)
*errp = "setsockopt(SO_REUSEADDR, 1)";
e = errno;
AZ(close(sd));
errno = e;
return (-1);
}
#ifdef IPV6_V6ONLY
/* forcibly use separate sockets for IPv4 and IPv6 */
val = 1;
if (proto == AF_INET6 &&
setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof val) != 0) {
if (errp != NULL)
*errp = "setsockopt(IPV6_V6ONLY, 1)";
e = errno;
AZ(close(sd));
errno = e;
return (-1);
}
#endif
so = VSA_Get_Sockaddr(sa, &sl);
if (bind(sd, so, sl) != 0) {
if (errp != NULL)
*errp = "bind(2)";
e = errno;
AZ(close(sd));
errno = e;
return (-1);
}
return (sd);
}
/*--------------------------------------------------------------------
* Given a struct suckaddr, open a socket of the appropriate type, bind it
* to the requested address, and start listening.
*/
int
VTCP_listen(const struct suckaddr *sa, int depth, const char **errp)
{
int sd;
int e;
if (errp != NULL)
*errp = NULL;
sd = VTCP_bind(sa, errp);
if (sd >= 0) {
if (listen(sd, depth) != 0) {
e = errno;
AZ(close(sd));
errno = e;
if (errp != NULL)
*errp = "listen(2)";
return (-1);
}
}
return (sd);
}
/*--------------------------------------------------------------------
* Set or reset SO_LINGER flag
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment