modules/lcr: Fixed to/from_gw tests when proto parameter is 0 (ANY)
[sip-router] / sctp_options.c
1 /* 
2  * $Id$
3  * 
4  * Copyright (C) 2008 iptelorg GmbH
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /* 
19  * sctp options
20  */
21 /*
22  * History:
23  * --------
24  *  2008-08-07  initial version (andrei)
25  *  2009-05-26  runtime cfg support (andrei)
26  */
27
28 /*!
29  * \file
30  * \brief SIP-router core :: 
31  * \ingroup core
32  * Module: \ref core
33  */
34
35 #include <string.h>
36 #include <sys/types.h>
37 #ifdef USE_SCTP
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/ip.h>
42 #include <netinet/sctp.h>
43 #endif /* USE_SCTP */
44 #include <errno.h>
45
46 #include "sctp_options.h"
47 #include "dprint.h"
48 #include "cfg/cfg.h"
49 #include "socket_info.h"
50 #include "sctp_server.h"
51
52 struct cfg_group_sctp sctp_default_cfg;
53
54
55
56 #ifdef USE_SCTP
57
58 #include "sctp_sockopts.h"
59
60 static int fix_autoclose(void* cfg_h, str* gname, str* name, void** val);
61 static void set_autoclose(str* gname, str* name);
62 static int fix_assoc_tracking(void* cfg_h, str* gname, str* name, void** val);
63 static int fix_assoc_reuse(void* cfg_h, str* gname, str* name, void** val);
64 static int fix_srto_initial(void* cfg_h, str* gname, str* name, void** val);
65 static void set_srto_initial(str* gname, str* name);
66 static int fix_srto_max(void* cfg_h, str* gname, str* name, void** val);
67 static void set_srto_max(str* gname, str* name);
68 static int fix_srto_min(void* cfg_h, str* gname, str* name, void** val);
69 static void set_srto_min(str* gname, str* name);
70 static int fix_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val);
71 static void set_asocmaxrxt(str* gname, str* name);
72 static int fix_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
73                                                                                 void** val);
74 static void set_sinit_max_init_timeo(str* gname, str* name);
75 static int fix_sinit_max_attempts(void* cfg_h, str* gname, str* name,
76                                                                                 void** val);
77 static void set_sinit_max_attempts(str* gname, str* name);
78 static int fix_hbinterval(void* cfg_h, str* gname, str* name, void** val);
79 static void set_hbinterval(str* gname, str* name);
80 static int fix_pathmaxrxt(void* cfg_h, str* gname, str* name, void** val);
81 static void set_pathmaxrxt(str* gname, str* name);
82 static int fix_sack_delay(void* cfg_h, str* gname, str* name, void** val);
83 static void set_sack_delay(str* gname, str* name);
84 static int fix_sack_freq(void* cfg_h, str* gname, str* name, void** val);
85 static void set_sack_freq(str* gname, str* name);
86 static int fix_max_burst(void* cfg_h, str* gname, str* name, void** val);
87 static void set_max_burst(str* gname, str* name);
88
89 /** cfg_group_sctp description (for the config framework). */
90 static cfg_def_t sctp_cfg_def[] = {
91         /*   name        , type |input type| chg type, min, max, fixup, proc. cbk.
92               description */
93         { "socket_rcvbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
94                 "socket receive buffer size (read-only)" },
95         { "socket_sndbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
96                 "socket send buffer size (read-only)" },
97         { "autoclose", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 1, 1<<30,
98                 fix_autoclose, set_autoclose,
99                 "seconds before closing and idle connection (must be non-zero)" },
100         { "send_ttl", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, 0, 0,
101                 "milliseconds before aborting a send" },
102         { "send_retries", CFG_VAR_INT| CFG_ATOMIC, 0, MAX_SCTP_SEND_RETRIES, 0, 0,
103                 "re-send attempts on failure" },
104         { "assoc_tracking", CFG_VAR_INT| CFG_ATOMIC, 0, 1, fix_assoc_tracking, 0,
105                 "connection/association tracking (see also assoc_reuse)" },
106         { "assoc_reuse", CFG_VAR_INT| CFG_ATOMIC, 0, 1, fix_assoc_reuse, 0,
107                 "connection/association reuse (for now used only for replies)"
108                 ", depends on assoc_tracking being set"},
109         { "max_assocs", CFG_VAR_INT| CFG_ATOMIC, 0, 0, 0, 0,
110                 "maximum allowed open associations (-1 = disable, "
111                         "as many as allowed by the OS)"},
112         { "srto_initial", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
113                 fix_srto_initial, set_srto_initial,
114                 "initial value of the retr. timeout, used in RTO calculations,"
115                         " in msecs" },
116         { "srto_max", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
117                 fix_srto_max, set_srto_max,
118                 "maximum value of the retransmission timeout (RTO), in msecs" },
119         { "srto_min", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
120                 fix_srto_min, set_srto_min,
121                 "minimum value of the retransmission timeout (RTO), in msecs" },
122         { "asocmaxrxt", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
123                 fix_asocmaxrxt, set_asocmaxrxt,
124                 "maximum retransmission attempts per association" },
125         { "init_max_attempts", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
126                 fix_sinit_max_attempts, set_sinit_max_attempts,
127                 "max INIT retransmission attempts" },
128         { "init_max_timeo", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
129                 fix_sinit_max_init_timeo, set_sinit_max_init_timeo,
130                 "max INIT retransmission timeout (RTO max for INIT), in msecs" },
131         { "hbinterval", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
132                 fix_hbinterval, set_hbinterval, "heartbeat interval in msecs" },
133         { "pathmaxrxt", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
134                 fix_pathmaxrxt, set_pathmaxrxt,
135                 "maximum retransmission attempts per path" },
136         { "sack_delay", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
137                 fix_sack_delay, set_sack_delay,
138                 "time since the last received packet before sending a SACK, in msecs"},
139         { "sack_freq", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
140                 fix_sack_freq, set_sack_freq,
141                 "number of received packets that trigger the sending of a SACK"},
142         { "max_burst", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
143                 fix_max_burst, set_max_burst,
144                 "maximum burst of packets that can be emitted by an association"},
145         {0, 0, 0, 0, 0, 0, 0}
146 };
147
148
149
150 void* sctp_cfg; /* sctp config handle */
151
152 #endif /* USE_SCTP */
153
154 void init_sctp_options()
155 {
156 #ifdef USE_SCTP
157         sctp_get_os_defaults(&sctp_default_cfg);
158 #if 0
159         sctp_default_cfg.so_rcvbuf=0; /* do nothing, use the kernel default */
160         sctp_default_cfg.so_sndbuf=0; /* do nothing, use the kernel default */
161 #endif
162         sctp_default_cfg.autoclose=DEFAULT_SCTP_AUTOCLOSE; /* in seconds */
163         sctp_default_cfg.send_ttl=DEFAULT_SCTP_SEND_TTL;   /* in milliseconds */
164         sctp_default_cfg.send_retries=DEFAULT_SCTP_SEND_RETRIES;
165         sctp_default_cfg.max_assocs=-1; /* as much as possible by default */
166 #ifdef SCTP_CONN_REUSE
167         sctp_default_cfg.assoc_tracking=1; /* on by default */
168         sctp_default_cfg.assoc_reuse=1; /* on by default */
169 #else
170         sctp_default_cfg.assoc_tracking=0;
171         sctp_default_cfg.assoc_reuse=0;
172 #endif /* SCTP_CONN_REUSE */
173 #endif
174 }
175
176
177
178 #define W_OPT_NSCTP(option) \
179         if (sctp_default_cfg.option){\
180                 WARN("sctp_options: " #option \
181                         " cannot be enabled (sctp support not compiled-in)\n"); \
182                         sctp_default_cfg.option=0; \
183         }
184
185
186
187 void sctp_options_check()
188 {
189 #ifndef USE_SCTP
190         W_OPT_NSCTP(autoclose);
191         W_OPT_NSCTP(send_ttl);
192         W_OPT_NSCTP(send_retries);
193         W_OPT_NSCTP(assoc_tracking);
194         W_OPT_NSCTP(assoc_reuse);
195         W_OPT_NSCTP(max_assocs);
196 #else /* USE_SCTP */
197         if (sctp_default_cfg.send_retries>MAX_SCTP_SEND_RETRIES) {
198                 WARN("sctp: sctp_send_retries too high (%d), setting it to %d\n",
199                                 sctp_default_cfg.send_retries, MAX_SCTP_SEND_RETRIES);
200                 sctp_default_cfg.send_retries=MAX_SCTP_SEND_RETRIES;
201         }
202 #ifndef CONN_REUSE
203         if (sctp_default_cfg.assoc_tracking || sctp_default_cfg.assoc_reuse){
204                 WARN("sctp_options: assoc_tracking and assoc_reuse support cannnot"
205                                 " be enabled (CONN_REUSE support not compiled-in)\n");
206                 sctp_default_cfg.assoc_tracking=0;
207                 sctp_default_cfg.assoc_reuse=0;
208         }
209 #else /* CONN_REUSE */
210         if (sctp_default_cfg.assoc_reuse && sctp_default_cfg.assoc_tracking==0){
211                 sctp_default_cfg.assoc_tracking=1;
212         }
213 #endif /* CONN_REUSE */
214 #endif /* USE_SCTP */
215 }
216
217
218
219 void sctp_options_get(struct cfg_group_sctp *s)
220 {
221 #ifdef USE_SCTP
222         *s=*(struct cfg_group_sctp*)sctp_cfg;
223 #else
224         memset(s, 0, sizeof(*s));
225 #endif /* USE_SCTP */
226 }
227
228
229
230 #ifdef USE_SCTP
231 /** register sctp config into the configuration framework.
232  * @return 0 on success, -1 on error */
233 int sctp_register_cfg()
234 {
235         if (cfg_declare("sctp", sctp_cfg_def, &sctp_default_cfg, cfg_sizeof(sctp),
236                                 &sctp_cfg))
237                 return -1;
238         if (sctp_cfg==0){
239                 BUG("null sctp cfg");
240                 return -1;
241         }
242         return 0;
243 }
244
245
246
247 #define SCTP_SET_SOCKOPT_DECLS \
248         int err; \
249         struct socket_info* si
250
251
252 #define SCTP_SET_SOCKOPT_BODY_NRET(lev, opt_name, val, err_prefix) \
253         err=0; \
254         for (si=sctp_listen; si; si=si->next){ \
255                 err+=(sctp_setsockopt(si->socket, (lev), (opt_name), (void*)(&(val)), \
256                                                         sizeof((val)), (err_prefix))<0); \
257         }
258
259 #define SCTP_SET_SOCKOPT_BODY(lev, opt_name, val, err_prefix) \
260         SCTP_SET_SOCKOPT_BODY_NRET(lev, opt_name, val, err_prefix) ; \
261         return -(err!=0)
262
263
264 static int fix_autoclose(void*cfg_h, str* gname, str* name, void** val)
265 {
266 #ifdef SCTP_AUTOCLOSE
267         return 0;
268 #else
269         ERR("no SCTP_AUTOCLOSE support, please upgrade your sctp library\n");
270         return -1;
271 #endif /* SCTP_AUTOCLOSE */
272 }
273
274
275 static void set_autoclose(str* gname, str* name)
276 {
277 #ifdef SCTP_AUTOCLOSE
278         int optval;
279         SCTP_SET_SOCKOPT_DECLS;
280         
281         optval=cfg_get(sctp, sctp_cfg, autoclose);
282         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_AUTOCLOSE, optval,
283                                                                 "cfg: setting SCTP_AUTOCLOSE");
284 #else
285         ERR("no SCTP_AUTOCLOSE support, please upgrade your sctp library\n");
286 #endif /* SCTP_AUTOCLOSE */
287 }
288
289
290
291 static int fix_assoc_tracking(void* cfg_h, str* gname, str* name, void** val)
292 {
293         int optval;
294         
295         optval=(int)(long)(*val);
296 #ifndef SCTP_CONN_REUSE
297         if (optval!=0){
298                 ERR("no SCTP_CONN_REUSE support, please recompile with it enabled\n");
299                 return -1;
300         }
301 #else /* SCTP_CONN_REUSE */
302         if (optval==0){
303                 /* turn tracking off */
304                 /* check if assoc_reuse is off */
305                 if (cfg_get(sctp, cfg_h, assoc_reuse)!=0){
306                         ERR("cannot turn sctp assoc_tracking off while assoc_reuse is"
307                                         " still on, please turn assoc_reuse off first\n");
308                         return -1;
309                 }
310                 sctp_con_tracking_flush();
311         }else if (optval==1 && cfg_get(sctp, cfg_h, assoc_reuse)==0){
312                 /* turning from off to on, make sure we flush the tracked list
313                    again, just incase the off flush was racing with a new connection*/
314                 sctp_con_tracking_flush();
315         }
316 #endif /* SCTP_CONN_REUSE */
317         return 0;
318 }
319
320
321
322 static int fix_assoc_reuse(void* cfg_h, str* gname, str* name, void** val)
323 {
324         int optval;
325         
326         optval=(int)(long)(*val);
327 #ifndef SCTP_CONN_REUSE
328         if (optval!=0){
329                 ERR("no SCTP_CONN_REUSE support, please recompile with it enabled\n");
330                 return -1;
331         }
332 #else /* SCTP_CONN_REUSE */
333         if (optval==1 && cfg_get(sctp, cfg_h, assoc_tracking)==0){
334                 /* conn reuse on, but assoc_tracking off => not possible */
335                 ERR("cannot turn sctp assoc_reuse on while assoc_tracking is"
336                                         " off, please turn assoc_tracking on first\n");
337                 return -1;
338         }
339 #endif /* SCTP_CONN_REUSE */
340         return 0;
341 }
342
343
344
345 static int fix_srto_initial(void* cfg_h, str* gname, str* name, void** val)
346 {
347 #ifdef SCTP_RTOINFO
348         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
349                 *val=(void*)(long)cfg_get(sctp, cfg_h, srto_initial);
350         }
351         return 0;
352 #else
353         ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
354         return -1;
355 #endif /* SCTP_RTOINFO */
356 }
357
358
359 static void set_srto_initial(str* gname, str* name)
360 {
361 #ifdef SCTP_RTOINFO
362         struct sctp_rtoinfo rto;
363         int optval;
364         SCTP_SET_SOCKOPT_DECLS;
365         
366         optval=cfg_get(sctp, sctp_cfg, srto_initial);
367         memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
368         rto.srto_assoc_id=0; /* all */
369         rto.srto_initial=optval;
370         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_RTOINFO, rto,
371                                                                 "cfg: setting SCTP_RTOINFO");
372 #else
373         ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
374 #endif /* SCTP_RTOINFO */
375 }
376
377
378
379 static int fix_srto_max(void* cfg_h, str* gname, str* name, void** val)
380 {
381 #ifdef SCTP_RTOINFO
382         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
383                 *val=(void*)(long)cfg_get(sctp, cfg_h, srto_max);
384         }
385         return 0;
386 #else
387         ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
388         return -1;
389 #endif /* SCTP_RTOINFO */
390 }
391
392
393 static void set_srto_max(str* gname, str* name)
394 {
395 #ifdef SCTP_RTOINFO
396         struct sctp_rtoinfo rto;
397         SCTP_SET_SOCKOPT_DECLS;
398         
399         memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
400         rto.srto_assoc_id=0; /* all */
401         rto.srto_max=cfg_get(sctp, sctp_cfg, srto_max);
402         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_RTOINFO, rto,
403                                                                 "cfg: setting SCTP_RTOINFO");
404 #else
405         ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
406 #endif /* SCTP_RTOINFO */
407 }
408
409
410
411 static int fix_srto_min(void* cfg_h, str* gname, str* name, void** val)
412 {
413 #ifdef SCTP_RTOINFO
414         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
415                 *val=(void*)(long)cfg_get(sctp, cfg_h, srto_min);
416         }
417         return 0;
418 #else
419         ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
420         return -1;
421 #endif /* SCTP_RTOINFO */
422 }
423
424
425 static void set_srto_min(str* gname, str* name)
426 {
427 #ifdef SCTP_RTOINFO
428         struct sctp_rtoinfo rto;
429         SCTP_SET_SOCKOPT_DECLS;
430         
431         memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
432         rto.srto_assoc_id=0; /* all */
433         rto.srto_min=cfg_get(sctp, sctp_cfg, srto_min);
434         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_RTOINFO, rto,
435                                                                 "cfg: setting SCTP_RTOINFO");
436 #else
437         ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
438 #endif /* SCTP_RTOINFO */
439 }
440
441
442
443 static int fix_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val)
444 {
445 #ifdef SCTP_ASSOCINFO
446         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
447                 *val=(void*)(long)cfg_get(sctp, cfg_h, asocmaxrxt);
448         }
449         return 0;
450 #else
451         ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
452         return -1;
453 #endif /* SCTP_ASSOCINFO */
454 }
455
456
457 static void set_asocmaxrxt(str* gname, str* name)
458 {
459 #ifdef SCTP_ASSOCINFO
460         struct sctp_assocparams ap;
461         SCTP_SET_SOCKOPT_DECLS;
462         
463         memset(&ap, 0, sizeof(ap)); /* zero everything we don't care about */
464         ap.sasoc_assoc_id=0; /* all */
465         ap.sasoc_asocmaxrxt= cfg_get(sctp, sctp_cfg, asocmaxrxt);
466         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_ASSOCINFO, ap,
467                                                                 "cfg: setting SCTP_ASSOCINFO");
468 #else
469         ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
470 #endif /* SCTP_ASSOCINFO */
471 }
472
473
474
475 static int fix_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
476                                                                         void** val)
477 {
478 #ifdef SCTP_INITMSG
479         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
480                 *val=(void*)(long)cfg_get(sctp, cfg_h, init_max_timeo);
481         }
482         return 0;
483 #else
484         ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
485         return -1;
486 #endif /* SCTP_INITMSG */
487 }
488
489
490 static void set_sinit_max_init_timeo(str* gname, str* name)
491 {
492 #ifdef SCTP_INITMSG
493         struct sctp_initmsg im;
494         SCTP_SET_SOCKOPT_DECLS;
495         
496         memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
497         im.sinit_max_init_timeo=cfg_get(sctp, sctp_cfg, init_max_timeo);
498         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_INITMSG, im,
499                                                                 "cfg: setting SCTP_INITMSG");
500 #else
501         ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
502 #endif /* SCTP_INITMSG */
503 }
504
505
506
507 static int fix_sinit_max_attempts(void* cfg_h, str* gname, str* name,
508                                                                         void** val)
509 {
510 #ifdef SCTP_INITMSG
511         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
512                 *val=(void*)(long)cfg_get(sctp, cfg_h, init_max_attempts);
513         }
514         return 0;
515 #else
516         ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
517         return -1;
518 #endif /* SCTP_INITMSG */
519 }
520
521
522 static void set_sinit_max_attempts(str* gname, str* name)
523 {
524 #ifdef SCTP_INITMSG
525         struct sctp_initmsg im;
526         SCTP_SET_SOCKOPT_DECLS;
527         
528         memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
529         im.sinit_max_attempts=cfg_get(sctp, sctp_cfg, init_max_attempts);
530         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_INITMSG, im,
531                                                                 "cfg: setting SCTP_INITMSG");
532 #else
533         ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
534 #endif /* SCTP_INITMSG */
535 }
536
537
538
539 static int fix_hbinterval(void* cfg_h, str* gname, str* name,
540                                                                         void** val)
541 {
542 #ifdef SCTP_PEER_ADDR_PARAMS
543         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
544                 *val=(void*)(long)cfg_get(sctp, cfg_h, hbinterval);
545         }
546         return 0;
547 #else
548         ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
549                         " sctp library\n");
550         return -1;
551 #endif /* SCTP_PEER_ADDR_PARAMS */
552 }
553
554
555 static void set_hbinterval(str* gname, str* name)
556 {
557 #ifdef SCTP_PEER_ADDR_PARAMS
558         struct sctp_paddrparams pp;
559         int optval;
560         SCTP_SET_SOCKOPT_DECLS;
561         
562         optval=cfg_get(sctp, sctp_cfg, hbinterval);
563         memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
564         if (optval!=-1){
565                 pp.spp_hbinterval=optval;
566                 pp.spp_flags=SPP_HB_ENABLE;
567         }else{
568                 pp.spp_flags=SPP_HB_DISABLE;
569         }
570         err=0;
571         for (si=sctp_listen; si; si=si->next){
572                 /* set the AF, needed on older linux kernels even for INADDR_ANY */
573                 pp.spp_address.ss_family=si->address.af;
574                 err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
575                                                                 (void*)(&pp), sizeof(pp),
576                                                                 "cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
577         }
578 #else
579         ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
580                         " sctp library\n");
581 #endif /* SCTP_PEER_ADDR_PARAMS */
582 }
583
584
585
586 static int fix_pathmaxrxt(void* cfg_h, str* gname, str* name,
587                                                                         void** val)
588 {
589 #ifdef SCTP_PEER_ADDR_PARAMS
590         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
591                 *val=(void*)(long)cfg_get(sctp, cfg_h, pathmaxrxt);
592         }
593         return 0;
594 #else
595         ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
596                         " sctp library\n");
597         return -1;
598 #endif /* SCTP_PEER_ADDR_PARAMS */
599 }
600
601
602 static void set_pathmaxrxt(str* gname, str* name)
603 {
604 #ifdef SCTP_PEER_ADDR_PARAMS
605         struct sctp_paddrparams pp;
606         SCTP_SET_SOCKOPT_DECLS;
607         
608         memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
609         pp.spp_pathmaxrxt=cfg_get(sctp, sctp_cfg, pathmaxrxt);
610         err=0;
611         for (si=sctp_listen; si; si=si->next){
612                 /* set the AF, needed on older linux kernels even for INADDR_ANY */
613                 pp.spp_address.ss_family=si->address.af;
614                 err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
615                                                                 (void*)(&pp), sizeof(pp),
616                                                                 "cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
617         }
618 #else
619         ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
620                         " sctp library\n");
621 #endif /* SCTP_PEER_ADDR_PARAMS */
622 }
623
624
625
626 static int fix_sack_delay(void* cfg_h, str* gname, str* name, void** val)
627 {
628 #if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
629         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
630                 *val=(void*)(long)cfg_get(sctp, cfg_h, sack_delay);
631         }
632         return 0;
633 #else
634         ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
635         return -1;
636 #endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
637 }
638
639
640 static void set_sack_delay(str* gname, str* name)
641 {
642 #if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
643 #ifdef SCTP_DELAYED_SACK
644         struct sctp_sack_info sack_info;
645 #endif /* SCTP_DELAYED_SACK */
646 #ifdef  SCTP_DELAYED_ACK_TIME
647         struct sctp_assoc_value sack_val; /* old version, sack delay only */
648 #endif /* SCTP_DELAYED_ACK_TIME */
649         SCTP_SET_SOCKOPT_DECLS;
650         
651 #ifdef SCTP_DELAYED_SACK
652         memset(&sack_info, 0, sizeof(sack_info)); /* zero everything we don't
653                                                                                                  care about */
654         sack_info.sack_delay=cfg_get(sctp, sctp_cfg, sack_delay);
655         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_DELAYED_SACK, sack_info, 0);
656         if (err==0){
657                 return;
658         }else
659 #endif /* SCTP_DELAYED_SACK */
660         {
661                 /* setting SCTP_DELAYED_SACK failed or no lib support for 
662                    SCTP_DELAYED_SACK => try the old obsolete SCTP_DELAYED_ACK_TIME */
663 #ifdef  SCTP_DELAYED_ACK_TIME
664                 memset(&sack_val, 0, sizeof(sack_val)); /* zero everything we don't
665                                                                                                    care about */
666                 sack_val.assoc_value=cfg_get(sctp, sctp_cfg, sack_delay);
667                 SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME,
668                                                                         sack_val,
669                                                                         "cfg: setting SCTP_DELAYED_ACK_TIME");
670                 if (err==0)
671                         return;
672 #else   /* SCTP_DELAYED_ACK_TIME */
673                 /* no SCTP_DELAYED_ACK_TIME support and SCTP_DELAYED_SACK failed
674                    => error */
675                 ERR("cfg: setting SCTP_DELAYED_SACK: %s [%d]\n",
676                                         strerror(errno), errno);
677 #endif /* SCTP_DELAYED_ACK_TIME */
678         }
679 #else
680         ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
681 #endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
682 }
683
684
685
686 static int fix_sack_freq(void* cfg_h, str* gname, str* name, void** val)
687 {
688 #ifdef SCTP_DELAYED_SACK
689         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
690                 *val=(void*)(long)cfg_get(sctp, cfg_h, sack_freq);
691         }
692         return 0;
693 #else
694         ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
695         return -1;
696 #endif /* SCTP_DELAYED_SACK */
697 }
698
699
700 static void set_sack_freq(str* gname, str* name)
701 {
702 #ifdef SCTP_DELAYED_SACK
703         struct sctp_sack_info sa;
704         SCTP_SET_SOCKOPT_DECLS;
705         
706         memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
707         sa.sack_freq=cfg_get(sctp, sctp_cfg, sack_freq);
708         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
709                                                                 "cfg: setting SCTP_DELAYED_SACK");
710 #else
711         ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
712 #endif /* SCTP_DELAYED_SACK */
713 }
714
715
716
717 static int fix_max_burst(void* cfg_h, str* gname, str* name, void** val)
718 {
719 #ifdef SCTP_MAX_BURST
720         if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
721                 *val=(void*)(long)cfg_get(sctp, cfg_h, max_burst);
722         }
723         return 0;
724 #else
725         ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
726         return -1;
727 #endif /* SCTP_MAX_BURST */
728 }
729
730
731 static void set_max_burst(str* gname, str* name)
732 {
733 #ifdef SCTP_MAX_BURST
734         struct sctp_assoc_value av;
735         SCTP_SET_SOCKOPT_DECLS;
736         
737         memset(&av, 0, sizeof(av)); /* zero everything we don't care about */
738         av.assoc_value=cfg_get(sctp, sctp_cfg, max_burst);
739         SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_MAX_BURST, av,
740                                                                 "cfg: setting SCTP_MAX_BURST");
741 #else
742         ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
743 #endif /* SCTP_MAX_BURST */
744 }
745
746 #endif /* USE_SCTP */