From: Kim Gunsoo Date: Fri, 6 Nov 2015 09:46:25 +0000 (+0900) Subject: Add KEEP_ALIVE option to the socket connected with sdbd. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db4d63aa3726317d09704bbebfa8410e54b9ddec;p=sdk%2Ftools%2Fsdb.git Add KEEP_ALIVE option to the socket connected with sdbd. - After connected with sdbd through TCP socket, add KEEP_ALIVE option to the socket. Change-Id: I39d3959db31ce8ad34f75bf735233d0f6d99ac92 Signed-off-by: Kim Gunsoo --- diff --git a/src/sockets.c b/src/sockets.c index cc32135..5e601f4 100755 --- a/src/sockets.c +++ b/src/sockets.c @@ -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); diff --git a/src/transport_local.c b/src/transport_local.c index 79f7c1a..5e4502c 100755 --- a/src/transport_local.c +++ b/src/transport_local.c @@ -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); diff --git a/src/utils.c b/src/utils.c index 683bcb2..0a49f50 100755 --- a/src/utils.c +++ b/src/utils.c @@ -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); diff --git a/src/utils.h b/src/utils.h index a80a584..30cc0b3 100755 --- a/src/utils.h +++ b/src/utils.h @@ -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); diff --git a/src/utils_backend.h b/src/utils_backend.h index ac3b437..efa55de 100755 --- a/src/utils_backend.h +++ b/src/utils_backend.h @@ -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); diff --git a/src/utils_unix.c b/src/utils_unix.c index d3c1719..b05c2c0 100755 --- a/src/utils_unix.c +++ b/src/utils_unix.c @@ -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, diff --git a/src/utils_windows.c b/src/utils_windows.c index 4032ddf..a4ec8b5 100755 --- a/src/utils_windows.c +++ b/src/utils_windows.c @@ -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,