Browse code

sctp: more config variables

Added more config variables for various sctp protocol specific
parameters:
asocmaxrxt - maximum retransmissions attempts per association
init_max_attempts - maximum INIT retransmission attempts
init_max_timeo - maximum INIT retransmission timeout (RTO max for
INIT)
hbinterval - sctp heartbeat interval, -1 for disable
pathmaxrxt - maximum retransmission attempts per path
sack_delay - delay until an ACK is generated after receiving a
packet.
sack_freq - number of packets received before an ACK is sent
max_burst - maximum burst of packets that can be emitted by an
association

All of them can be changed at runtime (e.g.
$ sercmd cfg.set_now_int sctp hbinterval -1 ), but the changes
will affect only new associations (they will not affect the
already established ones).

Andrei Pelinescu-Onciul authored on 10/06/2009 23:21:25
Showing 3 changed files
... ...
@@ -51,6 +51,16 @@ static int set_autoclose(void* cfg_h, str* gname, str* name, void** val);
51 51
 static int set_srto_initial(void* cfg_h, str* gname, str* name, void** val);
52 52
 static int set_srto_max(void* cfg_h, str* gname, str* name, void** val);
53 53
 static int set_srto_min(void* cfg_h, str* gname, str* name, void** val);
54
+static int set_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val);
55
+static int set_sinit_max_attempts(void* cfg_h, str* gname, str* name,
56
+										void** val);
57
+static int set_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
58
+										void** val);
59
+static int set_hbinterval(void* cfg_h, str* gname, str* name, void** val);
60
+static int set_pathmaxrxt(void* cfg_h, str* gname, str* name, void** val);
61
+static int set_sack_freq(void* cfg_h, str* gname, str* name, void** val);
62
+static int set_sack_delay(void* cfg_h, str* gname, str* name, void** val);
63
+static int set_max_burst(void* cfg_h, str* gname, str* name, void** val);
54 64
 
55 65
 /** cfg_group_sctp description (for the config framework). */
56 66
 static cfg_def_t sctp_cfg_def[] = {
... ...
@@ -72,7 +82,24 @@ static cfg_def_t sctp_cfg_def[] = {
72 82
 	{ "srto_max", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_max, 0,
73 83
 		"maximum value of the retransmission timeout (RTO), in msecs" },
74 84
 	{ "srto_min", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_min, 0,
75
-		"minimum value og the retransmission timeout (RTO), in msecs" },
85
+		"minimum value of the retransmission timeout (RTO), in msecs" },
86
+	{ "asocmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_asocmaxrxt, 0,
87
+		"maximum retransmission attempts per association" },
88
+	{ "init_max_attempts", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
89
+		set_sinit_max_attempts, 0, "max INIT retransmission attempts" },
90
+	{ "init_max_timeo", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
91
+		set_sinit_max_init_timeo, 0,
92
+		"max INIT retransmission timeout (RTO max for INIT), in msecs" },
93
+	{ "hbinterval", CFG_VAR_INT| CFG_ATOMIC, 0, 0, set_hbinterval, 0,
94
+		"heartbeat interval in msecs" },
95
+	{ "pathmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_pathmaxrxt, 0,
96
+		"maximum retransmission attempts per path" },
97
+	{ "sack_delay", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_sack_delay, 0,
98
+		"time since the last received packet before sending a SACK, in msecs"},
99
+	{ "sack_freq", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_sack_freq, 0,
100
+		"number of received packets that trigger the sending of a SACK"},
101
+	{ "max_burst", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_max_burst, 0,
102
+		"maximum burst of packets that can be emitted by an association"},
76 103
 	{0, 0, 0, 0, 0, 0, 0}
77 104
 };
78 105
 
... ...
@@ -250,4 +277,202 @@ static int set_srto_min(void* cfg_h, str* gname, str* name, void** val)
250 277
 #endif /* SCTP_RTOINFO */
251 278
 }
252 279
 
280
+
281
+
282
+static int set_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val)
283
+{
284
+#ifdef SCTP_ASSOCINFO
285
+	struct sctp_assocparams ap;
286
+	SCTP_SET_SOCKOPT_DECLS;
287
+	
288
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
289
+		*val=(void*)(long)cfg_get(sctp, cfg_h, asocmaxrxt);
290
+		return 0;
291
+	}
292
+	memset(&ap, 0, sizeof(ap)); /* zero everything we don't care about */
293
+	ap.sasoc_assoc_id=0; /* all */
294
+	ap.sasoc_asocmaxrxt=(int)(long)(*val);
295
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_ASSOCINFO, ap,
296
+							"cfg: setting SCTP_ASSOCINFO");
297
+#else
298
+	ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
299
+	return -1;
300
+#endif /* SCTP_ASSOCINFO */
301
+}
302
+
303
+
304
+
305
+static int set_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
306
+									void** val)
307
+{
308
+#ifdef SCTP_INITMSG
309
+	struct sctp_initmsg im;
310
+	SCTP_SET_SOCKOPT_DECLS;
311
+	
312
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
313
+		*val=(void*)(long)cfg_get(sctp, cfg_h, init_max_timeo);
314
+		return 0;
315
+	}
316
+	memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
317
+	im.sinit_max_init_timeo=(int)(long)(*val);
318
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
319
+							"cfg: setting SCTP_INITMSG");
320
+#else
321
+	ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
322
+	return -1;
323
+#endif /* SCTP_INITMSG */
324
+}
325
+
326
+
327
+
328
+static int set_sinit_max_attempts(void* cfg_h, str* gname, str* name,
329
+									void** val)
330
+{
331
+#ifdef SCTP_INITMSG
332
+	struct sctp_initmsg im;
333
+	SCTP_SET_SOCKOPT_DECLS;
334
+	
335
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
336
+		*val=(void*)(long)cfg_get(sctp, cfg_h, init_max_attempts);
337
+		return 0;
338
+	}
339
+	memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
340
+	im.sinit_max_attempts=(int)(long)(*val);
341
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
342
+							"cfg: setting SCTP_INITMSG");
343
+#else
344
+	ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
345
+	return -1;
346
+#endif /* SCTP_INITMSG */
347
+}
348
+
349
+
350
+
351
+static int set_hbinterval(void* cfg_h, str* gname, str* name,
352
+									void** val)
353
+{
354
+#ifdef SCTP_PEER_ADDR_PARAMS
355
+	struct sctp_paddrparams pp;
356
+	SCTP_SET_SOCKOPT_DECLS;
357
+	
358
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
359
+		*val=(void*)(long)cfg_get(sctp, cfg_h, hbinterval);
360
+		return 0;
361
+	}
362
+	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
363
+	if ((int)(long)(*val)!=-1){
364
+		pp.spp_hbinterval=(int)(long)(*val);
365
+		pp.spp_flags=SPP_HB_ENABLE;
366
+	}else{
367
+		pp.spp_flags=SPP_HB_DISABLE;
368
+	}
369
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
370
+							"cfg: setting SCTP_PEER_ADDR_PARAMS");
371
+#else
372
+	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
373
+			" sctp library\n");
374
+	return -1;
375
+#endif /* SCTP_PEER_ADDR_PARAMS */
376
+}
377
+
378
+
379
+
380
+static int set_pathmaxrxt(void* cfg_h, str* gname, str* name,
381
+									void** val)
382
+{
383
+#ifdef SCTP_PEER_ADDR_PARAMS
384
+	struct sctp_paddrparams pp;
385
+	SCTP_SET_SOCKOPT_DECLS;
386
+	
387
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
388
+		*val=(void*)(long)cfg_get(sctp, cfg_h, pathmaxrxt);
389
+		return 0;
390
+	}
391
+	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
392
+	pp.spp_pathmaxrxt=(int)(long)(*val);
393
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
394
+							"cfg: setting SCTP_PEER_ADDR_PARAMS");
395
+#else
396
+	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
397
+			" sctp library\n");
398
+	return -1;
399
+#endif /* SCTP_PEER_ADDR_PARAMS */
400
+}
401
+
402
+
403
+
404
+static int set_sack_delay(void* cfg_h, str* gname, str* name, void** val)
405
+{
406
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
407
+#ifdef SCTP_DELAYED_SACK
408
+	struct sctp_sack_info sa;
409
+#else /* old lib */
410
+	struct sctp_assoc_value sa;
411
+#endif /* SCTP_DELAYED_SACK */
412
+	SCTP_SET_SOCKOPT_DECLS;
413
+	
414
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
415
+		*val=(void*)(long)cfg_get(sctp, cfg_h, sack_delay);
416
+		return 0;
417
+	}
418
+	memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
419
+#ifdef SCTP_DELAYED_SACK
420
+	sa.sack_delay=(int)(long)(*val);
421
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
422
+							"cfg: setting SCTP_DELAYED_SACK");
423
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
424
+	sa.assoc_value=(int)(long)(*val);
425
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, sa,
426
+							"cfg: setting SCTP_DELAYED_ACK_TIME");
427
+#endif /* SCTP_DELAYED_SACK */
428
+#else
429
+	ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
430
+	return -1;
431
+#endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
432
+}
433
+
434
+
435
+
436
+static int set_sack_freq(void* cfg_h, str* gname, str* name, void** val)
437
+{
438
+#ifdef SCTP_DELAYED_SACK
439
+	struct sctp_sack_info sa;
440
+	SCTP_SET_SOCKOPT_DECLS;
441
+	
442
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
443
+		*val=(void*)(long)cfg_get(sctp, cfg_h, sack_freq);
444
+		return 0;
445
+	}
446
+	memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
447
+	sa.sack_freq=(int)(long)(*val);
448
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
449
+							"cfg: setting SCTP_DELAYED_SACK");
450
+#else
451
+	ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
452
+	return -1;
453
+#endif /* SCTP_DELAYED_SACK */
454
+}
455
+
456
+
457
+
458
+static int set_max_burst(void* cfg_h, str* gname, str* name, void** val)
459
+{
460
+#ifdef SCTP_MAX_BURST
461
+	struct sctp_assoc_value av;
462
+	SCTP_SET_SOCKOPT_DECLS;
463
+	
464
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
465
+		*val=(void*)(long)cfg_get(sctp, cfg_h, max_burst);
466
+		return 0;
467
+	}
468
+	memset(&av, 0, sizeof(av)); /* zero everything we don't care about */
469
+	av.assoc_value=(int)(long)(*val);
470
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_MAX_BURST, av,
471
+							"cfg: setting SCTP_MAX_BURST");
472
+#else
473
+	ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
474
+	return -1;
475
+#endif /* SCTP_MAX_BURST */
476
+}
477
+
253 478
 #endif /* USE_SCTP */
... ...
@@ -40,9 +40,17 @@ struct cfg_group_sctp{
40 40
 	unsigned int autoclose; /* in seconds */
41 41
 	unsigned int send_ttl; /* in milliseconds */
42 42
 	unsigned int send_retries;
43
-	unsigned int srto_initial;
44
-	unsigned int srto_max;
45
-	unsigned int srto_min;
43
+	unsigned int srto_initial; /** initial retr. timeout */
44
+	unsigned int srto_max;     /** max retr. timeout */
45
+	unsigned int srto_min;     /** min retr. timeout */
46
+	unsigned int asocmaxrxt; /** max. retr. attempts per association */
47
+	unsigned int init_max_attempts; /** max., INIT retr. attempts */
48
+	unsigned int init_max_timeo; /** rto max for INIT */
49
+	unsigned int hbinterval;  /** heartbeat interval in msecs */
50
+	unsigned int pathmaxrxt;  /** max. retr. attempts per path */
51
+	unsigned int sack_delay; /** msecs after which a delayed SACK is sent */
52
+	unsigned int sack_freq; /** no. of packets after which a SACK is sent */
53
+	unsigned int max_burst; /** maximum burst of packets per assoc. */
46 54
 };
47 55
 
48 56
 extern struct cfg_group_sctp sctp_default_cfg;
... ...
@@ -234,6 +234,23 @@ int sctp_get_os_defaults(struct cfg_group_sctp* cfg)
234 234
 #ifdef SCTP_RTOINFO
235 235
 	struct sctp_rtoinfo rto;
236 236
 #endif /* SCTP_RTOINFO */
237
+#ifdef SCTP_ASSOCINFO
238
+	struct sctp_assocparams ap;
239
+#endif /* SCTP_ASSOCINFO */
240
+#ifdef SCTP_INITMSG
241
+	struct sctp_initmsg im;
242
+#endif /* SCTP_INITMSG */
243
+#ifdef SCTP_PEER_ADDR_PARAMS
244
+	struct sctp_paddrparams pp;
245
+#endif /* SCTP_PEER_ADDR_PARAMS */
246
+#ifdef SCTP_DELAYED_SACK
247
+	struct sctp_sack_info sa;
248
+#elif defined SCTP_DELAYED_ACK_TIME /* old version */
249
+	struct sctp_assoc_value sa;
250
+#endif /* SCTP_DELAYED_SACK */
251
+#ifdef SCTP_MAX_BURST
252
+	struct sctp_assoc_value av;
253
+#endif /* SCTP_MAX_BURST */
237 254
 	
238 255
 	s = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
239 256
 	if (s==-1)
... ...
@@ -271,6 +288,63 @@ int sctp_get_os_defaults(struct cfg_group_sctp* cfg)
271 288
 		cfg->srto_max=rto.srto_max;
272 289
 	}
273 290
 #endif /* SCTP_RTOINFO */
291
+#ifdef SCTP_ASSOCINFO
292
+	optlen=sizeof(ap);
293
+	ap.sasoc_assoc_id=0;
294
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_ASSOCINFO, (void*)&ap,
295
+							&optlen, "SCTP_ASSOCINFO")==0){
296
+		/* success => hack to set the "default" values*/
297
+		cfg->asocmaxrxt=ap.sasoc_asocmaxrxt;
298
+	}
299
+#endif /* SCTP_ASSOCINFO */
300
+#ifdef SCTP_INITMSG
301
+	optlen=sizeof(im);
302
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, (void*)&im,
303
+							&optlen, "SCTP_INITMSG")==0){
304
+		/* success => hack to set the "default" values*/
305
+		cfg->init_max_attempts=im.sinit_max_attempts;
306
+		cfg->init_max_timeo=im.sinit_max_init_timeo;
307
+	}
308
+#endif /* SCTP_INITMSG */
309
+#ifdef SCTP_PEER_ADDR_PARAMS
310
+	optlen=sizeof(pp);
311
+	memset(&pp, 0, sizeof(pp)); /* get defaults */
312
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, (void*)&pp,
313
+							&optlen, "SCTP_PEER_ADDR_PARAMS")==0){
314
+		/* success => hack to set the "default" values*/
315
+		cfg->hbinterval=pp.spp_hbinterval;
316
+		cfg->pathmaxrxt=pp.spp_pathmaxrxt;
317
+	}
318
+#endif /* SCTP_PEER_ADDR_PARAMS */
319
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
320
+	optlen=sizeof(sa);
321
+	memset(&sa, 0, sizeof(sa));
322
+#ifdef SCTP_DELAYED_SACK
323
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_SACK, (void*)&sa,
324
+							&optlen, "SCTP_DELAYED_SACK")==0){
325
+		/* success => hack to set the "default" values*/
326
+		cfg->sack_delay=sa.sack_delay;
327
+		cfg->sack_freq=sa.sack_freq;
328
+	}
329
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
330
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, (void*)&sa,
331
+							&optlen, "SCTP_DELAYED_ACK_TIME")==0){
332
+		/* success => hack to set the "default" values*/
333
+		cfg->sack_delay=sa.assoc_value;
334
+		cfg->sack_freq=0; /* unknown */
335
+	}
336
+#endif /* SCTP_DELAYED_SACK */
337
+#endif /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK_TIME*/
338
+#ifdef SCTP_MAX_BURST
339
+	optlen=sizeof(av);
340
+	av.assoc_id=0;
341
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_MAX_BURST, (void*)&av,
342
+							&optlen, "SCTP_MAX_BURST")==0){
343
+		/* success => hack to set the "default" values*/
344
+		cfg->max_burst=av.assoc_value;
345
+	}
346
+#endif /* SCTP_MAX_BURST */
347
+	
274 348
 	close(s);
275 349
 	return 0;
276 350
 }
... ...
@@ -293,6 +367,24 @@ static int sctp_init_sock_opt_common(int s)
293 367
 #ifdef SCTP_RTOINFO
294 368
 	struct sctp_rtoinfo rto;
295 369
 #endif /* SCTP_RTOINFO */
370
+#ifdef SCTP_ASSOCINFO
371
+	struct sctp_assocparams ap;
372
+#endif /* SCTP_ASSOCINFO */
373
+#ifdef SCTP_INITMSG
374
+	struct sctp_initmsg im;
375
+#endif /* SCTP_INITMSG */
376
+#ifdef SCTP_PEER_ADDR_PARAMS
377
+	struct sctp_paddrparams pp;
378
+#endif /* SCTP_PEER_ADDR_PARAMS */
379
+#ifdef SCTP_DELAYED_SACK
380
+	struct sctp_sack_info sa;
381
+#elif defined SCTP_DELAYED_ACK_TIME /* old version */
382
+	struct sctp_assoc_value sa;
383
+#endif /* SCTP_DELAYED_SACK */
384
+#ifdef SCTP_MAX_BURST
385
+	struct sctp_assoc_value av;
386
+#endif /* SCTP_MAX_BURST */
387
+	
296 388
 #ifdef __OS_linux
297 389
 	union {
298 390
 		struct sctp_event_subscribe s;
... ...
@@ -470,6 +562,105 @@ static int sctp_init_sock_opt_common(int s)
470 562
 #else
471 563
 #warning no sctp lib support for SCTP_RTOINFO, consider upgrading
472 564
 #endif /* SCTP_RTOINFO */
565
+	/* set associnfo options: assocmaxrxt */
566
+#ifdef SCTP_ASSOCINFO
567
+	memset(&ap, 0, sizeof(ap));
568
+	ap.sasoc_asocmaxrxt=cfg_get(sctp, sctp_cfg, asocmaxrxt);
569
+	if (ap.sasoc_asocmaxrxt){
570
+		/* if at least one is non-null => we have to set it */
571
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_ASSOCINFO, (void*)&ap,
572
+							sizeof(ap), "setsockopt: SCTP_ASSOCINFO")!=0){
573
+			sctp_err++;
574
+			/* non critical, try to continue */
575
+		}
576
+	}
577
+#else
578
+#warning no sctp lib support for SCTP_ASSOCINFO, consider upgrading
579
+#endif /* SCTP_ASOCINFO */
580
+	/* set initmsg options: init_max_attempts & init_max_init_timeo */
581
+#ifdef SCTP_INITMSG
582
+	memset(&im, 0, sizeof(im));
583
+	im.sinit_max_attempts=cfg_get(sctp, sctp_cfg, init_max_attempts);
584
+	im.sinit_max_init_timeo=cfg_get(sctp, sctp_cfg, init_max_timeo);
585
+	if (im.sinit_max_attempts || im.sinit_max_init_timeo){
586
+		/* if at least one is non-null => we have to set it */
587
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, (void*)&im,
588
+							sizeof(im), "setsockopt: SCTP_INITMSG")!=0){
589
+			sctp_err++;
590
+			/* non critical, try to continue */
591
+		}
592
+	}
593
+#else
594
+#warning no sctp lib support for SCTP_INITMSG, consider upgrading
595
+#endif /* SCTP_INITMSG */
596
+	/* set sctp peer addr options: hbinterval & pathmaxrxt */
597
+#ifdef SCTP_PEER_ADDR_PARAMS
598
+	memset(&pp, 0, sizeof(pp));
599
+	pp.spp_hbinterval=cfg_get(sctp, sctp_cfg, hbinterval);
600
+	pp.spp_pathmaxrxt=cfg_get(sctp, sctp_cfg, pathmaxrxt);
601
+	if (pp.spp_hbinterval || pp.spp_pathmaxrxt){
602
+		if (pp.spp_hbinterval > 0)
603
+			pp.spp_flags=SPP_HB_ENABLE;
604
+		else if (pp.spp_hbinterval==-1){
605
+			pp.spp_flags=SPP_HB_DISABLE;
606
+			pp.spp_hbinterval=0;
607
+		}
608
+		/* if at least one is non-null => we have to set it */
609
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, (void*)&pp,
610
+						sizeof(pp), "setsockopt: SCTP_PEER_ADDR_PARAMS")!=0){
611
+			sctp_err++;
612
+			/* non critical, try to continue */
613
+		}
614
+	}
615
+#else
616
+#warning no sctp lib support for SCTP_PEER_ADDR_PARAMS, consider upgrading
617
+#endif /* SCTP_PEER_ADDR_PARAMS */
618
+	/* set delayed ack options: sack_delay & sack_freq */
619
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
620
+	memset(&sa, 0, sizeof(sa));
621
+#ifdef SCTP_DELAYED_SACK
622
+	sa.sack_delay=cfg_get(sctp, sctp_cfg, sack_delay);
623
+	sa.sack_freq=cfg_get(sctp, sctp_cfg, sack_freq);
624
+	if (sa.sack_delay || sa.sack_freq){
625
+		/* if at least one is non-null => we have to set it */
626
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_SACK, (void*)&sa,
627
+							sizeof(sa), "setsockopt: SCTP_DELAYED_SACK")!=0){
628
+			sctp_err++;
629
+			/* non critical, try to continue */
630
+		}
631
+	}
632
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
633
+	sa.assoc_value=cfg_get(sctp, sctp_cfg, sack_delay);
634
+	if (sa.assoc_value){
635
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, (void*)&sa,
636
+						sizeof(sa), "setsockopt: SCTP_DELAYED_ACK_TIME")!=0){
637
+			sctp_err++;
638
+			/* non critical, try to continue */
639
+		}
640
+	}
641
+	if (cfg_get(sctp, sctp_cfg, sack_freq)){
642
+		WARN("could not set sctp sack_freq, please upgrade your sctp"
643
+				" library\n");
644
+		((struct cfg_group_sctp*)sctp_cfg)->sack_freq=0;
645
+	}
646
+#endif /* SCTP_DELAYED_SACK */
647
+#else /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK*/
648
+#warning no sctp lib support for SCTP_DELAYED_SACK, consider upgrading
649
+#endif /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK_TIME*/
650
+	/* set max burst option */
651
+#ifdef SCTP_MAX_BURST
652
+	memset(&av, 0, sizeof(av));
653
+	av.assoc_value=cfg_get(sctp, sctp_cfg, max_burst);
654
+	if (av.assoc_value){
655
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_MAX_BURST, (void*)&av,
656
+							sizeof(av), "setsockopt: SCTP_MAX_BURST")!=0){
657
+			sctp_err++;
658
+			/* non critical, try to continue */
659
+		}
660
+	}
661
+#else
662
+#warning no sctp lib support for SCTP_MAX_BURST, consider upgrading
663
+#endif /* SCTP_MAX_BURST */
473 664
 	
474 665
 	memset(&es, 0, sizeof(es));
475 666
 	/* SCTP_EVENTS for SCTP_SNDRCV (sctp_data_io_event) -> per message