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