Browse code

tcp: use dynamic config framework, part 1

- 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

Andrei Pelinescu-Onciul authored on 05/03/2009 17:20:22
Showing 7 changed files
... ...
@@ -865,7 +865,7 @@ assign_stm:
865 865
 	| TCP_SOURCE_IPV6 EQUAL error { yyerror("IPv6 address expected"); }
866 866
 	| TCP_OPT_FD_CACHE EQUAL NUMBER {
867 867
 		#ifdef USE_TCP
868
-			tcp_options.fd_cache=$3;
868
+			tcp_default_cfg.fd_cache=$3;
869 869
 		#else
870 870
 			warn("tcp support not compiled in");
871 871
 		#endif
... ...
@@ -873,7 +873,7 @@ assign_stm:
873 873
 	| TCP_OPT_FD_CACHE EQUAL error { yyerror("boolean value expected"); }
874 874
 	| TCP_OPT_BUF_WRITE EQUAL NUMBER {
875 875
 		#ifdef USE_TCP
876
-			tcp_options.tcp_buf_write=$3;
876
+			tcp_default_cfg.tcp_buf_write=$3;
877 877
 		#else
878 878
 			warn("tcp support not compiled in");
879 879
 		#endif
... ...
@@ -881,7 +881,7 @@ assign_stm:
881 881
 	| TCP_OPT_BUF_WRITE EQUAL error { yyerror("boolean value expected"); }
882 882
 	| TCP_OPT_CONN_WQ_MAX EQUAL NUMBER {
883 883
 		#ifdef USE_TCP
884
-			tcp_options.tcpconn_wq_max=$3;
884
+			tcp_default_cfg.tcpconn_wq_max=$3;
885 885
 		#else
886 886
 			warn("tcp support not compiled in");
887 887
 		#endif
... ...
@@ -889,7 +889,7 @@ assign_stm:
889 889
 	| TCP_OPT_CONN_WQ_MAX error { yyerror("boolean value expected"); }
890 890
 	| TCP_OPT_WQ_MAX EQUAL NUMBER {
891 891
 		#ifdef USE_TCP
892
-			tcp_options.tcp_wq_max=$3;
892
+			tcp_default_cfg.tcp_wq_max=$3;
893 893
 		#else
894 894
 			warn("tcp support not compiled in");
895 895
 		#endif
... ...
@@ -897,7 +897,7 @@ assign_stm:
897 897
 	| TCP_OPT_WQ_MAX error { yyerror("boolean value expected"); }
898 898
 	| TCP_OPT_DEFER_ACCEPT EQUAL NUMBER {
899 899
 		#ifdef USE_TCP
900
-			tcp_options.defer_accept=$3;
900
+			tcp_default_cfg.defer_accept=$3;
901 901
 		#else
902 902
 			warn("tcp support not compiled in");
903 903
 		#endif
... ...
@@ -905,7 +905,7 @@ assign_stm:
905 905
 	| TCP_OPT_DEFER_ACCEPT EQUAL error { yyerror("boolean value expected"); }
906 906
 	| TCP_OPT_DELAYED_ACK EQUAL NUMBER {
907 907
 		#ifdef USE_TCP
908
-			tcp_options.delayed_ack=$3;
908
+			tcp_default_cfg.delayed_ack=$3;
909 909
 		#else
910 910
 			warn("tcp support not compiled in");
911 911
 		#endif
... ...
@@ -913,7 +913,7 @@ assign_stm:
913 913
 	| TCP_OPT_DELAYED_ACK EQUAL error { yyerror("boolean value expected"); }
914 914
 	| TCP_OPT_SYNCNT EQUAL NUMBER {
915 915
 		#ifdef USE_TCP
916
-			tcp_options.syncnt=$3;
916
+			tcp_default_cfg.syncnt=$3;
917 917
 		#else
918 918
 			warn("tcp support not compiled in");
919 919
 		#endif
... ...
@@ -921,7 +921,7 @@ assign_stm:
921 921
 	| TCP_OPT_SYNCNT EQUAL error { yyerror("number expected"); }
922 922
 	| TCP_OPT_LINGER2 EQUAL NUMBER {
923 923
 		#ifdef USE_TCP
924
-			tcp_options.linger2=$3;
924
+			tcp_default_cfg.linger2=$3;
925 925
 		#else
926 926
 			warn("tcp support not compiled in");
927 927
 		#endif
... ...
@@ -929,7 +929,7 @@ assign_stm:
929 929
 	| TCP_OPT_LINGER2 EQUAL error { yyerror("number expected"); }
930 930
 	| TCP_OPT_KEEPALIVE EQUAL NUMBER {
931 931
 		#ifdef USE_TCP
932
-			tcp_options.keepalive=$3;
932
+			tcp_default_cfg.keepalive=$3;
933 933
 		#else
934 934
 			warn("tcp support not compiled in");
935 935
 		#endif
... ...
@@ -937,7 +937,7 @@ assign_stm:
937 937
 	| TCP_OPT_KEEPALIVE EQUAL error { yyerror("boolean value expected");}
938 938
 	| TCP_OPT_KEEPIDLE EQUAL NUMBER {
939 939
 		#ifdef USE_TCP
940
-			tcp_options.keepidle=$3;
940
+			tcp_default_cfg.keepidle=$3;
941 941
 		#else
942 942
 			warn("tcp support not compiled in");
943 943
 		#endif
... ...
@@ -945,7 +945,7 @@ assign_stm:
945 945
 	| TCP_OPT_KEEPIDLE EQUAL error { yyerror("number expected"); }
946 946
 	| TCP_OPT_KEEPINTVL EQUAL NUMBER {
947 947
 		#ifdef USE_TCP
948
-			tcp_options.keepintvl=$3;
948
+			tcp_default_cfg.keepintvl=$3;
949 949
 		#else
950 950
 			warn("tcp support not compiled in");
951 951
 		#endif
... ...
@@ -953,7 +953,7 @@ assign_stm:
953 953
 	| TCP_OPT_KEEPINTVL EQUAL error { yyerror("number expected"); }
954 954
 	| TCP_OPT_KEEPCNT EQUAL NUMBER {
955 955
 		#ifdef USE_TCP
956
-			tcp_options.keepcnt=$3;
956
+			tcp_default_cfg.keepcnt=$3;
957 957
 		#else
958 958
 			warn("tcp support not compiled in");
959 959
 		#endif
... ...
@@ -961,7 +961,7 @@ assign_stm:
961 961
 	| TCP_OPT_KEEPCNT EQUAL error { yyerror("number expected"); }
962 962
 	| TCP_OPT_CRLF_PING EQUAL NUMBER {
963 963
 		#ifdef USE_TCP
964
-			tcp_options.crlf_ping=$3;
964
+			tcp_default_cfg.crlf_ping=$3;
965 965
 		#else
966 966
 			warn("tcp support not compiled in");
967 967
 		#endif
... ...
@@ -560,7 +560,7 @@ static void core_tcp_options(rpc_t* rpc, void* c)
560 560
 {
561 561
 #ifdef USE_TCP
562 562
 	void *handle;
563
-	struct tcp_cfg_options t;
563
+	struct cfg_group_tcp t;
564 564
 
565 565
 	if (!tcp_disable){
566 566
 		tcp_options_get(&t);
... ...
@@ -1612,6 +1612,10 @@ int main(int argc, char** argv)
1612 1612
 		}
1613 1613
 	}
1614 1614
 
1615
+	if (endianness_sanity_check() != 0){
1616
+		fprintf(stderr, "BUG: endianness sanity tests failed\n");
1617
+		goto error;
1618
+	}
1615 1619
 	if (init_routes()<0) goto error;
1616 1620
 	if (init_nonsip_hooks()<0) goto error;
1617 1621
 
... ...
@@ -1916,6 +1920,27 @@ try_again:
1916 1916
 		goto error;
1917 1917
 	if (init_atomic_ops()==-1)
1918 1918
 		goto error;
1919
+	if (init_basex() != 0){
1920
+		LOG(L_CRIT, "could not initialize base* framework\n");
1921
+		goto error;
1922
+	}
1923
+	if (cfg_init() < 0) {
1924
+		LOG(L_CRIT, "could not initialize configuration framework\n");
1925
+		goto error;
1926
+	}
1927
+	/* declare the core cfg before the module configs */
1928
+	if (cfg_declare("core", core_cfg_def, &default_core_cfg, cfg_sizeof(core),
1929
+			&core_cfg)
1930
+	) {
1931
+		LOG(L_CRIT, "could not declare the core configuration\n");
1932
+		goto error;
1933
+	}
1934
+#ifdef USE_TCP
1935
+	if (tcp_register_cfg()){
1936
+		LOG(L_CRIT, "could not register the tcp configuration\n");
1937
+		goto error;
1938
+	}
1939
+#endif /* USE_TCP */
1919 1940
 	/*init timer, before parsing the cfg!*/
1920 1941
 	if (init_timer()<0){
1921 1942
 		LOG(L_CRIT, "could not initialize timer, exiting...\n");
... ...
@@ -1991,27 +2016,6 @@ try_again:
1991 1991
 			set_rt_prio(rt_prio, rt_policy);
1992 1992
 
1993 1993
 	
1994
-	if (cfg_init() < 0) {
1995
-		LOG(L_CRIT, "could not initialize configuration framework\n");
1996
-		goto error;
1997
-	}
1998
-	/* declare the core cfg before the module configs */
1999
-	if (cfg_declare("core", core_cfg_def, &default_core_cfg, cfg_sizeof(core),
2000
-			&core_cfg)
2001
-	) {
2002
-		LOG(L_CRIT, "could not declare the core configuration\n");
2003
-		goto error;
2004
-	}
2005
-
2006
-	if (endianness_sanity_check() != 0){
2007
-		LOG(L_CRIT, "BUG: endianness sanity tests failed\n");
2008
-		goto error;
2009
-	}
2010
-	if (init_basex() != 0){
2011
-		LOG(L_CRIT, "could not initialize base* framework\n");
2012
-		goto error;
2013
-	}
2014
-	
2015 1994
 	if (init_modules() != 0) {
2016 1995
 		fprintf(stderr, "ERROR: error while initializing modules\n");
2017 1996
 		goto error;
... ...
@@ -315,7 +315,7 @@ static inline int init_sock_keepalive(int s)
315 315
 	int optval;
316 316
 	
317 317
 #ifdef HAVE_SO_KEEPALIVE
318
-	if (tcp_options.keepalive){
318
+	if (cfg_get(tcp, tcp_cfg, keepalive)){
319 319
 		optval=1;
320 320
 		if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval,
321 321
 						sizeof(optval))<0){
... ...
@@ -326,8 +326,7 @@ static inline int init_sock_keepalive(int s)
326 326
 	}
327 327
 #endif
328 328
 #ifdef HAVE_TCP_KEEPINTVL
329
-	if (tcp_options.keepintvl){
330
-		optval=tcp_options.keepintvl;
329
+	if ((optval=cfg_get(tcp, tcp_cfg, keepintvl))){
331 330
 		if (setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, &optval,
332 331
 						sizeof(optval))<0){
333 332
 			LOG(L_WARN, "WARNING: init_sock_keepalive: failed to set"
... ...
@@ -336,8 +335,7 @@ static inline int init_sock_keepalive(int s)
336 336
 	}
337 337
 #endif
338 338
 #ifdef HAVE_TCP_KEEPIDLE
339
-	if (tcp_options.keepidle){
340
-		optval=tcp_options.keepidle;
339
+	if ((optval=cfg_get(tcp, tcp_cfg, keepidle))){
341 340
 		if (setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, &optval,
342 341
 						sizeof(optval))<0){
343 342
 			LOG(L_WARN, "WARNING: init_sock_keepalive: failed to set"
... ...
@@ -346,8 +344,7 @@ static inline int init_sock_keepalive(int s)
346 346
 	}
347 347
 #endif
348 348
 #ifdef HAVE_TCP_KEEPCNT
349
-	if (tcp_options.keepcnt){
350
-		optval=tcp_options.keepcnt;
349
+	if ((optval=cfg_get(tcp, tcp_cfg, keepcnt))){
351 350
 		if (setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, &optval,
352 351
 						sizeof(optval))<0){
353 352
 			LOG(L_WARN, "WARNING: init_sock_keepalive: failed to set"
... ...
@@ -394,8 +391,7 @@ static int init_sock_opt(int s)
394 394
 	}
395 395
 #endif /* !TCP_DONT_REUSEADDR */
396 396
 #ifdef HAVE_TCP_SYNCNT
397
-	if (tcp_options.syncnt){
398
-		optval=tcp_options.syncnt;
397
+	if ((optval=cfg_get(tcp, tcp_cfg, syncnt))){
399 398
 		if (setsockopt(s, IPPROTO_TCP, TCP_SYNCNT, &optval,
400 399
 						sizeof(optval))<0){
401 400
 			LOG(L_WARN, "WARNING: init_sock_opt: failed to set"
... ...
@@ -404,8 +400,7 @@ static int init_sock_opt(int s)
404 404
 	}
405 405
 #endif
406 406
 #ifdef HAVE_TCP_LINGER2
407
-	if (tcp_options.linger2){
408
-		optval=tcp_options.linger2;
407
+	if ((optval=cfg_get(tcp, tcp_cfg, linger2))){
409 408
 		if (setsockopt(s, IPPROTO_TCP, TCP_LINGER2, &optval,
410 409
 						sizeof(optval))<0){
411 410
 			LOG(L_WARN, "WARNING: init_sock_opt: failed to set"
... ...
@@ -414,7 +409,7 @@ static int init_sock_opt(int s)
414 414
 	}
415 415
 #endif
416 416
 #ifdef HAVE_TCP_QUICKACK
417
-	if (tcp_options.delayed_ack){
417
+	if (cfg_get(tcp, tcp_cfg, delayed_ack)){
418 418
 		optval=0; /* reset quick ack => delayed ack */
419 419
 		if (setsockopt(s, IPPROTO_TCP, TCP_QUICKACK, &optval,
420 420
 						sizeof(optval))<0){
... ...
@@ -634,14 +629,15 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
634 634
 	
635 635
 	q=&c->wbuf_q;
636 636
 	t=get_ticks_raw();
637
-	if (unlikely(	((q->queued+size)>tcp_options.tcpconn_wq_max) ||
638
-					((*tcp_total_wq+size)>tcp_options.tcp_wq_max) ||
637
+	if (unlikely(	((q->queued+size)>cfg_get(tcp, tcp_cfg, tcpconn_wq_max)) ||
638
+					((*tcp_total_wq+size)>cfg_get(tcp, tcp_cfg, tcp_wq_max)) ||
639 639
 					(q->first &&
640 640
 					TICKS_LT(q->wr_timeout, t)) )){
641 641
 		LOG(L_ERR, "ERROR: wbufq_add(%d bytes): write queue full or timeout "
642 642
 					" (%d, total %d, last write %d s ago)\n",
643 643
 					size, q->queued, *tcp_total_wq,
644
-					TICKS_TO_S(t-q->wr_timeout-tcp_options.tcp_wq_timeout));
644
+					TICKS_TO_S(t-q->wr_timeout-
645
+						cfg_get(tcp, tcp_cfg, tcp_wq_timeout)));
645 646
 #ifdef USE_DST_BLACKLIST
646 647
 		if (q->first && TICKS_LT(q->wr_timeout, t) &&
647 648
 				cfg_get(core, core_cfg, use_dst_blacklist)){
... ...
@@ -665,7 +661,7 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
665 665
 		q->first=wb;
666 666
 		q->last_used=0;
667 667
 		q->offset=0;
668
-		q->wr_timeout=get_ticks_raw()+tcp_options.tcp_wq_timeout;
668
+		q->wr_timeout=get_ticks_raw()+cfg_get(tcp, tcp_cfg, tcp_wq_timeout);
669 669
 	}else{
670 670
 		wb=q->last;
671 671
 	}
... ...
@@ -713,12 +709,12 @@ inline static int _wbufq_insert(struct  tcp_connection* c, char* data,
713 713
 	if (likely(q->first==0)) /* if empty, use wbufq_add */
714 714
 		return _wbufq_add(c, data, size);
715 715
 	
716
-	if (unlikely((*tcp_total_wq+size)>tcp_options.tcp_wq_max)){
716
+	if (unlikely((*tcp_total_wq+size)>cfg_get(tcp, tcp_cfg, tcp_wq_max))){
717 717
 		LOG(L_ERR, "ERROR: wbufq_insert(%d bytes): write queue full"
718 718
 					" (%d, total %d, last write %d s ago)\n",
719 719
 					size, q->queued, *tcp_total_wq,
720 720
 					TICKS_TO_S(get_ticks_raw()-q->wr_timeout-
721
-										tcp_options.tcp_wq_timeout));
721
+									cfg_get(tcp, tcp_cfg, tcp_wq_timeout)));
722 722
 		goto error;
723 723
 	}
724 724
 	if (unlikely(q->offset)){
... ...
@@ -815,7 +811,7 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
815 815
 				atomic_add_int((int*)tcp_total_wq, -n);
816 816
 				break;
817 817
 			}
818
-			q->wr_timeout=t+tcp_options.tcp_wq_timeout;
818
+			q->wr_timeout=t+cfg_get(tcp, tcp_cfg, tcp_wq_timeout);
819 819
 		}else{
820 820
 			if (n<0){
821 821
 				/* EINTR is handled inside _tcpconn_write_nb */
... ...
@@ -1031,7 +1027,7 @@ inline static int tcp_do_connect(	union sockaddr_union* server,
1031 1031
 	}
1032 1032
 	*state=S_CONN_OK;
1033 1033
 #ifdef TCP_BUF_WRITE
1034
-	if (likely(tcp_options.tcp_buf_write)){
1034
+	if (likely(cfg_get(tcp, tcp_cfg, tcp_buf_write))){
1035 1035
 again:
1036 1036
 		n=connect(s, &server->s, sockaddru_len(*server));
1037 1037
 		if (unlikely(n==-1)){
... ...
@@ -1633,7 +1629,7 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
1633 1633
 	struct fd_cache_entry* fd_cache_e;
1634 1634
 	int use_fd_cache;
1635 1635
 	
1636
-	use_fd_cache=tcp_options.fd_cache;
1636
+	use_fd_cache=cfg_get(tcp, tcp_cfg, fd_cache);
1637 1637
 	fd_cache_e=0;
1638 1638
 #endif /* TCP_FD_CACHE */
1639 1639
 	do_close_fd=1; /* close the fd on exit */
... ...
@@ -1682,8 +1678,8 @@ no_id:
1682 1682
 				}
1683 1683
 			}
1684 1684
 #if defined(TCP_CONNECT_WAIT) && defined(TCP_BUF_WRITE)
1685
-			if (likely(tcp_options.tcp_connect_wait && 
1686
-						tcp_options.tcp_buf_write )){
1685
+			if (likely(cfg_get(tcp, tcp_cfg, tcp_connect_wait) && 
1686
+						cfg_get(tcp, tcp_cfg, tcp_buf_write) )){
1687 1687
 				if (unlikely(*tcp_connections_no >= tcp_max_connections)){
1688 1688
 					LOG(L_ERR, "ERROR: tcp_send %s: maximum number of"
1689 1689
 								" connections exceeded (%d/%d)\n",
... ...
@@ -1828,7 +1824,8 @@ no_id:
1828 1828
 get_fd:
1829 1829
 #ifdef TCP_BUF_WRITE
1830 1830
 		/* if data is already queued, we don't need the fd any more */
1831
-		if (unlikely(tcp_options.tcp_buf_write && (_wbufq_non_empty(c)
1831
+		if (unlikely(cfg_get(tcp, tcp_cfg, tcp_buf_write) &&
1832
+						(_wbufq_non_empty(c)
1832 1833
 #ifdef TCP_CONNECT_WAIT
1833 1834
 												|| (c->state==S_CONN_PENDING)
1834 1835
 #endif /* TCP_CONNECT_WAIT */
... ...
@@ -1911,7 +1908,7 @@ send_it:
1911 1911
 	DBG("tcp_send: sending...\n");
1912 1912
 	lock_get(&c->write_lock);
1913 1913
 #ifdef TCP_BUF_WRITE
1914
-	if (likely(tcp_options.tcp_buf_write)){
1914
+	if (likely(cfg_get(tcp, tcp_cfg, tcp_buf_write))){
1915 1915
 		if (_wbufq_non_empty(c)
1916 1916
 #ifdef TCP_CONNECT_WAIT
1917 1917
 			|| (c->state==S_CONN_PENDING) 
... ...
@@ -1946,7 +1943,7 @@ send_it:
1946 1946
 	DBG("tcp_send: buf=\n%.*s\n", (int)len, buf);
1947 1947
 	if (unlikely(n<(int)len)){
1948 1948
 #ifdef TCP_BUF_WRITE
1949
-		if (tcp_options.tcp_buf_write && 
1949
+		if (cfg_get(tcp, tcp_cfg, tcp_buf_write) && 
1950 1950
 				((n>=0) || errno==EAGAIN || errno==EWOULDBLOCK)){
1951 1951
 			enable_write_watch=_wbufq_empty(c);
1952 1952
 			if (n<0) n=0;
... ...
@@ -2023,7 +2020,7 @@ error:
2023 2023
 	
2024 2024
 #ifdef TCP_BUF_WRITE
2025 2025
 	lock_release(&c->write_lock);
2026
-	if (likely(tcp_options.tcp_buf_write)){
2026
+	if (likely(cfg_get(tcp, tcp_cfg, tcp_buf_write))){
2027 2027
 		if (unlikely(c->state==S_CONN_CONNECT))
2028 2028
 			c->state=S_CONN_OK;
2029 2029
 	}
... ...
@@ -2137,8 +2134,7 @@ int tcp_init(struct socket_info* sock_info)
2137 2137
 	}
2138 2138
 #ifdef HAVE_TCP_DEFER_ACCEPT
2139 2139
 	/* linux only */
2140
-	if (tcp_options.defer_accept){
2141
-		optval=tcp_options.defer_accept;
2140
+	if ((optval=cfg_get(tcp, tcp_cfg, defer_accept))){
2142 2141
 		if (setsockopt(sock_info->socket, IPPROTO_TCP, TCP_DEFER_ACCEPT,
2143 2142
 					(void*)&optval, sizeof(optval)) ==-1){
2144 2143
 			LOG(L_WARN, "WARNING: tcp_init: setsockopt TCP_DEFER_ACCEPT %s\n",
... ...
@@ -2148,8 +2144,7 @@ int tcp_init(struct socket_info* sock_info)
2148 2148
 	}
2149 2149
 #endif /* HAVE_TCP_DEFFER_ACCEPT */
2150 2150
 #ifdef HAVE_TCP_SYNCNT
2151
-	if (tcp_options.syncnt){
2152
-		optval=tcp_options.syncnt;
2151
+	if ((optval=cfg_get(tcp, tcp_cfg, syncnt))){
2153 2152
 		if (setsockopt(sock_info->socket, IPPROTO_TCP, TCP_SYNCNT, &optval,
2154 2153
 						sizeof(optval))<0){
2155 2154
 			LOG(L_WARN, "WARNING: tcp_init: failed to set"
... ...
@@ -2158,8 +2153,7 @@ int tcp_init(struct socket_info* sock_info)
2158 2158
 	}
2159 2159
 #endif
2160 2160
 #ifdef HAVE_TCP_LINGER2
2161
-	if (tcp_options.linger2){
2162
-		optval=tcp_options.linger2;
2161
+	if ((optval=cfg_get(tcp, tcp_cfg, linger2))){
2163 2162
 		if (setsockopt(sock_info->socket, IPPROTO_TCP, TCP_LINGER2, &optval,
2164 2163
 						sizeof(optval))<0){
2165 2164
 			LOG(L_WARN, "WARNING: tcp_init: failed to set"
... ...
@@ -2187,7 +2181,7 @@ int tcp_init(struct socket_info* sock_info)
2187 2187
 	}
2188 2188
 #ifdef HAVE_TCP_ACCEPT_FILTER
2189 2189
 	/* freebsd */
2190
-	if (tcp_options.defer_accept){
2190
+	if (cfg_get(tcp, tcp_cfg, defer_accept)){
2191 2191
 		memset(&afa, 0, sizeof(afa));
2192 2192
 		strcpy(afa.af_name, "dataready");
2193 2193
 		if (setsockopt(sock_info->socket, SOL_SOCKET, SO_ACCEPTFILTER,
... ...
@@ -2224,7 +2218,7 @@ inline static void tcpconn_close_main_fd(struct tcp_connection* tcpconn)
2224 2224
 		tls_close(tcpconn, fd);
2225 2225
 #endif
2226 2226
 #ifdef TCP_FD_CACHE
2227
-	if (likely(tcp_options.fd_cache)) shutdown(fd, SHUT_RDWR);
2227
+	if (likely(cfg_get(tcp, tcp_cfg, fd_cache))) shutdown(fd, SHUT_RDWR);
2228 2228
 #endif /* TCP_FD_CACHE */
2229 2229
 close_again:
2230 2230
 	if (unlikely(close(fd)<0)){
... ...
@@ -2659,7 +2653,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
2659 2659
 			tcpconn->timeout=t+tcp_con_lifetime;
2660 2660
 			crt_timeout=tcp_con_lifetime;
2661 2661
 #ifdef TCP_BUF_WRITE
2662
-			if (unlikely(tcp_options.tcp_buf_write && 
2662
+			if (unlikely(cfg_get(tcp, tcp_cfg, tcp_buf_write) && 
2663 2663
 							_wbufq_non_empty(tcpconn) )){
2664 2664
 				if (unlikely(TICKS_GE(t, tcpconn->wbuf_q.wr_timeout))){
2665 2665
 					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)
3449 3449
 {
3450 3450
 	struct tcp_connection *c;
3451 3451
 	int fd;
3452
+	int tcp_async;
3452 3453
 	
3453 3454
 	c=(struct tcp_connection*)data; 
3454 3455
 	/* 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)
3460 3460
 			c->wbuf_q.wr_timeout, TICKS_TO_S(c->wbuf_q.wr_timeout-t),
3461 3461
 			c->wbuf_q.queued);
3462 3462
 	
3463
-	if (TICKS_LT(t, c->timeout) && 
3464
-			(!tcp_options.tcp_buf_write | _wbufq_empty(c) |
3465
-				TICKS_LT(t, c->wbuf_q.wr_timeout)) ){
3466
-		if (unlikely(tcp_options.tcp_buf_write && _wbufq_non_empty(c)))
3463
+	tcp_async=cfg_get(tcp, tcp_cfg, tcp_buf_write);
3464
+	if (likely(TICKS_LT(t, c->timeout) && ( !tcp_async | _wbufq_empty(c) |
3465
+					TICKS_LT(t, c->wbuf_q.wr_timeout)) )){
3466
+		if (unlikely(tcp_async && _wbufq_non_empty(c)))
3467 3467
 			return (ticks_t)MIN_unsigned(c->timeout-t, c->wbuf_q.wr_timeout-t);
3468 3468
 		else
3469 3469
 			return (ticks_t)(c->timeout - t);
3470 3470
 	}
3471 3471
 #ifdef USE_DST_BLACKLIST
3472 3472
 	/* if time out due to write, add it to the blacklist */
3473
-	if (tcp_options.tcp_buf_write && _wbufq_non_empty(c) &&
3473
+	if (tcp_async && _wbufq_non_empty(c) &&
3474 3474
 			TICKS_GE(t, c->wbuf_q.wr_timeout) &&
3475 3475
 			cfg_get(core, core_cfg, use_dst_blacklist))
3476 3476
 		dst_blacklist_su((c->state==S_CONN_CONNECT)?  BLST_ERR_CONNECT:
... ...
@@ -3561,7 +3556,8 @@ static inline void tcpconn_destroy_all()
3561 3561
 				_tcpconn_rm(c);
3562 3562
 				if (fd>0) {
3563 3563
 #ifdef TCP_FD_CACHE
3564
-					if (likely(tcp_options.fd_cache)) shutdown(fd, SHUT_RDWR);
3564
+					if (likely(cfg_get(tcp, tcp_cfg, fd_cache)))
3565
+						shutdown(fd, SHUT_RDWR);
3565 3566
 #endif /* TCP_FD_CACHE */
3566 3567
 					close(fd);
3567 3568
 				}
... ...
@@ -3605,7 +3601,7 @@ void tcp_main_loop()
3605 3605
 		goto error;
3606 3606
 	}
3607 3607
 #ifdef TCP_FD_CACHE
3608
-	if (tcp_options.fd_cache) tcp_fd_cache_init();
3608
+	if (cfg_get(tcp, tcp_cfg, fd_cache)) tcp_fd_cache_init();
3609 3609
 #endif /* TCP_FD_CACHE */
3610 3610
 	
3611 3611
 	/* add all the sockets we listen on for connections */
... ...
@@ -3791,6 +3787,10 @@ int init_tcp()
3791 3791
 	char* poll_err;
3792 3792
 	
3793 3793
 	tcp_options_check();
3794
+	if (tcp_cfg==0){
3795
+		BUG("tcp_cfg not initialized\n");
3796
+		goto error;
3797
+	}
3794 3798
 	/* init lock */
3795 3799
 	tcpconn_lock=lock_alloc();
3796 3800
 	if (tcpconn_lock==0){
... ...
@@ -21,62 +21,137 @@
21 21
  * History:
22 22
  * --------
23 23
  *  2007-11-28  created by andrei
24
+ *  2009-03-05  use cfg framework (andrei)
24 25
  */
25 26
 
26 27
 #include "tcp_options.h"
27 28
 #include "dprint.h"
28 29
 #include "globals.h"
29 30
 #include "timer_ticks.h"
31
+#include "cfg/cfg.h"
30 32
 
31 33
 
32
-struct tcp_cfg_options tcp_options;
33 34
 
35
+/* default/initial values for tcp config options
36
+   NOTE: all the options are initialized in init_tcp_options()
37
+   depending on compile time defines */
38
+struct cfg_group_tcp tcp_default_cfg;
39
+#if 0
40
+{
41
+	1, /* fd_cache, default on */
42
+	/* tcp async options */
43
+	0, /* tcp_buf_write / tcp_async, default off */
44
+	1, /* tcp_connect_wait - depends on tcp_async */
45
+	32*1024, /* tcpconn_wq_max - max. write queue len per connection (32k) */
46
+	10*1024*1024, /* tcp_wq_max - max.  overall queued bytes  (10MB)*/
47
+	S_TO_TICKS(tcp_send_timeout), /* tcp_wq_timeout - timeout for queued 
48
+									 writes, depends on tcp_send_timeout */
49
+	/* tcp socket options */
50
+	0, /* defer_accept - on/off*/
51
+	1, /* delayed_ack - delay ack on connect (on/off)*/
52
+	0, /* syncnt - numbers of SYNs retrs. before giving up (0 = OS default) */
53
+	0, /* linger2 - lifetime of orphaned FIN_WAIT2 sockets (0 = OS default)*/
54
+	1, /* keepalive - on/off */
55
+	0, /* keepidle - idle time (s) before tcp starts sending keepalives */
56
+	0, /* keepintvl - interval between keep alives (0 = OS default) */
57
+	0, /* keepcnt - maximum no. of keepalives (0 = OS default)*/
58
+	
59
+	/* other options */
60
+	1 /* crlf_ping - respond to double CRLF ping/keepalive (on/off) */
61
+	
62
+};
63
+#endif
64
+
65
+
66
+
67
+/* cfg_group_tcp description (for the config framework)*/
68
+static cfg_def_t tcp_cfg_def[] = {
69
+	/*   name        , type |input type| chg type, min, max, fixup, proc. cbk 
70
+	      description */
71
+	{ "fd_cache",     CFG_VAR_INT | CFG_READONLY,    0,   1,     0,         0,
72
+		"file descriptor cache for tcp_send"},
73
+	/* tcp async options */
74
+	{ "async",        CFG_VAR_INT | CFG_READONLY,    0,   1,      0,         0,
75
+		"async mode for writes and connects"},
76
+	{ "connect_wait", CFG_VAR_INT | CFG_READONLY,    0,   1,      0,         0,
77
+		"parallel simultaneous connects to the same dst. (0) or one connect"},
78
+	{ "conn_wq_max",  CFG_VAR_INT | CFG_READONLY,    0, 1024*1024, 0,        0,
79
+		"maximum bytes queued for write per connection (depends on async)"},
80
+	{ "wq_max",       CFG_VAR_INT | CFG_READONLY,    0,  1<<30,    0,        0,
81
+		"maximum bytes queued for write allowed globally (depends on async)"},
82
+	{ "wq_timeout",   CFG_VAR_INT | CFG_READONLY,    1,  1<<30,    0,        0,
83
+		"timeout for queued writes (in ticks, use send_timeout for seconds)"},
84
+	/* tcp socket options */
85
+	{ "defer_accept", CFG_VAR_INT | CFG_READONLY,    0,   3600,   0,         0,
86
+		"0/1 on linux, seconds on freebsd (see docs)"},
87
+	{ "delayed_ack",  CFG_VAR_INT | CFG_READONLY,    0,      1,   0,         0,
88
+		"initial ack will be delayed and sent with the first data segment"},
89
+	{ "syncnt",       CFG_VAR_INT | CFG_READONLY,    0,      1,   0,         0,
90
+		"number of syn retransmissions before aborting a connect (0=not set)"},
91
+	{ "linger2",      CFG_VAR_INT | CFG_READONLY,    0,   3600,   0,         0,
92
+		"lifetime of orphaned sockets in FIN_WAIT2 state in s (0=not set)"},
93
+	{ "keepalive",    CFG_VAR_INT | CFG_READONLY,    0,      1,   0,         0,
94
+		"enables/disables keepalives for tcp"},
95
+	{ "keepidle",     CFG_VAR_INT | CFG_READONLY,    0, 24*3600,  0,         0,
96
+		"time before sending a keepalive if the connection is idle (linux)"},
97
+	{ "keepintvl",    CFG_VAR_INT | CFG_READONLY,    0, 24*3600,  0,         0,
98
+		"time interval between keepalive probes on failure (linux)"},
99
+	{ "keepcnt",     CFG_VAR_INT | CFG_READONLY,    0,    1<<10,  0,         0,
100
+		"number of failed keepalives before dropping the connection (linux)"},
101
+	/* other options */
102
+	{ "crlf_ping",   CFG_VAR_INT | CFG_READONLY,    0,        1,  0,         0,
103
+		"enable responding to CRLF SIP-level keepalives "},
104
+	{0, 0, 0, 0, 0, 0, 0}
105
+};
106
+
107
+
108
+void* tcp_cfg; /* tcp config handle */
34 109
 
35 110
 /* set defaults */
36 111
 void init_tcp_options()
37 112
 {
38 113
 #ifdef TCP_BUF_WRITE
39
-	tcp_options.tcp_buf_write=0;
40
-	tcp_options.tcpconn_wq_max=32*1024; /* 32 k */
41
-	tcp_options.tcp_wq_max=10*1024*1024; /* 10 MB */
42
-	tcp_options.tcp_wq_timeout=S_TO_TICKS(tcp_send_timeout);
114
+	tcp_default_cfg.tcp_buf_write=0;
115
+	tcp_default_cfg.tcpconn_wq_max=32*1024; /* 32 k */
116
+	tcp_default_cfg.tcp_wq_max=10*1024*1024; /* 10 MB */
117
+	tcp_default_cfg.tcp_wq_timeout=S_TO_TICKS(tcp_send_timeout);
43 118
 #ifdef TCP_CONNECT_WAIT
44
-	tcp_options.tcp_connect_wait=1;
119
+	tcp_default_cfg.tcp_connect_wait=1;
45 120
 #endif /* TCP_CONNECT_WAIT */
46 121
 #endif /* TCP_BUF_WRITE */
47 122
 #ifdef TCP_FD_CACHE
48
-	tcp_options.fd_cache=1;
123
+	tcp_default_cfg.fd_cache=1;
49 124
 #endif
50 125
 #ifdef HAVE_SO_KEEPALIVE
51
-	tcp_options.keepalive=1;
126
+	tcp_default_cfg.keepalive=1;
52 127
 #endif
53 128
 /*
54 129
 #if defined HAVE_TCP_DEFER_ACCEPT || defined HAVE_TCP_ACCEPT_FILTER
55
-	tcp_options.defer_accept=1;
130
+	tcp_default_cfg.defer_accept=1;
56 131
 #endif
57 132
 */
58 133
 #ifdef HAVE_TCP_QUICKACK
59
-	tcp_options.delayed_ack=1;
134
+	tcp_default_cfg.delayed_ack=1;
60 135
 #endif
61
-	tcp_options.crlf_ping=1;
136
+	tcp_default_cfg.crlf_ping=1;
62 137
 }
63 138
 
64 139
 
65 140
 
66 141
 #define W_OPT_NC(option) \
67
-	if (tcp_options.option){\
142
+	if (tcp_default_cfg.option){\
68 143
 		WARN("tcp_options: tcp_" #option \
69 144
 				" cannot be enabled (recompile needed)\n"); \
70
-		tcp_options.option=0; \
145
+		tcp_default_cfg.option=0; \
71 146
 	}
72 147
 
73 148
 
74 149
 
75 150
 #define W_OPT_NS(option) \
76
-	if (tcp_options.option){\
151
+	if (tcp_default_cfg.option){\
77 152
 		WARN("tcp_options: tcp_" #option \
78 153
 				" cannot be enabled (no OS support)\n"); \
79
-		tcp_options.option=0; \
154
+		tcp_default_cfg.option=0; \
80 155
 	}
81 156
 
82 157
 
... ...
@@ -97,10 +172,10 @@ void tcp_options_check()
97 97
 	W_OPT_NC(tcp_connect_wait);
98 98
 #endif /* TCP_CONNECT_WAIT */
99 99
 	
100
-	if (tcp_options.tcp_connect_wait && !tcp_options.tcp_buf_write){
100
+	if (tcp_default_cfg.tcp_connect_wait && !tcp_default_cfg.tcp_buf_write){
101 101
 		WARN("tcp_options: tcp_connect_wait depends on tcp_buf_write, "
102 102
 				" disabling...\n");
103
-		tcp_options.tcp_connect_wait=0;
103
+		tcp_default_cfg.tcp_connect_wait=0;
104 104
 	}
105 105
 	
106 106
 #if ! defined HAVE_TCP_DEFER_ACCEPT && ! defined HAVE_TCP_ACCEPT_FILTER
... ...
@@ -121,8 +196,9 @@ void tcp_options_check()
121 121
 #ifndef HAVE_TCP_KEEPCNT
122 122
 	W_OPT_NS(keepcnt);
123 123
 #endif
124
-	if (tcp_options.keepintvl || tcp_options.keepidle || tcp_options.keepcnt){
125
-		tcp_options.keepalive=1; /* force on */
124
+	if (tcp_default_cfg.keepintvl || tcp_default_cfg.keepidle || 
125
+			tcp_default_cfg.keepcnt){
126
+		tcp_default_cfg.keepalive=1; /* force on */
126 127
 	}
127 128
 #ifndef HAVE_SO_KEEPALIVE
128 129
 	W_OPT_NS(keepalive);
... ...
@@ -134,7 +210,23 @@ void tcp_options_check()
134 134
 
135 135
 
136 136
 
137
-void tcp_options_get(struct tcp_cfg_options* t)
137
+void tcp_options_get(struct cfg_group_tcp* t)
138 138
 {
139
-	*t=tcp_options;
139
+	*t=tcp_default_cfg;
140
+}
141
+
142
+
143
+
144
+/** register tcp config into the configuration framework.
145
+ *  @return 0 on succes, -1 on error*/
146
+int tcp_register_cfg()
147
+{
148
+	if (cfg_declare("tcp", tcp_cfg_def, &tcp_default_cfg, cfg_sizeof(tcp),
149
+					&tcp_cfg))
150
+		return -1;
151
+	if (tcp_cfg==0){
152
+		BUG("null tcp cfg");
153
+		return -1;
154
+	}
155
+	return 0;
140 156
 }
... ...
@@ -109,15 +109,15 @@
109 109
 
110 110
 #endif /* USE_TCP */
111 111
 
112
-struct tcp_cfg_options{
112
+struct cfg_group_tcp{
113 113
 	/* ser tcp options */
114 114
 	int fd_cache; /* on /off */
115
-	/* tcp buf. write options */
115
+	/* tcp async options */
116 116
 	int tcp_buf_write; /* on / off */
117 117
 	int tcp_connect_wait; /* on / off, depends on tcp_buf_write */
118 118
 	unsigned int tcpconn_wq_max; /* maximum queue len per connection */
119 119
 	unsigned int tcp_wq_max; /* maximum overall queued bytes */
120
-	unsigned int tcp_wq_timeout;      /* timeout for queue writes */
120
+	unsigned int tcp_wq_timeout;      /* timeout for queued writes */
121 121
 
122 122
 	/* tcp socket options */
123 123
 	int defer_accept; /* on / off */
... ...
@@ -128,14 +128,20 @@ struct tcp_cfg_options{
128 128
 	int keepidle;   /* idle time (s) before tcp starts sending keepalives */
129 129
 	int keepintvl;  /* interval between keep alives */
130 130
 	int keepcnt;    /* maximum no. of keepalives before giving up */
131
+	
132
+	/* other options */
131 133
 	int crlf_ping;  /* on/off - reply to double CRLF keepalives */
132 134
 };
133 135
 
136
+extern struct cfg_group_tcp tcp_default_cfg;
137
+
138
+/* tcp config handle*/
139
+extern void* tcp_cfg;
134 140
 
135
-extern struct tcp_cfg_options tcp_options;
136 141
 
137 142
 void init_tcp_options();
138 143
 void tcp_options_check();
139
-void tcp_options_get(struct tcp_cfg_options* t);
144
+int tcp_register_cfg();
145
+void tcp_options_get(struct cfg_group_tcp* t);
140 146
 
141 147
 #endif /* tcp_options_h */
... ...
@@ -351,7 +351,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
351 351
 					case '\n':
352 352
 						break;
353 353
 					case '\r':
354
-						if (tcp_options.crlf_ping) {
354
+						if (cfg_get(tcp, tcp_cfg, crlf_ping)) {
355 355
 							r->state=H_SKIP_EMPTY_CR_FOUND;
356 356
 							r->start=p;
357 357
 						}