123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748 |
- /*
- * $Id$
- *
- * Copyright (C) 2008 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- /*
- * sctp options
- */
- /*
- * History:
- * --------
- * 2008-08-07 initial version (andrei)
- * 2009-05-26 runtime cfg support (andrei)
- */
- /*!
- * \file
- * \brief SIP-router core ::
- * \ingroup core
- * Module: \ref core
- */
- #include <string.h>
- #include <sys/types.h>
- #ifdef USE_SCTP
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netinet/sctp.h>
- #endif /* USE_SCTP */
- #include <errno.h>
- #include "sctp_options.h"
- #include "../../dprint.h"
- #include "../../cfg/cfg.h"
- #include "../../socket_info.h"
- #include "sctp_server.h"
- struct cfg_group_sctp sctp_default_cfg;
- #ifdef USE_SCTP
- #include "sctp_sockopts.h"
- static int fix_autoclose(void* cfg_h, str* gname, str* name, void** val);
- static void set_autoclose(str* gname, str* name);
- static int fix_assoc_tracking(void* cfg_h, str* gname, str* name, void** val);
- static int fix_assoc_reuse(void* cfg_h, str* gname, str* name, void** val);
- static int fix_srto_initial(void* cfg_h, str* gname, str* name, void** val);
- static void set_srto_initial(str* gname, str* name);
- static int fix_srto_max(void* cfg_h, str* gname, str* name, void** val);
- static void set_srto_max(str* gname, str* name);
- static int fix_srto_min(void* cfg_h, str* gname, str* name, void** val);
- static void set_srto_min(str* gname, str* name);
- static int fix_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val);
- static void set_asocmaxrxt(str* gname, str* name);
- static int fix_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
- void** val);
- static void set_sinit_max_init_timeo(str* gname, str* name);
- static int fix_sinit_max_attempts(void* cfg_h, str* gname, str* name,
- void** val);
- static void set_sinit_max_attempts(str* gname, str* name);
- static int fix_hbinterval(void* cfg_h, str* gname, str* name, void** val);
- static void set_hbinterval(str* gname, str* name);
- static int fix_pathmaxrxt(void* cfg_h, str* gname, str* name, void** val);
- static void set_pathmaxrxt(str* gname, str* name);
- static int fix_sack_delay(void* cfg_h, str* gname, str* name, void** val);
- static void set_sack_delay(str* gname, str* name);
- static int fix_sack_freq(void* cfg_h, str* gname, str* name, void** val);
- static void set_sack_freq(str* gname, str* name);
- static int fix_max_burst(void* cfg_h, str* gname, str* name, void** val);
- static void set_max_burst(str* gname, str* name);
- /** cfg_group_sctp description (for the config framework). */
- static cfg_def_t sctp_cfg_def[] = {
- /* name , type |input type| chg type, min, max, fixup, proc. cbk.
- description */
- { "socket_rcvbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
- "socket receive buffer size (read-only)" },
- { "socket_sndbuf", CFG_VAR_INT| CFG_READONLY, 512, 102400, 0, 0,
- "socket send buffer size (read-only)" },
- { "autoclose", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 1, 1<<30,
- fix_autoclose, set_autoclose,
- "seconds before closing and idle connection (must be non-zero)" },
- { "send_ttl", CFG_VAR_INT| CFG_ATOMIC, 0, 1<<30, 0, 0,
- "milliseconds before aborting a send" },
- { "send_retries", CFG_VAR_INT| CFG_ATOMIC, 0, MAX_SCTP_SEND_RETRIES, 0, 0,
- "re-send attempts on failure" },
- { "assoc_tracking", CFG_VAR_INT| CFG_ATOMIC, 0, 1, fix_assoc_tracking, 0,
- "connection/association tracking (see also assoc_reuse)" },
- { "assoc_reuse", CFG_VAR_INT| CFG_ATOMIC, 0, 1, fix_assoc_reuse, 0,
- "connection/association reuse (for now used only for replies)"
- ", depends on assoc_tracking being set"},
- { "max_assocs", CFG_VAR_INT| CFG_ATOMIC, 0, 0, 0, 0,
- "maximum allowed open associations (-1 = disable, "
- "as many as allowed by the OS)"},
- { "srto_initial", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
- fix_srto_initial, set_srto_initial,
- "initial value of the retr. timeout, used in RTO calculations,"
- " in msecs" },
- { "srto_max", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
- fix_srto_max, set_srto_max,
- "maximum value of the retransmission timeout (RTO), in msecs" },
- { "srto_min", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
- fix_srto_min, set_srto_min,
- "minimum value of the retransmission timeout (RTO), in msecs" },
- { "asocmaxrxt", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
- fix_asocmaxrxt, set_asocmaxrxt,
- "maximum retransmission attempts per association" },
- { "init_max_attempts", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
- fix_sinit_max_attempts, set_sinit_max_attempts,
- "max INIT retransmission attempts" },
- { "init_max_timeo", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
- fix_sinit_max_init_timeo, set_sinit_max_init_timeo,
- "max INIT retransmission timeout (RTO max for INIT), in msecs" },
- { "hbinterval", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
- fix_hbinterval, set_hbinterval, "heartbeat interval in msecs" },
- { "pathmaxrxt", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
- fix_pathmaxrxt, set_pathmaxrxt,
- "maximum retransmission attempts per path" },
- { "sack_delay", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<30,
- fix_sack_delay, set_sack_delay,
- "time since the last received packet before sending a SACK, in msecs"},
- { "sack_freq", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
- fix_sack_freq, set_sack_freq,
- "number of received packets that trigger the sending of a SACK"},
- { "max_burst", CFG_VAR_INT| CFG_CB_ONLY_ONCE, 0, 1<<10,
- fix_max_burst, set_max_burst,
- "maximum burst of packets that can be emitted by an association"},
- {0, 0, 0, 0, 0, 0, 0}
- };
- void* sctp_cfg; /* sctp config handle */
- #endif /* USE_SCTP */
- void init_sctp_options()
- {
- #ifdef USE_SCTP
- sctp_get_os_defaults(&sctp_default_cfg);
- #if 0
- sctp_default_cfg.so_rcvbuf=0; /* do nothing, use the kernel default */
- sctp_default_cfg.so_sndbuf=0; /* do nothing, use the kernel default */
- #endif
- sctp_default_cfg.autoclose=DEFAULT_SCTP_AUTOCLOSE; /* in seconds */
- sctp_default_cfg.send_ttl=DEFAULT_SCTP_SEND_TTL; /* in milliseconds */
- sctp_default_cfg.send_retries=DEFAULT_SCTP_SEND_RETRIES;
- sctp_default_cfg.max_assocs=-1; /* as much as possible by default */
- #ifdef SCTP_CONN_REUSE
- sctp_default_cfg.assoc_tracking=1; /* on by default */
- sctp_default_cfg.assoc_reuse=1; /* on by default */
- #else
- sctp_default_cfg.assoc_tracking=0;
- sctp_default_cfg.assoc_reuse=0;
- #endif /* SCTP_CONN_REUSE */
- #endif
- }
- #define W_OPT_NSCTP(option) \
- if (sctp_default_cfg.option){\
- WARN("sctp_options: " #option \
- " cannot be enabled (sctp support not compiled-in)\n"); \
- sctp_default_cfg.option=0; \
- }
- void sctp_options_check()
- {
- #ifndef USE_SCTP
- W_OPT_NSCTP(autoclose);
- W_OPT_NSCTP(send_ttl);
- W_OPT_NSCTP(send_retries);
- W_OPT_NSCTP(assoc_tracking);
- W_OPT_NSCTP(assoc_reuse);
- W_OPT_NSCTP(max_assocs);
- #else /* USE_SCTP */
- if (sctp_default_cfg.send_retries>MAX_SCTP_SEND_RETRIES) {
- WARN("sctp: sctp_send_retries too high (%d), setting it to %d\n",
- sctp_default_cfg.send_retries, MAX_SCTP_SEND_RETRIES);
- sctp_default_cfg.send_retries=MAX_SCTP_SEND_RETRIES;
- }
- #ifndef CONN_REUSE
- if (sctp_default_cfg.assoc_tracking || sctp_default_cfg.assoc_reuse){
- WARN("sctp_options: assoc_tracking and assoc_reuse support cannnot"
- " be enabled (CONN_REUSE support not compiled-in)\n");
- sctp_default_cfg.assoc_tracking=0;
- sctp_default_cfg.assoc_reuse=0;
- }
- #else /* CONN_REUSE */
- if (sctp_default_cfg.assoc_reuse && sctp_default_cfg.assoc_tracking==0){
- sctp_default_cfg.assoc_tracking=1;
- }
- #endif /* CONN_REUSE */
- #endif /* USE_SCTP */
- }
- void sctp_options_get(struct cfg_group_sctp *s)
- {
- #ifdef USE_SCTP
- *s=*(struct cfg_group_sctp*)sctp_cfg;
- #else
- memset(s, 0, sizeof(*s));
- #endif /* USE_SCTP */
- }
- #ifdef USE_SCTP
- /** register sctp config into the configuration framework.
- * @return 0 on success, -1 on error */
- int sctp_register_cfg()
- {
- if (cfg_declare("sctp", sctp_cfg_def, &sctp_default_cfg, cfg_sizeof(sctp),
- &sctp_cfg))
- return -1;
- if (sctp_cfg==0){
- BUG("null sctp cfg");
- return -1;
- }
- return 0;
- }
- #define SCTP_SET_SOCKOPT_DECLS \
- int err; \
- struct socket_info* si
- #define SCTP_SET_SOCKOPT_BODY_NRET(lev, opt_name, val, err_prefix) \
- err=0; \
- for (si=sctp_listen; si; si=si->next){ \
- err+=(sctp_setsockopt(si->socket, (lev), (opt_name), (void*)(&(val)), \
- sizeof((val)), (err_prefix))<0); \
- }
- #define SCTP_SET_SOCKOPT_BODY(lev, opt_name, val, err_prefix) \
- SCTP_SET_SOCKOPT_BODY_NRET(lev, opt_name, val, err_prefix) ; \
- return -(err!=0)
- static int fix_autoclose(void*cfg_h, str* gname, str* name, void** val)
- {
- #ifdef SCTP_AUTOCLOSE
- return 0;
- #else
- ERR("no SCTP_AUTOCLOSE support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_AUTOCLOSE */
- }
- static void set_autoclose(str* gname, str* name)
- {
- #ifdef SCTP_AUTOCLOSE
- int optval;
- SCTP_SET_SOCKOPT_DECLS;
-
- optval=cfg_get(sctp, sctp_cfg, autoclose);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_AUTOCLOSE, optval,
- "cfg: setting SCTP_AUTOCLOSE");
- #else
- ERR("no SCTP_AUTOCLOSE support, please upgrade your sctp library\n");
- #endif /* SCTP_AUTOCLOSE */
- }
- static int fix_assoc_tracking(void* cfg_h, str* gname, str* name, void** val)
- {
- int optval;
-
- optval=(int)(long)(*val);
- #ifndef SCTP_CONN_REUSE
- if (optval!=0){
- ERR("no SCTP_CONN_REUSE support, please recompile with it enabled\n");
- return -1;
- }
- #else /* SCTP_CONN_REUSE */
- if (optval==0){
- /* turn tracking off */
- /* check if assoc_reuse is off */
- if (cfg_get(sctp, cfg_h, assoc_reuse)!=0){
- ERR("cannot turn sctp assoc_tracking off while assoc_reuse is"
- " still on, please turn assoc_reuse off first\n");
- return -1;
- }
- sctp_con_tracking_flush();
- }else if (optval==1 && cfg_get(sctp, cfg_h, assoc_reuse)==0){
- /* turning from off to on, make sure we flush the tracked list
- again, just incase the off flush was racing with a new connection*/
- sctp_con_tracking_flush();
- }
- #endif /* SCTP_CONN_REUSE */
- return 0;
- }
- static int fix_assoc_reuse(void* cfg_h, str* gname, str* name, void** val)
- {
- int optval;
-
- optval=(int)(long)(*val);
- #ifndef SCTP_CONN_REUSE
- if (optval!=0){
- ERR("no SCTP_CONN_REUSE support, please recompile with it enabled\n");
- return -1;
- }
- #else /* SCTP_CONN_REUSE */
- if (optval==1 && cfg_get(sctp, cfg_h, assoc_tracking)==0){
- /* conn reuse on, but assoc_tracking off => not possible */
- ERR("cannot turn sctp assoc_reuse on while assoc_tracking is"
- " off, please turn assoc_tracking on first\n");
- return -1;
- }
- #endif /* SCTP_CONN_REUSE */
- return 0;
- }
- static int fix_srto_initial(void* cfg_h, str* gname, str* name, void** val)
- {
- #ifdef SCTP_RTOINFO
- if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
- *val=(void*)(long)cfg_get(sctp, cfg_h, srto_initial);
- }
- return 0;
- #else
- ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_RTOINFO */
- }
- static void set_srto_initial(str* gname, str* name)
- {
- #ifdef SCTP_RTOINFO
- struct sctp_rtoinfo rto;
- int optval;
- SCTP_SET_SOCKOPT_DECLS;
-
- optval=cfg_get(sctp, sctp_cfg, srto_initial);
- memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
- rto.srto_assoc_id=0; /* all */
- rto.srto_initial=optval;
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_RTOINFO, rto,
- "cfg: setting SCTP_RTOINFO");
- #else
- ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
- #endif /* SCTP_RTOINFO */
- }
- static int fix_srto_max(void* cfg_h, str* gname, str* name, void** val)
- {
- #ifdef SCTP_RTOINFO
- if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
- *val=(void*)(long)cfg_get(sctp, cfg_h, srto_max);
- }
- return 0;
- #else
- ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_RTOINFO */
- }
- static void set_srto_max(str* gname, str* name)
- {
- #ifdef SCTP_RTOINFO
- struct sctp_rtoinfo rto;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
- rto.srto_assoc_id=0; /* all */
- rto.srto_max=cfg_get(sctp, sctp_cfg, srto_max);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_RTOINFO, rto,
- "cfg: setting SCTP_RTOINFO");
- #else
- ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
- #endif /* SCTP_RTOINFO */
- }
- static int fix_srto_min(void* cfg_h, str* gname, str* name, void** val)
- {
- #ifdef SCTP_RTOINFO
- if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
- *val=(void*)(long)cfg_get(sctp, cfg_h, srto_min);
- }
- return 0;
- #else
- ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_RTOINFO */
- }
- static void set_srto_min(str* gname, str* name)
- {
- #ifdef SCTP_RTOINFO
- struct sctp_rtoinfo rto;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&rto, 0, sizeof(rto)); /* zero everything we don't care about */
- rto.srto_assoc_id=0; /* all */
- rto.srto_min=cfg_get(sctp, sctp_cfg, srto_min);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_RTOINFO, rto,
- "cfg: setting SCTP_RTOINFO");
- #else
- ERR("no SCTP_RTOINFO support, please upgrade your sctp library\n");
- #endif /* SCTP_RTOINFO */
- }
- static int fix_asocmaxrxt(void* cfg_h, str* gname, str* name, void** val)
- {
- #ifdef SCTP_ASSOCINFO
- if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
- *val=(void*)(long)cfg_get(sctp, cfg_h, asocmaxrxt);
- }
- return 0;
- #else
- ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_ASSOCINFO */
- }
- static void set_asocmaxrxt(str* gname, str* name)
- {
- #ifdef SCTP_ASSOCINFO
- struct sctp_assocparams ap;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&ap, 0, sizeof(ap)); /* zero everything we don't care about */
- ap.sasoc_assoc_id=0; /* all */
- ap.sasoc_asocmaxrxt= cfg_get(sctp, sctp_cfg, asocmaxrxt);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_ASSOCINFO, ap,
- "cfg: setting SCTP_ASSOCINFO");
- #else
- ERR("no SCTP_ASSOCINFO support, please upgrade your sctp library\n");
- #endif /* SCTP_ASSOCINFO */
- }
- static int fix_sinit_max_init_timeo(void* cfg_h, str* gname, str* name,
- void** val)
- {
- #ifdef SCTP_INITMSG
- 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;
- #else
- ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_INITMSG */
- }
- static void set_sinit_max_init_timeo(str* gname, str* name)
- {
- #ifdef SCTP_INITMSG
- struct sctp_initmsg im;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
- im.sinit_max_init_timeo=cfg_get(sctp, sctp_cfg, init_max_timeo);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_INITMSG, im,
- "cfg: setting SCTP_INITMSG");
- #else
- ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
- #endif /* SCTP_INITMSG */
- }
- static int fix_sinit_max_attempts(void* cfg_h, str* gname, str* name,
- void** val)
- {
- #ifdef SCTP_INITMSG
- 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;
- #else
- ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_INITMSG */
- }
- static void set_sinit_max_attempts(str* gname, str* name)
- {
- #ifdef SCTP_INITMSG
- struct sctp_initmsg im;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&im, 0, sizeof(im)); /* zero everything we don't care about */
- im.sinit_max_attempts=cfg_get(sctp, sctp_cfg, init_max_attempts);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_INITMSG, im,
- "cfg: setting SCTP_INITMSG");
- #else
- ERR("no SCTP_INITMSG support, please upgrade your sctp library\n");
- #endif /* SCTP_INITMSG */
- }
- static int fix_hbinterval(void* cfg_h, str* gname, str* name,
- void** val)
- {
- #ifdef SCTP_PEER_ADDR_PARAMS
- if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
- *val=(void*)(long)cfg_get(sctp, cfg_h, hbinterval);
- }
- return 0;
- #else
- ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
- " sctp library\n");
- return -1;
- #endif /* SCTP_PEER_ADDR_PARAMS */
- }
- static void set_hbinterval(str* gname, str* name)
- {
- #ifdef SCTP_PEER_ADDR_PARAMS
- struct sctp_paddrparams pp;
- int optval;
- SCTP_SET_SOCKOPT_DECLS;
-
- optval=cfg_get(sctp, sctp_cfg, hbinterval);
- memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
- if (optval!=-1){
- pp.spp_hbinterval=optval;
- pp.spp_flags=SPP_HB_ENABLE;
- }else{
- pp.spp_flags=SPP_HB_DISABLE;
- }
- err=0;
- for (si=sctp_listen; si; si=si->next){
- /* set the AF, needed on older linux kernels even for INADDR_ANY */
- pp.spp_address.ss_family=si->address.af;
- err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
- (void*)(&pp), sizeof(pp),
- "cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
- }
- #else
- ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
- " sctp library\n");
- #endif /* SCTP_PEER_ADDR_PARAMS */
- }
- static int fix_pathmaxrxt(void* cfg_h, str* gname, str* name,
- void** val)
- {
- #ifdef SCTP_PEER_ADDR_PARAMS
- if ((int)(long)(*val)==0){ /* do nothing for 0, keep the old value */
- *val=(void*)(long)cfg_get(sctp, cfg_h, pathmaxrxt);
- }
- return 0;
- #else
- ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
- " sctp library\n");
- return -1;
- #endif /* SCTP_PEER_ADDR_PARAMS */
- }
- static void set_pathmaxrxt(str* gname, str* name)
- {
- #ifdef SCTP_PEER_ADDR_PARAMS
- struct sctp_paddrparams pp;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&pp, 0, sizeof(pp)); /* zero everything we don't care about */
- pp.spp_pathmaxrxt=cfg_get(sctp, sctp_cfg, pathmaxrxt);
- err=0;
- for (si=sctp_listen; si; si=si->next){
- /* set the AF, needed on older linux kernels even for INADDR_ANY */
- pp.spp_address.ss_family=si->address.af;
- err+=(sctp_setsockopt(si->socket, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS,
- (void*)(&pp), sizeof(pp),
- "cfg: setting SCTP_PEER_ADDR_PARAMS")<0);
- }
- #else
- ERR("no SCTP_PEER_ADDR_PARAMS support, please upgrade your"
- " sctp library\n");
- #endif /* SCTP_PEER_ADDR_PARAMS */
- }
- static int fix_sack_delay(void* cfg_h, str* gname, str* name, void** val)
- {
- #if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
- 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;
- #else
- ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
- }
- static void set_sack_delay(str* gname, str* name)
- {
- #if defined SCTP_DELAYED_SACK || defined SCTP_DELAYED_ACK_TIME
- #ifdef SCTP_DELAYED_SACK
- struct sctp_sack_info sack_info;
- #endif /* SCTP_DELAYED_SACK */
- #ifdef SCTP_DELAYED_ACK_TIME
- struct sctp_assoc_value sack_val; /* old version, sack delay only */
- #endif /* SCTP_DELAYED_ACK_TIME */
- SCTP_SET_SOCKOPT_DECLS;
-
- #ifdef SCTP_DELAYED_SACK
- memset(&sack_info, 0, sizeof(sack_info)); /* zero everything we don't
- care about */
- sack_info.sack_delay=cfg_get(sctp, sctp_cfg, sack_delay);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_DELAYED_SACK, sack_info, 0);
- if (err==0){
- return;
- }else
- #endif /* SCTP_DELAYED_SACK */
- {
- /* setting SCTP_DELAYED_SACK failed or no lib support for
- SCTP_DELAYED_SACK => try the old obsolete SCTP_DELAYED_ACK_TIME */
- #ifdef SCTP_DELAYED_ACK_TIME
- memset(&sack_val, 0, sizeof(sack_val)); /* zero everything we don't
- care about */
- sack_val.assoc_value=cfg_get(sctp, sctp_cfg, sack_delay);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_DELAYED_ACK_TIME,
- sack_val,
- "cfg: setting SCTP_DELAYED_ACK_TIME");
- if (err==0)
- return;
- #else /* SCTP_DELAYED_ACK_TIME */
- /* no SCTP_DELAYED_ACK_TIME support and SCTP_DELAYED_SACK failed
- => error */
- ERR("cfg: setting SCTP_DELAYED_SACK: %s [%d]\n",
- strerror(errno), errno);
- #endif /* SCTP_DELAYED_ACK_TIME */
- }
- #else
- ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
- #endif /* SCTP_DELAYED_SACK | SCTP_DELAYED_ACK_TIME */
- }
- static int fix_sack_freq(void* cfg_h, str* gname, str* name, void** val)
- {
- #ifdef SCTP_DELAYED_SACK
- 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;
- #else
- ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_DELAYED_SACK */
- }
- static void set_sack_freq(str* gname, str* name)
- {
- #ifdef SCTP_DELAYED_SACK
- struct sctp_sack_info sa;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&sa, 0, sizeof(sa)); /* zero everything we don't care about */
- sa.sack_freq=cfg_get(sctp, sctp_cfg, sack_freq);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_DELAYED_SACK, sa,
- "cfg: setting SCTP_DELAYED_SACK");
- #else
- ERR("no SCTP_DELAYED_SACK support, please upgrade your sctp library\n");
- #endif /* SCTP_DELAYED_SACK */
- }
- static int fix_max_burst(void* cfg_h, str* gname, str* name, void** val)
- {
- #ifdef SCTP_MAX_BURST
- 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;
- #else
- ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
- return -1;
- #endif /* SCTP_MAX_BURST */
- }
- static void set_max_burst(str* gname, str* name)
- {
- #ifdef SCTP_MAX_BURST
- struct sctp_assoc_value av;
- SCTP_SET_SOCKOPT_DECLS;
-
- memset(&av, 0, sizeof(av)); /* zero everything we don't care about */
- av.assoc_value=cfg_get(sctp, sctp_cfg, max_burst);
- SCTP_SET_SOCKOPT_BODY_NRET(IPPROTO_SCTP, SCTP_MAX_BURST, av,
- "cfg: setting SCTP_MAX_BURST");
- #else
- ERR("no SCTP_MAX_BURST support, please upgrade your sctp library\n");
- #endif /* SCTP_MAX_BURST */
- }
- #endif /* USE_SCTP */
|