[master] b0234c6 Add VTCP_bind() and VTCP_listen() functions to replace the VSS_ditto
Poul-Henning Kamp
phk at FreeBSD.org
Thu Mar 12 00:59:16 CET 2015
commit b0234c6f4654be476c15b8c417a854c2a73d6b67
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Mar 11 23:39:46 2015 +0000
Add VTCP_bind() and VTCP_listen() functions to replace the VSS_ditto
diff --git a/include/vtcp.h b/include/vtcp.h
index 174975e..8f25974 100644
--- a/include/vtcp.h
+++ b/include/vtcp.h
@@ -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
diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c
index d3d34de..0a72c5b 100644
--- a/lib/libvarnish/vtcp.c
+++ b/lib/libvarnish/vtcp.c
@@ -359,6 +359,93 @@ VTCP_open(const char *addr, const char *def_port, double timeout,
}
/*--------------------------------------------------------------------
+ * 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
*/
More information about the varnish-commit
mailing list