• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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