OSDN Git Service

socketoptionにkeepaliveを指定できるようにした。
authorMichiro Hibari <l05102@shibaura-it.ac.jp>
Thu, 8 Oct 2015 08:15:04 +0000 (17:15 +0900)
committerMichiro Hibari <l05102@shibaura-it.ac.jp>
Thu, 8 Oct 2015 08:15:04 +0000 (17:15 +0900)
l7directord.cf の virtualセクションで
socketoptionにkeepaliveを指定できるようになっています。

(l7directord.cf 設定例)
:
snip
:
virtual = XXX.XXX.XXX.XXX:YY
    socketoption = keepalive
:
snip
:

tcp_keepaliveのtimeoutやprobe間隔については
OSの設定をそのまま使っているので、
変更が必要な場合は/etc/sysctl.confに
設定を加えてください。

(sysctl.conf 設定例)
:
snip
:
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 5

l7directord/l7directord
l7vsd/include/tcp_socket.h
l7vsd/include/tcp_socket_option.h
l7vsd/include/tcp_ssl_socket.h
l7vsd/include/virtualservice_element.h
l7vsd/src/l7vsadm.cpp
l7vsd/src/virtualservice_tcp.cpp

index 5bdfc32..35b13eb 100644 (file)
@@ -987,10 +987,10 @@ sub validate_config {
                 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);
                 }
             }
@@ -4953,6 +4953,10 @@ Set TCP_NODELAY option to the Client and RealServer socket.
 
 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.
index c1e0f33..0eef044 100644 (file)
@@ -76,6 +76,17 @@ public:
                                 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
index 1bfbdf3..412643a 100644 (file)
@@ -42,6 +42,10 @@ struct tcp_socket_option_info {
         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)
index 64de5a4..1eda755 100644 (file)
@@ -100,6 +100,17 @@ public:
                                 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
index 11af252..1965b77 100644 (file)
@@ -83,6 +83,7 @@ public:
         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;
 
@@ -105,6 +106,7 @@ public:
                    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),
@@ -134,6 +136,7 @@ public:
                    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),
@@ -177,6 +180,7 @@ public:
                 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;
@@ -219,6 +223,7 @@ public:
                     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 &&
@@ -280,6 +285,7 @@ public:
                     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 &&
@@ -385,6 +391,7 @@ public:
                                     "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; "
@@ -410,6 +417,7 @@ public:
                    % 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
@@ -459,6 +467,7 @@ private:
                 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;
index 3a8070b..abc123b 100644 (file)
@@ -1111,11 +1111,13 @@ bool l7vs::l7vsadm::parse_opt_vs_socket_func(int &pos, int argc, char *argv[])
         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];
@@ -1159,6 +1161,18 @@ bool l7vs::l7vsadm::parse_opt_vs_socket_func(int &pos, int argc, char *argv[])
                                 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;
@@ -2288,7 +2302,7 @@ bool l7vs::l7vsadm::parse_help_func(l7vs::l7vsadm_request::COMMAND_CODE_TAG cmd,
                   "  --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"
@@ -2621,10 +2635,12 @@ void l7vs::l7vsadm::disp_list_verbose()
                                      "    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"));
 
 
index afaede1..7ee4389 100644 (file)
@@ -1861,6 +1861,10 @@ void l7vs::virtualservice_tcp::set_socket_option()
         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)
@@ -1888,6 +1892,13 @@ void l7vs::virtualservice_tcp::set_socket_option()
                 }
         }
 
+        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) {
@@ -1904,6 +1915,8 @@ void l7vs::virtualservice_tcp::set_socket_option()
                                         " nodelay_val[%s]"
                                         " cork_opt[%s]"
                                         " cork_val[%s]"
+                                        " keepalive_opt[%s]"
+                                        " keepalive_val[%s]"
                                         " quickack_opt[%s]"
                                         " quickack_val[%s]");
                 formatter
@@ -1913,6 +1926,8 @@ void l7vs::virtualservice_tcp::set_socket_option()
                 % (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__);