Przeglądaj źródła

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 16 lat temu
rodzic
commit
2c552c8d6e
3 zmienionych plików z 428 dodań i 4 usunięć
  1. 226 1
      sctp_options.c
  2. 11 3
      sctp_options.h
  3. 191 0
      sctp_server.c

+ 226 - 1
sctp_options.c

@@ -51,6 +51,16 @@ static int set_autoclose(void* cfg_h, str* gname, str* name, void** val);
 static int set_srto_initial(void* cfg_h, str* gname, str* name, void** val);
 static int set_srto_max(void* cfg_h, str* gname, str* name, void** val);
 static int set_srto_min(void* cfg_h, str* gname, str* name, void** val);
+static int set_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val);
+static int set_sinit_max_attempts(void* cfg_h, str* gname, str* name,
+										void** val);
+static int set_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
+										void** val);
+static int set_hbinterval(void* cfg_h, str* gname, str* name, void** val);
+static int set_pathmaxrxt(void* cfg_h, str* gname, str* name, void** val);
+static int set_sack_freq(void* cfg_h, str* gname, str* name, void** val);
+static int set_sack_delay(void* cfg_h, str* gname, str* name, void** val);
+static int set_max_burst(void* cfg_h, str* gname, str* name, void** val);
 
 /** cfg_group_sctp description (for the config framework). */
 static cfg_def_t sctp_cfg_def[] = {
@@ -72,7 +82,24 @@ static cfg_def_t sctp_cfg_def[] = {
 	{ "srto_max", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_max, 0,
 		"maximum value of the retransmission timeout (RTO), in msecs" },
 	{ "srto_min", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_min, 0,
-		"minimum value og the retransmission timeout (RTO), in msecs" },
+		"minimum value of the retransmission timeout (RTO), in msecs" },
+	{ "asocmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_asocmaxrxt, 0,
+		"maximum retransmission attempts per association" },
+	{ "init_max_attempts", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
+		set_sinit_max_attempts, 0, "max INIT retransmission attempts" },
+	{ "init_max_timeo", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
+		set_sinit_max_init_timeo, 0,
+		"max INIT retransmission timeout (RTO max for INIT), in msecs" },
+	{ "hbinterval", CFG_VAR_INT| CFG_ATOMIC, 0, 0, set_hbinterval, 0,
+		"heartbeat interval in msecs" },
+	{ "pathmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_pathmaxrxt, 0,
+		"maximum retransmission attempts per path" },
+	{ "sack_delay", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_sack_delay, 0,
+		"time since the last received packet before sending a SACK, in msecs"},
+	{ "sack_freq", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_sack_freq, 0,
+		"number of received packets that trigger the sending of a SACK"},
+	{ "max_burst", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_max_burst, 0,
+		"maximum burst of packets that can be emitted by an association"},
 	{0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -250,4 +277,202 @@ static int set_srto_min(void* cfg_h, str* gname, str* name, void** val)
 #endif /* SCTP_RTOINFO */
 }
 
+
+
+static int set_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val)
+{
+#ifdef SCTP_ASSOCINFO
+	struct sctp_assocparams ap;
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, asocmaxrxt);
+		return 0;
+	}
+	memset(&ap, 0, sizeof(ap)); /* zero everything we don't care about */
+	ap.sasoc_assoc_id=0; /* all */
+	ap.sasoc_asocmaxrxt=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_ASSOCINFO, ap,
+							"cfg: setting SCTP_ASSOCINFO");
+#else
+	ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
+	return -1;
+#endif /* SCTP_ASSOCINFO */
+}
+
+
+
+static int set_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
+									void** val)
+{
+#ifdef SCTP_INITMSG
+	struct sctp_initmsg im;
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, init_max_timeo);
+		return 0;
+	}
+	memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
+	im.sinit_max_init_timeo=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
+							"cfg: setting SCTP_INITMSG");
+#else
+	ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
+	return -1;
+#endif /* SCTP_INITMSG */
+}
+
+
+
+static int set_sinit_max_attempts(void* cfg_h, str* gname, str* name,
+									void** val)
+{
+#ifdef SCTP_INITMSG
+	struct sctp_initmsg im;
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, init_max_attempts);
+		return 0;
+	}
+	memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
+	im.sinit_max_attempts=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
+							"cfg: setting SCTP_INITMSG");
+#else
+	ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
+	return -1;
+#endif /* SCTP_INITMSG */
+}
+
+
+
+static int set_hbinterval(void* cfg_h, str* gname, str* name,
+									void** val)
+{
+#ifdef SCTP_PEER_ADDR_PARAMS
+	struct sctp_paddrparams pp;
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, hbinterval);
+		return 0;
+	}
+	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
+	if ((int)(long)(*val)!=-1){
+		pp.spp_hbinterval=(int)(long)(*val);
+		pp.spp_flags=SPP_HB_ENABLE;
+	}else{
+		pp.spp_flags=SPP_HB_DISABLE;
+	}
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
+							"cfg: setting SCTP_PEER_ADDR_PARAMS");
+#else
+	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
+			" sctp library\n");
+	return -1;
+#endif /* SCTP_PEER_ADDR_PARAMS */
+}
+
+
+
+static int set_pathmaxrxt(void* cfg_h, str* gname, str* name,
+									void** val)
+{
+#ifdef SCTP_PEER_ADDR_PARAMS
+	struct sctp_paddrparams pp;
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, pathmaxrxt);
+		return 0;
+	}
+	memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
+	pp.spp_pathmaxrxt=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, pp,
+							"cfg: setting SCTP_PEER_ADDR_PARAMS");
+#else
+	ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
+			" sctp library\n");
+	return -1;
+#endif /* SCTP_PEER_ADDR_PARAMS */
+}
+
+
+
+static int set_sack_delay(void* cfg_h, str* gname, str* name, void** val)
+{
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
+#ifdef SCTP_DELAYED_SACK
+	struct sctp_sack_info sa;
+#else /* old lib */
+	struct sctp_assoc_value sa;
+#endif /* SCTP_DELAYED_SACK */
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, sack_delay);
+		return 0;
+	}
+	memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
+#ifdef SCTP_DELAYED_SACK
+	sa.sack_delay=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
+							"cfg: setting SCTP_DELAYED_SACK");
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
+	sa.assoc_value=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, sa,
+							"cfg: setting SCTP_DELAYED_ACK_TIME");
+#endif /* SCTP_DELAYED_SACK */
+#else
+	ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
+	return -1;
+#endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
+}
+
+
+
+static int set_sack_freq(void* cfg_h, str* gname, str* name, void** val)
+{
+#ifdef SCTP_DELAYED_SACK
+	struct sctp_sack_info sa;
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, sack_freq);
+		return 0;
+	}
+	memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
+	sa.sack_freq=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
+							"cfg: setting SCTP_DELAYED_SACK");
+#else
+	ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
+	return -1;
+#endif /* SCTP_DELAYED_SACK */
+}
+
+
+
+static int set_max_burst(void* cfg_h, str* gname, str* name, void** val)
+{
+#ifdef SCTP_MAX_BURST
+	struct sctp_assoc_value av;
+	SCTP_SET_SOCKOPT_DECLS;
+	
+	if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
+		*val=(void*)(long)cfg_get(sctp, cfg_h, max_burst);
+		return 0;
+	}
+	memset(&av, 0, sizeof(av)); /* zero everything we don't care about */
+	av.assoc_value=(int)(long)(*val);
+	SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_MAX_BURST, av,
+							"cfg: setting SCTP_MAX_BURST");
+#else
+	ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
+	return -1;
+#endif /* SCTP_MAX_BURST */
+}
+
 #endif /* USE_SCTP */

+ 11 - 3
sctp_options.h

@@ -40,9 +40,17 @@ struct cfg_group_sctp{
 	unsigned int autoclose; /* in seconds */
 	unsigned int send_ttl; /* in milliseconds */
 	unsigned int send_retries;
-	unsigned int srto_initial;
-	unsigned int srto_max;
-	unsigned int srto_min;
+	unsigned int srto_initial; /** initial retr. timeout */
+	unsigned int srto_max;     /** max retr. timeout */
+	unsigned int srto_min;     /** min retr. timeout */
+	unsigned int asocmaxrxt; /** max. retr. attempts per association */
+	unsigned int init_max_attempts; /** max., INIT retr. attempts */
+	unsigned int init_max_timeo; /** rto max for INIT */
+	unsigned int hbinterval;  /** heartbeat interval in msecs */
+	unsigned int pathmaxrxt;  /** max. retr. attempts per path */
+	unsigned int sack_delay; /** msecs after which a delayed SACK is sent */
+	unsigned int sack_freq; /** no. of packets after which a SACK is sent */
+	unsigned int max_burst; /** maximum burst of packets per assoc. */
 };
 
 extern struct cfg_group_sctp sctp_default_cfg;

+ 191 - 0
sctp_server.c

@@ -234,6 +234,23 @@ int sctp_get_os_defaults(struct cfg_group_sctp* cfg)
 #ifdef SCTP_RTOINFO
 	struct sctp_rtoinfo rto;
 #endif /* SCTP_RTOINFO */
+#ifdef SCTP_ASSOCINFO
+	struct sctp_assocparams ap;
+#endif /* SCTP_ASSOCINFO */
+#ifdef SCTP_INITMSG
+	struct sctp_initmsg im;
+#endif /* SCTP_INITMSG */
+#ifdef SCTP_PEER_ADDR_PARAMS
+	struct sctp_paddrparams pp;
+#endif /* SCTP_PEER_ADDR_PARAMS */
+#ifdef SCTP_DELAYED_SACK
+	struct sctp_sack_info sa;
+#elif defined SCTP_DELAYED_ACK_TIME /* old version */
+	struct sctp_assoc_value sa;
+#endif /* SCTP_DELAYED_SACK */
+#ifdef SCTP_MAX_BURST
+	struct sctp_assoc_value av;
+#endif /* SCTP_MAX_BURST */
 	
 	s = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
 	if (s==-1)
@@ -271,6 +288,63 @@ int sctp_get_os_defaults(struct cfg_group_sctp* cfg)
 		cfg->srto_max=rto.srto_max;
 	}
 #endif /* SCTP_RTOINFO */
+#ifdef SCTP_ASSOCINFO
+	optlen=sizeof(ap);
+	ap.sasoc_assoc_id=0;
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_ASSOCINFO, (void*)&ap,
+							&optlen, "SCTP_ASSOCINFO")==0){
+		/* success => hack to set the "default" values*/
+		cfg->asocmaxrxt=ap.sasoc_asocmaxrxt;
+	}
+#endif /* SCTP_ASSOCINFO */
+#ifdef SCTP_INITMSG
+	optlen=sizeof(im);
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, (void*)&im,
+							&optlen, "SCTP_INITMSG")==0){
+		/* success => hack to set the "default" values*/
+		cfg->init_max_attempts=im.sinit_max_attempts;
+		cfg->init_max_timeo=im.sinit_max_init_timeo;
+	}
+#endif /* SCTP_INITMSG */
+#ifdef SCTP_PEER_ADDR_PARAMS
+	optlen=sizeof(pp);
+	memset(&pp, 0, sizeof(pp)); /* get defaults */
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, (void*)&pp,
+							&optlen, "SCTP_PEER_ADDR_PARAMS")==0){
+		/* success => hack to set the "default" values*/
+		cfg->hbinterval=pp.spp_hbinterval;
+		cfg->pathmaxrxt=pp.spp_pathmaxrxt;
+	}
+#endif /* SCTP_PEER_ADDR_PARAMS */
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
+	optlen=sizeof(sa);
+	memset(&sa, 0, sizeof(sa));
+#ifdef SCTP_DELAYED_SACK
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_SACK, (void*)&sa,
+							&optlen, "SCTP_DELAYED_SACK")==0){
+		/* success => hack to set the "default" values*/
+		cfg->sack_delay=sa.sack_delay;
+		cfg->sack_freq=sa.sack_freq;
+	}
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, (void*)&sa,
+							&optlen, "SCTP_DELAYED_ACK_TIME")==0){
+		/* success => hack to set the "default" values*/
+		cfg->sack_delay=sa.assoc_value;
+		cfg->sack_freq=0; /* unknown */
+	}
+#endif /* SCTP_DELAYED_SACK */
+#endif /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK_TIME*/
+#ifdef SCTP_MAX_BURST
+	optlen=sizeof(av);
+	av.assoc_id=0;
+	if (sctp_getsockopt(s, IPPROTO_SCTP, SCTP_MAX_BURST, (void*)&av,
+							&optlen, "SCTP_MAX_BURST")==0){
+		/* success => hack to set the "default" values*/
+		cfg->max_burst=av.assoc_value;
+	}
+#endif /* SCTP_MAX_BURST */
+	
 	close(s);
 	return 0;
 }
@@ -293,6 +367,24 @@ static int sctp_init_sock_opt_common(int s)
 #ifdef SCTP_RTOINFO
 	struct sctp_rtoinfo rto;
 #endif /* SCTP_RTOINFO */
+#ifdef SCTP_ASSOCINFO
+	struct sctp_assocparams ap;
+#endif /* SCTP_ASSOCINFO */
+#ifdef SCTP_INITMSG
+	struct sctp_initmsg im;
+#endif /* SCTP_INITMSG */
+#ifdef SCTP_PEER_ADDR_PARAMS
+	struct sctp_paddrparams pp;
+#endif /* SCTP_PEER_ADDR_PARAMS */
+#ifdef SCTP_DELAYED_SACK
+	struct sctp_sack_info sa;
+#elif defined SCTP_DELAYED_ACK_TIME /* old version */
+	struct sctp_assoc_value sa;
+#endif /* SCTP_DELAYED_SACK */
+#ifdef SCTP_MAX_BURST
+	struct sctp_assoc_value av;
+#endif /* SCTP_MAX_BURST */
+	
 #ifdef __OS_linux
 	union {
 		struct sctp_event_subscribe s;
@@ -470,6 +562,105 @@ static int sctp_init_sock_opt_common(int s)
 #else
 #warning no sctp lib support for SCTP_RTOINFO, consider upgrading
 #endif /* SCTP_RTOINFO */
+	/* set associnfo options: assocmaxrxt */
+#ifdef SCTP_ASSOCINFO
+	memset(&ap, 0, sizeof(ap));
+	ap.sasoc_asocmaxrxt=cfg_get(sctp, sctp_cfg, asocmaxrxt);
+	if (ap.sasoc_asocmaxrxt){
+		/* if at least one is non-null => we have to set it */
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_ASSOCINFO, (void*)&ap,
+							sizeof(ap), "setsockopt: SCTP_ASSOCINFO")!=0){
+			sctp_err++;
+			/* non critical, try to continue */
+		}
+	}
+#else
+#warning no sctp lib support for SCTP_ASSOCINFO, consider upgrading
+#endif /* SCTP_ASOCINFO */
+	/* set initmsg options: init_max_attempts & init_max_init_timeo */
+#ifdef SCTP_INITMSG
+	memset(&im, 0, sizeof(im));
+	im.sinit_max_attempts=cfg_get(sctp, sctp_cfg, init_max_attempts);
+	im.sinit_max_init_timeo=cfg_get(sctp, sctp_cfg, init_max_timeo);
+	if (im.sinit_max_attempts || im.sinit_max_init_timeo){
+		/* if at least one is non-null => we have to set it */
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, (void*)&im,
+							sizeof(im), "setsockopt: SCTP_INITMSG")!=0){
+			sctp_err++;
+			/* non critical, try to continue */
+		}
+	}
+#else
+#warning no sctp lib support for SCTP_INITMSG, consider upgrading
+#endif /* SCTP_INITMSG */
+	/* set sctp peer addr options: hbinterval & pathmaxrxt */
+#ifdef SCTP_PEER_ADDR_PARAMS
+	memset(&pp, 0, sizeof(pp));
+	pp.spp_hbinterval=cfg_get(sctp, sctp_cfg, hbinterval);
+	pp.spp_pathmaxrxt=cfg_get(sctp, sctp_cfg, pathmaxrxt);
+	if (pp.spp_hbinterval || pp.spp_pathmaxrxt){
+		if (pp.spp_hbinterval > 0)
+			pp.spp_flags=SPP_HB_ENABLE;
+		else if (pp.spp_hbinterval==-1){
+			pp.spp_flags=SPP_HB_DISABLE;
+			pp.spp_hbinterval=0;
+		}
+		/* if at least one is non-null => we have to set it */
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, (void*)&pp,
+						sizeof(pp), "setsockopt: SCTP_PEER_ADDR_PARAMS")!=0){
+			sctp_err++;
+			/* non critical, try to continue */
+		}
+	}
+#else
+#warning no sctp lib support for SCTP_PEER_ADDR_PARAMS, consider upgrading
+#endif /* SCTP_PEER_ADDR_PARAMS */
+	/* set delayed ack options: sack_delay & sack_freq */
+#if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
+	memset(&sa, 0, sizeof(sa));
+#ifdef SCTP_DELAYED_SACK
+	sa.sack_delay=cfg_get(sctp, sctp_cfg, sack_delay);
+	sa.sack_freq=cfg_get(sctp, sctp_cfg, sack_freq);
+	if (sa.sack_delay || sa.sack_freq){
+		/* if at least one is non-null => we have to set it */
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_SACK, (void*)&sa,
+							sizeof(sa), "setsockopt: SCTP_DELAYED_SACK")!=0){
+			sctp_err++;
+			/* non critical, try to continue */
+		}
+	}
+#else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
+	sa.assoc_value=cfg_get(sctp, sctp_cfg, sack_delay);
+	if (sa.assoc_value){
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, (void*)&sa,
+						sizeof(sa), "setsockopt: SCTP_DELAYED_ACK_TIME")!=0){
+			sctp_err++;
+			/* non critical, try to continue */
+		}
+	}
+	if (cfg_get(sctp, sctp_cfg, sack_freq)){
+		WARN("could not set sctp sack_freq, please upgrade your sctp"
+				" library\n");
+		((struct cfg_group_sctp*)sctp_cfg)->sack_freq=0;
+	}
+#endif /* SCTP_DELAYED_SACK */
+#else /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK*/
+#warning no sctp lib support for SCTP_DELAYED_SACK, consider upgrading
+#endif /* SCTP_DELAYED_SACK  | SCTP_DELAYED_ACK_TIME*/
+	/* set max burst option */
+#ifdef SCTP_MAX_BURST
+	memset(&av, 0, sizeof(av));
+	av.assoc_value=cfg_get(sctp, sctp_cfg, max_burst);
+	if (av.assoc_value){
+		if (sctp_setsockopt(s, IPPROTO_SCTP, SCTP_MAX_BURST, (void*)&av,
+							sizeof(av), "setsockopt: SCTP_MAX_BURST")!=0){
+			sctp_err++;
+			/* non critical, try to continue */
+		}
+	}
+#else
+#warning no sctp lib support for SCTP_MAX_BURST, consider upgrading
+#endif /* SCTP_MAX_BURST */
 	
 	memset(&es, 0, sizeof(es));
 	/* SCTP_EVENTS for SCTP_SNDRCV (sctp_data_io_event) -> per message