config_error($line, 'ERR0124', $config);
}
my @option_value = split /,/, $value;
- # OPTION:transparent,deferaccept,nodelay,cork,quickackon|quickackoff
+ # OPTION:transparent,deferaccept,nodelay,cork,keepalive,quickackon|quickackoff
for my $option (@option_value) {
$option =~ s/ //g;
- if($option !~ /^transparent|deferaccept|nodelay|cork|quickackon|quickackoff$/) {
+ if($option !~ /^transparent|deferaccept|nodelay|cork|keepalive|quickackon|quickackoff$/) {
config_error($line, 'ERR0124', $config);
}
}
Set TCP_CORK option to the Client and RealServer socket.
+=item B<keepalive>
+
+Set SO_KEEPALIVE option to the Client and RealServer socket.
+
=item B<quickackon> or B<quickackoff>
Set or unset TCP_QUICKACK option to the Client and RealServer socket.
Logger::putLogError(LOG_CAT_L7VSD_SESSION, 101, fmt.str(), __FILE__, __LINE__);
}
}
+ // set TCP_KEEPALIVE option
+ if (opt_info.keepalive_opt) {
+ int val = opt_info.keepalive_val;
+ int err = ::setsockopt(my_socket->native(), SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int));
+ if (unlikely(err)) {
+ error_code = boost::system::error_code(errno, boost::asio::error::get_system_category());
+ boost::format fmt("Thread ID[%d] socket option(SO_KEEPALIVE) set failed");
+ fmt % boost::this_thread::get_id();
+ Logger::putLogError(LOG_CAT_L7VSD_SESSION, 102, fmt.str(), __FILE__, __LINE__);
+ }
+ }
}
// connect
bool cork_opt;
//! TCP_CORK option value (false:off,true:on)
bool cork_val;
+ //! TCP_KEEPALIVE (false:not set,true:set option)
+ bool keepalive_opt;
+ //! TCP_KEEPALIVE option value (false:off,true:on)
+ bool keepalive_val;
//! TCP_QUICKACK (false:not set,true:set option)
bool quickack_opt;
//! TCP_QUICKACK option value (false:off,true:on)
Logger::putLogError(LOG_CAT_L7VSD_SESSION, 101, fmt.str(), __FILE__, __LINE__);
}
}
+ // set TCP_KEEPALIVE
+ if (opt_info.keepalive_opt) {
+ int val = opt_info.keepalive_val;
+ int err = ::setsockopt(my_socket->lowest_layer().native(), SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(int));
+ if (unlikely(err)) {
+ error_code = boost::system::error_code(errno, boost::asio::error::get_system_category());
+ boost::format fmt("Thread ID[%d] socket option(SO_KEEPALIVE) set failed");
+ fmt % boost::this_thread::get_id();
+ Logger::putLogError(LOG_CAT_L7VSD_SESSION, 102, fmt.str(), __FILE__, __LINE__);
+ }
+ }
}
// close
int socket_option_tcp_defer_accept;
int socket_option_tcp_nodelay;
int socket_option_tcp_cork;
+ int socket_option_tcp_keepalive;
int socket_option_tcp_quickack;
std::string socket_option_string;
socket_option_tcp_defer_accept(0),
socket_option_tcp_nodelay(0),
socket_option_tcp_cork(0),
+ socket_option_tcp_keepalive(0),
socket_option_tcp_quickack(0),
http_total_count(0ULL),
http_get_count(0ULL),
socket_option_tcp_defer_accept(in.socket_option_tcp_defer_accept),
socket_option_tcp_nodelay(in.socket_option_tcp_nodelay),
socket_option_tcp_cork(in.socket_option_tcp_cork),
+ socket_option_tcp_keepalive(in.socket_option_tcp_keepalive),
socket_option_tcp_quickack(in.socket_option_tcp_quickack),
socket_option_string(in.socket_option_string),
http_total_count(in.http_total_count),
socket_option_tcp_defer_accept = in.socket_option_tcp_defer_accept;
socket_option_tcp_nodelay = in.socket_option_tcp_nodelay;
socket_option_tcp_cork = in.socket_option_tcp_cork;
+ socket_option_tcp_keepalive = in.socket_option_tcp_keepalive;
socket_option_tcp_quickack = in.socket_option_tcp_quickack;
socket_option_string = in.socket_option_string;
http_total_count = in.http_total_count;
elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept &&
elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay &&
elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork &&
+ elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive &&
elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack &&
elem1.socket_option_string == elem2.socket_option_string &&
elem1.http_total_count == elem2.http_total_count &&
elem1.socket_option_tcp_defer_accept == elem2.socket_option_tcp_defer_accept &&
elem1.socket_option_tcp_nodelay == elem2.socket_option_tcp_nodelay &&
elem1.socket_option_tcp_cork == elem2.socket_option_tcp_cork &&
+ elem1.socket_option_tcp_keepalive == elem2.socket_option_tcp_keepalive &&
elem1.socket_option_tcp_quickack == elem2.socket_option_tcp_quickack &&
elem1.socket_option_string == elem2.socket_option_string &&
elem1.http_total_count == elem2.http_total_count &&
"socket_option_tcp_defer_accept=%d, "
"socket_option_tcp_nodelay=%d, "
"socket_option_tcp_cork=%d, "
+ "socket_option_tcp_keepalive=%d, "
"socket_option_tcp_quickack=%d, "
"socket_option_string=%s; "
"http_total_count=%d; "
% elem.socket_option_tcp_defer_accept
% elem.socket_option_tcp_nodelay
% elem.socket_option_tcp_cork
+ % elem.socket_option_tcp_keepalive
% elem.socket_option_tcp_quickack
% elem.socket_option_string
% elem.http_total_count
ar &socket_option_tcp_defer_accept;
ar &socket_option_tcp_nodelay;
ar &socket_option_tcp_cork;
+ ar &socket_option_tcp_keepalive;
ar &socket_option_tcp_quickack;
ar &socket_option_string;
ar &http_total_count;
bool is_set_defer_accept = false;
bool is_set_nodelay = false;
bool is_set_cork = false;
+ bool is_set_keepalive = false;
bool is_set_quickack = false;
request.vs_element.socket_option_tcp_defer_accept = 0;
request.vs_element.socket_option_tcp_nodelay = 0;
request.vs_element.socket_option_tcp_cork = 0;
+ request.vs_element.socket_option_tcp_keepalive = 0;
request.vs_element.socket_option_tcp_quickack = 0;
std::string socket_option_string = argv[pos];
Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 105, buf.str(), __FILE__, __LINE__);
return false;
}
+ } else if (option == "keepalive") {
+ if (!is_set_keepalive) {
+ is_set_keepalive = true;
+ request.vs_element.socket_option_tcp_keepalive = 1;
+ } else {
+ // keepalive is duplicated
+ std::stringstream buf;
+ buf << "socket option keepalive is duplicated.(--sockopt)";
+ l7vsadm_err.setter(true, buf.str());
+ Logger::putLogError(LOG_CAT_L7VSADM_PARSE, 108, buf.str(), __FILE__, __LINE__);
+ return false;
+ }
} else if (option == "quickackon" || option == "quickackoff") {
if (!is_set_quickack) {
is_set_quickack = true;
" --qos-up -Q QoSval-up QoS Threshold(bps) set to real server direction\n"
" --qos-down -q QoSval-down QoS Threshold(bps) set to client direction\n"
" --ssl -z ssl-config-file SSL configuration file(Use SSL)\n"
- " --sockopt -O socket-option deferaccept,nodelay,cork,quickackon or quickackoff set to socket option\n"
+ " --sockopt -O socket-option deferaccept,nodelay,cork,keepalive,quickackon or quickackoff set to socket option\n"
" --access-log -L access-log-flag access log flag 0(none) or 1(output)\n"
" --access-log-name -a access-log-file access log file\n"
" [logrotate-args]\n"
" TCP_DEFER_ACCEPT %s\n"
" TCP_NODELAY %s\n"
" TCP_CORK %s\n"
+ " TCP_KEEPALIVE %s\n"
" TCP_QUICKACK %s\n")
% ((0 == vse.socket_option_tcp_defer_accept) ? "disable" : "enable")
% ((0 == vse.socket_option_tcp_nodelay) ? "disable" : "enable")
% ((0 == vse.socket_option_tcp_cork) ? "disable" : "enable")
+ % ((0 == vse.socket_option_tcp_keepalive) ? "disable" : "enable")
% ((0 == vse.socket_option_tcp_quickack) ? "auto" : ((1 == vse.socket_option_tcp_quickack) ? "enable" : "disable"));
set_sock_opt.cork_opt = false;
//! TCP_CORK option value (false:off,true:on)
set_sock_opt.cork_val = false;
+ //! TCP_KEEPALIVE (false:not set,true:set option)
+ set_sock_opt.keepalive_opt = false;
+ //! TCP_KEEPALIVE option value (false:off,true:on)
+ set_sock_opt.keepalive_val = false;
//! TCP_QUICKACK (false:not set,true:set option)
set_sock_opt.quickack_opt = false;
//! TCP_QUICKACK option value (false:off,true:on)
}
}
+ if (element.socket_option_tcp_keepalive != 0) {
+ set_sock_opt.keepalive_opt = true;
+ if (element.socket_option_tcp_keepalive == 1) {
+ set_sock_opt.keepalive_val = true;
+ }
+ }
+
if (element.socket_option_tcp_quickack != 0) {
set_sock_opt.quickack_opt = true;
if (element.socket_option_tcp_quickack == 1) {
" nodelay_val[%s]"
" cork_opt[%s]"
" cork_val[%s]"
+ " keepalive_opt[%s]"
+ " keepalive_val[%s]"
" quickack_opt[%s]"
" quickack_val[%s]");
formatter
% (set_sock_opt.nodelay_val ? "true" : "false")
% (set_sock_opt.cork_opt ? "true" : "false")
% (set_sock_opt.cork_val ? "true" : "false")
+ % (set_sock_opt.keepalive_opt ? "true" : "false")
+ % (set_sock_opt.keepalive_val ? "true" : "false")
% (set_sock_opt.quickack_opt ? "true" : "false")
% (set_sock_opt.quickack_val ? "true" : "false");
Logger::putLogDebug(LOG_CAT_L7VSD_VIRTUALSERVICE, 97, formatter.str(), __FILE__, __LINE__);