sctp_options.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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. #include <string.h>
  28. #include <sys/types.h>
  29. #include <sys/socket.h>
  30. #include <netinet/in.h>
  31. #include <netinet/in_systm.h>
  32. #include <netinet/ip.h>
  33. #include <netinet/sctp.h>
  34. #include <errno.h>
  35. #include "sctp_options.h"
  36. #include "dprint.h"
  37. #include "cfg/cfg.h"
  38. #include "socket_info.h"
  39. #include "sctp_server.h"
  40. struct cfg_group_sctp sctp_default_cfg;
  41. #ifdef USE_SCTP
  42. static int set_autoclose(void* cfg_h, str* gname, str* name, void** val);
  43. static int set_assoc_tracking(void* cfg_h, str* gname, str* name, void** val);
  44. static int set_assoc_reuse(void* cfg_h, str* gname, str* name, void** val);
  45. static int set_srto_initial(void* cfg_h, str* gname, str* name, void** val);
  46. static int set_srto_max(void* cfg_h, str* gname, str* name, void** val);
  47. static int set_srto_min(void* cfg_h, str* gname, str* name, void** val);
  48. static int set_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val);
  49. static int set_sinit_max_attempts(void* cfg_h, str* gname, str* name,
  50. void** val);
  51. static int set_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
  52. void** val);
  53. static int set_hbinterval(void* cfg_h, str* gname, str* name, void** val);
  54. static int set_pathmaxrxt(void* cfg_h, str* gname, str* name, void** val);
  55. static int set_sack_freq(void* cfg_h, str* gname, str* name, void** val);
  56. static int set_sack_delay(void* cfg_h, str* gname, str* name, void** val);
  57. static int set_max_burst(void* cfg_h, str* gname, str* name, void** val);
  58. /** cfg_group_sctp description (for the config framework). */
  59. static cfg_def_t sctp_cfg_def[] = {
  60. /* name , type |input type| chg type, min, max, fixup, proc. cbk.
  61. description */
  62. { "socket_rcvbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
  63. "socket receive buffer size (read-only)" },
  64. { "socket_sndbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
  65. "socket send buffer size (read-only)" },
  66. { "autoclose", CFG_VAR_INT| CFG_ATOMIC, 1, 1<<30, set_autoclose, 0,
  67. "seconds before closing and idle connection (must be non-zero)" },
  68. { "send_ttl", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, 0, 0,
  69. "milliseconds before aborting a send" },
  70. { "send_retries", CFG_VAR_INT| CFG_ATOMIC, 0, MAX_SCTP_SEND_RETRIES, 0, 0,
  71. "re-send attempts on failure" },
  72. { "assoc_tracking", CFG_VAR_INT| CFG_ATOMIC, 0, 1, set_assoc_tracking, 0,
  73. "connection/association tracking (see also assoc_reuse)" },
  74. { "assoc_reuse", CFG_VAR_INT| CFG_ATOMIC, 0, 1, set_assoc_reuse, 0,
  75. "connection/association reuse (for now used only for replies)"
  76. ", depends on assoc_tracking being set"},
  77. { "max_assocs", CFG_VAR_INT| CFG_ATOMIC, 0, 0, 0, 0,
  78. "maximum allowed open associations (-1 = disable, "
  79. "as many as allowed by the OS)"},
  80. { "srto_initial", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_initial, 0,
  81. "initial value of the retr. timeout, used in RTO calculations,"
  82. " in msecs" },
  83. { "srto_max", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_max, 0,
  84. "maximum value of the retransmission timeout (RTO), in msecs" },
  85. { "srto_min", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_srto_min, 0,
  86. "minimum value of the retransmission timeout (RTO), in msecs" },
  87. { "asocmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_asocmaxrxt, 0,
  88. "maximum retransmission attempts per association" },
  89. { "init_max_attempts", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
  90. set_sinit_max_attempts, 0, "max INIT retransmission attempts" },
  91. { "init_max_timeo", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10,
  92. set_sinit_max_init_timeo, 0,
  93. "max INIT retransmission timeout (RTO max for INIT), in msecs" },
  94. { "hbinterval", CFG_VAR_INT| CFG_ATOMIC, 0, 0, set_hbinterval, 0,
  95. "heartbeat interval in msecs" },
  96. { "pathmaxrxt", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_pathmaxrxt, 0,
  97. "maximum retransmission attempts per path" },
  98. { "sack_delay", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, set_sack_delay, 0,
  99. "time since the last received packet before sending a SACK, in msecs"},
  100. { "sack_freq", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_sack_freq, 0,
  101. "number of received packets that trigger the sending of a SACK"},
  102. { "max_burst", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<10, set_max_burst, 0,
  103. "maximum burst of packets that can be emitted by an association"},
  104. {0, 0, 0, 0, 0, 0, 0}
  105. };
  106. void* sctp_cfg; /* sctp config handle */
  107. #endif /* USE_SCTP */
  108. void init_sctp_options()
  109. {
  110. #ifdef USE_SCTP
  111. sctp_get_os_defaults(&sctp_default_cfg);
  112. #if 0
  113. sctp_default_cfg.so_rcvbuf=0; /* do nothing, use the kernel default */
  114. sctp_default_cfg.so_sndbuf=0; /* do nothing, use the kernel default */
  115. #endif
  116. sctp_default_cfg.autoclose=DEFAULT_SCTP_AUTOCLOSE; /* in seconds */
  117. sctp_default_cfg.send_ttl=DEFAULT_SCTP_SEND_TTL; /* in milliseconds */
  118. sctp_default_cfg.send_retries=DEFAULT_SCTP_SEND_RETRIES;
  119. sctp_default_cfg.max_assocs=-1; /* as much as possible by default */
  120. #ifdef SCTP_CONN_REUSE
  121. sctp_default_cfg.assoc_tracking=1; /* on by default */
  122. sctp_default_cfg.assoc_reuse=1; /* on by default */
  123. #else
  124. sctp_default_cfg.assoc_tracking=0;
  125. sctp_default_cfg.assoc_reuse=0;
  126. #endif /* SCTP_CONN_REUSE */
  127. #endif
  128. }
  129. #define W_OPT_NSCTP(option) \
  130. if (sctp_default_cfg.option){\
  131. WARN("sctp_options: " #option \
  132. " cannot be enabled (sctp support not compiled-in)\n"); \
  133. sctp_default_cfg.option=0; \
  134. }
  135. void sctp_options_check()
  136. {
  137. #ifndef USE_SCTP
  138. W_OPT_NSCTP(autoclose);
  139. W_OPT_NSCTP(send_ttl);
  140. W_OPT_NSCTP(send_retries);
  141. W_OPT_NSCTP(assoc_tracking);
  142. W_OPT_NSCTP(assoc_reuse);
  143. W_OPT_NSCTP(max_assocs);
  144. #else /* USE_SCTP */
  145. if (sctp_default_cfg.send_retries>MAX_SCTP_SEND_RETRIES) {
  146. WARN("sctp: sctp_send_retries too high (%d), setting it to %d\n",
  147. sctp_default_cfg.send_retries, MAX_SCTP_SEND_RETRIES);
  148. sctp_default_cfg.send_retries=MAX_SCTP_SEND_RETRIES;
  149. }
  150. #ifndef CONN_REUSE
  151. if (sctp_default_cfg.assoc_tracking || sctp_default_cfg.assoc_reuse){
  152. WARN("sctp_options: assoc_tracking and assoc_reuse support cannnot"
  153. " be enabled (CONN_REUSE support not compiled-in)\n");
  154. sctp_default_cfg.assoc_tracking=0;
  155. sctp_default_cfg.assoc_reuse=0;
  156. }
  157. #else /* CONN_REUSE */
  158. if (sctp_default_cfg.assoc_reuse && sctp_default_cfg.assoc_tracking==0){
  159. sctp_default_cfg.assoc_tracking=1;
  160. }
  161. #endif /* CONN_REUSE */
  162. #endif /* USE_SCTP */
  163. }
  164. void sctp_options_get(struct cfg_group_sctp *s)
  165. {
  166. #ifdef USE_SCTP
  167. *s=*(struct cfg_group_sctp*)sctp_cfg;
  168. #else
  169. memset(s, 0, sizeof(*s));
  170. #endif /* USE_SCTP */
  171. }
  172. #ifdef USE_SCTP
  173. /** register sctp config into the configuration framework.
  174. * @return 0 on success, -1 on error */
  175. int sctp_register_cfg()
  176. {
  177. if (cfg_declare("sctp", sctp_cfg_def, &sctp_default_cfg, cfg_sizeof(sctp),
  178. &sctp_cfg))
  179. return -1;
  180. if (sctp_cfg==0){
  181. BUG("null sctp cfg");
  182. return -1;
  183. }
  184. return 0;
  185. }
  186. #define SCTP_SET_SOCKOPT_DECLS \
  187. int err; \
  188. struct socket_info* si
  189. #define SCTP_SET_SOCKOPT_BODY(lev, opt_name, val, err_prefix) \
  190. err=0; \
  191. for (si=sctp_listen; si; si=si->next){ \
  192. err+=(sctp_setsockopt(si->socket, (lev), (opt_name), (void*)(&(val)), \
  193. sizeof((val)), (err_prefix))<0); \
  194. } \
  195. return -(err!=0)
  196. static int set_autoclose(void* cfg_h, str* gname, str* name, void** val)
  197. {
  198. #ifdef SCTP_AUTOCLOSE
  199. int optval;
  200. SCTP_SET_SOCKOPT_DECLS;
  201. optval=(int)(long)(*val);
  202. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_AUTOCLOSE, optval,
  203. "cfg: setting SCTP_AUTOCLOSE");
  204. #else
  205. ERR("no SCTP_AUTOCLOSE support, please upgrade your sctp library\n");
  206. return -1;
  207. #endif /* SCTP_AUTOCLOSE */
  208. }
  209. static int set_assoc_tracking(void* cfg_h, str* gname, str* name, void** val)
  210. {
  211. int optval;
  212. optval=(int)(long)(*val);
  213. #ifndef SCTP_CONN_REUSE
  214. if (optval!=0){
  215. ERR("no SCTP_CONN_REUSE support, please recompile with it enabled\n");
  216. return -1;
  217. }
  218. #else /* SCTP_CONN_REUSE */
  219. if (optval==0){
  220. /* turn tracking off */
  221. /* check if assoc_reuse is off */
  222. if (cfg_get(sctp, cfg_h, assoc_reuse)!=0){
  223. ERR("cannot turn sctp assoc_tracking off while assoc_reuse is"
  224. " still on, please turn assoc_reuse off first\n");
  225. return -1;
  226. }
  227. sctp_con_tracking_flush();
  228. }else if (optval==1 && cfg_get(sctp, cfg_h, assoc_reuse)==0){
  229. /* turning from off to on, make sure we flush the tracked list
  230. again, just incase the off flush was racing with a new connection*/
  231. sctp_con_tracking_flush();
  232. }
  233. #endif /* SCTP_CONN_REUSE */
  234. return 0;
  235. }
  236. static int set_assoc_reuse(void* cfg_h, str* gname, str* name, void** val)
  237. {
  238. int optval;
  239. optval=(int)(long)(*val);
  240. #ifndef SCTP_CONN_REUSE
  241. if (optval!=0){
  242. ERR("no SCTP_CONN_REUSE support, please recompile with it enabled\n");
  243. return -1;
  244. }
  245. #else /* SCTP_CONN_REUSE */
  246. if (optval==1 && cfg_get(sctp, cfg_h, assoc_tracking)==0){
  247. /* conn reuse on, but assoc_tracking off => not possible */
  248. ERR("cannot turn sctp assoc_reuse on while assoc_tracking is"
  249. " off, please turn assoc_tracking on first\n");
  250. return -1;
  251. }
  252. #endif /* SCTP_CONN_REUSE */
  253. return 0;
  254. }
  255. static int set_srto_initial(void* cfg_h, str* gname, str* name, void** val)
  256. {
  257. #ifdef SCTP_RTOINFO
  258. struct sctp_rtoinfo rto;
  259. SCTP_SET_SOCKOPT_DECLS;
  260. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  261. *val=(void*)(long)cfg_get(sctp, cfg_h, srto_initial);
  262. return 0;
  263. }
  264. memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
  265. rto.srto_assoc_id=0; /* all */
  266. rto.srto_initial=(int)(long)(*val);
  267. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_RTOINFO, rto,
  268. "cfg: setting SCTP_RTOINFO");
  269. #else
  270. ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
  271. return -1;
  272. #endif /* SCTP_RTOINFO */
  273. }
  274. static int set_srto_max(void* cfg_h, str* gname, str* name, void** val)
  275. {
  276. #ifdef SCTP_RTOINFO
  277. struct sctp_rtoinfo rto;
  278. SCTP_SET_SOCKOPT_DECLS;
  279. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  280. *val=(void*)(long)cfg_get(sctp, cfg_h, srto_max);
  281. return 0;
  282. }
  283. memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
  284. rto.srto_assoc_id=0; /* all */
  285. rto.srto_max=(int)(long)(*val);
  286. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_RTOINFO, rto,
  287. "cfg: setting SCTP_RTOINFO");
  288. #else
  289. ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
  290. return -1;
  291. #endif /* SCTP_RTOINFO */
  292. }
  293. static int set_srto_min(void* cfg_h, str* gname, str* name, void** val)
  294. {
  295. #ifdef SCTP_RTOINFO
  296. struct sctp_rtoinfo rto;
  297. SCTP_SET_SOCKOPT_DECLS;
  298. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  299. *val=(void*)(long)cfg_get(sctp, cfg_h, srto_min);
  300. return 0;
  301. }
  302. memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
  303. rto.srto_assoc_id=0; /* all */
  304. rto.srto_min=(int)(long)(*val);
  305. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_RTOINFO, rto,
  306. "cfg: setting SCTP_RTOINFO");
  307. #else
  308. ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
  309. return -1;
  310. #endif /* SCTP_RTOINFO */
  311. }
  312. static int set_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val)
  313. {
  314. #ifdef SCTP_ASSOCINFO
  315. struct sctp_assocparams ap;
  316. SCTP_SET_SOCKOPT_DECLS;
  317. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  318. *val=(void*)(long)cfg_get(sctp, cfg_h, asocmaxrxt);
  319. return 0;
  320. }
  321. memset(&ap, 0, sizeof(ap)); /* zero everything we don't care about */
  322. ap.sasoc_assoc_id=0; /* all */
  323. ap.sasoc_asocmaxrxt=(int)(long)(*val);
  324. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_ASSOCINFO, ap,
  325. "cfg: setting SCTP_ASSOCINFO");
  326. #else
  327. ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
  328. return -1;
  329. #endif /* SCTP_ASSOCINFO */
  330. }
  331. static int set_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
  332. void** val)
  333. {
  334. #ifdef SCTP_INITMSG
  335. struct sctp_initmsg im;
  336. SCTP_SET_SOCKOPT_DECLS;
  337. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  338. *val=(void*)(long)cfg_get(sctp, cfg_h, init_max_timeo);
  339. return 0;
  340. }
  341. memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
  342. im.sinit_max_init_timeo=(int)(long)(*val);
  343. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
  344. "cfg: setting SCTP_INITMSG");
  345. #else
  346. ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
  347. return -1;
  348. #endif /* SCTP_INITMSG */
  349. }
  350. static int set_sinit_max_attempts(void* cfg_h, str* gname, str* name,
  351. void** val)
  352. {
  353. #ifdef SCTP_INITMSG
  354. struct sctp_initmsg im;
  355. SCTP_SET_SOCKOPT_DECLS;
  356. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  357. *val=(void*)(long)cfg_get(sctp, cfg_h, init_max_attempts);
  358. return 0;
  359. }
  360. memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
  361. im.sinit_max_attempts=(int)(long)(*val);
  362. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_INITMSG, im,
  363. "cfg: setting SCTP_INITMSG");
  364. #else
  365. ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
  366. return -1;
  367. #endif /* SCTP_INITMSG */
  368. }
  369. static int set_hbinterval(void* cfg_h, str* gname, str* name,
  370. void** val)
  371. {
  372. #ifdef SCTP_PEER_ADDR_PARAMS
  373. struct sctp_paddrparams pp;
  374. SCTP_SET_SOCKOPT_DECLS;
  375. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  376. *val=(void*)(long)cfg_get(sctp, cfg_h, hbinterval);
  377. return 0;
  378. }
  379. memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
  380. if ((int)(long)(*val)!=-1){
  381. pp.spp_hbinterval=(int)(long)(*val);
  382. pp.spp_flags=SPP_HB_ENABLE;
  383. }else{
  384. pp.spp_flags=SPP_HB_DISABLE;
  385. }
  386. err=0;
  387. for (si=sctp_listen; si; si=si->next){
  388. /* set the AF, needed on older linux kernels even for INADDR_ANY */
  389. pp.spp_address.ss_family=si->address.af;
  390. err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
  391. (void*)(&pp), sizeof(pp),
  392. "cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
  393. }
  394. return -(err!=0);
  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. static int set_pathmaxrxt(void* cfg_h, str* gname, str* name,
  402. void** val)
  403. {
  404. #ifdef SCTP_PEER_ADDR_PARAMS
  405. struct sctp_paddrparams pp;
  406. SCTP_SET_SOCKOPT_DECLS;
  407. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  408. *val=(void*)(long)cfg_get(sctp, cfg_h, pathmaxrxt);
  409. return 0;
  410. }
  411. memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
  412. pp.spp_pathmaxrxt=(int)(long)(*val);
  413. err=0;
  414. for (si=sctp_listen; si; si=si->next){
  415. /* set the AF, needed on older linux kernels even for INADDR_ANY */
  416. pp.spp_address.ss_family=si->address.af;
  417. err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
  418. (void*)(&pp), sizeof(pp),
  419. "cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
  420. }
  421. return -(err!=0);
  422. #else
  423. ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
  424. " sctp library\n");
  425. return -1;
  426. #endif /* SCTP_PEER_ADDR_PARAMS */
  427. }
  428. static int set_sack_delay(void* cfg_h, str* gname, str* name, void** val)
  429. {
  430. #if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
  431. #ifdef SCTP_DELAYED_SACK
  432. struct sctp_sack_info sa;
  433. #else /* old lib */
  434. struct sctp_assoc_value sa;
  435. #endif /* SCTP_DELAYED_SACK */
  436. SCTP_SET_SOCKOPT_DECLS;
  437. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  438. *val=(void*)(long)cfg_get(sctp, cfg_h, sack_delay);
  439. return 0;
  440. }
  441. memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
  442. #ifdef SCTP_DELAYED_SACK
  443. sa.sack_delay=(int)(long)(*val);
  444. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
  445. "cfg: setting SCTP_DELAYED_SACK");
  446. #else /* old sctp lib version which uses SCTP_DELAYED_ACK_TIME */
  447. sa.assoc_value=(int)(long)(*val);
  448. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME, sa,
  449. "cfg: setting SCTP_DELAYED_ACK_TIME");
  450. #endif /* SCTP_DELAYED_SACK */
  451. #else
  452. ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
  453. return -1;
  454. #endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
  455. }
  456. static int set_sack_freq(void* cfg_h, str* gname, str* name, void** val)
  457. {
  458. #ifdef SCTP_DELAYED_SACK
  459. struct sctp_sack_info sa;
  460. SCTP_SET_SOCKOPT_DECLS;
  461. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  462. *val=(void*)(long)cfg_get(sctp, cfg_h, sack_freq);
  463. return 0;
  464. }
  465. memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
  466. sa.sack_freq=(int)(long)(*val);
  467. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
  468. "cfg: setting SCTP_DELAYED_SACK");
  469. #else
  470. ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
  471. return -1;
  472. #endif /* SCTP_DELAYED_SACK */
  473. }
  474. static int set_max_burst(void* cfg_h, str* gname, str* name, void** val)
  475. {
  476. #ifdef SCTP_MAX_BURST
  477. struct sctp_assoc_value av;
  478. SCTP_SET_SOCKOPT_DECLS;
  479. if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
  480. *val=(void*)(long)cfg_get(sctp, cfg_h, max_burst);
  481. return 0;
  482. }
  483. memset(&av, 0, sizeof(av)); /* zero everything we don't care about */
  484. av.assoc_value=(int)(long)(*val);
  485. SCTP_SET_SOCKOPT_BODY(IPPROTO_SCTP, SCTP_MAX_BURST, av,
  486. "cfg: setting SCTP_MAX_BURST");
  487. #else
  488. ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
  489. return -1;
  490. #endif /* SCTP_MAX_BURST */
  491. }
  492. #endif /* USE_SCTP */