2
0

sctp_options.c 22 KB

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