Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Feb 2011 15:46:28 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r218193 - head/sbin/hastd
Message-ID:  <201102021546.p12FkS06013874@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Wed Feb  2 15:46:28 2011
New Revision: 218193
URL: http://svn.freebsd.org/changeset/base/218193

Log:
  Add proto_connect_wait() to wait for connection to finish.
  If timeout argument to proto_connect() is -1, then the caller needs to use
  this new function to wait for connection.
  
  This change is in preparation for capsicum, where sandboxed worker wants
  to ask main process to connect in worker's behalf and pass descriptor
  to the worker. Because we don't want the main process to wait for the
  connection, it will start async connection and pass descriptor to the
  worker who will be responsible for waiting for the connection to finish.
  
  MFC after:	1 week

Modified:
  head/sbin/hastd/proto.c
  head/sbin/hastd/proto.h
  head/sbin/hastd/proto_impl.h
  head/sbin/hastd/proto_tcp4.c
  head/sbin/hastd/proto_uds.c

Modified: head/sbin/hastd/proto.c
==============================================================================
--- head/sbin/hastd/proto.c	Wed Feb  2 15:42:00 2011	(r218192)
+++ head/sbin/hastd/proto.c	Wed Feb  2 15:46:28 2011	(r218193)
@@ -174,7 +174,7 @@ proto_connect(struct proto_conn *conn, i
 	PJDLOG_ASSERT(conn->pc_side == PROTO_SIDE_CLIENT);
 	PJDLOG_ASSERT(conn->pc_proto != NULL);
 	PJDLOG_ASSERT(conn->pc_proto->hp_connect != NULL);
-	PJDLOG_ASSERT(timeout >= 0);
+	PJDLOG_ASSERT(timeout >= -1);
 
 	ret = conn->pc_proto->hp_connect(conn->pc_ctx, timeout);
 	if (ret != 0) {
@@ -186,6 +186,27 @@ proto_connect(struct proto_conn *conn, i
 }
 
 int
+proto_connect_wait(struct proto_conn *conn, int timeout)
+{
+	int ret;
+
+	PJDLOG_ASSERT(conn != NULL);
+	PJDLOG_ASSERT(conn->pc_magic == PROTO_CONN_MAGIC);
+	PJDLOG_ASSERT(conn->pc_side == PROTO_SIDE_CLIENT);
+	PJDLOG_ASSERT(conn->pc_proto != NULL);
+	PJDLOG_ASSERT(conn->pc_proto->hp_connect_wait != NULL);
+	PJDLOG_ASSERT(timeout >= 0);
+
+	ret = conn->pc_proto->hp_connect_wait(conn->pc_ctx, timeout);
+	if (ret != 0) {
+		errno = ret;
+		return (-1);
+	}
+
+	return (0);
+}
+
+int
 proto_server(const char *addr, struct proto_conn **connp)
 {
 

Modified: head/sbin/hastd/proto.h
==============================================================================
--- head/sbin/hastd/proto.h	Wed Feb  2 15:42:00 2011	(r218192)
+++ head/sbin/hastd/proto.h	Wed Feb  2 15:46:28 2011	(r218193)
@@ -39,6 +39,7 @@ struct proto_conn;
 
 int proto_client(const char *addr, struct proto_conn **connp);
 int proto_connect(struct proto_conn *conn, int timeout);
+int proto_connect_wait(struct proto_conn *conn, int timeout);
 int proto_server(const char *addr, struct proto_conn **connp);
 int proto_accept(struct proto_conn *conn, struct proto_conn **newconnp);
 int proto_send(const struct proto_conn *conn, const void *data, size_t size);

Modified: head/sbin/hastd/proto_impl.h
==============================================================================
--- head/sbin/hastd/proto_impl.h	Wed Feb  2 15:42:00 2011	(r218192)
+++ head/sbin/hastd/proto_impl.h	Wed Feb  2 15:46:28 2011	(r218193)
@@ -41,6 +41,7 @@
 
 typedef int hp_client_t(const char *, void **);
 typedef int hp_connect_t(void *, int);
+typedef int hp_connect_wait_t(void *, int);
 typedef int hp_server_t(const char *, void **);
 typedef int hp_accept_t(void *, void **);
 typedef int hp_send_t(void *, const unsigned char *, size_t);
@@ -57,6 +58,7 @@ struct hast_proto {
 	const char	*hp_name;
 	hp_client_t	*hp_client;
 	hp_connect_t	*hp_connect;
+	hp_connect_wait_t *hp_connect_wait;
 	hp_server_t	*hp_server;
 	hp_accept_t	*hp_accept;
 	hp_send_t	*hp_send;

Modified: head/sbin/hastd/proto_tcp4.c
==============================================================================
--- head/sbin/hastd/proto_tcp4.c	Wed Feb  2 15:42:00 2011	(r218192)
+++ head/sbin/hastd/proto_tcp4.c	Wed Feb  2 15:46:28 2011	(r218193)
@@ -60,6 +60,7 @@ struct tcp4_ctx {
 #define	TCP4_SIDE_SERVER_WORK	2
 };
 
+static int tcp4_connect_wait(void *ctx, int timeout);
 static void tcp4_close(void *ctx);
 
 static in_addr_t
@@ -214,16 +215,14 @@ static int
 tcp4_connect(void *ctx, int timeout)
 {
 	struct tcp4_ctx *tctx = ctx;
-	struct timeval tv;
-	fd_set fdset;
-	socklen_t esize;
-	int error, flags, ret;
+	int error, flags;
 
 	PJDLOG_ASSERT(tctx != NULL);
 	PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
 	PJDLOG_ASSERT(tctx->tc_side == TCP4_SIDE_CLIENT);
 	PJDLOG_ASSERT(tctx->tc_fd >= 0);
-	PJDLOG_ASSERT(timeout >= 0);
+	PJDLOG_ASSERT(tctx->tc_sin.sin_family != AF_UNSPEC);
+	PJDLOG_ASSERT(timeout >= -1);
 
 	flags = fcntl(tctx->tc_fd, F_GETFL);
 	if (flags == -1) {
@@ -244,6 +243,8 @@ tcp4_connect(void *ctx, int timeout)
 
 	if (connect(tctx->tc_fd, (struct sockaddr *)&tctx->tc_sin,
 	    sizeof(tctx->tc_sin)) == 0) {
+		if (timeout == -1)
+			return (0);
 		error = 0;
 		goto done;
 	}
@@ -252,10 +253,35 @@ tcp4_connect(void *ctx, int timeout)
 		pjdlog_common(LOG_DEBUG, 1, errno, "connect() failed");
 		goto done;
 	}
-	/*
-	 * Connection can't be established immediately, let's wait
-	 * for HAST_TIMEOUT seconds.
-	 */
+	if (timeout == -1)
+		return (0);
+	return (tcp4_connect_wait(ctx, timeout));
+done:
+	flags &= ~O_NONBLOCK;
+	if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
+		if (error == 0)
+			error = errno;
+		pjdlog_common(LOG_DEBUG, 1, errno,
+		    "fcntl(F_SETFL, ~O_NONBLOCK) failed");
+	}
+	return (error);
+}
+
+static int
+tcp4_connect_wait(void *ctx, int timeout)
+{
+	struct tcp4_ctx *tctx = ctx;
+	struct timeval tv;
+	fd_set fdset;
+	socklen_t esize;
+	int error, flags, ret;
+
+	PJDLOG_ASSERT(tctx != NULL);
+	PJDLOG_ASSERT(tctx->tc_magic == TCP4_CTX_MAGIC);
+	PJDLOG_ASSERT(tctx->tc_side == TCP4_SIDE_CLIENT);
+	PJDLOG_ASSERT(tctx->tc_fd >= 0);
+	PJDLOG_ASSERT(timeout >= 0);
+
 	tv.tv_sec = timeout;
 	tv.tv_usec = 0;
 again:
@@ -289,6 +315,13 @@ again:
 	}
 	error = 0;
 done:
+	flags = fcntl(tctx->tc_fd, F_GETFL);
+	if (flags == -1) {
+		if (error == 0)
+			error = errno;
+		pjdlog_common(LOG_DEBUG, 1, errno, "fcntl(F_GETFL) failed");
+		return (error);
+	}
 	flags &= ~O_NONBLOCK;
 	if (fcntl(tctx->tc_fd, F_SETFL, flags) == -1) {
 		if (error == 0)
@@ -492,6 +525,7 @@ static struct hast_proto tcp4_proto = {
 	.hp_name = "tcp4",
 	.hp_client = tcp4_client,
 	.hp_connect = tcp4_connect,
+	.hp_connect_wait = tcp4_connect_wait,
 	.hp_server = tcp4_server,
 	.hp_accept = tcp4_accept,
 	.hp_send = tcp4_send,

Modified: head/sbin/hastd/proto_uds.c
==============================================================================
--- head/sbin/hastd/proto_uds.c	Wed Feb  2 15:42:00 2011	(r218192)
+++ head/sbin/hastd/proto_uds.c	Wed Feb  2 15:46:28 2011	(r218193)
@@ -131,7 +131,7 @@ uds_connect(void *ctx, int timeout)
 	PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC);
 	PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_CLIENT);
 	PJDLOG_ASSERT(uctx->uc_fd >= 0);
-	PJDLOG_ASSERT(timeout >= 0);
+	PJDLOG_ASSERT(timeout >= -1);
 
 	if (connect(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun,
 	    sizeof(uctx->uc_sun)) < 0) {
@@ -142,6 +142,20 @@ uds_connect(void *ctx, int timeout)
 }
 
 static int
+uds_connect_wait(void *ctx, int timeout)
+{
+	struct uds_ctx *uctx = ctx;
+
+	PJDLOG_ASSERT(uctx != NULL);
+	PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC);
+	PJDLOG_ASSERT(uctx->uc_side == UDS_SIDE_CLIENT);
+	PJDLOG_ASSERT(uctx->uc_fd >= 0);
+	PJDLOG_ASSERT(timeout >= 0);
+
+	return (0);
+}
+
+static int
 uds_server(const char *addr, void **ctxp)
 {
 	struct uds_ctx *uctx;
@@ -330,6 +344,7 @@ static struct hast_proto uds_proto = {
 	.hp_name = "uds",
 	.hp_client = uds_client,
 	.hp_connect = uds_connect,
+	.hp_connect_wait = uds_connect_wait,
 	.hp_server = uds_server,
 	.hp_accept = uds_accept,
 	.hp_send = uds_send,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102021546.p12FkS06013874>