Browse code

sctp: sctp autoclose can now be changed at runtime

sctp_autoclose can now be changed at runtime, but it will affect
only new associations (autoclose for the pre-existing ones will
not be changed).
E.g.:
$ sercmd cfg.set_now_int sctp autoclose 120

Andrei Pelinescu-Onciul authored on 29/05/2009 08:42:28
Showing 4 changed files
... ...
@@ -271,11 +271,14 @@ new config variables:
271 271
   sctp_socket_rcvbuf = number - size for the sctp socket receive buffer
272 272
   sctp_socket_sndbuf = number - size for the sctp socket send buffer
273 273
   sctp_autoclose = seconds - number of seconds before autoclosing an idle
274
-     assocation (default: 180 s).
274
+                   assocation (default: 180 s).
275
+                   Can be changed at runtime, but it will affect only new
276
+                   associations. E.g.:
277
+                   $ sercmd cfg.set_now_int sctp autoclose 120
275 278
   sctp_send_ttl = milliseconds - number of milliseconds before an unsent
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
279
+                  message/chunk is dropped (default: 32000 ms or 32 s).
280
+                  Can be changed at runtime, e.g.:
281
+                  $ sercmd cfg.set_now_int sctp send_ttl 180000
279 282
   sctp_send_retries - how many times to attempt re-sending a message on a
280 283
                       re-opened association, if the sctp stack did give up
281 284
                       sending it (it's not related to sctp protocol level
... ...
@@ -26,16 +26,29 @@
26 26
  */
27 27
 
28 28
 #include <string.h>
29
+#include <sys/types.h>
30
+#include <sys/socket.h>
31
+#include <netinet/in.h>
32
+#include <netinet/in_systm.h>
33
+#include <netinet/ip.h>
34
+#include <netinet/sctp.h>
35
+#include <errno.h>
29 36
 
30 37
 #include "sctp_options.h"
31 38
 #include "dprint.h"
32 39
 #include "cfg/cfg.h"
40
+#include "socket_info.h"
41
+#include "sctp_server.h"
33 42
 
34 43
 struct cfg_group_sctp sctp_default_cfg;
35 44
 
36 45
 
37 46
 
38 47
 #ifdef USE_SCTP
48
+
49
+
50
+static int set_autoclose(void* cfg_h, str* gname, str* name, void** val);
51
+
39 52
 /** cfg_group_sctp description (for the config framework). */
40 53
 static cfg_def_t sctp_cfg_def[] = {
41 54
 	/*   name        , type |input type| chg type, min, max, fixup, proc. cbk.
... ...
@@ -44,7 +57,7 @@ static cfg_def_t sctp_cfg_def[] = {
44 44
 		"socket receive buffer size (read-only)" },
45 45
 	{ "socket_sndbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
46 46
 		"socket send buffer size (read-only)" },
47
-	{ "autoclose", CFG_VAR_INT| CFG_READONLY, 1, 1<<30, 0, 0,
47
+	{ "autoclose", CFG_VAR_INT| CFG_ATOMIC, 1, 1<<30, set_autoclose, 0,
48 48
 		"seconds before closing and idle connection (must be non-zero)" },
49 49
 	{ "send_ttl", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, 0, 0,
50 50
 		"milliseconds before aborting a send" },
... ...
@@ -123,4 +136,26 @@ int sctp_register_cfg()
123 123
 	}
124 124
 	return 0;
125 125
 }
126
+
127
+
128
+
129
+static int set_autoclose(void* cfg_h, str* gname, str* name, void** val)
130
+{
131
+#ifdef SCTP_AUTOCLOSE
132
+	int optval;
133
+	int err;
134
+	struct socket_info* si;
135
+	
136
+	optval=(int)(long)(*val);
137
+	err=0;
138
+	for (si=sctp_listen; si; si=si->next){
139
+		err+=(sctp_sockopt(si, IPPROTO_SCTP, SCTP_AUTOCLOSE, (void*)&optval,
140
+							sizeof(optval), "cfg: setting SCTP_AUTOCLOSE")<0);
141
+	}
142
+	return -(err!=0);
143
+#else
144
+	ERR("no SCTP_AUTOCLOSE support, please upgrade your sctp library\n");
145
+	return -1;
146
+#endif /* SCTP_AUTOCLOSE */
147
+}
126 148
 #endif /* USE_SCTP */
... ...
@@ -185,6 +185,23 @@ error:
185 185
 
186 186
 
187 187
 
188
+/** set a socket option (wrapper over setsockopt).
189
+  * @param err_prefix - if 0 no error message is printed on failure, if !=0
190
+  *                     it will be prepended to the error message.
191
+  * @return 0 on success, -1 on error */
192
+int sctp_sockopt(struct socket_info* si, int level, int optname, void* optval,
193
+					socklen_t optlen, char* err_prefix)
194
+{
195
+	if (setsockopt(si->socket, level, optname, optval, optlen) ==-1){
196
+		if (err_prefix)
197
+			ERR("%s: %s [%d]\n", err_prefix, strerror(errno), errno);
198
+		return -1;
199
+	}
200
+	return 0;
201
+}
202
+
203
+
204
+
188 205
 /* set common (for one to many and one to one) sctp socket options
189 206
    tries to ignore non-critical errors (it will only log them), for
190 207
    improved portability (for example older linux kernel version support
... ...
@@ -48,4 +48,6 @@ void sctp_get_info(struct sctp_gen_info* sinf);
48 48
 
49 49
 void destroy_sctp();
50 50
 
51
+int sctp_sockopt(struct socket_info* si, int level, int optname, void* optval,
52
+					socklen_t optlen, char* err_prefix);
51 53
 #endif /* _sctp_server_h */