tcp: use dynamic config framework, part 1
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Thu, 5 Mar 2009 17:20:22 +0000 (17:20 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Thu, 5 Mar 2009 17:20:22 +0000 (17:20 +0000)
- all tcp config variables from tcp_options.h migrated to the
  dynamic configuration framework. For now all are read only, but
  write support will come soon where it makes sense.
  E.g.: (with the cfg_rpc module loaded)
  $ sercmd cfg.help tcp async
  async mode for writes and connects
  (parameter type is integer)

  $ sercmd cfg.get tcp async
  0

cfg.y
core_cmd.c
main.c
tcp_main.c
tcp_options.c
tcp_options.h
tcp_read.c

diff --git a/cfg.y b/cfg.y
index 8d56371..c52cacb 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -865,7 +865,7 @@ assign_stm:
        | TCP_SOURCE_IPV6 EQUAL error { yyerror("IPv6 address expected"); }
        | TCP_OPT_FD_CACHE EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.fd_cache=$3;
+                       tcp_default_cfg.fd_cache=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -873,7 +873,7 @@ assign_stm:
        | TCP_OPT_FD_CACHE EQUAL error { yyerror("boolean value expected"); }
        | TCP_OPT_BUF_WRITE EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.tcp_buf_write=$3;
+                       tcp_default_cfg.tcp_buf_write=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -881,7 +881,7 @@ assign_stm:
        | TCP_OPT_BUF_WRITE EQUAL error { yyerror("boolean value expected"); }
        | TCP_OPT_CONN_WQ_MAX EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.tcpconn_wq_max=$3;
+                       tcp_default_cfg.tcpconn_wq_max=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -889,7 +889,7 @@ assign_stm:
        | TCP_OPT_CONN_WQ_MAX error { yyerror("boolean value expected"); }
        | TCP_OPT_WQ_MAX EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.tcp_wq_max=$3;
+                       tcp_default_cfg.tcp_wq_max=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -897,7 +897,7 @@ assign_stm:
        | TCP_OPT_WQ_MAX error { yyerror("boolean value expected"); }
        | TCP_OPT_DEFER_ACCEPT EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.defer_accept=$3;
+                       tcp_default_cfg.defer_accept=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -905,7 +905,7 @@ assign_stm:
        | TCP_OPT_DEFER_ACCEPT EQUAL error { yyerror("boolean value expected"); }
        | TCP_OPT_DELAYED_ACK EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.delayed_ack=$3;
+                       tcp_default_cfg.delayed_ack=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -913,7 +913,7 @@ assign_stm:
        | TCP_OPT_DELAYED_ACK EQUAL error { yyerror("boolean value expected"); }
        | TCP_OPT_SYNCNT EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.syncnt=$3;
+                       tcp_default_cfg.syncnt=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -921,7 +921,7 @@ assign_stm:
        | TCP_OPT_SYNCNT EQUAL error { yyerror("number expected"); }
        | TCP_OPT_LINGER2 EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.linger2=$3;
+                       tcp_default_cfg.linger2=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -929,7 +929,7 @@ assign_stm:
        | TCP_OPT_LINGER2 EQUAL error { yyerror("number expected"); }
        | TCP_OPT_KEEPALIVE EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.keepalive=$3;
+                       tcp_default_cfg.keepalive=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -937,7 +937,7 @@ assign_stm:
        | TCP_OPT_KEEPALIVE EQUAL error { yyerror("boolean value expected");}
        | TCP_OPT_KEEPIDLE EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.keepidle=$3;
+                       tcp_default_cfg.keepidle=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -945,7 +945,7 @@ assign_stm:
        | TCP_OPT_KEEPIDLE EQUAL error { yyerror("number expected"); }
        | TCP_OPT_KEEPINTVL EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.keepintvl=$3;
+                       tcp_default_cfg.keepintvl=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -953,7 +953,7 @@ assign_stm:
        | TCP_OPT_KEEPINTVL EQUAL error { yyerror("number expected"); }
        | TCP_OPT_KEEPCNT EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.keepcnt=$3;
+                       tcp_default_cfg.keepcnt=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
@@ -961,7 +961,7 @@ assign_stm:
        | TCP_OPT_KEEPCNT EQUAL error { yyerror("number expected"); }
        | TCP_OPT_CRLF_PING EQUAL NUMBER {
                #ifdef USE_TCP
-                       tcp_options.crlf_ping=$3;
+                       tcp_default_cfg.crlf_ping=$3;
                #else
                        warn("tcp support not compiled in");
                #endif
index 988a774..fdb66a0 100644 (file)
@@ -560,7 +560,7 @@ static void core_tcp_options(rpc_t* rpc, void* c)
 {
 #ifdef USE_TCP
        void *handle;
-       struct tcp_cfg_options t;
+       struct cfg_group_tcp t;
 
        if (!tcp_disable){
                tcp_options_get(&t);
diff --git a/main.c b/main.c
index e40174a..25d95ce 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1612,6 +1612,10 @@ int main(int argc, char** argv)
                }
        }
 
+       if (endianness_sanity_check() != 0){
+               fprintf(stderr, "BUG: endianness sanity tests failed\n");
+               goto error;
+       }
        if (init_routes()<0) goto error;
        if (init_nonsip_hooks()<0) goto error;
 
@@ -1916,6 +1920,27 @@ try_again:
                goto error;
        if (init_atomic_ops()==-1)
                goto error;
+       if (init_basex() != 0){
+               LOG(L_CRIT, "could not initialize base* framework\n");
+               goto error;
+       }
+       if (cfg_init() < 0) {
+               LOG(L_CRIT, "could not initialize configuration framework\n");
+               goto error;
+       }
+       /* declare the core cfg before the module configs */
+       if (cfg_declare("core", core_cfg_def, &default_core_cfg, cfg_sizeof(core),
+                       &core_cfg)
+       ) {
+               LOG(L_CRIT, "could not declare the core configuration\n");
+               goto error;
+       }
+#ifdef USE_TCP
+       if (tcp_register_cfg()){
+               LOG(L_CRIT, "could not register the tcp configuration\n");
+               goto error;
+       }
+#endif /* USE_TCP */
        /*init timer, before parsing the cfg!*/
        if (init_timer()<0){
                LOG(L_CRIT, "could not initialize timer, exiting...\n");
@@ -1991,27 +2016,6 @@ try_again:
                        set_rt_prio(rt_prio, rt_policy);
 
        
-       if (cfg_init() < 0) {
-               LOG(L_CRIT, "could not initialize configuration framework\n");
-               goto error;
-       }
-       /* declare the core cfg before the module configs */
-       if (cfg_declare("core", core_cfg_def, &default_core_cfg, cfg_sizeof(core),
-                       &core_cfg)
-       ) {
-               LOG(L_CRIT, "could not declare the core configuration\n");
-               goto error;
-       }
-
-       if (endianness_sanity_check() != 0){
-               LOG(L_CRIT, "BUG: endianness sanity tests failed\n");
-               goto error;
-       }
-       if (init_basex() != 0){
-               LOG(L_CRIT, "could not initialize base* framework\n");
-               goto error;
-       }
-       
        if (init_modules() != 0) {
                fprintf(stderr, "ERROR: error while initializing modules\n");
                goto error;
index d9dd7f8..4358345 100644 (file)
@@ -315,7 +315,7 @@ static inline int init_sock_keepalive(int s)
        int optval;
        
 #ifdef HAVE_SO_KEEPALIVE
-       if (tcp_options.keepalive){
+       if (cfg_get(tcp, tcp_cfg, keepalive)){
                optval=1;
                if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval,
                                                sizeof(optval))<0){
@@ -326,8 +326,7 @@ static inline int init_sock_keepalive(int s)
        }
 #endif
 #ifdef HAVE_TCP_KEEPINTVL
-       if (tcp_options.keepintvl){
-               optval=tcp_options.keepintvl;
+       if ((optval=cfg_get(tcp, tcp_cfg, keepintvl))){
                if (setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, &optval,
                                                sizeof(optval))<0){
                        LOG(L_WARN, "WARNING: init_sock_keepalive: failed to set"
@@ -336,8 +335,7 @@ static inline int init_sock_keepalive(int s)
        }
 #endif
 #ifdef HAVE_TCP_KEEPIDLE
-       if (tcp_options.keepidle){
-               optval=tcp_options.keepidle;
+       if ((optval=cfg_get(tcp, tcp_cfg, keepidle))){
                if (setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, &optval,
                                                sizeof(optval))<0){
                        LOG(L_WARN, "WARNING: init_sock_keepalive: failed to set"
@@ -346,8 +344,7 @@ static inline int init_sock_keepalive(int s)
        }
 #endif
 #ifdef HAVE_TCP_KEEPCNT
-       if (tcp_options.keepcnt){
-               optval=tcp_options.keepcnt;
+       if ((optval=cfg_get(tcp, tcp_cfg, keepcnt))){
                if (setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, &optval,
                                                sizeof(optval))<0){
                        LOG(L_WARN, "WARNING: init_sock_keepalive: failed to set"
@@ -394,8 +391,7 @@ static int init_sock_opt(int s)
        }
 #endif /* !TCP_DONT_REUSEADDR */
 #ifdef HAVE_TCP_SYNCNT
-       if (tcp_options.syncnt){
-               optval=tcp_options.syncnt;
+       if ((optval=cfg_get(tcp, tcp_cfg, syncnt))){
                if (setsockopt(s, IPPROTO_TCP, TCP_SYNCNT, &optval,
                                                sizeof(optval))<0){
                        LOG(L_WARN, "WARNING: init_sock_opt: failed to set"
@@ -404,8 +400,7 @@ static int init_sock_opt(int s)
        }
 #endif
 #ifdef HAVE_TCP_LINGER2
-       if (tcp_options.linger2){
-               optval=tcp_options.linger2;
+       if ((optval=cfg_get(tcp, tcp_cfg, linger2))){
                if (setsockopt(s, IPPROTO_TCP, TCP_LINGER2, &optval,
                                                sizeof(optval))<0){
                        LOG(L_WARN, "WARNING: init_sock_opt: failed to set"
@@ -414,7 +409,7 @@ static int init_sock_opt(int s)
        }
 #endif
 #ifdef HAVE_TCP_QUICKACK
-       if (tcp_options.delayed_ack){
+       if (cfg_get(tcp, tcp_cfg, delayed_ack)){
                optval=0; /* reset quick ack => delayed ack */
                if (setsockopt(s, IPPROTO_TCP, TCP_QUICKACK, &optval,
                                                sizeof(optval))<0){
@@ -634,14 +629,15 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
        
        q=&c->wbuf_q;
        t=get_ticks_raw();
-       if (unlikely(   ((q->queued+size)>tcp_options.tcpconn_wq_max) ||
-                                       ((*tcp_total_wq+size)>tcp_options.tcp_wq_max) ||
+       if (unlikely(   ((q->queued+size)>cfg_get(tcp, tcp_cfg, tcpconn_wq_max)) ||
+                                       ((*tcp_total_wq+size)>cfg_get(tcp, tcp_cfg, tcp_wq_max)) ||
                                        (q->first &&
                                        TICKS_LT(q->wr_timeout, t)) )){
                LOG(L_ERR, "ERROR: wbufq_add(%d bytes): write queue full or timeout "
                                        " (%d, total %d, last write %d s ago)\n",
                                        size, q->queued, *tcp_total_wq,
-                                       TICKS_TO_S(t-q->wr_timeout-tcp_options.tcp_wq_timeout));
+                                       TICKS_TO_S(t-q->wr_timeout-
+                                               cfg_get(tcp, tcp_cfg, tcp_wq_timeout)));
 #ifdef USE_DST_BLACKLIST
                if (q->first && TICKS_LT(q->wr_timeout, t) &&
                                cfg_get(core, core_cfg, use_dst_blacklist)){
@@ -665,7 +661,7 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
                q->first=wb;
                q->last_used=0;
                q->offset=0;
-               q->wr_timeout=get_ticks_raw()+tcp_options.tcp_wq_timeout;
+               q->wr_timeout=get_ticks_raw()+cfg_get(tcp, tcp_cfg, tcp_wq_timeout);
        }else{
                wb=q->last;
        }
@@ -713,12 +709,12 @@ inline static int _wbufq_insert(struct  tcp_connection* c, char* data,
        if (likely(q->first==0)) /* if empty, use wbufq_add */
                return _wbufq_add(c, data, size);
        
-       if (unlikely((*tcp_total_wq+size)>tcp_options.tcp_wq_max)){
+       if (unlikely((*tcp_total_wq+size)>cfg_get(tcp, tcp_cfg, tcp_wq_max))){
                LOG(L_ERR, "ERROR: wbufq_insert(%d bytes): write queue full"
                                        " (%d, total %d, last write %d s ago)\n",
                                        size, q->queued, *tcp_total_wq,
                                        TICKS_TO_S(get_ticks_raw()-q->wr_timeout-
-                                                                               tcp_options.tcp_wq_timeout));
+                                                                       cfg_get(tcp, tcp_cfg, tcp_wq_timeout)));
                goto error;
        }
        if (unlikely(q->offset)){
@@ -815,7 +811,7 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
                                atomic_add_int((int*)tcp_total_wq, -n);
                                break;
                        }
-                       q->wr_timeout=t+tcp_options.tcp_wq_timeout;
+                       q->wr_timeout=t+cfg_get(tcp, tcp_cfg, tcp_wq_timeout);
                }else{
                        if (n<0){
                                /* EINTR is handled inside _tcpconn_write_nb */
@@ -1031,7 +1027,7 @@ inline static int tcp_do_connect( union sockaddr_union* server,
        }
        *state=S_CONN_OK;
 #ifdef TCP_BUF_WRITE
-       if (likely(tcp_options.tcp_buf_write)){
+       if (likely(cfg_get(tcp, tcp_cfg, tcp_buf_write))){
 again:
                n=connect(s, &server->s, sockaddru_len(*server));
                if (unlikely(n==-1)){
@@ -1633,7 +1629,7 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
        struct fd_cache_entry* fd_cache_e;
        int use_fd_cache;
        
-       use_fd_cache=tcp_options.fd_cache;
+       use_fd_cache=cfg_get(tcp, tcp_cfg, fd_cache);
        fd_cache_e=0;
 #endif /* TCP_FD_CACHE */
        do_close_fd=1; /* close the fd on exit */
@@ -1682,8 +1678,8 @@ no_id:
                                }
                        }
 #if defined(TCP_CONNECT_WAIT) && defined(TCP_BUF_WRITE)
-                       if (likely(tcp_options.tcp_connect_wait && 
-                                               tcp_options.tcp_buf_write )){
+                       if (likely(cfg_get(tcp, tcp_cfg, tcp_connect_wait) && 
+                                               cfg_get(tcp, tcp_cfg, tcp_buf_write) )){
                                if (unlikely(*tcp_connections_no >= tcp_max_connections)){
                                        LOG(L_ERR, "ERROR: tcp_send %s: maximum number of"
                                                                " connections exceeded (%d/%d)\n",
@@ -1828,7 +1824,8 @@ no_id:
 get_fd:
 #ifdef TCP_BUF_WRITE
                /* if data is already queued, we don't need the fd any more */
-               if (unlikely(tcp_options.tcp_buf_write && (_wbufq_non_empty(c)
+               if (unlikely(cfg_get(tcp, tcp_cfg, tcp_buf_write) &&
+                                               (_wbufq_non_empty(c)
 #ifdef TCP_CONNECT_WAIT
                                                                                                || (c->state==S_CONN_PENDING)
 #endif /* TCP_CONNECT_WAIT */
@@ -1911,7 +1908,7 @@ send_it:
        DBG("tcp_send: sending...\n");
        lock_get(&c->write_lock);
 #ifdef TCP_BUF_WRITE
-       if (likely(tcp_options.tcp_buf_write)){
+       if (likely(cfg_get(tcp, tcp_cfg, tcp_buf_write))){
                if (_wbufq_non_empty(c)
 #ifdef TCP_CONNECT_WAIT
                        || (c->state==S_CONN_PENDING) 
@@ -1946,7 +1943,7 @@ send_it:
        DBG("tcp_send: buf=\n%.*s\n", (int)len, buf);
        if (unlikely(n<(int)len)){
 #ifdef TCP_BUF_WRITE
-               if (tcp_options.tcp_buf_write && 
+               if (cfg_get(tcp, tcp_cfg, tcp_buf_write) && 
                                ((n>=0) || errno==EAGAIN || errno==EWOULDBLOCK)){
                        enable_write_watch=_wbufq_empty(c);
                        if (n<0) n=0;
@@ -2023,7 +2020,7 @@ error:
        
 #ifdef TCP_BUF_WRITE
        lock_release(&c->write_lock);
-       if (likely(tcp_options.tcp_buf_write)){
+       if (likely(cfg_get(tcp, tcp_cfg, tcp_buf_write))){
                if (unlikely(c->state==S_CONN_CONNECT))
                        c->state=S_CONN_OK;
        }
@@ -2137,8 +2134,7 @@ int tcp_init(struct socket_info* sock_info)
        }
 #ifdef HAVE_TCP_DEFER_ACCEPT
        /* linux only */
-       if (tcp_options.defer_accept){
-               optval=tcp_options.defer_accept;
+       if ((optval=cfg_get(tcp, tcp_cfg, defer_accept))){
                if (setsockopt(sock_info->socket, IPPROTO_TCP, TCP_DEFER_ACCEPT,
                                        (void*)&optval, sizeof(optval)) ==-1){
                        LOG(L_WARN, "WARNING: tcp_init: setsockopt TCP_DEFER_ACCEPT %s\n",
@@ -2148,8 +2144,7 @@ int tcp_init(struct socket_info* sock_info)
        }
 #endif /* HAVE_TCP_DEFFER_ACCEPT */
 #ifdef HAVE_TCP_SYNCNT
-       if (tcp_options.syncnt){
-               optval=tcp_options.syncnt;
+       if ((optval=cfg_get(tcp, tcp_cfg, syncnt))){
                if (setsockopt(sock_info->socket, IPPROTO_TCP, TCP_SYNCNT, &optval,
                                                sizeof(optval))<0){
                        LOG(L_WARN, "WARNING: tcp_init: failed to set"
@@ -2158,8 +2153,7 @@ int tcp_init(struct socket_info* sock_info)
        }
 #endif
 #ifdef HAVE_TCP_LINGER2
-       if (tcp_options.linger2){
-               optval=tcp_options.linger2;
+       if ((optval=cfg_get(tcp, tcp_cfg, linger2))){
                if (setsockopt(sock_info->socket, IPPROTO_TCP, TCP_LINGER2, &optval,
                                                sizeof(optval))<0){
                        LOG(L_WARN, "WARNING: tcp_init: failed to set"
@@ -2187,7 +2181,7 @@ int tcp_init(struct socket_info* sock_info)
        }
 #ifdef HAVE_TCP_ACCEPT_FILTER
        /* freebsd */
-       if (tcp_options.defer_accept){
+       if (cfg_get(tcp, tcp_cfg, defer_accept)){
                memset(&afa, 0, sizeof(afa));
                strcpy(afa.af_name, "dataready");
                if (setsockopt(sock_info->socket, SOL_SOCKET, SO_ACCEPTFILTER,
@@ -2224,7 +2218,7 @@ inline static void tcpconn_close_main_fd(struct tcp_connection* tcpconn)
                tls_close(tcpconn, fd);
 #endif
 #ifdef TCP_FD_CACHE
-       if (likely(tcp_options.fd_cache)) shutdown(fd, SHUT_RDWR);
+       if (likely(cfg_get(tcp, tcp_cfg, fd_cache))) shutdown(fd, SHUT_RDWR);
 #endif /* TCP_FD_CACHE */
 close_again:
        if (unlikely(close(fd)<0)){
@@ -2659,7 +2653,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
                        tcpconn->timeout=t+tcp_con_lifetime;
                        crt_timeout=tcp_con_lifetime;
 #ifdef TCP_BUF_WRITE
-                       if (unlikely(tcp_options.tcp_buf_write && 
+                       if (unlikely(cfg_get(tcp, tcp_cfg, tcp_buf_write) && 
                                                        _wbufq_non_empty(tcpconn) )){
                                if (unlikely(TICKS_GE(t, tcpconn->wbuf_q.wr_timeout))){
                                        DBG("handle_tcp_child: wr. timeout on CONN_RELEASE for %p "
@@ -3449,6 +3443,7 @@ static ticks_t tcpconn_main_timeout(ticks_t t, struct timer_ln* tl, void* data)
 {
        struct tcp_connection *c;
        int fd;
+       int tcp_async;
        
        c=(struct tcp_connection*)data; 
        /* or (struct tcp...*)(tl-offset(c->timer)) */
@@ -3460,17 +3455,17 @@ static ticks_t tcpconn_main_timeout(ticks_t t, struct timer_ln* tl, void* data)
                        c->wbuf_q.wr_timeout, TICKS_TO_S(c->wbuf_q.wr_timeout-t),
                        c->wbuf_q.queued);
        
-       if (TICKS_LT(t, c->timeout) && 
-                       (!tcp_options.tcp_buf_write | _wbufq_empty(c) |
-                               TICKS_LT(t, c->wbuf_q.wr_timeout)) ){
-               if (unlikely(tcp_options.tcp_buf_write && _wbufq_non_empty(c)))
+       tcp_async=cfg_get(tcp, tcp_cfg, tcp_buf_write);
+       if (likely(TICKS_LT(t, c->timeout) && ( !tcp_async | _wbufq_empty(c) |
+                                       TICKS_LT(t, c->wbuf_q.wr_timeout)) )){
+               if (unlikely(tcp_async && _wbufq_non_empty(c)))
                        return (ticks_t)MIN_unsigned(c->timeout-t, c->wbuf_q.wr_timeout-t);
                else
                        return (ticks_t)(c->timeout - t);
        }
 #ifdef USE_DST_BLACKLIST
        /* if time out due to write, add it to the blacklist */
-       if (tcp_options.tcp_buf_write && _wbufq_non_empty(c) &&
+       if (tcp_async && _wbufq_non_empty(c) &&
                        TICKS_GE(t, c->wbuf_q.wr_timeout) &&
                        cfg_get(core, core_cfg, use_dst_blacklist))
                dst_blacklist_su((c->state==S_CONN_CONNECT)?  BLST_ERR_CONNECT:
@@ -3561,7 +3556,8 @@ static inline void tcpconn_destroy_all()
                                _tcpconn_rm(c);
                                if (fd>0) {
 #ifdef TCP_FD_CACHE
-                                       if (likely(tcp_options.fd_cache)) shutdown(fd, SHUT_RDWR);
+                                       if (likely(cfg_get(tcp, tcp_cfg, fd_cache)))
+                                               shutdown(fd, SHUT_RDWR);
 #endif /* TCP_FD_CACHE */
                                        close(fd);
                                }
@@ -3605,7 +3601,7 @@ void tcp_main_loop()
                goto error;
        }
 #ifdef TCP_FD_CACHE
-       if (tcp_options.fd_cache) tcp_fd_cache_init();
+       if (cfg_get(tcp, tcp_cfg, fd_cache)) tcp_fd_cache_init();
 #endif /* TCP_FD_CACHE */
        
        /* add all the sockets we listen on for connections */
@@ -3791,6 +3787,10 @@ int init_tcp()
        char* poll_err;
        
        tcp_options_check();
+       if (tcp_cfg==0){
+               BUG("tcp_cfg not initialized\n");
+               goto error;
+       }
        /* init lock */
        tcpconn_lock=lock_alloc();
        if (tcpconn_lock==0){
index 67a8dcd..7612f64 100644 (file)
  * History:
  * --------
  *  2007-11-28  created by andrei
+ *  2009-03-05  use cfg framework (andrei)
  */
 
 #include "tcp_options.h"
 #include "dprint.h"
 #include "globals.h"
 #include "timer_ticks.h"
+#include "cfg/cfg.h"
 
 
-struct tcp_cfg_options tcp_options;
 
+/* default/initial values for tcp config options
+   NOTE: all the options are initialized in init_tcp_options()
+   depending on compile time defines */
+struct cfg_group_tcp tcp_default_cfg;
+#if 0
+{
+       1, /* fd_cache, default on */
+       /* tcp async options */
+       0, /* tcp_buf_write / tcp_async, default off */
+       1, /* tcp_connect_wait - depends on tcp_async */
+       32*1024, /* tcpconn_wq_max - max. write queue len per connection (32k) */
+       10*1024*1024, /* tcp_wq_max - max.  overall queued bytes  (10MB)*/
+       S_TO_TICKS(tcp_send_timeout), /* tcp_wq_timeout - timeout for queued 
+                                                                        writes, depends on tcp_send_timeout */
+       /* tcp socket options */
+       0, /* defer_accept - on/off*/
+       1, /* delayed_ack - delay ack on connect (on/off)*/
+       0, /* syncnt - numbers of SYNs retrs. before giving up (0 = OS default) */
+       0, /* linger2 - lifetime of orphaned FIN_WAIT2 sockets (0 = OS default)*/
+       1, /* keepalive - on/off */
+       0, /* keepidle - idle time (s) before tcp starts sending keepalives */
+       0, /* keepintvl - interval between keep alives (0 = OS default) */
+       0, /* keepcnt - maximum no. of keepalives (0 = OS default)*/
+       
+       /* other options */
+       1 /* crlf_ping - respond to double CRLF ping/keepalive (on/off) */
+       
+};
+#endif
+
+
+
+/* cfg_group_tcp description (for the config framework)*/
+static cfg_def_t tcp_cfg_def[] = {
+       /*   name        , type |input type| chg type, min, max, fixup, proc. cbk 
+             description */
+       { "fd_cache",     CFG_VAR_INT | CFG_READONLY,    0,   1,     0,         0,
+               "file descriptor cache for tcp_send"},
+       /* tcp async options */
+       { "async",        CFG_VAR_INT | CFG_READONLY,    0,   1,      0,         0,
+               "async mode for writes and connects"},
+       { "connect_wait", CFG_VAR_INT | CFG_READONLY,    0,   1,      0,         0,
+               "parallel simultaneous connects to the same dst. (0) or one connect"},
+       { "conn_wq_max",  CFG_VAR_INT | CFG_READONLY,    0, 1024*1024, 0,        0,
+               "maximum bytes queued for write per connection (depends on async)"},
+       { "wq_max",       CFG_VAR_INT | CFG_READONLY,    0,  1<<30,    0,        0,
+               "maximum bytes queued for write allowed globally (depends on async)"},
+       { "wq_timeout",   CFG_VAR_INT | CFG_READONLY,    1,  1<<30,    0,        0,
+               "timeout for queued writes (in ticks, use send_timeout for seconds)"},
+       /* tcp socket options */
+       { "defer_accept", CFG_VAR_INT | CFG_READONLY,    0,   3600,   0,         0,
+               "0/1 on linux, seconds on freebsd (see docs)"},
+       { "delayed_ack",  CFG_VAR_INT | CFG_READONLY,    0,      1,   0,         0,
+               "initial ack will be delayed and sent with the first data segment"},
+       { "syncnt",       CFG_VAR_INT | CFG_READONLY,    0,      1,   0,         0,
+               "number of syn retransmissions before aborting a connect (0=not set)"},
+       { "linger2",      CFG_VAR_INT | CFG_READONLY,    0,   3600,   0,         0,
+               "lifetime of orphaned sockets in FIN_WAIT2 state in s (0=not set)"},
+       { "keepalive",    CFG_VAR_INT | CFG_READONLY,    0,      1,   0,         0,
+               "enables/disables keepalives for tcp"},
+       { "keepidle",     CFG_VAR_INT | CFG_READONLY,    0, 24*3600,  0,         0,
+               "time before sending a keepalive if the connection is idle (linux)"},
+       { "keepintvl",    CFG_VAR_INT | CFG_READONLY,    0, 24*3600,  0,         0,
+               "time interval between keepalive probes on failure (linux)"},
+       { "keepcnt",     CFG_VAR_INT | CFG_READONLY,    0,    1<<10,  0,         0,
+               "number of failed keepalives before dropping the connection (linux)"},
+       /* other options */
+       { "crlf_ping",   CFG_VAR_INT | CFG_READONLY,    0,        1,  0,         0,
+               "enable responding to CRLF SIP-level keepalives "},
+       {0, 0, 0, 0, 0, 0, 0}
+};
+
+
+void* tcp_cfg; /* tcp config handle */
 
 /* set defaults */
 void init_tcp_options()
 {
 #ifdef TCP_BUF_WRITE
-       tcp_options.tcp_buf_write=0;
-       tcp_options.tcpconn_wq_max=32*1024; /* 32 k */
-       tcp_options.tcp_wq_max=10*1024*1024; /* 10 MB */
-       tcp_options.tcp_wq_timeout=S_TO_TICKS(tcp_send_timeout);
+       tcp_default_cfg.tcp_buf_write=0;
+       tcp_default_cfg.tcpconn_wq_max=32*1024; /* 32 k */
+       tcp_default_cfg.tcp_wq_max=10*1024*1024; /* 10 MB */
+       tcp_default_cfg.tcp_wq_timeout=S_TO_TICKS(tcp_send_timeout);
 #ifdef TCP_CONNECT_WAIT
-       tcp_options.tcp_connect_wait=1;
+       tcp_default_cfg.tcp_connect_wait=1;
 #endif /* TCP_CONNECT_WAIT */
 #endif /* TCP_BUF_WRITE */
 #ifdef TCP_FD_CACHE
-       tcp_options.fd_cache=1;
+       tcp_default_cfg.fd_cache=1;
 #endif
 #ifdef HAVE_SO_KEEPALIVE
-       tcp_options.keepalive=1;
+       tcp_default_cfg.keepalive=1;
 #endif
 /*
 #if defined HAVE_TCP_DEFER_ACCEPT || defined HAVE_TCP_ACCEPT_FILTER
-       tcp_options.defer_accept=1;
+       tcp_default_cfg.defer_accept=1;
 #endif
 */
 #ifdef HAVE_TCP_QUICKACK
-       tcp_options.delayed_ack=1;
+       tcp_default_cfg.delayed_ack=1;
 #endif
-       tcp_options.crlf_ping=1;
+       tcp_default_cfg.crlf_ping=1;
 }
 
 
 
 #define W_OPT_NC(option) \
-       if (tcp_options.option){\
+       if (tcp_default_cfg.option){\
                WARN("tcp_options: tcp_" #option \
                                " cannot be enabled (recompile needed)\n"); \
-               tcp_options.option=0; \
+               tcp_default_cfg.option=0; \
        }
 
 
 
 #define W_OPT_NS(option) \
-       if (tcp_options.option){\
+       if (tcp_default_cfg.option){\
                WARN("tcp_options: tcp_" #option \
                                " cannot be enabled (no OS support)\n"); \
-               tcp_options.option=0; \
+               tcp_default_cfg.option=0; \
        }
 
 
@@ -97,10 +172,10 @@ void tcp_options_check()
        W_OPT_NC(tcp_connect_wait);
 #endif /* TCP_CONNECT_WAIT */
        
-       if (tcp_options.tcp_connect_wait && !tcp_options.tcp_buf_write){
+       if (tcp_default_cfg.tcp_connect_wait && !tcp_default_cfg.tcp_buf_write){
                WARN("tcp_options: tcp_connect_wait depends on tcp_buf_write, "
                                " disabling...\n");
-               tcp_options.tcp_connect_wait=0;
+               tcp_default_cfg.tcp_connect_wait=0;
        }
        
 #if ! defined HAVE_TCP_DEFER_ACCEPT && ! defined HAVE_TCP_ACCEPT_FILTER
@@ -121,8 +196,9 @@ void tcp_options_check()
 #ifndef HAVE_TCP_KEEPCNT
        W_OPT_NS(keepcnt);
 #endif
-       if (tcp_options.keepintvl || tcp_options.keepidle || tcp_options.keepcnt){
-               tcp_options.keepalive=1; /* force on */
+       if (tcp_default_cfg.keepintvl || tcp_default_cfg.keepidle || 
+                       tcp_default_cfg.keepcnt){
+               tcp_default_cfg.keepalive=1; /* force on */
        }
 #ifndef HAVE_SO_KEEPALIVE
        W_OPT_NS(keepalive);
@@ -134,7 +210,23 @@ void tcp_options_check()
 
 
 
-void tcp_options_get(struct tcp_cfg_options* t)
+void tcp_options_get(struct cfg_group_tcp* t)
 {
-       *t=tcp_options;
+       *t=tcp_default_cfg;
+}
+
+
+
+/** register tcp config into the configuration framework.
+ *  @return 0 on succes, -1 on error*/
+int tcp_register_cfg()
+{
+       if (cfg_declare("tcp", tcp_cfg_def, &tcp_default_cfg, cfg_sizeof(tcp),
+                                       &tcp_cfg))
+               return -1;
+       if (tcp_cfg==0){
+               BUG("null tcp cfg");
+               return -1;
+       }
+       return 0;
 }
index de876c5..f7a243a 100644 (file)
 
 #endif /* USE_TCP */
 
-struct tcp_cfg_options{
+struct cfg_group_tcp{
        /* ser tcp options */
        int fd_cache; /* on /off */
-       /* tcp buf. write options */
+       /* tcp async options */
        int tcp_buf_write; /* on / off */
        int tcp_connect_wait; /* on / off, depends on tcp_buf_write */
        unsigned int tcpconn_wq_max; /* maximum queue len per connection */
        unsigned int tcp_wq_max; /* maximum overall queued bytes */
-       unsigned int tcp_wq_timeout;      /* timeout for queue writes */
+       unsigned int tcp_wq_timeout;      /* timeout for queued writes */
 
        /* tcp socket options */
        int defer_accept; /* on / off */
@@ -128,14 +128,20 @@ struct tcp_cfg_options{
        int keepidle;   /* idle time (s) before tcp starts sending keepalives */
        int keepintvl;  /* interval between keep alives */
        int keepcnt;    /* maximum no. of keepalives before giving up */
+       
+       /* other options */
        int crlf_ping;  /* on/off - reply to double CRLF keepalives */
 };
 
+extern struct cfg_group_tcp tcp_default_cfg;
+
+/* tcp config handle*/
+extern void* tcp_cfg;
 
-extern struct tcp_cfg_options tcp_options;
 
 void init_tcp_options();
 void tcp_options_check();
-void tcp_options_get(struct tcp_cfg_options* t);
+int tcp_register_cfg();
+void tcp_options_get(struct cfg_group_tcp* t);
 
 #endif /* tcp_options_h */
index a1b2117..d58d73d 100644 (file)
@@ -351,7 +351,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
                                        case '\n':
                                                break;
                                        case '\r':
-                                               if (tcp_options.crlf_ping) {
+                                               if (cfg_get(tcp, tcp_cfg, crlf_ping)) {
                                                        r->state=H_SKIP_EMPTY_CR_FOUND;
                                                        r->start=p;
                                                }