sctp_server.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  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 one to many
  20. */
  21. /*
  22. * History:
  23. * --------
  24. * 2008-08-07 initial version (andrei)
  25. */
  26. #ifdef USE_SCTP
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <sys/types.h>
  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. #include <errno.h>
  36. #include <arpa/inet.h>
  37. #include <unistd.h>
  38. #include <fcntl.h>
  39. #include "sctp_server.h"
  40. #include "sctp_options.h"
  41. #include "globals.h"
  42. #include "config.h"
  43. #include "dprint.h"
  44. #include "receive.h"
  45. #include "mem/mem.h"
  46. #include "ip_addr.h"
  47. #include "cfg/cfg_struct.h"
  48. /* check if the underlying OS supports sctp
  49. returns 0 if yes, -1 on error */
  50. int sctp_check_support()
  51. {
  52. int s;
  53. char buf[256];
  54. s = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
  55. if (s!=-1){
  56. close(s);
  57. if (sctp_check_compiled_sockopts(buf, sizeof(buf))!=0){
  58. LOG(L_WARN, "WARNING: sctp: your ser version was compiled"
  59. " without support for the following sctp options: %s"
  60. ", which might cause unforseen problems \n", buf);
  61. LOG(L_WARN, "WARNING: sctp: please consider recompiling ser with"
  62. " an upgraded sctp library version\n");
  63. }
  64. return 0;
  65. }
  66. return -1;
  67. }
  68. /* append a token to a buffer (uses space between tokens) */
  69. inline static void append_tok2buf(char* buf, int blen, char* tok)
  70. {
  71. char* p;
  72. char* end;
  73. int len;
  74. if (buf && blen){
  75. end=buf+blen;
  76. p=memchr(buf, 0, blen);
  77. if (p==0) goto error;
  78. if (p!=buf && p<(end-1)){
  79. *p=' ';
  80. p++;
  81. }
  82. len=MIN_int(strlen(tok), end-1-p);
  83. memcpy(p, tok, len);
  84. p[len]=0;
  85. }
  86. error:
  87. return;
  88. }
  89. /* check if support fot all the needed sockopts was compiled;
  90. an ascii list of the unsuported options is returned in buf
  91. returns 0 on success and -number of unsuported options on failure
  92. (<0 on failure)
  93. */
  94. int sctp_check_compiled_sockopts(char* buf, int size)
  95. {
  96. int err;
  97. err=0;
  98. if (buf && (size>0)) *buf=0; /* "" */
  99. #ifndef SCTP_FRAGMENT_INTERLEAVE
  100. err++;
  101. append_tok2buf(buf, size, "SCTP_FRAGMENT_INTERLEAVE");
  102. #endif
  103. #ifndef SCTP_PARTIAL_DELIVERY_POINT
  104. err++;
  105. append_tok2buf(buf, size, "SCTP_PARTIAL_DELIVERY_POINT");
  106. #endif
  107. #ifndef SCTP_NODELAY
  108. err++;
  109. append_tok2buf(buf, size, "SCTP_NODELAY");
  110. #endif
  111. #ifndef SCTP_DISABLE_FRAGMENTS
  112. err++;
  113. append_tok2buf(buf, size, "SCTP_DISABLE_FRAGMENTS");
  114. #endif
  115. #ifndef SCTP_AUTOCLOSE
  116. err++;
  117. append_tok2buf(buf, size, "SCTP_AUTOCLOSE");
  118. #endif
  119. #ifndef SCTP_EVENTS
  120. err++;
  121. append_tok2buf(buf, size, "SCTP_EVENTS");
  122. #endif
  123. return -err;
  124. }
  125. /* init all the sockaddr_union members of the socket_info struct
  126. returns 0 on success and -1 on error */
  127. inline static int sctp_init_su(struct socket_info* sock_info)
  128. {
  129. union sockaddr_union* addr;
  130. struct addr_info* ai;
  131. addr=&sock_info->su;
  132. if (init_su(addr, &sock_info->address, sock_info->port_no)<0){
  133. LOG(L_ERR, "ERROR: sctp_init_su: could not init sockaddr_union for"
  134. "primary sctp address %.*s:%d\n",
  135. sock_info->address_str.len, sock_info->address_str.s,
  136. sock_info->port_no );
  137. goto error;
  138. }
  139. for (ai=sock_info->addr_info_lst; ai; ai=ai->next)
  140. if (init_su(&ai->su, &ai->address, sock_info->port_no)<0){
  141. LOG(L_ERR, "ERROR: sctp_init_su: could not init"
  142. "backup sctp sockaddr_union for %.*s:%d\n",
  143. ai->address_str.len, ai->address_str.s,
  144. sock_info->port_no );
  145. goto error;
  146. }
  147. return 0;
  148. error:
  149. return -1;
  150. }
  151. /* set common (for one to many and one to one) sctp socket options
  152. tries to ignore non-critical errors (it will only log them), for
  153. improved portability (for example older linux kernel version support
  154. only a limited number of sctp socket options)
  155. returns 0 on success, -1 on error
  156. WARNING: please keep it sync'ed w/ sctp_check_compiled_sockopts() */
  157. static int sctp_init_sock_opt_common(int s)
  158. {
  159. struct sctp_event_subscribe es;
  160. int optval;
  161. socklen_t optlen;
  162. int sctp_err;
  163. sctp_err=0;
  164. /* set tos */
  165. optval = tos;
  166. if (setsockopt(s, IPPROTO_IP, IP_TOS, (void*)&optval,sizeof(optval)) ==-1){
  167. LOG(L_WARN, "WARNING: sctp_init_sock_opt_common: setsockopt tos: %s\n",
  168. strerror(errno));
  169. /* continue since this is not critical */
  170. }
  171. /* set receive buffer: SO_RCVBUF*/
  172. if (sctp_options.sctp_so_rcvbuf){
  173. optval=sctp_options.sctp_so_rcvbuf;
  174. if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
  175. (void*)&optval, sizeof(optval)) ==-1){
  176. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt:"
  177. " SO_RCVBUF (%d): %s\n", optval, strerror(errno));
  178. /* continue, non-critical */
  179. }
  180. }
  181. /* set send buffer: SO_SNDBUF */
  182. if (sctp_options.sctp_so_sndbuf){
  183. optval=sctp_options.sctp_so_sndbuf;
  184. if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
  185. (void*)&optval, sizeof(optval)) ==-1){
  186. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt:"
  187. " SO_SNDBUF (%d): %s\n", optval, strerror(errno));
  188. /* continue, non-critical */
  189. }
  190. }
  191. /* disable fragments interleave (SCTP_FRAGMENT_INTERLEAVE) --
  192. * we don't want partial delivery, so fragment interleave must be off too
  193. */
  194. #ifdef SCTP_FRAGMENT_INTERLEAVE
  195. optval=0;
  196. if (setsockopt(s, IPPROTO_SCTP, SCTP_FRAGMENT_INTERLEAVE ,
  197. (void*)&optval, sizeof(optval)) ==-1){
  198. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
  199. "SCTP_FRAGMENT_INTERLEAVE: %s\n", strerror(errno));
  200. sctp_err++;
  201. /* try to continue */
  202. }
  203. #else
  204. #warning no sctp lib support for SCTP_FRAGMENT_INTERLEAVE, consider upgrading
  205. #endif /* SCTP_FRAGMENT_INTERLEAVE */
  206. /* turn off partial delivery: on linux setting SCTP_PARTIAL_DELIVERY_POINT
  207. * to 0 or a very large number seems to be enough, however the portable
  208. * way to do it is to set it to the socket receive buffer size
  209. * (this is the maximum value allowed in the sctp api draft) */
  210. #ifdef SCTP_PARTIAL_DELIVERY_POINT
  211. optlen=sizeof(optval);
  212. if (getsockopt(s, SOL_SOCKET, SO_RCVBUF,
  213. (void*)&optval, &optlen) ==-1){
  214. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: getsockopt: "
  215. "SO_RCVBUF: %s\n", strerror(errno));
  216. /* try to continue */
  217. optval=0;
  218. }
  219. if (setsockopt(s, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
  220. (void*)&optval, sizeof(optval)) ==-1){
  221. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
  222. "SCTP_PARTIAL_DELIVERY_POINT (%d): %s\n",
  223. optval, strerror(errno));
  224. sctp_err++;
  225. /* try to continue */
  226. }
  227. #else
  228. #warning no sctp lib support for SCTP_PARTIAL_DELIVERY_POINT, consider upgrading
  229. #endif /* SCTP_PARTIAL_DELIVERY_POINT */
  230. /* nagle / no delay */
  231. #ifdef SCTP_NODELAY
  232. optval=1;
  233. if (setsockopt(s, IPPROTO_SCTP, SCTP_NODELAY,
  234. (void*)&optval, sizeof(optval)) ==-1){
  235. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
  236. "SCTP_NODELAY: %s\n", strerror(errno));
  237. sctp_err++;
  238. /* non critical, try to continue */
  239. }
  240. #else
  241. #warning no sctp lib support for SCTP_NODELAY, consider upgrading
  242. #endif /* SCTP_NODELAY */
  243. /* enable message fragmentation (SCTP_DISABLE_FRAGMENTS) (on send) */
  244. #ifdef SCTP_DISABLE_FRAGMENTS
  245. optval=0;
  246. if (setsockopt(s, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS,
  247. (void*)&optval, sizeof(optval)) ==-1){
  248. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
  249. "SCTP_DISABLE_FRAGMENTS: %s\n", strerror(errno));
  250. sctp_err++;
  251. /* non critical, try to continue */
  252. }
  253. #else
  254. #warning no sctp lib support for SCTP_DISABLE_FRAGMENTS, consider upgrading
  255. #endif /* SCTP_DISABLE_FRAGMENTS */
  256. /* set autoclose */
  257. #ifdef SCTP_AUTOCLOSE
  258. optval=sctp_options.sctp_autoclose;
  259. if (setsockopt(s, IPPROTO_SCTP, SCTP_AUTOCLOSE,
  260. (void*)&optval, sizeof(optval)) ==-1){
  261. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
  262. "SCTP_AUTOCLOSE: %s (critical)\n", strerror(errno));
  263. /* critical: w/o autoclose we could have sctp connection living
  264. forever (if the remote side doesn't close them) */
  265. sctp_err++;
  266. goto error;
  267. }
  268. #else
  269. #error SCTP_AUTOCLOSE not supported, please upgrade your sctp library
  270. #endif /* SCTP_AUTOCLOSE */
  271. memset(&es, 0, sizeof(es));
  272. /* SCTP_EVENTS for SCTP_SNDRCV (sctp_data_io_event) -> per message
  273. * information in sctp_sndrcvinfo */
  274. es.sctp_data_io_event=1;
  275. /* enable association event notifications */
  276. es.sctp_association_event=1; /* SCTP_ASSOC_CHANGE */
  277. es.sctp_address_event=1; /* enable address events notifications */
  278. es.sctp_send_failure_event=1; /* SCTP_SEND_FAILED */
  279. es.sctp_peer_error_event=1;
  280. es.sctp_shutdown_event=1;
  281. es.sctp_partial_delivery_event=1;
  282. /* es.sctp_adaptation_layer_event=1; - not supported by lksctp<=1.0.6*/
  283. /* es.sctp_authentication_event=1; -- not supported on linux 2.6.25 */
  284. /* enable the SCTP_EVENTS */
  285. #ifdef SCTP_EVENTS
  286. if (setsockopt(s, IPPROTO_SCTP, SCTP_EVENTS, &es, sizeof(es))==-1){
  287. LOG(L_ERR, "ERROR: sctp_init_sock_opt_common: setsockopt: "
  288. "SCTP_EVENTS: %s\n", strerror(errno));
  289. sctp_err++;
  290. /* non critical, try to continue */
  291. }
  292. #else
  293. #warning no sctp lib support for SCTP_EVENTS, consider upgrading
  294. #endif /* SCTP_EVENTS */
  295. if (sctp_err){
  296. LOG(L_ERR, "ERROR: sctp: setting some sctp sockopts failed, "
  297. "consider upgrading your kernel\n");
  298. }
  299. return 0;
  300. error:
  301. return -1;
  302. }
  303. /* bind all addresses from sock (sockaddr_unions)
  304. returns 0 on success, .1 on error */
  305. static int sctp_bind_sock(struct socket_info* sock_info)
  306. {
  307. struct addr_info* ai;
  308. union sockaddr_union* addr;
  309. addr=&sock_info->su;
  310. /* bind the addresses*/
  311. if (bind(sock_info->socket, &addr->s, sockaddru_len(*addr))==-1){
  312. LOG(L_ERR, "ERROR: sctp_bind_sock: bind(%x, %p, %d) on %s: %s\n",
  313. sock_info->socket, &addr->s,
  314. (unsigned)sockaddru_len(*addr),
  315. sock_info->address_str.s,
  316. strerror(errno));
  317. #ifdef USE_IPV6
  318. if (addr->s.sa_family==AF_INET6)
  319. LOG(L_ERR, "ERROR: sctp_bind_sock: might be caused by using a "
  320. "link local address, try site local or global\n");
  321. #endif
  322. goto error;
  323. }
  324. for (ai=sock_info->addr_info_lst; ai; ai=ai->next)
  325. if (sctp_bindx(sock_info->socket, &ai->su.s, 1, SCTP_BINDX_ADD_ADDR)
  326. ==-1){
  327. LOG(L_ERR, "ERROR: sctp_bind_sock: sctp_bindx(%x, %.*s:%d, 1, ...)"
  328. " on %s:%d : [%d] %s (trying to continue)\n",
  329. sock_info->socket,
  330. ai->address_str.len, ai->address_str.s,
  331. sock_info->port_no,
  332. sock_info->address_str.s, sock_info->port_no,
  333. errno, strerror(errno));
  334. #ifdef USE_IPV6
  335. if (ai->su.s.sa_family==AF_INET6)
  336. LOG(L_ERR, "ERROR: sctp_bind_sock: might be caused by using a "
  337. "link local address, try site local or global\n");
  338. #endif
  339. /* try to continue, a secondary address bind failure is not
  340. * critical */
  341. }
  342. return 0;
  343. error:
  344. return -1;
  345. }
  346. /* init, bind & start listening on the corresp. sctp socket
  347. returns 0 on success, -1 on error */
  348. int sctp_init_sock(struct socket_info* sock_info)
  349. {
  350. union sockaddr_union* addr;
  351. sock_info->proto=PROTO_SCTP;
  352. addr=&sock_info->su;
  353. if (sctp_init_su(sock_info)!=0)
  354. goto error;
  355. sock_info->socket = socket(AF2PF(addr->s.sa_family), SOCK_SEQPACKET,
  356. IPPROTO_SCTP);
  357. if (sock_info->socket==-1){
  358. LOG(L_ERR, "ERROR: sctp_init_sock: socket: %s\n", strerror(errno));
  359. goto error;
  360. }
  361. INFO("sctp: socket %d initialized (%p)\n", sock_info->socket, sock_info);
  362. /* make socket non-blocking */
  363. #if 0
  364. /* recvmsg must block so use blocking sockets
  365. * and send with MSG_DONTWAIT */
  366. optval=fcntl(sock_info->socket, F_GETFL);
  367. if (optval==-1){
  368. LOG(L_ERR, "ERROR: init_sctp: fnctl failed: (%d) %s\n",
  369. errno, strerror(errno));
  370. goto error;
  371. }
  372. if (fcntl(sock_info->socket, F_SETFL, optval|O_NONBLOCK)==-1){
  373. LOG(L_ERR, "ERROR: init_sctp: fcntl: set non-blocking failed:"
  374. " (%d) %s\n", errno, strerror(errno));
  375. goto error;
  376. }
  377. #endif
  378. /* set sock opts */
  379. if (sctp_init_sock_opt_common(sock_info->socket)!=0)
  380. goto error;
  381. /* SCTP_EVENTS for send dried out -> present in the draft not yet
  382. * present in linux (might help to detect when we could send again to
  383. * some peer, kind of poor's man poll on write, based on received
  384. * SCTP_SENDER_DRY_EVENTs */
  385. if (sctp_bind_sock(sock_info)<0)
  386. goto error;
  387. if (listen(sock_info->socket, 1)<0){
  388. LOG(L_ERR, "ERROR: sctp_init_sock: listen(%x, 1) on %s: %s\n",
  389. sock_info->socket, sock_info->address_str.s,
  390. strerror(errno));
  391. goto error;
  392. }
  393. return 0;
  394. error:
  395. return -1;
  396. }
  397. #define USE_SCTP_OO
  398. #ifdef USE_SCTP_OO
  399. /* init, bind & start listening on the corresp. sctp socket, using
  400. sctp one-to-one mode
  401. returns 0 on success, -1 on error */
  402. int sctp_init_sock_oo(struct socket_info* sock_info)
  403. {
  404. union sockaddr_union* addr;
  405. int optval;
  406. sock_info->proto=PROTO_SCTP;
  407. addr=&sock_info->su;
  408. if (sctp_init_su(sock_info)!=0)
  409. goto error;
  410. sock_info->socket = socket(AF2PF(addr->s.sa_family), SOCK_STREAM,
  411. IPPROTO_SCTP);
  412. if (sock_info->socket==-1){
  413. LOG(L_ERR, "ERROR: sctp_init_sock_oo: socket: %s\n", strerror(errno));
  414. goto error;
  415. }
  416. INFO("sctp:oo socket %d initialized (%p)\n", sock_info->socket, sock_info);
  417. /* make socket non-blocking */
  418. optval=fcntl(sock_info->socket, F_GETFL);
  419. if (optval==-1){
  420. LOG(L_ERR, "ERROR: sctp_init_sock_oo: fnctl failed: (%d) %s\n",
  421. errno, strerror(errno));
  422. goto error;
  423. }
  424. if (fcntl(sock_info->socket, F_SETFL, optval|O_NONBLOCK)==-1){
  425. LOG(L_ERR, "ERROR: sctp_init_sock_oo: fcntl: set non-blocking failed:"
  426. " (%d) %s\n", errno, strerror(errno));
  427. goto error;
  428. }
  429. /* set sock opts */
  430. if (sctp_init_sock_opt_common(sock_info->socket)!=0)
  431. goto error;
  432. #ifdef SCTP_REUSE_PORT
  433. /* set reuse port */
  434. optval=1;
  435. if (setsockopt(sock_info->socket, IPPROTO_SCTP, SCTP_REUSE_PORT ,
  436. (void*)&optval, sizeof(optval)) ==-1){
  437. LOG(L_ERR, "ERROR: sctp_init_sock_oo: setsockopt: "
  438. "SCTP_REUSE_PORT: %s\n", strerror(errno));
  439. goto error;
  440. }
  441. #endif /* SCTP_REUSE_PORT */
  442. if (sctp_bind_sock(sock_info)<0)
  443. goto error;
  444. if (listen(sock_info->socket, 1)<0){
  445. LOG(L_ERR, "ERROR: sctp_init_sock_oo: listen(%x, 1) on %s: %s\n",
  446. sock_info->socket, sock_info->address_str.s,
  447. strerror(errno));
  448. goto error;
  449. }
  450. return 0;
  451. error:
  452. return -1;
  453. }
  454. #endif /* USE_SCTP_OO */
  455. /* debugging: return a string name for SCTP_ASSOC_CHANGE state */
  456. static char* sctp_assoc_change_state2s(short int state)
  457. {
  458. char* s;
  459. switch(state){
  460. case SCTP_COMM_UP:
  461. s="SCTP_COMM_UP";
  462. break;
  463. case SCTP_COMM_LOST:
  464. s="SCTP_COMM_LOST";
  465. break;
  466. case SCTP_RESTART:
  467. s="SCTP_RESTART";
  468. break;
  469. case SCTP_SHUTDOWN_COMP:
  470. s="SCTP_SHUTDOWN_COMP";
  471. break;
  472. case SCTP_CANT_STR_ASSOC:
  473. s="SCTP_CANT_STR_ASSOC";
  474. break;
  475. default:
  476. s="UNKOWN";
  477. break;
  478. };
  479. return s;
  480. }
  481. /* debugging: return a string name for a SCTP_PEER_ADDR_CHANGE state */
  482. static char* sctp_paddr_change_state2s(unsigned int state)
  483. {
  484. char* s;
  485. switch (state){
  486. case SCTP_ADDR_AVAILABLE:
  487. s="SCTP_ADDR_AVAILABLE";
  488. break;
  489. case SCTP_ADDR_UNREACHABLE:
  490. s="SCTP_ADDR_UNREACHABLE";
  491. break;
  492. case SCTP_ADDR_REMOVED:
  493. s="SCTP_ADDR_REMOVED";
  494. break;
  495. case SCTP_ADDR_ADDED:
  496. s="SCTP_ADDR_ADDED";
  497. break;
  498. case SCTP_ADDR_MADE_PRIM:
  499. s="SCTP_ADDR_MADE_PRIM";
  500. break;
  501. /* not supported by lksctp 1.0.6
  502. case SCTP_ADDR_CONFIRMED:
  503. s="SCTP_ADDR_CONFIRMED";
  504. break;
  505. */
  506. default:
  507. s="UNKNOWN";
  508. break;
  509. }
  510. return s;
  511. }
  512. static int sctp_handle_notification(struct socket_info* si,
  513. union sockaddr_union* su,
  514. char* buf, unsigned len)
  515. {
  516. union sctp_notification* snp;
  517. char su_buf[SU2A_MAX_STR_SIZE];
  518. DBG("sctp_rcv_loop: MSG_NOTIFICATION\n");
  519. #define SNOT DBG
  520. #define ERR_LEN_TOO_SMALL(length, val, bind_addr, from_su, text) \
  521. if (unlikely((length)<(val))){\
  522. SNOT("ERROR: sctp notification from %s on %.*s:%d: " \
  523. text " too short (%d bytes instead of %d bytes)\n", \
  524. su2a((from_su), sizeof(*(from_su))), \
  525. (bind_addr)->name.len, (bind_addr)->name.s, \
  526. (bind_addr)->port_no, (length), (val)); \
  527. goto error; \
  528. }
  529. if (len < sizeof(snp->sn_header)){
  530. LOG(L_ERR, "ERROR: sctp_handle_notification: invalid length %d "
  531. "on %.*s:%d, from %s\n",
  532. len, si->name.len, si->name.s, si->port_no,
  533. su2a(su, sizeof(*su)));
  534. goto error;
  535. }
  536. snp=(union sctp_notification*) buf;
  537. switch(snp->sn_header.sn_type){
  538. case SCTP_REMOTE_ERROR:
  539. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_remote_error), si, su,
  540. "SCTP_REMOTE_ERROR");
  541. SNOT("sctp notification from %s on %.*s:%d: SCTP_REMOTE_ERROR:"
  542. " %d, len %d\n, assoc. %d",
  543. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  544. si->port_no,
  545. ntohs(snp->sn_remote_error.sre_error),
  546. ntohs(snp->sn_remote_error.sre_length),
  547. snp->sn_remote_error.sre_assoc_id
  548. );
  549. break;
  550. case SCTP_SEND_FAILED:
  551. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_send_failed), si, su,
  552. "SCTP_SEND_FAILED");
  553. SNOT("sctp notification from %s on %.*s:%d: SCTP_SEND_FAILED:"
  554. " error %d, assoc. %d, flags %x\n",
  555. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  556. si->port_no, snp->sn_send_failed.ssf_error,
  557. snp->sn_send_failed.ssf_assoc_id,
  558. snp->sn_send_failed.ssf_flags);
  559. break;
  560. case SCTP_PEER_ADDR_CHANGE:
  561. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_paddr_change), si, su,
  562. "SCTP_PEER_ADDR_CHANGE");
  563. strcpy(su_buf, su2a((union sockaddr_union*)
  564. &snp->sn_paddr_change.spc_aaddr,
  565. sizeof(snp->sn_paddr_change.spc_aaddr)));
  566. SNOT("sctp notification from %s on %.*s:%d: SCTP_PEER_ADDR_CHANGE"
  567. ": %s: %s: assoc. %d \n",
  568. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  569. si->port_no, su_buf,
  570. sctp_paddr_change_state2s(snp->sn_paddr_change.spc_state),
  571. snp->sn_paddr_change.spc_assoc_id
  572. );
  573. break;
  574. case SCTP_SHUTDOWN_EVENT:
  575. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_shutdown_event), si, su,
  576. "SCTP_SHUTDOWN_EVENT");
  577. SNOT("sctp notification from %s on %.*s:%d: SCTP_SHUTDOWN_EVENT:"
  578. " assoc. %d\n",
  579. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  580. si->port_no, snp->sn_shutdown_event.sse_assoc_id);
  581. break;
  582. case SCTP_ASSOC_CHANGE:
  583. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_assoc_change), si, su,
  584. "SCTP_ASSOC_CHANGE");
  585. SNOT("sctp notification from %s on %.*s:%d: SCTP_ASSOC_CHANGE"
  586. ": %s: assoc. %d, ostreams %d, istreams %d\n",
  587. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  588. si->port_no,
  589. sctp_assoc_change_state2s(snp->sn_assoc_change.sac_state),
  590. snp->sn_assoc_change.sac_assoc_id,
  591. snp->sn_assoc_change.sac_outbound_streams,
  592. snp->sn_assoc_change.sac_inbound_streams
  593. );
  594. break;
  595. #ifdef SCTP_ADAPTION_INDICATION
  596. case SCTP_ADAPTION_INDICATION:
  597. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_adaption_event), si, su,
  598. "SCTP_ADAPTION_INDICATION");
  599. SNOT("sctp notification from %s on %.*s:%d: "
  600. "SCTP_ADAPTION_INDICATION \n",
  601. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  602. si->port_no);
  603. break;
  604. #endif /* SCTP_ADAPTION_INDICATION */
  605. case SCTP_PARTIAL_DELIVERY_EVENT:
  606. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_pdapi_event), si, su,
  607. "SCTP_PARTIAL_DELIVERY_EVENT");
  608. SNOT("sctp notification from %s on %.*s:%d: "
  609. "SCTP_PARTIAL_DELIVERY_EVENT: %d%s, assoc. %d\n",
  610. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  611. si->port_no, snp->sn_pdapi_event.pdapi_indication,
  612. (snp->sn_pdapi_event.pdapi_indication==
  613. SCTP_PARTIAL_DELIVERY_ABORTED)? " PD ABORTED":"",
  614. snp->sn_pdapi_event.pdapi_assoc_id);
  615. break;
  616. #ifdef SCTP_SENDER_DRY_EVENT /* new, not yet supported */
  617. case SCTP_SENDER_DRY_EVENT:
  618. ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_sender_dry_event),
  619. si, su, "SCTP_SENDER_DRY_EVENT");
  620. SNOT("sctp notification from %s on %.*s:%d: "
  621. "SCTP_SENDER_DRY_EVENT on %d\n",
  622. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  623. si->port_no, snp->sn_sender_dry_event.sender_dry_assoc_id);
  624. break;
  625. #endif /* SCTP_SENDER_DRY_EVENT */
  626. default:
  627. SNOT("sctp notification from %s on %.*s:%d: UNKNOWN (%d)\n",
  628. su2a(su, sizeof(*su)), si->name.len, si->name.s,
  629. si->port_no, snp->sn_header.sn_type);
  630. }
  631. return 0;
  632. error:
  633. return -1;
  634. #undef ERR_LEN_TOO_SMALL
  635. }
  636. int sctp_rcv_loop()
  637. {
  638. unsigned len;
  639. static char buf [BUF_SIZE+1];
  640. char *tmp;
  641. struct receive_info ri;
  642. struct sctp_sndrcvinfo* sinfo;
  643. struct msghdr msg;
  644. struct iovec iov[1];
  645. struct cmsghdr* cmsg;
  646. /* use a larger buffer then needed in case some other ancillary info
  647. * is enabled */
  648. char cbuf[CMSG_SPACE(sizeof(*sinfo))+CMSG_SPACE(1024)];
  649. ri.bind_address=bind_address; /* this will not change */
  650. ri.dst_port=bind_address->port_no;
  651. ri.dst_ip=bind_address->address;
  652. ri.proto=PROTO_SCTP;
  653. ri.proto_reserved1=ri.proto_reserved2=0;
  654. iov[0].iov_base=buf;
  655. iov[0].iov_len=BUF_SIZE;
  656. msg.msg_iov=iov;
  657. msg.msg_iovlen=1;
  658. msg.msg_flags=0;
  659. /* initialize the config framework */
  660. if (cfg_child_init()) goto error;
  661. for(;;){
  662. msg.msg_name=&ri.src_su.s;
  663. msg.msg_namelen=sockaddru_len(bind_address->su);
  664. msg.msg_control=cbuf;
  665. msg.msg_controllen=sizeof(cbuf);
  666. len=recvmsg(bind_address->socket, &msg, 0);
  667. /* len=sctp_recvmsg(bind_address->socket, buf, BUF_SIZE, &ri.src_su.s,
  668. &msg.msg_namelen, &sinfo, &msg.msg_flags); */
  669. if (len==-1){
  670. if (errno==EAGAIN){
  671. DBG("sctp_rcv_loop: EAGAIN on sctp socket\n");
  672. continue;
  673. }
  674. LOG(L_ERR, "ERROR: sctp_rcv_loop: sctp_recvmsg on %d (%p):"
  675. "[%d] %s\n", bind_address->socket, bind_address,
  676. errno, strerror(errno));
  677. if ((errno==EINTR)||(errno==EWOULDBLOCK)|| (errno==ECONNREFUSED))
  678. continue; /* goto skip;*/
  679. else goto error;
  680. }
  681. if (unlikely(msg.msg_flags & MSG_NOTIFICATION)){
  682. /* intercept usefull notifications */
  683. sctp_handle_notification(bind_address, &ri.src_su, buf, len);
  684. continue;
  685. }else if (unlikely(!(msg.msg_flags & MSG_EOR))){
  686. LOG(L_ERR, "ERROR: sctp_rcv_loop: partial delivery not"
  687. "supported\n");
  688. continue;
  689. }
  690. su2ip_addr(&ri.src_ip, &ri.src_su);
  691. ri.src_port=su_getport(&ri.src_su);
  692. /* get ancillary data */
  693. for (cmsg=CMSG_FIRSTHDR(&msg); cmsg; cmsg=CMSG_NXTHDR(&msg, cmsg)){
  694. if (likely((cmsg->cmsg_level==IPPROTO_SCTP) &&
  695. ((cmsg->cmsg_type==SCTP_SNDRCV)
  696. #ifdef SCTP_EXT
  697. || (cmsg->cmsg_type==SCTP_EXTRCV)
  698. #endif
  699. ) && (cmsg->cmsg_len>=CMSG_LEN(sizeof(*sinfo)))) ){
  700. sinfo=(struct sctp_sndrcvinfo*)CMSG_DATA(cmsg);
  701. DBG("sctp recv: message from %s:%d stream %d ppid %x"
  702. " flags %x%s tsn %u" " cumtsn %u associd %d\n",
  703. ip_addr2a(&ri.src_ip), htons(ri.src_port),
  704. sinfo->sinfo_stream, sinfo->sinfo_ppid,
  705. sinfo->sinfo_flags,
  706. (sinfo->sinfo_flags&SCTP_UNORDERED)?
  707. " (SCTP_UNORDERED)":"",
  708. sinfo->sinfo_tsn, sinfo->sinfo_cumtsn,
  709. sinfo->sinfo_assoc_id);
  710. break;
  711. }
  712. }
  713. /* we 0-term the messages for debugging */
  714. buf[len]=0; /* no need to save the previous char */
  715. /* sanity checks */
  716. if (len<MIN_SCTP_PACKET) {
  717. tmp=ip_addr2a(&ri.src_ip);
  718. DBG("sctp_rcv_loop: probing packet received from %s %d\n",
  719. tmp, htons(ri.src_port));
  720. continue;
  721. }
  722. if (ri.src_port==0){
  723. tmp=ip_addr2a(&ri.src_ip);
  724. LOG(L_INFO, "sctp_rcv_loop: dropping 0 port packet from %s\n",
  725. tmp);
  726. continue;
  727. }
  728. #ifdef USE_COMP
  729. ri.comp=COMP_NONE;
  730. #endif
  731. /* update the local config */
  732. cfg_update();
  733. receive_msg(buf, len, &ri);
  734. }
  735. error:
  736. return -1;
  737. }
  738. /* send buf:len over udp to dst (uses only the to and send_sock dst members)
  739. * returns the numbers of bytes sent on success (>=0) and -1 on error
  740. */
  741. int sctp_msg_send(struct dest_info* dst, char* buf, unsigned len)
  742. {
  743. int n;
  744. int tolen;
  745. struct ip_addr ip; /* used only on error, for debugging */
  746. struct msghdr msg;
  747. struct iovec iov[1];
  748. tolen=sockaddru_len(dst->to);
  749. iov[0].iov_base=buf;
  750. iov[0].iov_len=len;
  751. msg.msg_iov=iov;
  752. msg.msg_iovlen=1;
  753. msg.msg_name=&dst->to.s;
  754. msg.msg_namelen=tolen;
  755. msg.msg_control=0;
  756. msg.msg_controllen=0;
  757. msg.msg_flags=SCTP_UNORDERED;
  758. again:
  759. n=sendmsg(dst->send_sock->socket, &msg, MSG_DONTWAIT);
  760. #if 0
  761. n=sctp_sendmsg(dst->send_sock->socket, buf, len, &dst->to.s, tolen,
  762. 0 /* ppid */, SCTP_UNORDERED /* | SCTP_EOR */ /* flags */,
  763. 0 /* stream */, sctp_options.sctp_send_ttl /* ttl */,
  764. 0 /* context */);
  765. #endif
  766. if (n==-1){
  767. su2ip_addr(&ip, &dst->to);
  768. LOG(L_ERR, "ERROR: sctp_msg_send: sendmsg(sock,%p,%d,0,%s:%d,%d):"
  769. " %s(%d)\n", buf, len, ip_addr2a(&ip), su_getport(&dst->to),
  770. tolen, strerror(errno),errno);
  771. if (errno==EINTR) goto again;
  772. if (errno==EINVAL) {
  773. LOG(L_CRIT,"CRITICAL: invalid sendmsg parameters\n"
  774. "one possible reason is the server is bound to localhost and\n"
  775. "attempts to send to the net\n");
  776. }else if (errno==EAGAIN || errno==EWOULDBLOCK){
  777. LOG(L_ERR, "ERROR: sctp_msg_send: failed to send, send buffers"
  778. " full\n");
  779. /* TODO: fix blocking writes */
  780. }
  781. }
  782. return n;
  783. }
  784. void destroy_sctp()
  785. {
  786. }
  787. #endif /* USE_SCTP */