From b475fae56b7d795e82b3d0eb28b77afbbb9d8dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 8 Jul 2013 22:15:56 +0200 Subject: [PATCH] Add uc_set_tcp_keepalive_cfg too set keepalive options --- include/ucore/fd_utils.h | 38 +++++++++++++++++++++++++------ src/fd_utils.c | 48 +++++++++++++++++++++++++++++++++------- 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/include/ucore/fd_utils.h b/include/ucore/fd_utils.h index c2145bc..9c8d178 100644 --- a/include/ucore/fd_utils.h +++ b/include/ucore/fd_utils.h @@ -10,42 +10,66 @@ extern "C" { * @param fd file descriptor * @return 0 on success -1 on failure */ -int set_nonblocking(int fd); +int uc_set_nonblocking(int fd); /** * set the file descriptor to blocking * @param fd file descriptor * @return 0 on success -1 on failure */ -int set_blocking(int fd); +int uc_set_blocking(int fd); /** * set the socket file descriptor to SO_REUSEADDR * @param fd file descriptor * @return 0 on success -1 on failure */ -int set_reuseaddr(int sockfd); +int uc_set_reuseaddr(int sockfd); /** * enable TCP keepalive on the socket * @param fd file descriptor * @return 0 on success -1 on failure */ -int set_tcp_keepalive(int sockfd); +int uc_set_tcp_keepalive(int sockfd); + +struct UCKeepConfig { + /** The maximum number of keepalive probes TCP should + * send before dropping the connection. (TCP_KEEPCNT socket option) + */ + int keepcnt; + /** The time (in seconds) the connection needs to remain + * idle before TCP starts sending keepalive probes (TCP_KEEPIDLE socket option) + */ + int keepidle; + /** The time (in seconds) between individual keepalive probes. + * (TCP_KEEPINTVL socket option) + */ + int keepintvl; +}; + +/** Set the keepalive options on the socket +* This also enables TCP keepalive on the socket +* +* @param fd file descriptor +* @param fd file descriptor +* @return 0 on success -1 on failure +*/ +int uc_set_tcp_keepalive_cfg(int sockfd, const struct UCKeepConfig *cfg); /** * Set the socket send timeout, in miliseconds * @param fd file descriptor * @return 0 on success -1 on failure */ -int set_send_timeout(int sockfd,long timeoutms); +int uc_set_send_timeout(int sockfd,long timeoutms); /** * Set the socket receive timeout, in miliseconds * @param fd file descriptor * @return 0 on success -1 on failure */ -int set_receive_timeout(int sockfd,long timeoutms); +int uc_set_receive_timeout(int sockfd,long timeoutms); /* * Set the IP DSCP (differnetiated services code point) header value @@ -53,7 +77,7 @@ int set_receive_timeout(int sockfd,long timeoutms); * @param fd file descriptor * @return 0 on success -1 on failure */ -int set_ip_dscp(int fd, unsigned int dscp); +int uc_set_ip_dscp(int fd, unsigned int dscp); #ifdef __cplusplus diff --git a/src/fd_utils.c b/src/fd_utils.c index 9e7d539..20c158d 100644 --- a/src/fd_utils.c +++ b/src/fd_utils.c @@ -2,11 +2,12 @@ #include #include #include +#include #include #include #include "ucore/fd_utils.h" -int set_nonblocking(int fd) +int uc_set_nonblocking(int fd) { int flags = fcntl(fd,F_GETFL,NULL); if(flags < 0 ) { @@ -15,7 +16,7 @@ int set_nonblocking(int fd) return fcntl(fd,F_SETFL,flags | O_NONBLOCK); } -int set_blocking(int fd) +int uc_set_blocking(int fd) { int flags = fcntl(fd,F_GETFL,NULL); if(flags < 0 ) { @@ -25,35 +26,66 @@ int set_blocking(int fd) return fcntl(fd,F_SETFL,flags&~O_NONBLOCK); } -int set_reuseaddr(int sockfd) +int uc_set_reuseaddr(int sockfd) { int opt = 1; return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)); } -int set_tcp_keepalive(int sockfd) +int uc_set_tcp_keepalive(int sockfd) { int optval = 1; + return setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)); } +int uc_set_tcp_keepalive_cfg(int sockfd, const struct UCKeepConfig *cfg) +{ + int rc; -int set_send_timeout(int sockfd,long timeoutms) + //first turn on keepalive + rc = uc_set_tcp_keepalive(sockfd); + if (rc != 0) { + return rc; + } + + //set the keepalive options + + rc = setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &cfg->keepcnt, sizeof cfg->keepcnt); + if (rc != 0) { + return rc; + } + + rc = setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &cfg->keepidle, sizeof cfg->keepintvl); + if (rc != 0) { + return rc; + } + + rc = setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &cfg->keepintvl, sizeof cfg->keepintvl); + if (rc != 0) { + return rc; + } + + return 0; +} + + +int uc_set_send_timeout(int sockfd,long timeoutms) { struct timeval so_sndtimeo = {timeoutms/1000,(timeoutms%1000)*1000}; return setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &so_sndtimeo, sizeof(so_sndtimeo)); } -int set_receive_timeout(int sockfd,long timeoutms) +int uc_set_receive_timeout(int sockfd,long timeoutms) { struct timeval so_sndtimeo = {timeoutms/1000,(timeoutms%1000)*1000}; return setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &so_sndtimeo, sizeof(so_sndtimeo)); } -int -set_ip_dscp(int fd, unsigned int dscp) { + +int uc_set_ip_dscp(int fd, unsigned int dscp) { int val; if (dscp > 63) {