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 72
 	{ "srto_max", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_max, 0,
73 73
 		"maximum value of the retransmission timeout (RTO), in msecs" },
74 74
 	{ "srto_min", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_min, 0,
75
-		"minimum value og the retransmission timeout (RTO), in msecs" },
75
+		"minimum value of the retransmission timeout (RTO), in msecs" },
76
+	{ "asocmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_asocmaxrxt, 0,
77
+		"maximum retransmission attempts per association" },
78
+	{ "init_max_attempts", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
79
+		set_sinit_max_attempts, 0, "max INIT retransmission attempts" },
80
+	{ "init_max_timeo", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
81
+		set_sinit_max_init_timeo, 0,
82
+		"max INIT retransmission timeout (RTO max for INIT), in msecs" },
83
+	{ "hbinterval", CFG_VAR_INT| CFG_ATOMIC, 0, 0, set_hbinterval, 0,
84
+		"heartbeat interval in msecs" },
85
+	{ "pathmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_pathmaxrxt, 0,
86
+		"maximum retransmission attempts per path" },
87
+	{ "sack_delay", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_sack_delay, 0,
88
+		"time since the last received packet before sending a SACK, in msecs"},
89
+	{ "sack_freq", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_sack_freq, 0,
90
+		"number of received packets that trigger the sending of a SACK"},
91
+	{ "max_burst", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_max_burst, 0,
92
+		"maximum burst of packets that can be emitted by an association"},
76 93
 	{0, 0, 0, 0, 0, 0, 0}
77 94
 };
78 95
 
... ...
@@ -250,4 +277,202 @@ static int set_srto_min(void* cfg_h, str* gname, str* name, void** val)
250 250
 #endif /* SCTP_RTOINFO */
251 251
 }
252 252
 
253
+
254
+
255
+static int set_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val)
256
+{
257
+#ifdef SCTP_ASSOCINFO
258
+	struct sctp_assocparams ap;
259
+	SCTP_SET_SOCKOPT_DECLS;
260
+	
261
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
262
+		*val=(void*)(long)cfg_get(sctp, cfg_h, asocmaxrxt);
263
+		return 0;
264
+	}
265
+	memset(&ap, 0, sizeof(ap)); /* zero everything we don't care about */
266
+	ap.sasoc_assoc_id=0; /* all */
267
+	ap.sasoc_asocmaxrxt=(int)(long)(*val);
268
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_ASSOCINFO, ap,
269
+							"cfg: setting SCTP_ASSOCINFO");
270
+#else
271
+	ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
272
+	return -1;
273
+#endif /* SCTP_ASSOCINFO */
274
+}
275
+
276
+
277
+
278
+static int set_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
279
+									void** val)
280
+{
281
+#ifdef SCTP_INITMSG
282
+	struct sctp_initmsg im;
283
+	SCTP_SET_SOCKOPT_DECLS;
284
+	
285
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
286
+		*val=(void*)(long)cfg_get(sctp, cfg_h, init_max_timeo);
287
+		return 0;
288
+	}
289
+	memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
290
+	im.sinit_max_init_timeo=(int)(long)(*val);
291
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
292
+							"cfg: setting SCTP_INITMSG");
293
+#else
294
+	ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
295
+	return -1;
296
+#endif /* SCTP_INITMSG */
297
+}
298
+
299
+
300
+
301
+static int set_sinit_max_attempts(void* cfg_h, str* gname, str* name,
302
+									void** val)
303
+{
304
+#ifdef SCTP_INITMSG
305
+	struct sctp_initmsg im;
306
+	SCTP_SET_SOCKOPT_DECLS;
307
+	
308
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
309
+		*val=(void*)(long)cfg_get(sctp, cfg_h, init_max_attempts);
310
+		return 0;
311
+	}
312
+	memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
313
+	im.sinit_max_attempts=(int)(long)(*val);
314
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
315
+							"cfg: setting SCTP_INITMSG");
316
+#else
317
+	ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
318
+	return -1;
319
+#endif /* SCTP_INITMSG */
320
+}
321
+
322
+
323
+
324
+static int set_hbinterval(void* cfg_h, str* gname, str* name,
325
+									void** val)
326
+{
327
+#ifdef SCTP_PEER_ADDR_PARAMS
328
+	struct sctp_paddrparams pp;
329
+	SCTP_SET_SOCKOPT_DECLS;
330
+	
331
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
332
+		*val=(void*)(long)cfg_get(sctp, cfg_h, hbinterval);
333
+		return 0;
334
+	}
335
+	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
336
+	if ((int)(long)(*val)!=-1){
337
+		pp.spp_hbinterval=(int)(long)(*val);
338
+		pp.spp_flags=SPP_HB_ENABLE;
339
+	}else{
340
+		pp.spp_flags=SPP_HB_DISABLE;
341
+	}
342
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
343
+							"cfg: setting SCTP_PEER_ADDR_PARAMS");
344
+#else
345
+	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
346
+			" sctp library\n");
347
+	return -1;
348
+#endif /* SCTP_PEER_ADDR_PARAMS */
349
+}
350
+
351
+
352
+
353
+static int set_pathmaxrxt(void* cfg_h, str* gname, str* name,
354
+									void** val)
355
+{
356
+#ifdef SCTP_PEER_ADDR_PARAMS
357
+	struct sctp_paddrparams pp;
358
+	SCTP_SET_SOCKOPT_DECLS;
359
+	
360
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
361
+		*val=(void*)(long)cfg_get(sctp, cfg_h, pathmaxrxt);
362
+		return 0;
363
+	}
364
+	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
365
+	pp.spp_pathmaxrxt=(int)(long)(*val);
366
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
367
+							"cfg: setting SCTP_PEER_ADDR_PARAMS");
368
+#else
369
+	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
370
+			" sctp library\n");
371
+	return -1;
372
+#endif /* SCTP_PEER_ADDR_PARAMS */
373
+}
374
+
375
+
376
+
377
+static int set_sack_delay(void* cfg_h, str* gname, str* name, void** val)
378
+{
379
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
380
+#ifdef SCTP_DELAYED_SACK
381
+	struct sctp_sack_info sa;
382
+#else /* old lib */
383
+	struct sctp_assoc_value sa;
384
+#endif /* SCTP_DELAYED_SACK */
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, sack_delay);
389
+		return 0;
390
+	}
391
+	memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
392
+#ifdef SCTP_DELAYED_SACK
393
+	sa.sack_delay=(int)(long)(*val);
394
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
395
+							"cfg: setting SCTP_DELAYED_SACK");
396
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
397
+	sa.assoc_value=(int)(long)(*val);
398
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, sa,
399
+							"cfg: setting SCTP_DELAYED_ACK_TIME");
400
+#endif /* SCTP_DELAYED_SACK */
401
+#else
402
+	ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
403
+	return -1;
404
+#endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
405
+}
406
+
407
+
408
+
409
+static int set_sack_freq(void* cfg_h, str* gname, str* name, void** val)
410
+{
411
+#ifdef SCTP_DELAYED_SACK
412
+	struct sctp_sack_info sa;
413
+	SCTP_SET_SOCKOPT_DECLS;
414
+	
415
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
416
+		*val=(void*)(long)cfg_get(sctp, cfg_h, sack_freq);
417
+		return 0;
418
+	}
419
+	memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
420
+	sa.sack_freq=(int)(long)(*val);
421
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
422
+							"cfg: setting SCTP_DELAYED_SACK");
423
+#else
424
+	ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
425
+	return -1;
426
+#endif /* SCTP_DELAYED_SACK */
427
+}
428
+
429
+
430
+
431
+static int set_max_burst(void* cfg_h, str* gname, str* name, void** val)
432
+{
433
+#ifdef SCTP_MAX_BURST
434
+	struct sctp_assoc_value av;
435
+	SCTP_SET_SOCKOPT_DECLS;
436
+	
437
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
438
+		*val=(void*)(long)cfg_get(sctp, cfg_h, max_burst);
439
+		return 0;
440
+	}
441
+	memset(&av, 0, sizeof(av)); /* zero everything we don't care about */
442
+	av.assoc_value=(int)(long)(*val);
443
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_MAX_BURST, av,
444
+							"cfg: setting SCTP_MAX_BURST");
445
+#else
446
+	ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
447
+	return -1;
448
+#endif /* SCTP_MAX_BURST */
449
+}
450
+
253 451
 #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 271
 		cfg->srto_max=rto.srto_max;
272 272
 	}
273 273
 #endif /* SCTP_RTOINFO */
274
+#ifdef SCTP_ASSOCINFO
275
+	optlen=sizeof(ap);
276
+	ap.sasoc_assoc_id=0;
277
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_ASSOCINFO, (void*)&ap,
278
+							&optlen, "SCTP_ASSOCINFO")==0){
279
+		/* success => hack to set the "default" values*/
280
+		cfg->asocmaxrxt=ap.sasoc_asocmaxrxt;
281
+	}
282
+#endif /* SCTP_ASSOCINFO */
283
+#ifdef SCTP_INITMSG
284
+	optlen=sizeof(im);
285
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, (void*)&im,
286
+							&optlen, "SCTP_INITMSG")==0){
287
+		/* success => hack to set the "default" values*/
288
+		cfg->init_max_attempts=im.sinit_max_attempts;
289
+		cfg->init_max_timeo=im.sinit_max_init_timeo;
290
+	}
291
+#endif /* SCTP_INITMSG */
292
+#ifdef SCTP_PEER_ADDR_PARAMS
293
+	optlen=sizeof(pp);
294
+	memset(&pp, 0, sizeof(pp)); /* get defaults */
295
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, (void*)&pp,
296
+							&optlen, "SCTP_PEER_ADDR_PARAMS")==0){
297
+		/* success => hack to set the "default" values*/
298
+		cfg->hbinterval=pp.spp_hbinterval;
299
+		cfg->pathmaxrxt=pp.spp_pathmaxrxt;
300
+	}
301
+#endif /* SCTP_PEER_ADDR_PARAMS */
302
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
303
+	optlen=sizeof(sa);
304
+	memset(&sa, 0, sizeof(sa));
305
+#ifdef SCTP_DELAYED_SACK
306
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_SACK, (void*)&sa,
307
+							&optlen, "SCTP_DELAYED_SACK")==0){
308
+		/* success => hack to set the "default" values*/
309
+		cfg->sack_delay=sa.sack_delay;
310
+		cfg->sack_freq=sa.sack_freq;
311
+	}
312
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
313
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, (void*)&sa,
314
+							&optlen, "SCTP_DELAYED_ACK_TIME")==0){
315
+		/* success => hack to set the "default" values*/
316
+		cfg->sack_delay=sa.assoc_value;
317
+		cfg->sack_freq=0; /* unknown */
318
+	}
319
+#endif /* SCTP_DELAYED_SACK */
320
+#endif /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK_TIME*/
321
+#ifdef SCTP_MAX_BURST
322
+	optlen=sizeof(av);
323
+	av.assoc_id=0;
324
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_MAX_BURST, (void*)&av,
325
+							&optlen, "SCTP_MAX_BURST")==0){
326
+		/* success => hack to set the "default" values*/
327
+		cfg->max_burst=av.assoc_value;
328
+	}
329
+#endif /* SCTP_MAX_BURST */
330
+	
274 331
 	close(s);
275 332
 	return 0;
276 333
 }
... ...
@@ -293,6 +367,24 @@ static int sctp_init_sock_opt_common(int s)
293 293
 #ifdef SCTP_RTOINFO
294 294
 	struct sctp_rtoinfo rto;
295 295
 #endif /* SCTP_RTOINFO */
296
+#ifdef SCTP_ASSOCINFO
297
+	struct sctp_assocparams ap;
298
+#endif /* SCTP_ASSOCINFO */
299
+#ifdef SCTP_INITMSG
300
+	struct sctp_initmsg im;
301
+#endif /* SCTP_INITMSG */
302
+#ifdef SCTP_PEER_ADDR_PARAMS
303
+	struct sctp_paddrparams pp;
304
+#endif /* SCTP_PEER_ADDR_PARAMS */
305
+#ifdef SCTP_DELAYED_SACK
306
+	struct sctp_sack_info sa;
307
+#elif defined SCTP_DELAYED_ACK_TIME /* old version */
308
+	struct sctp_assoc_value sa;
309
+#endif /* SCTP_DELAYED_SACK */
310
+#ifdef SCTP_MAX_BURST
311
+	struct sctp_assoc_value av;
312
+#endif /* SCTP_MAX_BURST */
313
+	
296 314
 #ifdef __OS_linux
297 315
 	union {
298 316
 		struct sctp_event_subscribe s;
... ...
@@ -470,6 +562,105 @@ static int sctp_init_sock_opt_common(int s)
470 470
 #else
471 471
 #warning no sctp lib support for SCTP_RTOINFO, consider upgrading
472 472
 #endif /* SCTP_RTOINFO */
473
+	/* set associnfo options: assocmaxrxt */
474
+#ifdef SCTP_ASSOCINFO
475
+	memset(&ap, 0, sizeof(ap));
476
+	ap.sasoc_asocmaxrxt=cfg_get(sctp, sctp_cfg, asocmaxrxt);
477
+	if (ap.sasoc_asocmaxrxt){
478
+		/* if at least one is non-null => we have to set it */
479
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_ASSOCINFO, (void*)&ap,
480
+							sizeof(ap), "setsockopt: SCTP_ASSOCINFO")!=0){
481
+			sctp_err++;
482
+			/* non critical, try to continue */
483
+		}
484
+	}
485
+#else
486
+#warning no sctp lib support for SCTP_ASSOCINFO, consider upgrading
487
+#endif /* SCTP_ASOCINFO */
488
+	/* set initmsg options: init_max_attempts & init_max_init_timeo */
489
+#ifdef SCTP_INITMSG
490
+	memset(&im, 0, sizeof(im));
491
+	im.sinit_max_attempts=cfg_get(sctp, sctp_cfg, init_max_attempts);
492
+	im.sinit_max_init_timeo=cfg_get(sctp, sctp_cfg, init_max_timeo);
493
+	if (im.sinit_max_attempts || im.sinit_max_init_timeo){
494
+		/* if at least one is non-null => we have to set it */
495
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, (void*)&im,
496
+							sizeof(im), "setsockopt: SCTP_INITMSG")!=0){
497
+			sctp_err++;
498
+			/* non critical, try to continue */
499
+		}
500
+	}
501
+#else
502
+#warning no sctp lib support for SCTP_INITMSG, consider upgrading
503
+#endif /* SCTP_INITMSG */
504
+	/* set sctp peer addr options: hbinterval & pathmaxrxt */
505
+#ifdef SCTP_PEER_ADDR_PARAMS
506
+	memset(&pp, 0, sizeof(pp));
507
+	pp.spp_hbinterval=cfg_get(sctp, sctp_cfg, hbinterval);
508
+	pp.spp_pathmaxrxt=cfg_get(sctp, sctp_cfg, pathmaxrxt);
509
+	if (pp.spp_hbinterval || pp.spp_pathmaxrxt){
510
+		if (pp.spp_hbinterval > 0)
511
+			pp.spp_flags=SPP_HB_ENABLE;
512
+		else if (pp.spp_hbinterval==-1){
513
+			pp.spp_flags=SPP_HB_DISABLE;
514
+			pp.spp_hbinterval=0;
515
+		}
516
+		/* if at least one is non-null => we have to set it */
517
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, (void*)&pp,
518
+						sizeof(pp), "setsockopt: SCTP_PEER_ADDR_PARAMS")!=0){
519
+			sctp_err++;
520
+			/* non critical, try to continue */
521
+		}
522
+	}
523
+#else
524
+#warning no sctp lib support for SCTP_PEER_ADDR_PARAMS, consider upgrading
525
+#endif /* SCTP_PEER_ADDR_PARAMS */
526
+	/* set delayed ack options: sack_delay & sack_freq */
527
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
528
+	memset(&sa, 0, sizeof(sa));
529
+#ifdef SCTP_DELAYED_SACK
530
+	sa.sack_delay=cfg_get(sctp, sctp_cfg, sack_delay);
531
+	sa.sack_freq=cfg_get(sctp, sctp_cfg, sack_freq);
532
+	if (sa.sack_delay || sa.sack_freq){
533
+		/* if at least one is non-null => we have to set it */
534
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_SACK, (void*)&sa,
535
+							sizeof(sa), "setsockopt: SCTP_DELAYED_SACK")!=0){
536
+			sctp_err++;
537
+			/* non critical, try to continue */
538
+		}
539
+	}
540
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
541
+	sa.assoc_value=cfg_get(sctp, sctp_cfg, sack_delay);
542
+	if (sa.assoc_value){
543
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, (void*)&sa,
544
+						sizeof(sa), "setsockopt: SCTP_DELAYED_ACK_TIME")!=0){
545
+			sctp_err++;
546
+			/* non critical, try to continue */
547
+		}
548
+	}
549
+	if (cfg_get(sctp, sctp_cfg, sack_freq)){
550
+		WARN("could not set sctp sack_freq, please upgrade your sctp"
551
+				" library\n");
552
+		((struct cfg_group_sctp*)sctp_cfg)->sack_freq=0;
553
+	}
554
+#endif /* SCTP_DELAYED_SACK */
555
+#else /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK*/
556
+#warning no sctp lib support for SCTP_DELAYED_SACK, consider upgrading
557
+#endif /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK_TIME*/
558
+	/* set max burst option */
559
+#ifdef SCTP_MAX_BURST
560
+	memset(&av, 0, sizeof(av));
561
+	av.assoc_value=cfg_get(sctp, sctp_cfg, max_burst);
562
+	if (av.assoc_value){
563
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_MAX_BURST, (void*)&av,
564
+							sizeof(av), "setsockopt: SCTP_MAX_BURST")!=0){
565
+			sctp_err++;
566
+			/* non critical, try to continue */
567
+		}
568
+	}
569
+#else
570
+#warning no sctp lib support for SCTP_MAX_BURST, consider upgrading
571
+#endif /* SCTP_MAX_BURST */
473 572
 	
474 573
 	memset(&es, 0, sizeof(es));
475 574
 	/* SCTP_EVENTS for SCTP_SNDRCV (sctp_data_io_event) -> per message