Add KEEP_ALIVE option to the socket connected with sdbd.
authorKim Gunsoo <gunsoo83.kim@samsung.com>
Fri, 6 Nov 2015 09:46:25 +0000 (18:46 +0900)
committerGunSoo Kim <gunsoo83.kim@samsung.com>
Tue, 10 Nov 2015 06:26:33 +0000 (15:26 +0900)
- After connected with sdbd through TCP socket, add KEEP_ALIVE
  option to the socket.

Change-Id: I39d3959db31ce8ad34f75bf735233d0f6d99ac92
Signed-off-by: Kim Gunsoo <gunsoo83.kim@samsung.com>
src/sockets.c
src/transport_local.c
src/utils.c
src/utils.h
src/utils_backend.h
src/utils_unix.c
src/utils_windows.c

index cc32135bb4c22bbf4850d7fe1e835e721bee42d1..5e601f432917091ad8c03f26edd5640378566f38 100755 (executable)
@@ -1443,6 +1443,7 @@ static void connect_emulator(char* host, int port, char* buf, int buf_len) {
     LOG_INFO("FD(%d) connected\n", fd);
     close_on_exec(fd);
     disable_tcp_nagle(fd);
+    keep_alive(fd, 1, SDB_KEEPALIVE_CNT, SDB_KEEPALIVE_IDLE, SDB_KEEPALIVE_INTVL);
     char serial[100];
     snprintf(serial, sizeof(serial), "%s:%d", host, port);
 
index 79f7c1af7998d05d932dfe4526f9ddad6c9c7f9a..5e4502c0eea4f830eefa4eea1b3efc1f65440804 100755 (executable)
@@ -100,6 +100,7 @@ int local_connect(int sdb_port, const char *device_name) {
 
     if (fd >= 0) {
         D("connected on remote on fd '%d', port '%d'\n", fd, sdb_port);
+        keep_alive(fd, 1, SDB_KEEPALIVE_CNT, SDB_KEEPALIVE_IDLE, SDB_KEEPALIVE_INTVL);
         close_on_exec(fd);
         disable_tcp_nagle(fd);
 
index 683bcb2b1229ca977317197718a9bdfcab5c2eb3..0a49f502e07ceeeb67e936392b80cb7072b00acd 100755 (executable)
@@ -265,6 +265,10 @@ void close_on_exec(int fd) {
     return utils_backend->close_on_exec(fd);
 }
 
+void keep_alive(int fd, int onoff, int cnt, int idle, int interval) {
+    return utils_backend->keep_alive(fd, onoff, cnt, idle, interval);
+}
+
 int sdb_socket_accept(int serverfd) {
        LOG_INFO("FD(%d)\n");
     return utils_backend->sdb_socket_accept(serverfd);
index a80a58437ee7f8041bec318e63a2bdbc4adfd296..30cc0b3f09804126f8026b4f25b33690e4728b73 100755 (executable)
@@ -121,6 +121,7 @@ int sdb_close(int fd);
 int unix_unlink(const char* path);
 int sdb_mkdir(const char* path, int mode);
 void close_on_exec(int fd);
+void keep_alive(int fd, int onoff, int cnt, int idle, int interval);
 int sdb_socket_accept(int serverfd);
 int sdb_socketpair(int sv[2]);
 void sdb_sleep_ms(int mseconds);
@@ -132,9 +133,12 @@ int sdb_getsockname(int fd, struct sockaddr *addr, int *sockaddr_len);
 int sdb_getpeername(int fd, struct sockaddr *addr, int *sockaddr_len);
 
 // sockets
-#define LISTEN_BACKLOG 4
+#define LISTEN_BACKLOG                  (4)
 #define SDB_MAX_CONNECT_TIMEOUT         (10.0f)
 #define SDB_DEFAULT_CONNECT_TIMEOUT     (1.0f)
+#define SDB_KEEPALIVE_CNT               (9)
+#define SDB_KEEPALIVE_IDLE              (1)
+#define SDB_KEEPALIVE_INTVL             (1)
 
 int sdb_host_connect(const char *host, int port, int type);
 int sdb_host_connect_timeout(const char *host, int port, int type, double timeout);
index ac3b437c6e2940df4c84acc1bf50afdfdbb467a7..efa55dea9992b80eaddb3ca1fae184b8fdf598d8 100755 (executable)
@@ -68,6 +68,7 @@ struct utils_os_backend {
     int (*sdb_close)(int fd);
     int (*sdb_mkdir)(const char* path, int mode);
     void (*close_on_exec)(int fd);
+    void (*keep_alive)(int fd, int onoff, int cnt, int idle, int interval);
     int (*sdb_socket_accept)(int serverfd);
     int (*sdb_socketpair)(int sv[2]);
     void (*sdb_sleep_ms)(int mseconds);
index d3c1719a66f696ceea01ab12b3f8394f8139b681..b05c2c0d1573f12f3ed10685f09505c82529eb30 100755 (executable)
@@ -152,6 +152,40 @@ static void  _close_on_exec(int  fd)
         LOG_ERROR("failed to set the file descriptor '%d': %s",fd ,strerror(errno));
 }
 
+static void _keep_alive(int fd, int onoff, int cnt, int idle, int interval)
+{
+    int ret = -1;
+
+    ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &onoff, sizeof(onoff));
+    if (ret == -1) {
+        LOG_ERROR("failed to set keep alive option. FD(%d), error=%s\n", fd, strerror(errno));
+        return;
+    }
+
+    /* override /proc/sys/net/ipv4/tcp_keepalive_probes */
+    ret = setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
+    if (ret == -1) {
+        LOG_ERROR("failed to set keep count option. FD(%d), error=%s\n", fd, strerror(errno));
+        return;
+    }
+
+    /* override /proc/sys/net/ipv4/tcp_keepalive_time */
+    ret = setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
+    if (ret == -1) {
+        LOG_ERROR("failed to set keep idle option. FD(%d), error=%s\n", fd, strerror(errno));
+        return;
+    }
+
+    /* override /proc/sys/net/ipv4/tcp_keepalive_intvl */
+    ret = setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
+    if (ret == -1) {
+        LOG_ERROR("failed to set keep interval option. FD(%d), error=%s\n", fd, strerror(errno));
+        return;
+    }
+
+    LOG_INFO("Success to set keep alive option. FD(%d), onoff=%d, cnt=%d, idle=%d(sec), interval=%d(sec)\n", onoff, cnt, idle, interval);
+}
+
 static int _sdb_open( const char*  pathname, int  options )
 {
     int  fd = open( pathname, options );
@@ -441,6 +475,7 @@ const struct utils_os_backend utils_unix_backend = {
     .sdb_transport_close = _sdb_close,
     .sdb_close = _sdb_close,
     .close_on_exec = _close_on_exec,
+    .keep_alive = _keep_alive,
     .sdb_mkdir = _sdb_mkdir,
     .sdb_socket_accept = _sdb_socket_accept,
     .sdb_socketpair = _sdb_socketpair,
index 4032ddfb2ba1dff38a1fda6f23ee24add5bc63bb..a4ec8b58a0dfb537ce3ee2861a54029a75239c93 100755 (executable)
@@ -558,6 +558,47 @@ static void _close_on_exec(int fd) {
     /* nothing really */
 }
 
+/* XXX: Include the mstcpip.h.
+ * Defines tcp_keepalive structure and SIO_KEEPALIVE_VALS manually,
+ * because mstcpip.h is not supported in mingw32. */
+struct tcp_keepalive {
+    u_long  onoff;
+    u_long  keepalivetime;
+    u_long  keepaliveinterval;
+};
+#define SIO_KEEPALIVE_VALS  _WSAIOW(IOC_VENDOR,4)
+
+static void _keep_alive(int fd, int onoff, int cnt, int idle, int interval) {
+    SDB_HANDLE* sdb_handle = sdb_handle_map_get(fd);
+    SOCKET s;
+    struct tcp_keepalive keep_alive, out_keep_alive;
+    DWORD outBytes;
+    int ret = 0;
+
+    if (sdb_handle == NULL) {
+        LOG_ERROR("FD(%d) not exists\n", fd);
+        return;
+    }
+    s = sdb_handle->u.socket;
+
+    keep_alive.onoff = onoff;
+    /* specifies the timeout in milliseconds,
+     * with no activity until the first keep-alive packet is sent. */
+    keep_alive.keepalivetime = idle * 1000;
+    /* specifies the interval in milliseconds,
+     * between when successive keep-alive packet are sent if no acknowledgment is received. */
+    keep_alive.keepaliveinterval = interval * 1000;
+
+    ret = WSAIoctl(s, SIO_KEEPALIVE_VALS, &keep_alive, sizeof(keep_alive),
+            &out_keep_alive, sizeof(out_keep_alive), &outBytes, NULL, NULL);
+    if (ret == SOCKET_ERROR) {
+        LOG_ERROR("Failed to set keep alive option. FD(%d), GetLastError=%ld\n", fd, WSAGetLastError());
+        return;
+    }
+
+    LOG_INFO("Success to set keep alive option. FD(%d), onoff=%d, idle=%d(sec), interval=%d(sec)\n", onoff, idle, interval);
+}
+
 static void _sdb_sleep_ms(int mseconds) {
     Sleep(mseconds);
 }
@@ -1086,6 +1127,7 @@ const struct utils_os_backend utils_windows_backend = {
     .sdb_transport_close = _sdb_transport_close,
     .sdb_close = _sdb_close,
     .close_on_exec = _close_on_exec,
+    .keep_alive = _keep_alive,
     .sdb_mkdir = _sdb_mkdir,
     .sdb_socket_accept = _sdb_socket_accept,
     .sdb_socketpair = _sdb_socketpair,