[sheepdog] [PATCH 2/2] net: add a send timeout for sockfd

Liu Yuan namei.unix at gmail.com
Mon Aug 27 11:32:34 CEST 2012


From: Liu Yuan <tailai.ly at taobao.com>

This fixes the bug found by 035.

This is kind of a subtle case:

'sendmsg' of A  would fill its sock buffer to full whlile the other end B is failed
in the middle of the 'sendsmg'. The sock buffer of A is full, then kernel block
the thread awaiting on the buffer drain, which will never happen because B is
down. Keepalive won't be triggered because the kernel detect that sock buffer
has data to send. So the final result is that, the blocked thread will never be
woke up.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 include/net.h |    1 +
 lib/net.c     |   18 ++++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/include/net.h b/include/net.h
index 4ee0eb6..15ee703 100644
--- a/include/net.h
+++ b/include/net.h
@@ -51,6 +51,7 @@ uint8_t *str_to_addr(int af, const char *ipstr, uint8_t *addr);
 int set_nonblocking(int fd);
 int set_nodelay(int fd);
 int set_keepalive(int fd);
+int set_snd_timeout(int fd);
 int set_timeout(int fd);
 int get_local_addr(uint8_t *bytes);
 
diff --git a/lib/net.c b/lib/net.c
index 6ed046a..ef91446 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -243,6 +243,12 @@ int connect_to(const char *name, int port)
 			break;
 		}
 
+		ret = set_snd_timeout(fd);
+		if (ret) {
+			close(fd);
+			break;
+		}
+
 		ret = set_nodelay(fd);
 		if (ret) {
 			eprintf("%m\n");
@@ -425,6 +431,18 @@ int set_nonblocking(int fd)
 	return ret;
 }
 
+/* Send timeout for 5 second */
+int set_snd_timeout(int fd)
+{
+	struct timeval timeout;
+
+	timeout.tv_sec = 5;
+	timeout.tv_usec = 0;
+
+	return setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
+			  sizeof(timeout));
+}
+
 int set_nodelay(int fd)
 {
 	int ret, opt;
-- 
1.7.10.2




More information about the sheepdog mailing list