Browse Source

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 16 years ago
parent
commit
57f57a4336
7 changed files with 129 additions and 52 deletions
  1. 3 0
      NEWS
  2. 5 5
      cfg.y
  3. 7 6
      core_cmd.c
  4. 6 0
      main.c
  5. 66 14
      sctp_options.c
  6. 13 8
      sctp_options.h
  7. 29 19
      sctp_server.c

+ 3 - 0
NEWS

@@ -274,6 +274,8 @@ new config variables:
      assocation (default: 180 s).
   sctp_send_ttl = milliseconds - number of milliseconds before an unsent
      message/chunk is dropped (default: 32000 ms or 32 s).
+     Can be changed at runtime, e.g.:
+        $ sercmd cfg.set_now_int sctp send_ttl 180000
   sctp_send_retries - how many times to attempt re-sending a message on a
                       re-opened association, if the sctp stack did give up
                       sending it (it's not related to sctp protocol level
@@ -282,6 +284,7 @@ new config variables:
                       machine. WARNING: use with care and low values (e.g.
                       1-3) to avoid "multiplying" traffic to unresponding 
                       hosts (default: 0).
+                      Can be changed at runtime.
   server_id = number - A configurable unique server id that can be used to
                        discriminate server instances within a cluster of
                        servers when all other information, such as IP addresses

+ 5 - 5
cfg.y

@@ -1149,7 +1149,7 @@ assign_stm:
 	| SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
 	| SCTP_SOCKET_RCVBUF EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_so_rcvbuf=$3;
+			sctp_default_cfg.so_rcvbuf=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1157,7 +1157,7 @@ assign_stm:
 	| SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
 	| SCTP_SOCKET_SNDBUF EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_so_sndbuf=$3;
+			sctp_default_cfg.so_sndbuf=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1165,7 +1165,7 @@ assign_stm:
 	| SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
 	| SCTP_AUTOCLOSE EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_autoclose=$3;
+			sctp_default_cfg.autoclose=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1173,7 +1173,7 @@ assign_stm:
 	| SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
 	| SCTP_SEND_TTL EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_send_ttl=$3;
+			sctp_default_cfg.send_ttl=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif
@@ -1181,7 +1181,7 @@ assign_stm:
 	| SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
 	| SCTP_SEND_RETRIES EQUAL NUMBER {
 		#ifdef USE_SCTP
-			sctp_options.sctp_send_retries=$3;
+			sctp_default_cfg.send_retries=$3;
 		#else
 			warn("sctp support not compiled in");
 		#endif

+ 7 - 6
core_cmd.c

@@ -608,16 +608,17 @@ static void core_sctp_options(rpc_t* rpc, void* c)
 {
 #ifdef USE_SCTP
 	void *handle;
-	struct sctp_cfg_options t;
+	struct cfg_group_sctp t;
 
 	if (!sctp_disable){
 		sctp_options_get(&t);
 		rpc->add(c, "{", &handle);
-		rpc->struct_add(handle, "dddd",
-			"sctp_autoclose",		t.sctp_autoclose,
-			"sctp_send_ttl",	t.sctp_autoclose,
-			"sctp_socket_rcvbuf",	t.sctp_so_rcvbuf,
-			"sctp_socket_sndbuf",	t.sctp_so_sndbuf
+		rpc->struct_add(handle, "ddddd",
+			"sctp_autoclose",		t.autoclose,
+			"sctp_send_ttl",	t.send_ttl,
+			"sctp_send_retries",	t.send_retries,
+			"sctp_socket_rcvbuf",	t.so_rcvbuf,
+			"sctp_socket_sndbuf",	t.so_sndbuf
 		);
 	}else{
 		rpc->fault(c, 500, "sctp support disabled");

+ 6 - 0
main.c

@@ -1941,6 +1941,12 @@ try_again:
 		goto error;
 	}
 #endif /* USE_TCP */
+#ifdef USE_SCTP
+	if (sctp_register_cfg()){
+		LOG(L_CRIT, "could not register the sctp configuration\n");
+		goto error;
+	}
+#endif /* USE_SCTP */
 	/*init timer, before parsing the cfg!*/
 	if (init_timer()<0){
 		LOG(L_CRIT, "could not initialize timer, exiting...\n");

+ 66 - 14
sctp_options.c

@@ -22,31 +22,61 @@
  * History:
  * --------
  *  2008-08-07  initial version (andrei)
+ *  2009-05-26  runtime cfg support (andrei)
  */
 
+#include <string.h>
 
 #include "sctp_options.h"
 #include "dprint.h"
+#include "cfg/cfg.h"
 
+struct cfg_group_sctp sctp_default_cfg;
 
-struct sctp_cfg_options sctp_options;
+
+
+#ifdef USE_SCTP
+/** cfg_group_sctp description (for the config framework). */
+static cfg_def_t sctp_cfg_def[] = {
+	/*   name        , type |input type| chg type, min, max, fixup, proc. cbk.
+	      description */
+	{ "socket_rcvbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
+		"socket receive buffer size (read-only)" },
+	{ "socket_sndbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
+		"socket send buffer size (read-only)" },
+	{ "autoclose", CFG_VAR_INT| CFG_READONLY, 1, 1<<30, 0, 0,
+		"seconds before closing and idle connection (must be non-zero)" },
+	{ "send_ttl", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, 0, 0,
+		"milliseconds before aborting a send" },
+	{ "send_retries", CFG_VAR_INT| CFG_ATOMIC, 0, MAX_SCTP_SEND_RETRIES, 0, 0,
+		"re-send attempts on failure" },
+	{0, 0, 0, 0, 0, 0, 0}
+};
+
+
+
+void* sctp_cfg; /* sctp config handle */
+
+#endif /* USE_SCTP */
 
 void init_sctp_options()
 {
 #ifdef USE_SCTP
-	sctp_options.sctp_autoclose=DEFAULT_SCTP_AUTOCLOSE; /* in seconds */
-	sctp_options.sctp_send_ttl=DEFAULT_SCTP_SEND_TTL;   /* in milliseconds */
-	sctp_options.sctp_send_retries=DEFAULT_SCTP_SEND_RETRIES;
+	sctp_default_cfg.so_rcvbuf=0; /* do nothing, use the kernel default */
+	sctp_default_cfg.so_sndbuf=0; /* do nothing, use the kernel default */
+	sctp_default_cfg.autoclose=DEFAULT_SCTP_AUTOCLOSE; /* in seconds */
+	sctp_default_cfg.send_ttl=DEFAULT_SCTP_SEND_TTL;   /* in milliseconds */
+	sctp_default_cfg.send_retries=DEFAULT_SCTP_SEND_RETRIES;
 #endif
 }
 
 
 
 #define W_OPT_NSCTP(option) \
-	if (sctp_options.option){\
+	if (sctp_default_cfg.option){\
 		WARN("sctp_options: " #option \
 			" cannot be enabled (sctp support not compiled-in)\n"); \
-			sctp_options.option=0; \
+			sctp_default_cfg.option=0; \
 	}
 
 
@@ -54,21 +84,43 @@ void init_sctp_options()
 void sctp_options_check()
 {
 #ifndef USE_SCTP
-	W_OPT_NSCTP(sctp_autoclose);
-	W_OPT_NSCTP(sctp_send_ttl);
-	W_OPT_NSCTP(sctp_send_retries);
+	W_OPT_NSCTP(autoclose);
+	W_OPT_NSCTP(send_ttl);
+	W_OPT_NSCTP(send_retries);
 #else
-	if (sctp_options.sctp_send_retries>MAX_SCTP_SEND_RETRIES) {
+	if (sctp_default_cfg.send_retries>MAX_SCTP_SEND_RETRIES) {
 		WARN("sctp: sctp_send_retries too high (%d), setting it to %d\n",
-				sctp_options.sctp_send_retries, MAX_SCTP_SEND_RETRIES);
-		sctp_options.sctp_send_retries=MAX_SCTP_SEND_RETRIES;
+				sctp_default_cfg.send_retries, MAX_SCTP_SEND_RETRIES);
+		sctp_default_cfg.send_retries=MAX_SCTP_SEND_RETRIES;
 	}
 #endif
 }
 
 
 
-void sctp_options_get(struct sctp_cfg_options *s)
+void sctp_options_get(struct cfg_group_sctp *s)
+{
+#ifdef USE_SCTP
+	*s=*(struct cfg_group_sctp*)sctp_cfg;
+#else
+	memset(s, 0, sizeof(*s));
+#endif /* USE_SCTP */
+}
+
+
+
+#ifdef USE_SCTP
+/** register sctp config into the configuration framework.
+ * @return 0 on success, -1 on error */
+int sctp_register_cfg()
 {
-	*s=sctp_options;
+	if (cfg_declare("sctp", sctp_cfg_def, &sctp_default_cfg, cfg_sizeof(sctp),
+				&sctp_cfg))
+		return -1;
+	if (sctp_cfg==0){
+		BUG("null sctp cfg");
+		return -1;
+	}
+	return 0;
 }
+#endif /* USE_SCTP */

+ 13 - 8
sctp_options.h

@@ -22,6 +22,7 @@
  * History:
  * --------
  *  2008-08-07  initial version (andrei)
+ *  2009-05-26  runtime cfg support (andrei)
  */
 
 #ifndef _sctp_options_h
@@ -33,18 +34,22 @@
 #define MAX_SCTP_SEND_RETRIES 9
 
 
-struct sctp_cfg_options{
-	int sctp_so_rcvbuf;
-	int sctp_so_sndbuf;
-	unsigned int sctp_autoclose; /* in seconds */
-	unsigned int sctp_send_ttl; /* in milliseconds */
-	unsigned int sctp_send_retries;
+struct cfg_group_sctp{
+	int so_rcvbuf;
+	int so_sndbuf;
+	unsigned int autoclose; /* in seconds */
+	unsigned int send_ttl; /* in milliseconds */
+	unsigned int send_retries;
 };
 
-extern struct sctp_cfg_options sctp_options;
+extern struct cfg_group_sctp sctp_default_cfg;
+
+/* sctp config handle */
+extern void* sctp_cfg;
 
 void init_sctp_options();
 void sctp_options_check();
-void sctp_options_get(struct sctp_cfg_options *s);
+int sctp_register_cfg();
+void sctp_options_get(struct cfg_group_sctp *s);
 
 #endif /* _sctp_options_h */

+ 29 - 19
sctp_server.c

@@ -223,8 +223,8 @@ static int sctp_init_sock_opt_common(int s)
 	}
 	
 	/* set receive buffer: SO_RCVBUF*/
-	if (sctp_options.sctp_so_rcvbuf){
-		optval=sctp_options.sctp_so_rcvbuf;
+	if (cfg_get(sctp, sctp_cfg, so_rcvbuf)){
+		optval=cfg_get(sctp, sctp_cfg, so_rcvbuf);
 		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
 					(void*)&optval, sizeof(optval)) ==-1){
 			LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt:"
@@ -234,8 +234,8 @@ static int sctp_init_sock_opt_common(int s)
 	}
 	
 	/* set send buffer: SO_SNDBUF */
-	if (sctp_options.sctp_so_sndbuf){
-		optval=sctp_options.sctp_so_sndbuf;
+	if (cfg_get(sctp, sctp_cfg, so_sndbuf)){
+		optval=cfg_get(sctp, sctp_cfg, so_sndbuf);
 		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
 					(void*)&optval, sizeof(optval)) ==-1){
 			LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt:"
@@ -345,7 +345,7 @@ static int sctp_init_sock_opt_common(int s)
 	
 	/* set autoclose */
 #ifdef SCTP_AUTOCLOSE
-	optval=sctp_options.sctp_autoclose;
+	optval=cfg_get(sctp, sctp_cfg, autoclose);
 	if (setsockopt(s, IPPROTO_SCTP, SCTP_AUTOCLOSE,
 					(void*)&optval, sizeof(optval)) ==-1){
 		LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
@@ -1255,7 +1255,8 @@ again:
 					if (_sctp_con_del_id_locked(h, e)==0)
 						goto skip_unlock;
 				}else
-					e->con.expire=now+S_TO_TICKS(sctp_options.sctp_autoclose);
+					e->con.expire=now +
+								S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
 				break;
 			}
 #if 0
@@ -1305,7 +1306,8 @@ again:
 					if (_sctp_con_del_assoc_locked(h, e)==0)
 						goto skip_unlock;
 				}else
-					e->con.expire=now+S_TO_TICKS(sctp_options.sctp_autoclose);
+					e->con.expire=now +
+								S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
 				break;
 			}
 #if 0
@@ -1357,7 +1359,8 @@ again:
 					if (_sctp_con_del_addr_locked(h, e)==0)
 						goto skip_unlock;
 				}else
-					e->con.expire=now+S_TO_TICKS(sctp_options.sctp_autoclose);
+					e->con.expire=now +
+								S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
 				break;
 			}
 #if 0
@@ -1414,7 +1417,8 @@ struct sctp_con_elem* sctp_con_new(unsigned id, unsigned assoc_id,
 	else
 		memset(&e->con.remote, 0, sizeof(e->con.remote));
 	e->con.start=get_ticks_raw();
-	e->con.expire=e->con.start+S_TO_TICKS(sctp_options.sctp_autoclose);
+	e->con.expire=e->con.start +
+				S_TO_TICKS(cfg_get(sctp, sctp_cfg, autoclose));
 	return e;
 error:
 	return 0;
@@ -1678,6 +1682,9 @@ static int sctp_handle_send_failed(struct socket_info* si,
 	unsigned data_len;
 	int retries;
 	int ret;
+#ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
+	int send_ttl;
+#endif
 	
 	ret=-1;
 	SCTP_STATS_SEND_FAILED();
@@ -1700,13 +1707,13 @@ static int sctp_handle_send_failed(struct socket_info* si,
 		memset(&sinfo, 0, sizeof(sinfo));
 		sinfo.sinfo_flags=SCTP_UNORDERED;
 #ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
-		if (sctp_options.sctp_send_ttl){
+		if ((send_ttl=cfg_get(sctp, sctp_cfg, send_ttl))){
 			sinfo.sinfo_pr_policy=SCTP_PR_SCTP_TTL;
-			sinfo.sinfo_pr_value=sctp_options.sctp_send_ttl;
+			sinfo.sinfo_pr_value=send_ttl;
 		}else
 			sinfo.info_pr_policy=SCTP_PR_SCTP_NONE;
 #else
-		sinfo.sinfo_timetolive=sctp_options.sctp_send_ttl;
+		sinfo.sinfo_timetolive=cfg_get(sctp, sctp_cfg, send_ttl);
 #endif
 		sinfo.sinfo_context=retries;
 		
@@ -1722,7 +1729,7 @@ static int sctp_handle_send_failed(struct socket_info* si,
 	}
 #ifdef USE_DST_BLACKLIST
 	 else if (cfg_get(core, core_cfg, use_dst_blacklist) &&
-					sctp_options.sctp_send_retries) {
+					cfg_get(sctp, sctp_cfg, send_retries)) {
 		/* blacklist only if send_retries is on, if off we blacklist
 		   from SCTP_ASSOC_CHANGE: SCTP_COMM_LOST/SCTP_CANT_STR_ASSOC
 		   which is better (because we can tell connect errors from send
@@ -1782,7 +1789,7 @@ again:
 			/* blacklist only if send_retries is turned off (if on we don't
 			   know here if we did retry or we are at the first error) */
 			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
-					(sctp_options.sctp_send_retries==0))
+					(cfg_get(sctp, sctp_cfg, send_retries)==0))
 						dst_blacklist_su(BLST_ERR_SEND, PROTO_SCTP, su, 0);
 #endif /* USE_DST_BLACKLIST */
 			/* no break */
@@ -1811,7 +1818,7 @@ again:
 			/* blacklist only if send_retries is turned off (if on we don't 
 			   know here if we did retry or we are at the first error) */
 			if (cfg_get(core, core_cfg, use_dst_blacklist) &&
-					(sctp_options.sctp_send_retries==0))
+					(cfg_get(sctp, sctp_cfg, send_retries)==0))
 						dst_blacklist_su(BLST_ERR_CONNECT, PROTO_SCTP, su, 0);
 #endif /* USE_DST_BLACKLIST */
 			break;
@@ -2266,19 +2273,22 @@ again:
 int sctp_msg_send(struct dest_info* dst, char* buf, unsigned len)
 {
 	struct sctp_sndrcvinfo sinfo;
+#ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
+	int send_ttl;
+#endif
 	
 	memset(&sinfo, 0, sizeof(sinfo));
 	sinfo.sinfo_flags=SCTP_UNORDERED;
 #ifdef HAVE_SCTP_SNDRCVINFO_PR_POLICY
-	if (sctp_options.sctp_send_ttl){
+	if ((send_ttl=cfg_get(sctp, sctp_cfg, send_ttl))){
 		sinfo.sinfo_pr_policy=SCTP_PR_SCTP_TTL;
-		sinfo.sinfo_pr_value=sctp_options.sctp_send_ttl;
+		sinfo.sinfo_pr_value=send_ttl;
 	}else
 		sinfo->sinfo_pr_policy=SCTP_PR_SCTP_NONE;
 #else
-		sinfo.sinfo_timetolive=sctp_options.sctp_send_ttl;
+		sinfo.sinfo_timetolive=cfg_get(sctp, sctp_cfg, send_ttl);
 #endif
-	sinfo.sinfo_context=sctp_options.sctp_send_retries;
+	sinfo.sinfo_context=cfg_get(sctp, sctp_cfg, send_retries);
 	return sctp_msg_send_raw(dst, buf, len, &sinfo);
 }