Browse code

sctp: enable runtime changing for some of the cfg vars

Migrated sctp to the cfg. framework.
All config variables can be interrogated at runtime using the
cfg.get rpc (e.g. $ sercmd cfg.get sctp send_ttl) and some of
them can also be changed (send_ttl and send_retries for now).

Andrei Pelinescu-Onciul authored on 26/05/2009 17:20:12
Showing 7 changed files
... ...
@@ -274,6 +274,8 @@ new config variables:
274 274
      assocation (default: 180 s).
275 275
   sctp_send_ttl = milliseconds - number of milliseconds before an unsent
276 276
      message/chunk is dropped (default: 32000 ms or 32 s).
277
+     Can be changed at runtime, e.g.:
278
+        $ sercmd cfg.set_now_int sctp send_ttl 180000
277 279
   sctp_send_retries - how many times to attempt re-sending a message on a
278 280
                       re-opened association, if the sctp stack did give up
279 281
                       sending it (it's not related to sctp protocol level
... ...
@@ -282,6 +284,7 @@ new config variables:
282 282
                       machine. WARNING: use with care and low values (e.g.
283 283
                       1-3) to avoid "multiplying" traffic to unresponding 
284 284
                       hosts (default: 0).
285
+                      Can be changed at runtime.
285 286
   server_id = number - A configurable unique server id that can be used to
286 287
                        discriminate server instances within a cluster of
287 288
                        servers when all other information, such as IP addresses
... ...
@@ -1149,7 +1149,7 @@ assign_stm:
1149 1149
 	| SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
1150 1150
 	| SCTP_SOCKET_RCVBUF EQUAL NUMBER {
1151 1151
 		#ifdef USE_SCTP
1152
-			sctp_options.sctp_so_rcvbuf=$3;
1152
+			sctp_default_cfg.so_rcvbuf=$3;
1153 1153
 		#else
1154 1154
 			warn("sctp support not compiled in");
1155 1155
 		#endif
... ...
@@ -1157,7 +1157,7 @@ assign_stm:
1157 1157
 	| SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
1158 1158
 	| SCTP_SOCKET_SNDBUF EQUAL NUMBER {
1159 1159
 		#ifdef USE_SCTP
1160
-			sctp_options.sctp_so_sndbuf=$3;
1160
+			sctp_default_cfg.so_sndbuf=$3;
1161 1161
 		#else
1162 1162
 			warn("sctp support not compiled in");
1163 1163
 		#endif
... ...
@@ -1165,7 +1165,7 @@ assign_stm:
1165 1165
 	| SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
1166 1166
 	| SCTP_AUTOCLOSE EQUAL NUMBER {
1167 1167
 		#ifdef USE_SCTP
1168
-			sctp_options.sctp_autoclose=$3;
1168
+			sctp_default_cfg.autoclose=$3;
1169 1169
 		#else
1170 1170
 			warn("sctp support not compiled in");
1171 1171
 		#endif
... ...
@@ -1173,7 +1173,7 @@ assign_stm:
1173 1173
 	| SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
1174 1174
 	| SCTP_SEND_TTL EQUAL NUMBER {
1175 1175
 		#ifdef USE_SCTP
1176
-			sctp_options.sctp_send_ttl=$3;
1176
+			sctp_default_cfg.send_ttl=$3;
1177 1177
 		#else
1178 1178
 			warn("sctp support not compiled in");
1179 1179
 		#endif
... ...
@@ -1181,7 +1181,7 @@ assign_stm:
1181 1181
 	| SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
1182 1182
 	| SCTP_SEND_RETRIES EQUAL NUMBER {
1183 1183
 		#ifdef USE_SCTP
1184
-			sctp_options.sctp_send_retries=$3;
1184
+			sctp_default_cfg.send_retries=$3;
1185 1185
 		#else
1186 1186
 			warn("sctp support not compiled in");
1187 1187
 		#endif
... ...
@@ -608,16 +608,17 @@ static void core_sctp_options(rpc_t* rpc, void* c)
608 608
 {
609 609
 #ifdef USE_SCTP
610 610
 	void *handle;
611
-	struct sctp_cfg_options t;
611
+	struct cfg_group_sctp t;
612 612
 
613 613
 	if (!sctp_disable){
614 614
 		sctp_options_get(&t);
615 615
 		rpc->add(c, "{", &handle);
616
-		rpc->struct_add(handle, "dddd",
617
-			"sctp_autoclose",		t.sctp_autoclose,
618
-			"sctp_send_ttl",	t.sctp_autoclose,
619
-			"sctp_socket_rcvbuf",	t.sctp_so_rcvbuf,
620
-			"sctp_socket_sndbuf",	t.sctp_so_sndbuf
616
+		rpc->struct_add(handle, "ddddd",
617
+			"sctp_autoclose",		t.autoclose,
618
+			"sctp_send_ttl",	t.send_ttl,
619
+			"sctp_send_retries",	t.send_retries,
620
+			"sctp_socket_rcvbuf",	t.so_rcvbuf,
621
+			"sctp_socket_sndbuf",	t.so_sndbuf
621 622
 		);
622 623
 	}else{
623 624
 		rpc->fault(c, 500, "sctp support disabled");
... ...
@@ -1941,6 +1941,12 @@ try_again:
1941 1941
 		goto error;
1942 1942
 	}
1943 1943
 #endif /* USE_TCP */
1944
+#ifdef USE_SCTP
1945
+	if (sctp_register_cfg()){
1946
+		LOG(L_CRIT, "could not register the sctp configuration\n");
1947
+		goto error;
1948
+	}
1949
+#endif /* USE_SCTP */
1944 1950
 	/*init timer, before parsing the cfg!*/
1945 1951
 	if (init_timer()<0){
1946 1952
 		LOG(L_CRIT, "could not initialize timer, exiting...\n");
... ...
@@ -22,31 +22,61 @@
22 22
  * History:
23 23
  * --------
24 24
  *  2008-08-07  initial version (andrei)
25
+ *  2009-05-26  runtime cfg support (andrei)
25 26
  */
26 27
 
28
+#include <string.h>
27 29
 
28 30
 #include "sctp_options.h"
29 31
 #include "dprint.h"
32
+#include "cfg/cfg.h"
30 33
 
34
+struct cfg_group_sctp sctp_default_cfg;
31 35
 
32
-struct sctp_cfg_options sctp_options;
36
+
37
+
38
+#ifdef USE_SCTP
39
+/** cfg_group_sctp description (for the config framework). */
40
+static cfg_def_t sctp_cfg_def[] = {
41
+	/*   name        , type |input type| chg type, min, max, fixup, proc. cbk.
42
+	      description */
43
+	{ "socket_rcvbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
44
+		"socket receive buffer size (read-only)" },
45
+	{ "socket_sndbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
46
+		"socket send buffer size (read-only)" },
47
+	{ "autoclose", CFG_VAR_INT| CFG_READONLY, 1, 1<<30, 0, 0,
48
+		"seconds before closing and idle connection (must be non-zero)" },
49
+	{ "send_ttl", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, 0, 0,
50
+		"milliseconds before aborting a send" },
51
+	{ "send_retries", CFG_VAR_INT| CFG_ATOMIC, 0, MAX_SCTP_SEND_RETRIES, 0, 0,
52
+		"re-send attempts on failure" },
53
+	{0, 0, 0, 0, 0, 0, 0}
54
+};
55
+
56
+
57
+
58
+void* sctp_cfg; /* sctp config handle */
59
+
60
+#endif /* USE_SCTP */
33 61
 
34 62
 void init_sctp_options()
35 63
 {
36 64
 #ifdef USE_SCTP
37
-	sctp_options.sctp_autoclose=DEFAULT_SCTP_AUTOCLOSE; /* in seconds */
38
-	sctp_options.sctp_send_ttl=DEFAULT_SCTP_SEND_TTL;   /* in milliseconds */
39
-	sctp_options.sctp_send_retries=DEFAULT_SCTP_SEND_RETRIES;
65
+	sctp_default_cfg.so_rcvbuf=0; /* do nothing, use the kernel default */
66
+	sctp_default_cfg.so_sndbuf=0; /* do nothing, use the kernel default */
67
+	sctp_default_cfg.autoclose=DEFAULT_SCTP_AUTOCLOSE; /* in seconds */
68
+	sctp_default_cfg.send_ttl=DEFAULT_SCTP_SEND_TTL;   /* in milliseconds */
69
+	sctp_default_cfg.send_retries=DEFAULT_SCTP_SEND_RETRIES;
40 70
 #endif
41 71
 }
42 72
 
43 73
 
44 74
 
45 75
 #define W_OPT_NSCTP(option) \
46
-	if (sctp_options.option){\
76
+	if (sctp_default_cfg.option){\
47 77
 		WARN("sctp_options: " #option \
48 78
 			" cannot be enabled (sctp support not compiled-in)\n"); \
49
-			sctp_options.option=0; \
79
+			sctp_default_cfg.option=0; \
50 80
 	}
51 81
 
52 82
 
... ...
@@ -54,21 +84,43 @@ void init_sctp_options()
54 54
 void sctp_options_check()
55 55
 {
56 56
 #ifndef USE_SCTP
57
-	W_OPT_NSCTP(sctp_autoclose);
58
-	W_OPT_NSCTP(sctp_send_ttl);
59
-	W_OPT_NSCTP(sctp_send_retries);
57
+	W_OPT_NSCTP(autoclose);
58
+	W_OPT_NSCTP(send_ttl);
59
+	W_OPT_NSCTP(send_retries);
60 60
 #else
61
-	if (sctp_options.sctp_send_retries>MAX_SCTP_SEND_RETRIES) {
61
+	if (sctp_default_cfg.send_retries>MAX_SCTP_SEND_RETRIES) {
62 62
 		WARN("sctp: sctp_send_retries too high (%d), setting it to %d\n",
63
-				sctp_options.sctp_send_retries, MAX_SCTP_SEND_RETRIES);
64
-		sctp_options.sctp_send_retries=MAX_SCTP_SEND_RETRIES;
63
+				sctp_default_cfg.send_retries, MAX_SCTP_SEND_RETRIES);
64
+		sctp_default_cfg.send_retries=MAX_SCTP_SEND_RETRIES;
65 65
 	}
66 66
 #endif
67 67
 }
68 68
 
69 69
 
70 70
 
71
-void sctp_options_get(struct sctp_cfg_options *s)
71
+void sctp_options_get(struct cfg_group_sctp *s)
72
+{
73
+#ifdef USE_SCTP
74
+	*s=*(struct cfg_group_sctp*)sctp_cfg;
75
+#else
76
+	memset(s, 0, sizeof(*s));
77
+#endif /* USE_SCTP */
78
+}
79
+
80
+
81
+
82
+#ifdef USE_SCTP
83
+/** register sctp config into the configuration framework.
84
+ * @return 0 on success, -1 on error */
85
+int sctp_register_cfg()
72 86
 {
73
-	*s=sctp_options;
87
+	if (cfg_declare("sctp", sctp_cfg_def, &sctp_default_cfg, cfg_sizeof(sctp),
88
+				&sctp_cfg))
89
+		return -1;
90
+	if (sctp_cfg==0){
91
+		BUG("null sctp cfg");
92
+		return -1;
93
+	}
94
+	return 0;
74 95
 }
96
+#endif /* USE_SCTP */
... ...
@@ -22,6 +22,7 @@
22 22
  * History:
23 23
  * --------
24 24
  *  2008-08-07  initial version (andrei)
25
+ *  2009-05-26  runtime cfg support (andrei)
25 26
  */
26 27
 
27 28
 #ifndef _sctp_options_h
... ...
@@ -33,18 +34,22 @@
33 33
 #define MAX_SCTP_SEND_RETRIES 9
34 34
 
35 35
 
36
-struct sctp_cfg_options{
37
-	int sctp_so_rcvbuf;
38
-	int sctp_so_sndbuf;
39
-	unsigned int sctp_autoclose; /* in seconds */
40
-	unsigned int sctp_send_ttl; /* in milliseconds */
41
-	unsigned int sctp_send_retries;
36
+struct cfg_group_sctp{
37
+	int so_rcvbuf;
38
+	int so_sndbuf;
39
+	unsigned int autoclose; /* in seconds */
40
+	unsigned int send_ttl; /* in milliseconds */
41
+	unsigned int send_retries;
42 42
 };
43 43
 
44
-extern struct sctp_cfg_options sctp_options;
44
+extern struct cfg_group_sctp sctp_default_cfg;
45
+
46
+/* sctp config handle */
47
+extern void* sctp_cfg;
45 48
 
46 49
 void init_sctp_options();
47 50
 void sctp_options_check();
48
-void sctp_options_get(struct sctp_cfg_options *s);
51
+int sctp_register_cfg();
52
+void sctp_options_get(struct cfg_group_sctp *s);
49 53
 
50 54
 #endif /* _sctp_options_h */
... ...
@@ -223,8 +223,8 @@ static int sctp_init_sock_opt_common(int s)
223 223
 	}
224 224
 	
225 225
 	/* set receive buffer: SO_RCVBUF*/
226
-	if (sctp_options.sctp_so_rcvbuf){
227
-		optval=sctp_options.sctp_so_rcvbuf;
226
+	if (cfg_get(sctp, sctp_cfg, so_rcvbuf)){
227
+		optval=cfg_get(sctp, sctp_cfg, so_rcvbuf);
228 228
 		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
229 229
 					(void*)&optval, sizeof(optval)) ==-1){
230 230
 			LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt:"
... ...
@@ -234,8 +234,8 @@ static int sctp_init_sock_opt_common(int s)
234 234
 	}
235 235
 	
236 236
 	/* set send buffer: SO_SNDBUF */
237
-	if (sctp_options.sctp_so_sndbuf){
238
-		optval=sctp_options.sctp_so_sndbuf;
237
+	if (cfg_get(sctp, sctp_cfg, so_sndbuf)){
238
+		optval=cfg_get(sctp, sctp_cfg, so_sndbuf);
239 239
 		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
240 240
 					(void*)&optval, sizeof(optval)) ==-1){
241 241
 			LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt:"
... ...
@@ -345,7 +345,7 @@ static int sctp_init_sock_opt_common(int s)
345 345
 	
346 346
 	/* set autoclose */
347 347
 #ifdef SCTP_AUTOCLOSE
348
-	optval=sctp_options.sctp_autoclose;
348
+	optval=cfg_get(sctp, sctp_cfg, autoclose);
349 349
 	if (setsockopt(s, IPPROTO_SCTP, SCTP_AUTOCLOSE,
350 350
 					(void*)&optval, sizeof(optval)) ==-1){
351 351
 		LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
... ...
@@ -1255,7 +1255,8 @@ again:
1255 1255
 					if (_sctp_con_del_id_locked(h, e)==0)
1256 1256
 						goto skip_unlock;
1257 1257
 				}else
1258
-					e->con.expire=now+S_TO_TICKS(sctp_options.sctp_autoclose);
1258
+					e->con.expire=now +
1259
+								S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
1259 1260
 				break;
1260 1261
 			}
1261 1262
 #if 0
... ...
@@ -1305,7 +1306,8 @@ again:
1305 1305
 					if (_sctp_con_del_assoc_locked(h, e)==0)
1306 1306
 						goto skip_unlock;
1307 1307
 				}else
1308
-					e->con.expire=now+S_TO_TICKS(sctp_options.sctp_autoclose);
1308
+					e->con.expire=now +
1309
+								S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
1309 1310
 				break;
1310 1311
 			}
1311 1312
 #if 0
... ...
@@ -1357,7 +1359,8 @@ again:
1357 1357
 					if (_sctp_con_del_addr_locked(h, e)==0)
1358 1358
 						goto skip_unlock;
1359 1359
 				}else
1360
-					e->con.expire=now+S_TO_TICKS(sctp_options.sctp_autoclose);
1360
+					e->con.expire=now +
1361
+								S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
1361 1362
 				break;
1362 1363
 			}
1363 1364
 #if 0
... ...
@@ -1414,7 +1417,8 @@ struct sctp_con_elem* sctp_con_new(unsigned id, unsigned assoc_id,
1414 1414
 	else
1415 1415
 		memset(&e->con.remote, 0, sizeof(e->con.remote));
1416 1416
 	e->con.start=get_ticks_raw();
1417
-	e->con.expire=e->con.start+S_TO_TICKS(sctp_options.sctp_autoclose);
1417
+	e->con.expire=e->con.start +
1418
+				S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
1418 1419
 	return e;
1419 1420
 error:
1420 1421
 	return 0;
... ...
@@ -1678,6 +1682,9 @@ static int sctp_handle_send_failed(struct socket_info* si,
1678 1678
 	unsigned data_len;
1679 1679
 	int retries;
1680 1680
 	int ret;
1681
+#ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
1682
+	int send_ttl;
1683
+#endif
1681 1684
 	
1682 1685
 	ret=-1;
1683 1686
 	SCTP_STATS_SEND_FAILED();
... ...
@@ -1700,13 +1707,13 @@ static int sctp_handle_send_failed(struct socket_info* si,
1700 1700
 		memset(&sinfo, 0, sizeof(sinfo));
1701 1701
 		sinfo.sinfo_flags=SCTP_UNORDERED;
1702 1702
 #ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
1703
-		if (sctp_options.sctp_send_ttl){
1703
+		if ((send_ttl=cfg_get(sctp, sctp_cfg, send_ttl))){
1704 1704
 			sinfo.sinfo_pr_policy=SCTP_PR_SCTP_TTL;
1705
-			sinfo.sinfo_pr_value=sctp_options.sctp_send_ttl;
1705
+			sinfo.sinfo_pr_value=send_ttl;
1706 1706
 		}else
1707 1707
 			sinfo.info_pr_policy=SCTP_PR_SCTP_NONE;
1708 1708
 #else
1709
-		sinfo.sinfo_timetolive=sctp_options.sctp_send_ttl;
1709
+		sinfo.sinfo_timetolive=cfg_get(sctp, sctp_cfg, send_ttl);
1710 1710
 #endif
1711 1711
 		sinfo.sinfo_context=retries;
1712 1712
 		
... ...
@@ -1722,7 +1729,7 @@ static int sctp_handle_send_failed(struct socket_info* si,
1722 1722
 	}
1723 1723
 #ifdef USE_DST_BLACKLIST
1724 1724
 	 else if (cfg_get(core, core_cfg, use_dst_blacklist) &&
1725
-					sctp_options.sctp_send_retries) {
1725
+					cfg_get(sctp, sctp_cfg, send_retries)) {
1726 1726
 		/* blacklist only if send_retries is on, if off we blacklist
1727 1727
 		   from SCTP_ASSOC_CHANGE: SCTP_COMM_LOST/SCTP_CANT_STR_ASSOC
1728 1728
 		   which is better (because we can tell connect errors from send
... ...
@@ -1782,7 +1789,7 @@ again:
1782 1782
 			/* blacklist only if send_retries is turned off (if on we don't
1783 1783
 			   know here if we did retry or we are at the first error) */
1784 1784
 			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
1785
-					(sctp_options.sctp_send_retries==0))
1785
+					(cfg_get(sctp, sctp_cfg, send_retries)==0))
1786 1786
 						dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0);
1787 1787
 #endif /* USE_DST_BLACKLIST */
1788 1788
 			/* no break */
... ...
@@ -1811,7 +1818,7 @@ again:
1811 1811
 			/* blacklist only if send_retries is turned off (if on we don't 
1812 1812
 			   know here if we did retry or we are at the first error) */
1813 1813
 			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
1814
-					(sctp_options.sctp_send_retries==0))
1814
+					(cfg_get(sctp, sctp_cfg, send_retries)==0))
1815 1815
 						dst_blacklist_su(BLST_ERR_CONNECT, PROTO_SCTP, su, 0);
1816 1816
 #endif /* USE_DST_BLACKLIST */
1817 1817
 			break;
... ...
@@ -2266,19 +2273,22 @@ again:
2266 2266
 int sctp_msg_send(struct dest_info* dst, char* buf, unsigned len)
2267 2267
 {
2268 2268
 	struct sctp_sndrcvinfo sinfo;
2269
+#ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
2270
+	int send_ttl;
2271
+#endif
2269 2272
 	
2270 2273
 	memset(&sinfo, 0, sizeof(sinfo));
2271 2274
 	sinfo.sinfo_flags=SCTP_UNORDERED;
2272 2275
 #ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
2273
-	if (sctp_options.sctp_send_ttl){
2276
+	if ((send_ttl=cfg_get(sctp, sctp_cfg, send_ttl))){
2274 2277
 		sinfo.sinfo_pr_policy=SCTP_PR_SCTP_TTL;
2275
-		sinfo.sinfo_pr_value=sctp_options.sctp_send_ttl;
2278
+		sinfo.sinfo_pr_value=send_ttl;
2276 2279
 	}else
2277 2280
 		sinfo->sinfo_pr_policy=SCTP_PR_SCTP_NONE;
2278 2281
 #else
2279
-		sinfo.sinfo_timetolive=sctp_options.sctp_send_ttl;
2282
+		sinfo.sinfo_timetolive=cfg_get(sctp, sctp_cfg, send_ttl);
2280 2283
 #endif
2281
-	sinfo.sinfo_context=sctp_options.sctp_send_retries;
2284
+	sinfo.sinfo_context=cfg_get(sctp, sctp_cfg, send_retries);
2282 2285
 	return sctp_msg_send_raw(dst, buf, len, &sinfo);
2283 2286
 }
2284 2287