rtcweb.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531
  1. /*-
  2. * Copyright (C) 2012-2013 Michael Tuexen
  3. * Copyright (C) 2012-2013 Irene Ruengeler
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the project nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * $Id: rtcweb.c,v 1.26 2012-07-17 13:50:02 tuexen Exp $
  32. */
  33. /*
  34. * gcc -Wall -std=c99 -pedantic -o rtcweb rtcweb.c -lusrsctp
  35. */
  36. #ifdef _WIN32
  37. #define _CRT_SECURE_NO_WARNINGS
  38. #endif
  39. #include <stdarg.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <errno.h>
  44. #include <sys/types.h>
  45. #ifndef _WIN32
  46. #include <sys/socket.h>
  47. #include <sys/select.h>
  48. #include <netinet/in.h>
  49. #include <arpa/inet.h>
  50. #include <pthread.h>
  51. #include <unistd.h>
  52. #include <stdint.h>
  53. #else
  54. #include <winsock2.h>
  55. #include <ws2tcpip.h>
  56. #include <crtdbg.h>
  57. #endif
  58. #include <usrsctp.h>
  59. #include "programs_helper.h"
  60. #define LINE_LENGTH (1024)
  61. #define BUFFER_SIZE (1<<16)
  62. #define NUMBER_OF_CHANNELS (100)
  63. #define NUMBER_OF_STREAMS (100)
  64. #define DATA_CHANNEL_PPID_CONTROL 50
  65. #define DATA_CHANNEL_PPID_DOMSTRING 51
  66. #define DATA_CHANNEL_PPID_BINARY 52
  67. #define DATA_CHANNEL_CLOSED 0
  68. #define DATA_CHANNEL_CONNECTING 1
  69. #define DATA_CHANNEL_OPEN 2
  70. #define DATA_CHANNEL_CLOSING 3
  71. #define DATA_CHANNEL_FLAGS_SEND_REQ 0x00000001
  72. #define DATA_CHANNEL_FLAGS_SEND_RSP 0x00000002
  73. #define DATA_CHANNEL_FLAGS_SEND_ACK 0x00000004
  74. struct channel {
  75. uint32_t id;
  76. uint32_t pr_value;
  77. uint16_t pr_policy;
  78. uint16_t i_stream;
  79. uint16_t o_stream;
  80. uint8_t unordered;
  81. uint8_t state;
  82. uint32_t flags;
  83. };
  84. struct peer_connection {
  85. struct channel channels[NUMBER_OF_CHANNELS];
  86. struct channel *i_stream_channel[NUMBER_OF_STREAMS];
  87. struct channel *o_stream_channel[NUMBER_OF_STREAMS];
  88. uint16_t o_stream_buffer[NUMBER_OF_STREAMS];
  89. uint32_t o_stream_buffer_counter;
  90. #ifdef _WIN32
  91. CRITICAL_SECTION mutex;
  92. #else
  93. pthread_mutex_t mutex;
  94. #endif
  95. struct socket *sock;
  96. } peer_connection;
  97. #define DATA_CHANNEL_OPEN_REQUEST 0
  98. #define DATA_CHANNEL_OPEN_RESPONSE 1
  99. #define DATA_CHANNEL_ACK 2
  100. #define DATA_CHANNEL_RELIABLE 0
  101. #define DATA_CHANNEL_RELIABLE_STREAM 1
  102. #define DATA_CHANNEL_UNRELIABLE 2
  103. #define DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT 3
  104. #define DATA_CHANNEL_PARTIAL_RELIABLE_TIMED 4
  105. #define DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED 0x0001
  106. #ifndef _WIN32
  107. #define SCTP_PACKED __attribute__((packed))
  108. #else
  109. #pragma pack (push, 1)
  110. #define SCTP_PACKED
  111. #endif
  112. #if defined(_WIN32) && !defined(__MINGW32__)
  113. #pragma warning( push )
  114. #pragma warning( disable : 4200 )
  115. #endif /* defined(_WIN32) && !defined(__MINGW32__) */
  116. struct rtcweb_datachannel_open_request {
  117. uint8_t msg_type; /* DATA_CHANNEL_OPEN_REQUEST */
  118. uint8_t channel_type;
  119. uint16_t flags;
  120. uint16_t reliability_params;
  121. int16_t priority;
  122. char label[];
  123. } SCTP_PACKED;
  124. #if defined(_WIN32) && !defined(__MINGW32__)
  125. #pragma warning( pop )
  126. #endif /* defined(_WIN32) && !defined(__MINGW32__) */
  127. struct rtcweb_datachannel_open_response {
  128. uint8_t msg_type; /* DATA_CHANNEL_OPEN_RESPONSE */
  129. uint8_t error;
  130. uint16_t flags;
  131. uint16_t reverse_stream;
  132. } SCTP_PACKED;
  133. struct rtcweb_datachannel_ack {
  134. uint8_t msg_type; /* DATA_CHANNEL_ACK */
  135. } SCTP_PACKED;
  136. #ifdef _WIN32
  137. #pragma pack(pop)
  138. #endif
  139. #undef SCTP_PACKED
  140. static void
  141. lock_peer_connection(struct peer_connection *);
  142. static void
  143. unlock_peer_connection(struct peer_connection *);
  144. static void
  145. init_peer_connection(struct peer_connection *pc)
  146. {
  147. uint32_t i;
  148. struct channel *channel;
  149. #ifdef _WIN32
  150. InitializeCriticalSection(&(pc->mutex));
  151. #else
  152. pthread_mutex_init(&pc->mutex, NULL);
  153. #endif
  154. lock_peer_connection(pc);
  155. for (i = 0; i < NUMBER_OF_CHANNELS; i++) {
  156. channel = &(pc->channels[i]);
  157. channel->id = i;
  158. channel->state = DATA_CHANNEL_CLOSED;
  159. channel->pr_policy = SCTP_PR_SCTP_NONE;
  160. channel->pr_value = 0;
  161. channel->i_stream = 0;
  162. channel->o_stream = 0;
  163. channel->unordered = 0;
  164. channel->flags = 0;
  165. }
  166. for (i = 0; i < NUMBER_OF_STREAMS; i++) {
  167. pc->i_stream_channel[i] = NULL;
  168. pc->o_stream_channel[i] = NULL;
  169. pc->o_stream_buffer[i] = 0;
  170. }
  171. pc->o_stream_buffer_counter = 0;
  172. pc->sock = NULL;
  173. unlock_peer_connection(pc);
  174. }
  175. static void
  176. lock_peer_connection(struct peer_connection *pc)
  177. {
  178. #ifdef _WIN32
  179. EnterCriticalSection(&(pc->mutex));
  180. #else
  181. pthread_mutex_lock(&pc->mutex);
  182. #endif
  183. }
  184. static void
  185. unlock_peer_connection(struct peer_connection *pc)
  186. {
  187. #ifdef _WIN32
  188. LeaveCriticalSection(&(pc->mutex));
  189. #else
  190. pthread_mutex_unlock(&pc->mutex);
  191. #endif
  192. }
  193. static struct channel *
  194. find_channel_by_i_stream(struct peer_connection *pc, uint16_t i_stream)
  195. {
  196. if (i_stream < NUMBER_OF_STREAMS) {
  197. return (pc->i_stream_channel[i_stream]);
  198. } else {
  199. return (NULL);
  200. }
  201. }
  202. static struct channel *
  203. find_channel_by_o_stream(struct peer_connection *pc, uint16_t o_stream)
  204. {
  205. if (o_stream < NUMBER_OF_STREAMS) {
  206. return (pc->o_stream_channel[o_stream]);
  207. } else {
  208. return (NULL);
  209. }
  210. }
  211. static struct channel *
  212. find_free_channel(struct peer_connection *pc)
  213. {
  214. uint32_t i;
  215. for (i = 0; i < NUMBER_OF_CHANNELS; i++) {
  216. if (pc->channels[i].state == DATA_CHANNEL_CLOSED) {
  217. break;
  218. }
  219. }
  220. if (i == NUMBER_OF_CHANNELS) {
  221. return (NULL);
  222. } else {
  223. return (&(pc->channels[i]));
  224. }
  225. }
  226. static uint16_t
  227. find_free_o_stream(struct peer_connection *pc)
  228. {
  229. struct sctp_status status;
  230. uint32_t i, limit;
  231. socklen_t len;
  232. len = (socklen_t)sizeof(struct sctp_status);
  233. if (usrsctp_getsockopt(pc->sock, IPPROTO_SCTP, SCTP_STATUS, &status, &len) < 0) {
  234. perror("getsockopt");
  235. return (0);
  236. }
  237. if (status.sstat_outstrms < NUMBER_OF_STREAMS) {
  238. limit = status.sstat_outstrms;
  239. } else {
  240. limit = NUMBER_OF_STREAMS;
  241. }
  242. /* stream id 0 is reserved */
  243. for (i = 1; i < limit; i++) {
  244. if (pc->o_stream_channel[i] == NULL) {
  245. break;
  246. }
  247. }
  248. if (i == limit) {
  249. return (0);
  250. } else {
  251. return ((uint16_t)i);
  252. }
  253. }
  254. static void
  255. request_more_o_streams(struct peer_connection *pc)
  256. {
  257. struct sctp_status status;
  258. struct sctp_add_streams sas;
  259. uint32_t i, o_streams_needed;
  260. socklen_t len;
  261. o_streams_needed = 0;
  262. for (i = 0; i < NUMBER_OF_CHANNELS; i++) {
  263. if ((pc->channels[i].state == DATA_CHANNEL_CONNECTING) &&
  264. (pc->channels[i].o_stream == 0)) {
  265. o_streams_needed++;
  266. }
  267. }
  268. len = (socklen_t)sizeof(struct sctp_status);
  269. if (usrsctp_getsockopt(pc->sock, IPPROTO_SCTP, SCTP_STATUS, &status, &len) < 0) {
  270. perror("getsockopt");
  271. return;
  272. }
  273. if (status.sstat_outstrms + o_streams_needed > NUMBER_OF_STREAMS) {
  274. o_streams_needed = NUMBER_OF_STREAMS - status.sstat_outstrms;
  275. }
  276. if (o_streams_needed == 0) {
  277. return;
  278. }
  279. memset(&sas, 0, sizeof(struct sctp_add_streams));
  280. sas.sas_instrms = 0;
  281. sas.sas_outstrms = (uint16_t)o_streams_needed; /* XXX error handling */
  282. if (usrsctp_setsockopt(pc->sock, IPPROTO_SCTP, SCTP_ADD_STREAMS, &sas, (socklen_t)sizeof(struct sctp_add_streams)) < 0) {
  283. perror("setsockopt");
  284. }
  285. return;
  286. }
  287. static int
  288. send_open_request_message(struct socket *sock, uint16_t o_stream, uint8_t unordered, uint16_t pr_policy, uint32_t pr_value)
  289. {
  290. /* XXX: This should be encoded in a better way */
  291. struct rtcweb_datachannel_open_request req;
  292. struct sctp_sndinfo sndinfo;
  293. memset(&req, 0, sizeof(struct rtcweb_datachannel_open_request));
  294. req.msg_type = DATA_CHANNEL_OPEN_REQUEST;
  295. switch (pr_policy) {
  296. case SCTP_PR_SCTP_NONE:
  297. /* XXX: What about DATA_CHANNEL_RELIABLE_STREAM */
  298. req.channel_type = DATA_CHANNEL_RELIABLE;
  299. break;
  300. case SCTP_PR_SCTP_TTL:
  301. /* XXX: What about DATA_CHANNEL_UNRELIABLE */
  302. req.channel_type = DATA_CHANNEL_PARTIAL_RELIABLE_TIMED;
  303. break;
  304. case SCTP_PR_SCTP_RTX:
  305. req.channel_type = DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT;
  306. break;
  307. default:
  308. return (0);
  309. }
  310. req.flags = htons(0);
  311. if (unordered) {
  312. req.flags |= htons(DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED);
  313. }
  314. req.reliability_params = htons((uint16_t)pr_value); /* XXX Why 16-bit */
  315. req.priority = htons(0); /* XXX: add support */
  316. memset(&sndinfo, 0, sizeof(struct sctp_sndinfo));
  317. sndinfo.snd_sid = o_stream;
  318. sndinfo.snd_flags = SCTP_EOR;
  319. sndinfo.snd_ppid = htonl(DATA_CHANNEL_PPID_CONTROL);
  320. if (usrsctp_sendv(sock,
  321. &req, sizeof(struct rtcweb_datachannel_open_request),
  322. NULL, 0,
  323. &sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
  324. SCTP_SENDV_SNDINFO, 0) < 0) {
  325. perror("sctp_sendv");
  326. return (0);
  327. } else {
  328. return (1);
  329. }
  330. }
  331. static int
  332. send_open_response_message(struct socket *sock, uint16_t o_stream, uint16_t i_stream)
  333. {
  334. /* XXX: This should be encoded in a better way */
  335. struct rtcweb_datachannel_open_response rsp;
  336. struct sctp_sndinfo sndinfo;
  337. memset(&rsp, 0, sizeof(struct rtcweb_datachannel_open_response));
  338. rsp.msg_type = DATA_CHANNEL_OPEN_RESPONSE;
  339. rsp.error = 0;
  340. rsp.flags = htons(0);
  341. rsp.reverse_stream = htons(i_stream);
  342. memset(&sndinfo, 0, sizeof(struct sctp_sndinfo));
  343. sndinfo.snd_sid = o_stream;
  344. sndinfo.snd_flags = SCTP_EOR;
  345. sndinfo.snd_ppid = htonl(DATA_CHANNEL_PPID_CONTROL);
  346. if (usrsctp_sendv(sock,
  347. &rsp, sizeof(struct rtcweb_datachannel_open_response),
  348. NULL, 0,
  349. &sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
  350. SCTP_SENDV_SNDINFO, 0) < 0) {
  351. perror("sctp_sendv");
  352. return (0);
  353. } else {
  354. return (1);
  355. }
  356. }
  357. static int
  358. send_open_ack_message(struct socket *sock, uint16_t o_stream)
  359. {
  360. /* XXX: This should be encoded in a better way */
  361. struct rtcweb_datachannel_ack ack;
  362. struct sctp_sndinfo sndinfo;
  363. memset(&ack, 0, sizeof(struct rtcweb_datachannel_ack));
  364. ack.msg_type = DATA_CHANNEL_ACK;
  365. memset(&sndinfo, 0, sizeof(struct sctp_sndinfo));
  366. sndinfo.snd_sid = o_stream;
  367. sndinfo.snd_flags = SCTP_EOR;
  368. sndinfo.snd_ppid = htonl(DATA_CHANNEL_PPID_CONTROL);
  369. if (usrsctp_sendv(sock,
  370. &ack, sizeof(struct rtcweb_datachannel_ack),
  371. NULL, 0,
  372. &sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
  373. SCTP_SENDV_SNDINFO, 0) < 0) {
  374. perror("sctp_sendv");
  375. return (0);
  376. } else {
  377. return (1);
  378. }
  379. }
  380. static void
  381. send_deferred_messages(struct peer_connection *pc)
  382. {
  383. uint32_t i;
  384. struct channel *channel;
  385. for (i = 0; i < NUMBER_OF_CHANNELS; i++) {
  386. channel = &(pc->channels[i]);
  387. if (channel->flags & DATA_CHANNEL_FLAGS_SEND_REQ) {
  388. if (send_open_request_message(pc->sock, channel->o_stream, channel->unordered, channel->pr_policy, channel->pr_value)) {
  389. channel->flags &= ~DATA_CHANNEL_FLAGS_SEND_REQ;
  390. } else {
  391. if (errno != EAGAIN) {
  392. /* XXX: error handling */
  393. }
  394. }
  395. }
  396. if (channel->flags & DATA_CHANNEL_FLAGS_SEND_RSP) {
  397. if (send_open_response_message(pc->sock, channel->o_stream, channel->i_stream)) {
  398. channel->flags &= ~DATA_CHANNEL_FLAGS_SEND_RSP;
  399. } else {
  400. if (errno != EAGAIN) {
  401. /* XXX: error handling */
  402. }
  403. }
  404. }
  405. if (channel->flags & DATA_CHANNEL_FLAGS_SEND_ACK) {
  406. if (send_open_ack_message(pc->sock, channel->o_stream)) {
  407. channel->flags &= ~DATA_CHANNEL_FLAGS_SEND_ACK;
  408. } else {
  409. if (errno != EAGAIN) {
  410. /* XXX: error handling */
  411. }
  412. }
  413. }
  414. }
  415. return;
  416. }
  417. static struct channel *
  418. open_channel(struct peer_connection *pc, uint8_t unordered, uint16_t pr_policy, uint32_t pr_value)
  419. {
  420. struct channel *channel;
  421. uint16_t o_stream;
  422. if ((pr_policy != SCTP_PR_SCTP_NONE) &&
  423. (pr_policy != SCTP_PR_SCTP_TTL) &&
  424. (pr_policy != SCTP_PR_SCTP_RTX)) {
  425. return (NULL);
  426. }
  427. if ((unordered != 0) && (unordered != 1)) {
  428. return (NULL);
  429. }
  430. if ((pr_policy == SCTP_PR_SCTP_NONE) && (pr_value != 0)) {
  431. return (NULL);
  432. }
  433. if ((channel = find_free_channel(pc)) == NULL) {
  434. return (NULL);
  435. }
  436. o_stream = find_free_o_stream(pc);
  437. channel->state = DATA_CHANNEL_CONNECTING;
  438. channel->unordered = unordered;
  439. channel->pr_policy = pr_policy;
  440. channel->pr_value = pr_value;
  441. channel->o_stream = o_stream;
  442. channel->flags = 0;
  443. if (o_stream == 0) {
  444. request_more_o_streams(pc);
  445. } else {
  446. if (send_open_request_message(pc->sock, o_stream, unordered, pr_policy, pr_value)) {
  447. pc->o_stream_channel[o_stream] = channel;
  448. } else {
  449. if (errno == EAGAIN) {
  450. pc->o_stream_channel[o_stream] = channel;
  451. channel->flags |= DATA_CHANNEL_FLAGS_SEND_REQ;
  452. } else {
  453. channel->state = DATA_CHANNEL_CLOSED;
  454. channel->unordered = 0;
  455. channel->pr_policy = 0;
  456. channel->pr_value = 0;
  457. channel->o_stream = 0;
  458. channel->flags = 0;
  459. channel = NULL;
  460. }
  461. }
  462. }
  463. return (channel);
  464. }
  465. static int
  466. send_user_message(struct peer_connection *pc, struct channel *channel, char *message, size_t length)
  467. {
  468. struct sctp_sendv_spa spa;
  469. if (channel == NULL) {
  470. return (0);
  471. }
  472. if ((channel->state != DATA_CHANNEL_OPEN) &&
  473. (channel->state != DATA_CHANNEL_CONNECTING)) {
  474. /* XXX: What to do in other states */
  475. return (0);
  476. }
  477. memset(&spa, 0, sizeof(struct sctp_sendv_spa));
  478. spa.sendv_sndinfo.snd_sid = channel->o_stream;
  479. if ((channel->state == DATA_CHANNEL_OPEN) &&
  480. (channel->unordered)) {
  481. spa.sendv_sndinfo.snd_flags = SCTP_EOR | SCTP_UNORDERED;
  482. } else {
  483. spa.sendv_sndinfo.snd_flags = SCTP_EOR;
  484. }
  485. spa.sendv_sndinfo.snd_ppid = htonl(DATA_CHANNEL_PPID_DOMSTRING);
  486. spa.sendv_flags = SCTP_SEND_SNDINFO_VALID;
  487. if ((channel->pr_policy == SCTP_PR_SCTP_TTL) ||
  488. (channel->pr_policy == SCTP_PR_SCTP_RTX)) {
  489. spa.sendv_prinfo.pr_policy = channel->pr_policy;
  490. spa.sendv_prinfo.pr_value = channel->pr_value;
  491. spa.sendv_flags |= SCTP_SEND_PRINFO_VALID;
  492. }
  493. if (usrsctp_sendv(pc->sock,
  494. message, length,
  495. NULL, 0,
  496. &spa, (socklen_t)sizeof(struct sctp_sendv_spa),
  497. SCTP_SENDV_SPA, 0) < 0) {
  498. perror("sctp_sendv");
  499. return (0);
  500. } else {
  501. return (1);
  502. }
  503. }
  504. static void
  505. reset_outgoing_stream(struct peer_connection *pc, uint16_t o_stream)
  506. {
  507. uint32_t i;
  508. for (i = 0; i < pc->o_stream_buffer_counter; i++) {
  509. if (pc->o_stream_buffer[i] == o_stream) {
  510. return;
  511. }
  512. }
  513. pc->o_stream_buffer[pc->o_stream_buffer_counter++] = o_stream;
  514. return;
  515. }
  516. static void
  517. send_outgoing_stream_reset(struct peer_connection *pc)
  518. {
  519. struct sctp_reset_streams *srs;
  520. uint32_t i;
  521. size_t len;
  522. if (pc->o_stream_buffer_counter == 0) {
  523. return;
  524. }
  525. len = sizeof(sctp_assoc_t) + (2 + pc->o_stream_buffer_counter) * sizeof(uint16_t);
  526. srs = (struct sctp_reset_streams *)malloc(len);
  527. if (srs == NULL) {
  528. return;
  529. }
  530. memset(srs, 0, len);
  531. srs->srs_flags = SCTP_STREAM_RESET_OUTGOING;
  532. srs->srs_number_streams = pc->o_stream_buffer_counter;
  533. for (i = 0; i < pc->o_stream_buffer_counter; i++) {
  534. srs->srs_stream_list[i] = pc->o_stream_buffer[i];
  535. }
  536. if (usrsctp_setsockopt(pc->sock, IPPROTO_SCTP, SCTP_RESET_STREAMS, srs, (socklen_t)len) < 0) {
  537. perror("setsockopt");
  538. } else {
  539. for (i = 0; i < pc->o_stream_buffer_counter; i++) {
  540. srs->srs_stream_list[i] = 0;
  541. }
  542. pc->o_stream_buffer_counter = 0;
  543. }
  544. free(srs);
  545. return;
  546. }
  547. static void
  548. close_channel(struct peer_connection *pc, struct channel *channel)
  549. {
  550. if (channel == NULL) {
  551. return;
  552. }
  553. if (channel->state != DATA_CHANNEL_OPEN) {
  554. return;
  555. }
  556. reset_outgoing_stream(pc, channel->o_stream);
  557. send_outgoing_stream_reset(pc);
  558. channel->state = DATA_CHANNEL_CLOSING;
  559. return;
  560. }
  561. static void
  562. handle_open_request_message(struct peer_connection *pc,
  563. struct rtcweb_datachannel_open_request *req,
  564. size_t length,
  565. uint16_t i_stream)
  566. {
  567. struct channel *channel;
  568. uint32_t pr_value;
  569. uint16_t pr_policy;
  570. uint16_t o_stream;
  571. uint8_t unordered;
  572. if ((channel = find_channel_by_i_stream(pc, i_stream))) {
  573. printf("handle_open_request_message: channel %u is in state %u instead of CLOSED.\n",
  574. channel->id, channel->state);
  575. /* XXX: some error handling */
  576. return;
  577. }
  578. if ((channel = find_free_channel(pc)) == NULL) {
  579. /* XXX: some error handling */
  580. return;
  581. }
  582. switch (req->channel_type) {
  583. case DATA_CHANNEL_RELIABLE:
  584. pr_policy = SCTP_PR_SCTP_NONE;
  585. break;
  586. /* XXX Doesn't make sense */
  587. case DATA_CHANNEL_RELIABLE_STREAM:
  588. pr_policy = SCTP_PR_SCTP_NONE;
  589. break;
  590. /* XXX Doesn't make sense */
  591. case DATA_CHANNEL_UNRELIABLE:
  592. pr_policy = SCTP_PR_SCTP_TTL;
  593. break;
  594. case DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT:
  595. pr_policy = SCTP_PR_SCTP_RTX;
  596. break;
  597. case DATA_CHANNEL_PARTIAL_RELIABLE_TIMED:
  598. pr_policy = SCTP_PR_SCTP_TTL;
  599. break;
  600. default:
  601. pr_policy = SCTP_PR_SCTP_NONE;
  602. /* XXX error handling */
  603. break;
  604. }
  605. pr_value = ntohs(req->reliability_params);
  606. if (ntohs(req->flags) & DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED) {
  607. unordered = 1;
  608. } else {
  609. unordered = 0;
  610. }
  611. o_stream = find_free_o_stream(pc);
  612. channel->state = DATA_CHANNEL_CONNECTING;
  613. channel->unordered = unordered;
  614. channel->pr_policy = pr_policy;
  615. channel->pr_value = pr_value;
  616. channel->i_stream = i_stream;
  617. channel->o_stream = o_stream;
  618. channel->flags = 0;
  619. pc->i_stream_channel[i_stream] = channel;
  620. if (o_stream == 0) {
  621. request_more_o_streams(pc);
  622. } else {
  623. if (send_open_response_message(pc->sock, o_stream, i_stream)) {
  624. pc->o_stream_channel[o_stream] = channel;
  625. } else {
  626. if (errno == EAGAIN) {
  627. channel->flags |= DATA_CHANNEL_FLAGS_SEND_RSP;
  628. pc->o_stream_channel[o_stream] = channel;
  629. } else {
  630. /* XXX: Signal error to the other end. */
  631. pc->i_stream_channel[i_stream] = NULL;
  632. channel->state = DATA_CHANNEL_CLOSED;
  633. channel->unordered = 0;
  634. channel->pr_policy = 0;
  635. channel->pr_value = 0;
  636. channel->i_stream = 0;
  637. channel->o_stream = 0;
  638. channel->flags = 0;
  639. }
  640. }
  641. }
  642. }
  643. static void
  644. handle_open_response_message(struct peer_connection *pc,
  645. struct rtcweb_datachannel_open_response *rsp,
  646. size_t length, uint16_t i_stream)
  647. {
  648. uint16_t o_stream;
  649. struct channel *channel;
  650. o_stream = ntohs(rsp->reverse_stream);
  651. channel = find_channel_by_o_stream(pc, o_stream);
  652. if (channel == NULL) {
  653. /* XXX: improve error handling */
  654. printf("handle_open_response_message: Can't find channel for outgoing steam %d.\n", o_stream);
  655. return;
  656. }
  657. if (channel->state != DATA_CHANNEL_CONNECTING) {
  658. /* XXX: improve error handling */
  659. printf("handle_open_response_message: Channel with id %u for outgoing steam %u is in state %u.\n", channel->id, o_stream, channel->state);
  660. return;
  661. }
  662. if (find_channel_by_i_stream(pc, i_stream)) {
  663. /* XXX: improve error handling */
  664. printf("handle_open_response_message: Channel collision for channel with id %u and streams (in/out) = (%u/%u).\n", channel->id, i_stream, o_stream);
  665. return;
  666. }
  667. channel->i_stream = i_stream;
  668. channel->state = DATA_CHANNEL_OPEN;
  669. pc->i_stream_channel[i_stream] = channel;
  670. if (send_open_ack_message(pc->sock, o_stream)) {
  671. channel->flags = 0;
  672. } else {
  673. channel->flags |= DATA_CHANNEL_FLAGS_SEND_ACK;
  674. }
  675. return;
  676. }
  677. static void
  678. handle_open_ack_message(struct peer_connection *pc,
  679. struct rtcweb_datachannel_ack *ack,
  680. size_t length, uint16_t i_stream)
  681. {
  682. struct channel *channel;
  683. channel = find_channel_by_i_stream(pc, i_stream);
  684. if (channel == NULL) {
  685. /* XXX: some error handling */
  686. return;
  687. }
  688. if (channel->state == DATA_CHANNEL_OPEN) {
  689. return;
  690. }
  691. if (channel->state != DATA_CHANNEL_CONNECTING) {
  692. /* XXX: error handling */
  693. return;
  694. }
  695. channel->state = DATA_CHANNEL_OPEN;
  696. return;
  697. }
  698. static void
  699. handle_unknown_message(char *msg, size_t length, uint16_t i_stream)
  700. {
  701. /* XXX: Send an error message */
  702. return;
  703. }
  704. static void
  705. handle_data_message(struct peer_connection *pc,
  706. char *buffer, size_t length, uint16_t i_stream)
  707. {
  708. struct channel *channel;
  709. channel = find_channel_by_i_stream(pc, i_stream);
  710. if (channel == NULL) {
  711. /* XXX: Some error handling */
  712. return;
  713. }
  714. if (channel->state == DATA_CHANNEL_CONNECTING) {
  715. /* Implicit ACK */
  716. channel->state = DATA_CHANNEL_OPEN;
  717. }
  718. if (channel->state != DATA_CHANNEL_OPEN) {
  719. /* XXX: What about other states? */
  720. /* XXX: Some error handling */
  721. return;
  722. } else {
  723. /* Assuming DATA_CHANNEL_PPID_DOMSTRING */
  724. /* XXX: Protect for non 0 terminated buffer */
  725. printf("Message received of length %zu on channel with id %u: %.*s\n",
  726. length, channel->id, (int)length, buffer);
  727. }
  728. return;
  729. }
  730. static void
  731. handle_message(struct peer_connection *pc, char *buffer, size_t length, uint32_t ppid, uint16_t i_stream)
  732. {
  733. struct rtcweb_datachannel_open_request *req;
  734. struct rtcweb_datachannel_open_response *rsp;
  735. struct rtcweb_datachannel_ack *ack, *msg;
  736. switch (ppid) {
  737. case DATA_CHANNEL_PPID_CONTROL:
  738. if (length < sizeof(struct rtcweb_datachannel_ack)) {
  739. return;
  740. }
  741. msg = (struct rtcweb_datachannel_ack *)buffer;
  742. switch (msg->msg_type) {
  743. case DATA_CHANNEL_OPEN_REQUEST:
  744. if (length < sizeof(struct rtcweb_datachannel_open_request)) {
  745. /* XXX: error handling? */
  746. return;
  747. }
  748. req = (struct rtcweb_datachannel_open_request *)buffer;
  749. handle_open_request_message(pc, req, length, i_stream);
  750. break;
  751. case DATA_CHANNEL_OPEN_RESPONSE:
  752. if (length < sizeof(struct rtcweb_datachannel_open_response)) {
  753. /* XXX: error handling? */
  754. return;
  755. }
  756. rsp = (struct rtcweb_datachannel_open_response *)buffer;
  757. handle_open_response_message(pc, rsp, length, i_stream);
  758. break;
  759. case DATA_CHANNEL_ACK:
  760. if (length < sizeof(struct rtcweb_datachannel_ack)) {
  761. /* XXX: error handling? */
  762. return;
  763. }
  764. ack = (struct rtcweb_datachannel_ack *)buffer;
  765. handle_open_ack_message(pc, ack, length, i_stream);
  766. break;
  767. default:
  768. handle_unknown_message(buffer, length, i_stream);
  769. break;
  770. }
  771. break;
  772. case DATA_CHANNEL_PPID_DOMSTRING:
  773. case DATA_CHANNEL_PPID_BINARY:
  774. handle_data_message(pc, buffer, length, i_stream);
  775. break;
  776. default:
  777. printf("Message of length %zu, PPID %u on stream %u received.\n",
  778. length, ppid, i_stream);
  779. break;
  780. }
  781. }
  782. static void
  783. handle_association_change_event(struct sctp_assoc_change *sac)
  784. {
  785. unsigned int i, n;
  786. printf("Association change ");
  787. switch (sac->sac_state) {
  788. case SCTP_COMM_UP:
  789. printf("SCTP_COMM_UP");
  790. break;
  791. case SCTP_COMM_LOST:
  792. printf("SCTP_COMM_LOST");
  793. break;
  794. case SCTP_RESTART:
  795. printf("SCTP_RESTART");
  796. break;
  797. case SCTP_SHUTDOWN_COMP:
  798. printf("SCTP_SHUTDOWN_COMP");
  799. break;
  800. case SCTP_CANT_STR_ASSOC:
  801. printf("SCTP_CANT_STR_ASSOC");
  802. break;
  803. default:
  804. printf("UNKNOWN");
  805. break;
  806. }
  807. printf(", streams (in/out) = (%u/%u)",
  808. sac->sac_inbound_streams, sac->sac_outbound_streams);
  809. n = sac->sac_length - sizeof(struct sctp_assoc_change);
  810. if (((sac->sac_state == SCTP_COMM_UP) ||
  811. (sac->sac_state == SCTP_RESTART)) && (n > 0)) {
  812. printf(", supports");
  813. for (i = 0; i < n; i++) {
  814. switch (sac->sac_info[i]) {
  815. case SCTP_ASSOC_SUPPORTS_PR:
  816. printf(" PR");
  817. break;
  818. case SCTP_ASSOC_SUPPORTS_AUTH:
  819. printf(" AUTH");
  820. break;
  821. case SCTP_ASSOC_SUPPORTS_ASCONF:
  822. printf(" ASCONF");
  823. break;
  824. case SCTP_ASSOC_SUPPORTS_MULTIBUF:
  825. printf(" MULTIBUF");
  826. break;
  827. case SCTP_ASSOC_SUPPORTS_RE_CONFIG:
  828. printf(" RE-CONFIG");
  829. break;
  830. case SCTP_ASSOC_SUPPORTS_INTERLEAVING:
  831. printf(" INTERLEAVING");
  832. break;
  833. default:
  834. printf(" UNKNOWN(0x%02x)", sac->sac_info[i]);
  835. break;
  836. }
  837. }
  838. } else if (((sac->sac_state == SCTP_COMM_LOST) ||
  839. (sac->sac_state == SCTP_CANT_STR_ASSOC)) && (n > 0)) {
  840. printf(", ABORT =");
  841. for (i = 0; i < n; i++) {
  842. printf(" 0x%02x", sac->sac_info[i]);
  843. }
  844. }
  845. printf(".\n");
  846. if ((sac->sac_state == SCTP_CANT_STR_ASSOC) ||
  847. (sac->sac_state == SCTP_SHUTDOWN_COMP) ||
  848. (sac->sac_state == SCTP_COMM_LOST)) {
  849. exit(0);
  850. }
  851. return;
  852. }
  853. static void
  854. handle_peer_address_change_event(struct sctp_paddr_change *spc)
  855. {
  856. char addr_buf[INET6_ADDRSTRLEN];
  857. const char *addr;
  858. struct sockaddr_in *sin;
  859. struct sockaddr_in6 *sin6;
  860. switch (spc->spc_aaddr.ss_family) {
  861. case AF_INET:
  862. sin = (struct sockaddr_in *)&spc->spc_aaddr;
  863. addr = inet_ntop(AF_INET, &sin->sin_addr, addr_buf, INET_ADDRSTRLEN);
  864. break;
  865. case AF_INET6:
  866. sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
  867. addr = inet_ntop(AF_INET6, &sin6->sin6_addr, addr_buf, INET6_ADDRSTRLEN);
  868. break;
  869. default:
  870. #ifdef _WIN32
  871. if (_snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family) < 0) {
  872. #else
  873. if (snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family) < 0) {
  874. #endif
  875. addr_buf[0] = '\0';
  876. }
  877. addr = addr_buf;
  878. break;
  879. }
  880. printf("Peer address %s is now ", addr);
  881. switch (spc->spc_state) {
  882. case SCTP_ADDR_AVAILABLE:
  883. printf("SCTP_ADDR_AVAILABLE");
  884. break;
  885. case SCTP_ADDR_UNREACHABLE:
  886. printf("SCTP_ADDR_UNREACHABLE");
  887. break;
  888. case SCTP_ADDR_REMOVED:
  889. printf("SCTP_ADDR_REMOVED");
  890. break;
  891. case SCTP_ADDR_ADDED:
  892. printf("SCTP_ADDR_ADDED");
  893. break;
  894. case SCTP_ADDR_MADE_PRIM:
  895. printf("SCTP_ADDR_MADE_PRIM");
  896. break;
  897. case SCTP_ADDR_CONFIRMED:
  898. printf("SCTP_ADDR_CONFIRMED");
  899. break;
  900. default:
  901. printf("UNKNOWN");
  902. break;
  903. }
  904. printf(" (error = 0x%08x).\n", spc->spc_error);
  905. return;
  906. }
  907. static void
  908. handle_adaptation_indication(struct sctp_adaptation_event *sai)
  909. {
  910. printf("Adaptation indication: %x.\n", sai-> sai_adaptation_ind);
  911. return;
  912. }
  913. static void
  914. handle_shutdown_event(struct sctp_shutdown_event *sse)
  915. {
  916. printf("Shutdown event.\n");
  917. /* XXX: notify all channels. */
  918. return;
  919. }
  920. static void
  921. handle_stream_reset_event(struct peer_connection *pc, struct sctp_stream_reset_event *strrst)
  922. {
  923. uint32_t n, i;
  924. struct channel *channel;
  925. n = (strrst->strreset_length - sizeof(struct sctp_stream_reset_event)) / sizeof(uint16_t);
  926. printf("Stream reset event: flags = %x, ", strrst->strreset_flags);
  927. if (strrst->strreset_flags & SCTP_STREAM_RESET_INCOMING_SSN) {
  928. if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
  929. printf("incoming/");
  930. }
  931. printf("incoming ");
  932. }
  933. if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
  934. printf("outgoing ");
  935. }
  936. printf("stream ids = ");
  937. for (i = 0; i < n; i++) {
  938. if (i > 0) {
  939. printf(", ");
  940. }
  941. printf("%d", strrst->strreset_stream_list[i]);
  942. }
  943. printf(".\n");
  944. if (!(strrst->strreset_flags & SCTP_STREAM_RESET_DENIED) &&
  945. !(strrst->strreset_flags & SCTP_STREAM_RESET_FAILED)) {
  946. for (i = 0; i < n; i++) {
  947. if (strrst->strreset_flags & SCTP_STREAM_RESET_INCOMING_SSN) {
  948. channel = find_channel_by_i_stream(pc, strrst->strreset_stream_list[i]);
  949. if (channel != NULL) {
  950. pc->i_stream_channel[channel->i_stream] = NULL;
  951. channel->i_stream = 0;
  952. if (channel->o_stream == 0) {
  953. channel->pr_policy = SCTP_PR_SCTP_NONE;
  954. channel->pr_value = 0;
  955. channel->unordered = 0;
  956. channel->flags = 0;
  957. channel->state = DATA_CHANNEL_CLOSED;
  958. } else {
  959. if (channel->state == DATA_CHANNEL_OPEN) {
  960. reset_outgoing_stream(pc, channel->o_stream);
  961. channel->state = DATA_CHANNEL_CLOSING;
  962. } else {
  963. /* XXX: What to do? */
  964. }
  965. }
  966. }
  967. }
  968. if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
  969. channel = find_channel_by_o_stream(pc, strrst->strreset_stream_list[i]);
  970. if (channel != NULL) {
  971. pc->o_stream_channel[channel->o_stream] = NULL;
  972. channel->o_stream = 0;
  973. if (channel->i_stream == 0) {
  974. channel->pr_policy = SCTP_PR_SCTP_NONE;
  975. channel->pr_value = 0;
  976. channel->unordered = 0;
  977. channel->flags = 0;
  978. channel->state = DATA_CHANNEL_CLOSED;
  979. }
  980. }
  981. }
  982. }
  983. }
  984. return;
  985. }
  986. static void
  987. handle_stream_change_event(struct peer_connection *pc, struct sctp_stream_change_event *strchg)
  988. {
  989. uint16_t o_stream;
  990. uint32_t i;
  991. struct channel *channel;
  992. printf("Stream change event: streams (in/out) = (%u/%u), flags = %x.\n",
  993. strchg->strchange_instrms, strchg->strchange_outstrms, strchg->strchange_flags);
  994. for (i = 0; i < NUMBER_OF_CHANNELS; i++) {
  995. channel = &(pc->channels[i]);
  996. if ((channel->state == DATA_CHANNEL_CONNECTING) &&
  997. (channel->o_stream == 0)) {
  998. if ((strchg->strchange_flags & SCTP_STREAM_CHANGE_DENIED) ||
  999. (strchg->strchange_flags & SCTP_STREAM_CHANGE_FAILED)) {
  1000. /* XXX: Signal to the other end. */
  1001. if (channel->i_stream != 0) {
  1002. pc->i_stream_channel[channel->i_stream] = NULL;
  1003. }
  1004. channel->unordered = 0;
  1005. channel->pr_policy = SCTP_PR_SCTP_NONE;
  1006. channel->pr_value = 0;
  1007. channel->i_stream = 0;
  1008. channel->o_stream = 0;
  1009. channel->flags = 0;
  1010. channel->state = DATA_CHANNEL_CLOSED;
  1011. } else {
  1012. o_stream = find_free_o_stream(pc);
  1013. if (o_stream != 0) {
  1014. channel->o_stream = o_stream;
  1015. pc->o_stream_channel[o_stream] = channel;
  1016. if (channel->i_stream == 0) {
  1017. channel->flags |= DATA_CHANNEL_FLAGS_SEND_REQ;
  1018. } else {
  1019. channel->flags |= DATA_CHANNEL_FLAGS_SEND_RSP;
  1020. }
  1021. } else {
  1022. /* We will not find more ... */
  1023. break;
  1024. }
  1025. }
  1026. }
  1027. }
  1028. return;
  1029. }
  1030. static void
  1031. handle_remote_error_event(struct sctp_remote_error *sre)
  1032. {
  1033. size_t i, n;
  1034. n = sre->sre_length - sizeof(struct sctp_remote_error);
  1035. printf("Remote Error (error = 0x%04x): ", sre->sre_error);
  1036. for (i = 0; i < n; i++) {
  1037. printf(" 0x%02x", sre-> sre_data[i]);
  1038. }
  1039. printf(".\n");
  1040. return;
  1041. }
  1042. static void
  1043. handle_send_failed_event(struct sctp_send_failed_event *ssfe)
  1044. {
  1045. size_t i, n;
  1046. if (ssfe->ssfe_flags & SCTP_DATA_UNSENT) {
  1047. printf("Unsent ");
  1048. }
  1049. if (ssfe->ssfe_flags & SCTP_DATA_SENT) {
  1050. printf("Sent ");
  1051. }
  1052. if (ssfe->ssfe_flags & ~(SCTP_DATA_SENT | SCTP_DATA_UNSENT)) {
  1053. printf("(flags = %x) ", ssfe->ssfe_flags);
  1054. }
  1055. printf("message with PPID = %u, SID = %u, flags: 0x%04x due to error = 0x%08x",
  1056. (uint32_t)ntohl(ssfe->ssfe_info.snd_ppid), ssfe->ssfe_info.snd_sid,
  1057. ssfe->ssfe_info.snd_flags, ssfe->ssfe_error);
  1058. n = ssfe->ssfe_length - sizeof(struct sctp_send_failed_event);
  1059. for (i = 0; i < n; i++) {
  1060. printf(" 0x%02x", ssfe->ssfe_data[i]);
  1061. }
  1062. printf(".\n");
  1063. return;
  1064. }
  1065. static void
  1066. handle_notification_rtcweb(struct peer_connection *pc, union sctp_notification *notif, size_t n)
  1067. {
  1068. if (notif->sn_header.sn_length != (uint32_t)n) {
  1069. return;
  1070. }
  1071. switch (notif->sn_header.sn_type) {
  1072. case SCTP_ASSOC_CHANGE:
  1073. handle_association_change_event(&(notif->sn_assoc_change));
  1074. break;
  1075. case SCTP_PEER_ADDR_CHANGE:
  1076. handle_peer_address_change_event(&(notif->sn_paddr_change));
  1077. break;
  1078. case SCTP_REMOTE_ERROR:
  1079. handle_remote_error_event(&(notif->sn_remote_error));
  1080. break;
  1081. case SCTP_SHUTDOWN_EVENT:
  1082. handle_shutdown_event(&(notif->sn_shutdown_event));
  1083. break;
  1084. case SCTP_ADAPTATION_INDICATION:
  1085. handle_adaptation_indication(&(notif->sn_adaptation_event));
  1086. break;
  1087. case SCTP_PARTIAL_DELIVERY_EVENT:
  1088. break;
  1089. case SCTP_AUTHENTICATION_EVENT:
  1090. break;
  1091. case SCTP_SENDER_DRY_EVENT:
  1092. break;
  1093. case SCTP_NOTIFICATIONS_STOPPED_EVENT:
  1094. break;
  1095. case SCTP_SEND_FAILED_EVENT:
  1096. handle_send_failed_event(&(notif->sn_send_failed_event));
  1097. break;
  1098. case SCTP_STREAM_RESET_EVENT:
  1099. handle_stream_reset_event(pc, &(notif->sn_strreset_event));
  1100. send_deferred_messages(pc);
  1101. send_outgoing_stream_reset(pc);
  1102. request_more_o_streams(pc);
  1103. break;
  1104. case SCTP_ASSOC_RESET_EVENT:
  1105. break;
  1106. case SCTP_STREAM_CHANGE_EVENT:
  1107. handle_stream_change_event(pc, &(notif->sn_strchange_event));
  1108. send_deferred_messages(pc);
  1109. send_outgoing_stream_reset(pc);
  1110. request_more_o_streams(pc);
  1111. break;
  1112. default:
  1113. break;
  1114. }
  1115. }
  1116. static void
  1117. print_status(struct peer_connection *pc)
  1118. {
  1119. struct sctp_status status;
  1120. socklen_t len;
  1121. uint32_t i;
  1122. struct channel *channel;
  1123. len = (socklen_t)sizeof(struct sctp_status);
  1124. if (usrsctp_getsockopt(pc->sock, IPPROTO_SCTP, SCTP_STATUS, &status, &len) < 0) {
  1125. perror("getsockopt");
  1126. return;
  1127. }
  1128. printf("Association state: ");
  1129. switch (status.sstat_state) {
  1130. case SCTP_CLOSED:
  1131. printf("CLOSED\n");
  1132. break;
  1133. case SCTP_BOUND:
  1134. printf("BOUND\n");
  1135. break;
  1136. case SCTP_LISTEN:
  1137. printf("LISTEN\n");
  1138. break;
  1139. case SCTP_COOKIE_WAIT:
  1140. printf("COOKIE_WAIT\n");
  1141. break;
  1142. case SCTP_COOKIE_ECHOED:
  1143. printf("COOKIE_ECHOED\n");
  1144. break;
  1145. case SCTP_ESTABLISHED:
  1146. printf("ESTABLISHED\n");
  1147. break;
  1148. case SCTP_SHUTDOWN_PENDING:
  1149. printf("SHUTDOWN_PENDING\n");
  1150. break;
  1151. case SCTP_SHUTDOWN_SENT:
  1152. printf("SHUTDOWN_SENT\n");
  1153. break;
  1154. case SCTP_SHUTDOWN_RECEIVED:
  1155. printf("SHUTDOWN_RECEIVED\n");
  1156. break;
  1157. case SCTP_SHUTDOWN_ACK_SENT:
  1158. printf("SHUTDOWN_ACK_SENT\n");
  1159. break;
  1160. default:
  1161. printf("UNKNOWN\n");
  1162. break;
  1163. }
  1164. printf("Number of streams (i/o) = (%u/%u)\n",
  1165. status.sstat_instrms, status.sstat_outstrms);
  1166. for (i = 0; i < NUMBER_OF_CHANNELS; i++) {
  1167. channel = &(pc->channels[i]);
  1168. if (channel->state == DATA_CHANNEL_CLOSED) {
  1169. continue;
  1170. }
  1171. printf("Channel with id = %u: state ", channel->id);
  1172. switch (channel->state) {
  1173. case DATA_CHANNEL_CLOSED:
  1174. printf("CLOSED");
  1175. break;
  1176. case DATA_CHANNEL_CONNECTING:
  1177. printf("CONNECTING");
  1178. break;
  1179. case DATA_CHANNEL_OPEN:
  1180. printf("OPEN");
  1181. break;
  1182. case DATA_CHANNEL_CLOSING:
  1183. printf("CLOSING");
  1184. break;
  1185. default:
  1186. printf("UNKNOWN(%d)", channel->state);
  1187. break;
  1188. }
  1189. printf(", flags = 0x%08x, stream id (in/out): (%u/%u), ",
  1190. channel->flags,
  1191. channel->i_stream,
  1192. channel->o_stream);
  1193. if (channel->unordered) {
  1194. printf("unordered, ");
  1195. } else {
  1196. printf("ordered, ");
  1197. }
  1198. switch (channel->pr_policy) {
  1199. case SCTP_PR_SCTP_NONE:
  1200. printf("reliable.\n");
  1201. break;
  1202. case SCTP_PR_SCTP_TTL:
  1203. printf("unreliable (timeout %ums).\n", channel->pr_value);
  1204. break;
  1205. case SCTP_PR_SCTP_RTX:
  1206. printf("unreliable (max. %u rtx).\n", channel->pr_value);
  1207. break;
  1208. default:
  1209. printf("unknown policy %u.\n", channel->pr_policy);
  1210. break;
  1211. }
  1212. }
  1213. }
  1214. static int
  1215. receive_cb(struct socket *sock, union sctp_sockstore addr, void *data,
  1216. size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
  1217. {
  1218. struct peer_connection *pc;
  1219. pc = (struct peer_connection *)ulp_info;
  1220. if (data) {
  1221. lock_peer_connection(pc);
  1222. if (flags & MSG_NOTIFICATION) {
  1223. handle_notification_rtcweb(pc, (union sctp_notification *)data, datalen);
  1224. } else {
  1225. handle_message(pc, data, datalen, ntohl(rcv.rcv_ppid), rcv.rcv_sid);
  1226. }
  1227. unlock_peer_connection(pc);
  1228. }
  1229. return (1);
  1230. }
  1231. int
  1232. main(int argc, char *argv[])
  1233. {
  1234. struct socket *sock;
  1235. struct sockaddr_in addr;
  1236. socklen_t addr_len;
  1237. char line[LINE_LENGTH + 1];
  1238. unsigned int unordered, policy, value, id, seconds;
  1239. unsigned int i;
  1240. struct channel *channel;
  1241. const int on = 1;
  1242. struct sctp_assoc_value av;
  1243. struct sctp_event event;
  1244. struct sctp_udpencaps encaps;
  1245. struct sctp_initmsg initmsg;
  1246. uint16_t event_types[] = {SCTP_ASSOC_CHANGE,
  1247. SCTP_PEER_ADDR_CHANGE,
  1248. SCTP_REMOTE_ERROR,
  1249. SCTP_SHUTDOWN_EVENT,
  1250. SCTP_ADAPTATION_INDICATION,
  1251. SCTP_SEND_FAILED_EVENT,
  1252. SCTP_STREAM_RESET_EVENT,
  1253. SCTP_STREAM_CHANGE_EVENT};
  1254. char addrbuf[INET_ADDRSTRLEN];
  1255. if (argc > 1) {
  1256. usrsctp_init(atoi(argv[1]), NULL, debug_printf_stack);
  1257. } else {
  1258. usrsctp_init(9899, NULL, debug_printf_stack);
  1259. }
  1260. #ifdef SCTP_DEBUG
  1261. usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
  1262. #endif
  1263. usrsctp_sysctl_set_sctp_blackhole(2);
  1264. usrsctp_sysctl_set_sctp_no_csum_on_loopback(0);
  1265. if ((sock = usrsctp_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, &peer_connection)) == NULL) {
  1266. perror("socket");
  1267. }
  1268. init_peer_connection(&peer_connection);
  1269. if (argc > 2) {
  1270. memset(&encaps, 0, sizeof(struct sctp_udpencaps));
  1271. encaps.sue_address.ss_family = AF_INET6;
  1272. encaps.sue_port = htons(atoi(argv[2]));
  1273. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
  1274. perror("setsockopt");
  1275. }
  1276. }
  1277. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int)) < 0) {
  1278. perror("setsockopt SCTP_RECVRCVINFO");
  1279. }
  1280. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EXPLICIT_EOR, &on, sizeof(int)) < 0) {
  1281. perror("setsockopt SCTP_EXPLICIT_EOR");
  1282. }
  1283. /* Allow resetting streams. */
  1284. av.assoc_id = SCTP_ALL_ASSOC;
  1285. av.assoc_value = SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ;
  1286. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &av, sizeof(struct sctp_assoc_value)) < 0) {
  1287. perror("setsockopt SCTP_ENABLE_STREAM_RESET");
  1288. }
  1289. /* Enable the events of interest. */
  1290. memset(&event, 0, sizeof(event));
  1291. event.se_assoc_id = SCTP_ALL_ASSOC;
  1292. event.se_on = 1;
  1293. for (i = 0; i < sizeof(event_types)/sizeof(uint16_t); i++) {
  1294. event.se_type = event_types[i];
  1295. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) < 0) {
  1296. perror("setsockopt SCTP_EVENT");
  1297. }
  1298. }
  1299. memset(&initmsg, 0, sizeof(struct sctp_initmsg));
  1300. initmsg.sinit_num_ostreams = 5;
  1301. initmsg.sinit_max_instreams = 65535;
  1302. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg)) < 0) {
  1303. perror("setsockopt SCTP_INITMSG");
  1304. }
  1305. if (argc == 5) {
  1306. /* operating as client */
  1307. memset(&addr, 0, sizeof(struct sockaddr_in));
  1308. addr.sin_family = AF_INET;
  1309. #ifdef HAVE_SIN_LEN
  1310. addr.sin_len = sizeof(struct sockaddr_in);
  1311. #endif
  1312. if (!inet_pton(AF_INET, argv[3], &addr.sin_addr.s_addr)){
  1313. printf("error: invalid address\n");
  1314. exit(1);
  1315. }
  1316. addr.sin_port = htons(atoi(argv[4]));
  1317. if (usrsctp_connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
  1318. perror("connect");
  1319. }
  1320. printf("Connected to %s:%d.\n", inet_ntop(AF_INET, &(addr.sin_addr), addrbuf, INET_ADDRSTRLEN), ntohs(addr.sin_port));
  1321. } else if (argc == 4) {
  1322. struct socket *conn_sock;
  1323. /* operating as server */
  1324. memset(&addr, 0, sizeof(struct sockaddr_in));
  1325. addr.sin_family = AF_INET;
  1326. #ifdef HAVE_SIN_LEN
  1327. addr.sin_len = sizeof(struct sockaddr_in);
  1328. #endif
  1329. addr.sin_addr.s_addr = INADDR_ANY;
  1330. addr.sin_port = htons(atoi(argv[3]));
  1331. if (usrsctp_bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
  1332. perror("bind");
  1333. }
  1334. if (usrsctp_listen(sock, 1) < 0) {
  1335. perror("listen");
  1336. }
  1337. addr_len = (socklen_t)sizeof(struct sockaddr_in);
  1338. memset(&addr, 0, sizeof(struct sockaddr_in));
  1339. if ((conn_sock = usrsctp_accept(sock, (struct sockaddr *)&addr, &addr_len)) == NULL) {
  1340. perror("accept");
  1341. }
  1342. usrsctp_close(sock);
  1343. sock = conn_sock;
  1344. printf("Connected to %s:%d.\n", inet_ntop(AF_INET, &(addr.sin_addr), addrbuf, INET_ADDRSTRLEN), ntohs(addr.sin_port));
  1345. } else {
  1346. printf("Usage: %s local_udp_port remote_udp_port local_port when operating as server\n"
  1347. " %s local_udp_port remote_udp_port remote_addr remote_port when operating as client\n",
  1348. argv[0], argv[0]);
  1349. return (0);
  1350. }
  1351. lock_peer_connection(&peer_connection);
  1352. peer_connection.sock = sock;
  1353. unlock_peer_connection(&peer_connection);
  1354. for (;;) {
  1355. #if defined(_WIN32) && !defined(__MINGW32__)
  1356. if (gets_s(line, LINE_LENGTH) == NULL) {
  1357. #else
  1358. if (fgets(line, LINE_LENGTH, stdin) == NULL) {
  1359. #endif
  1360. if (usrsctp_shutdown(sock, SHUT_WR) < 0) {
  1361. perror("usrsctp_shutdown");
  1362. }
  1363. while (usrsctp_finish() != 0) {
  1364. #ifdef _WIN32
  1365. Sleep(1000);
  1366. #else
  1367. sleep(1);
  1368. #endif
  1369. }
  1370. break;
  1371. }
  1372. if (strncmp(line, "?", strlen("?")) == 0 ||
  1373. strncmp(line, "help", strlen("help")) == 0) {
  1374. printf("Commands:\n"
  1375. "open unordered pr_policy pr_value - opens a channel\n"
  1376. "close channel - closes the channel\n"
  1377. "send channel:string - sends string using channel\n"
  1378. "status - prints the status\n"
  1379. "sleep n - sleep for n seconds\n"
  1380. "help - this message\n");
  1381. } else if (strncmp(line, "status", strlen("status")) == 0) {
  1382. lock_peer_connection(&peer_connection);
  1383. print_status(&peer_connection);
  1384. unlock_peer_connection(&peer_connection);
  1385. } else if (strncmp(line, "quit", strlen("quit")) == 0) {
  1386. if (usrsctp_shutdown(sock, SHUT_WR) < 0) {
  1387. perror("usrsctp_shutdown");
  1388. }
  1389. while (usrsctp_finish() != 0) {
  1390. #ifdef _WIN32
  1391. Sleep(1000);
  1392. #else
  1393. sleep(1);
  1394. #endif
  1395. }
  1396. break;
  1397. } else if (sscanf(line, "open %u %u %u", &unordered, &policy, &value) == 3) {
  1398. lock_peer_connection(&peer_connection);
  1399. channel = open_channel(&peer_connection, (uint8_t)unordered, (uint16_t)policy, (uint32_t)value);
  1400. unlock_peer_connection(&peer_connection);
  1401. if (channel == NULL) {
  1402. printf("Creating channel failed.\n");
  1403. } else {
  1404. printf("Channel with id %u created.\n", channel->id);
  1405. }
  1406. } else if (sscanf(line, "close %u", &id) == 1) {
  1407. if (id < NUMBER_OF_CHANNELS) {
  1408. lock_peer_connection(&peer_connection);
  1409. close_channel(&peer_connection, &peer_connection.channels[id]);
  1410. unlock_peer_connection(&peer_connection);
  1411. }
  1412. } else if (sscanf(line, "send %u", &id) == 1) {
  1413. if (id < NUMBER_OF_CHANNELS) {
  1414. char *msg;
  1415. msg = strstr(line, ":");
  1416. if (msg) {
  1417. msg++;
  1418. lock_peer_connection(&peer_connection);
  1419. #ifdef _WIN32
  1420. if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg))) {
  1421. #else
  1422. if (send_user_message(&peer_connection, &peer_connection.channels[id], msg, strlen(msg) - 1)) {
  1423. #endif
  1424. printf("Message sent.\n");
  1425. } else {
  1426. printf("Message sending failed.\n");
  1427. }
  1428. unlock_peer_connection(&peer_connection);
  1429. }
  1430. }
  1431. } else if (sscanf(line, "sleep %u", &seconds) == 1) {
  1432. #ifdef _WIN32
  1433. Sleep(seconds * 1000);
  1434. #else
  1435. sleep(seconds);
  1436. #endif
  1437. } else {
  1438. printf("Unknown command: %s", line);
  1439. }
  1440. }
  1441. return (0);
  1442. }