sctp_options.c 22 KB

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