Exemple #1
0
static void *
handle_packets(void *arg)
{
#ifdef _WIN32
	SOCKET *fdp;
#else
	int *fdp;
#endif
	char *dump_buf;
	ssize_t length;
	char buf[MAX_PACKET_SIZE];

#ifdef _WIN32
	fdp = (SOCKET *)arg;
#else
	fdp = (int *)arg;
#endif
	for (;;) {
		length = recv(*fdp, buf, MAX_PACKET_SIZE, 0);
		if (length > 0) {
			if ((dump_buf = usrsctp_dumppacket(buf, (size_t)length, SCTP_DUMP_INBOUND)) != NULL) {
				fprintf(stderr, "%s", dump_buf);
				usrsctp_freedumpbuffer(dump_buf);
			}
			usrsctp_conninput(fdp, buf, (size_t)length, 0);
		}
	}
	return (NULL);
}
Exemple #2
0
static int
conn_output(void *addr, void *buf, size_t length, uint8_t tos, uint8_t set_df)
{
	char *dump_buf;
#ifdef _WIN32
	SOCKET *fdp;
#else
	int *fdp;
#endif

#ifdef _WIN32
	fdp = (SOCKET *)addr;
#else
	fdp = (int *)addr;
#endif
	if ((dump_buf = usrsctp_dumppacket(buf, length, SCTP_DUMP_OUTBOUND)) != NULL) {
		//fprintf(stderr, "%s", dump_buf);
		usrsctp_freedumpbuffer(dump_buf);
	}
#ifdef _WIN32
	if (send(*fdp, buf, (int)length, 0) == SOCKET_ERROR) {
		return (WSAGetLastError());
#else
	if (send(*fdp, buf, length, 0) < 0) {
		return (errno);
#endif
	} else {
		return (0);
	}
}

static int
receive_cb(struct socket *sock, union sctp_sockstore addr, void *data,
           size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{
	printf("Message %p received on sock = %p.\n", data, (void *)sock);
	if (data) {
		if ((flags & MSG_NOTIFICATION) == 0) {
			printf("Messsage of length %d received via %p:%u on stream %u with SSN %u and TSN %u, PPID %u, context %u, flags %x.\n",
			       (int)datalen,
			       addr.sconn.sconn_addr,
			       ntohs(addr.sconn.sconn_port),
			       rcv.rcv_sid,
			       rcv.rcv_ssn,
			       rcv.rcv_tsn,
			       ntohl(rcv.rcv_ppid),
			       rcv.rcv_context,
			       flags);
		}
		free(data);
	} else {
		usrsctp_deregister_address(ulp_info);
		usrsctp_close(sock);
	}
	return (1);
}
static DWORD WINAPI
#else
static void *
#endif
handle_packets(void *arg)
{
#ifdef _WIN32
	SOCKET *fdp;
#else
	int *fdp;
#endif
	char *dump_buf;
	ssize_t length;
	char buf[MAX_PACKET_SIZE];

#ifdef _WIN32
	fdp = (SOCKET *)arg;
#else
	fdp = (int *)arg;
#endif
	for (;;) {
#if defined(__NetBSD__)
		pthread_testcancel();
#endif
		length = recv(*fdp, buf, MAX_PACKET_SIZE, 0);
		if (length > 0) {
			if ((dump_buf = usrsctp_dumppacket(buf, (size_t)length, SCTP_DUMP_INBOUND)) != NULL) {
				fprintf(stderr, "%s", dump_buf);
				usrsctp_freedumpbuffer(dump_buf);
			}
			usrsctp_conninput(fdp, buf, (size_t)length, 0);
		}
	}
#ifdef _WIN32
	return 0;
#else
	return (NULL);
#endif
}
Exemple #4
0
static int
conn_output(void *addr, void *buf, size_t length, uint8_t tos, uint8_t set_df)
{
	char *dump_buf;
#ifdef _WIN32
	SOCKET *fdp;
#else
	int *fdp;
#endif

#ifdef _WIN32
	fdp = (SOCKET *)addr;
#else
	fdp = (int *)addr;
#endif
	if ((dump_buf = usrsctp_dumppacket(buf, length, SCTP_DUMP_OUTBOUND)) != NULL) {
		fprintf(stderr, "%s", dump_buf);
		usrsctp_freedumpbuffer(dump_buf);
	}
#ifdef _WIN32
	if (send(*fdp, buf, (int)length, 0) == SOCKET_ERROR) {
		return (WSAGetLastError());
#else
	if (send(*fdp, buf, length, 0) < 0) {
		return (errno);
#endif
	} else {
		return (0);
	}
}

static int
receive_cb(struct socket *s, union sctp_sockstore addr, void *data,
           size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
{

	if (data) {
		if (flags & MSG_NOTIFICATION) {
			printf("Notification of length %d received.\n", (int)datalen);
		} else {
			printf("Msg of length %d received via %p:%u on stream %u with SSN %u and TSN %u, PPID %u, context %u.\n",
			       (int)datalen,
			       addr.sconn.sconn_addr,
			       ntohs(addr.sconn.sconn_port),
			       rcv.rcv_sid,
			       rcv.rcv_ssn,
			       rcv.rcv_tsn,
			       ntohl(rcv.rcv_ppid),
			       rcv.rcv_context);
		}
		free(data);
	} else {
		usrsctp_close(s);
	}
	return (1);
}

void
debug_printf(const char *format, ...)
{
	va_list ap;

	va_start(ap, format);
	vprintf(format, ap);
	va_end(ap);
}
Exemple #5
0
void *janus_sctp_thread(void *data) {
	janus_sctp_association *sctp = (janus_sctp_association *)data;
	if(sctp == NULL) {
		JANUS_LOG(LOG_ERR, "Invalid SCTP association, closing thread\n");
		g_thread_unref(g_thread_self());
		return NULL;
	}
	JANUS_LOG(LOG_INFO, "[%"SCNu64"] Starting thread for SCTP association\n", sctp->handle_id);
	janus_sctp_message *message = NULL;
	gboolean sent_data = FALSE;
	while(sctp->dtls != NULL && sctp_running) {
		/* Anything to do at all? */
		janus_mutex_lock(&sctp->mutex);
		if(!sctp->ready || (g_queue_is_empty(sctp->in_messages) && g_queue_is_empty(sctp->out_messages))) {
			janus_mutex_unlock(&sctp->mutex);
			g_usleep (10000);
			continue;
		}
		/* Check incoming messages */
		if(!g_queue_is_empty(sctp->in_messages) && sent_data) {
			while(!g_queue_is_empty(sctp->in_messages)) {
				message = g_queue_pop_head(sctp->in_messages);
				if(message == NULL)
					continue;
#ifdef DEBUG_SCTP
				if(sctp->debug_dump != NULL) {
					/* Dump incoming message */
					char *dump = usrsctp_dumppacket(message->buffer, message->length, SCTP_DUMP_INBOUND);
					if(dump != NULL) {
						fwrite(dump, sizeof(char), strlen(dump), sctp->debug_dump);
						fflush(sctp->debug_dump);
						usrsctp_freedumpbuffer(dump);
					}
				}
#endif
				/* Pass this data to the SCTP association */
				janus_mutex_unlock(&sctp->mutex);
				usrsctp_conninput((void *)sctp, message->buffer, message->length, 0);
				janus_mutex_lock(&sctp->mutex);
				janus_sctp_message_destroy(message);
				message = NULL;
			}
		}
		/* Check outgoing messages */
		if(sctp->dtls == NULL) {
			/* No DTLS stack anymore, we're done */
			janus_mutex_unlock(&sctp->mutex);
			break;
		}
		if(!g_queue_is_empty(sctp->out_messages)) {
			while(!g_queue_is_empty(sctp->out_messages)) {
				message = g_queue_pop_head(sctp->out_messages);
				if(message == NULL)
					continue;
#ifdef DEBUG_SCTP
				if(sctp->debug_dump != NULL) {
					/* Dump incoming message */
					char *dump = usrsctp_dumppacket(message->buffer, message->length, SCTP_DUMP_OUTBOUND);
					if(dump != NULL) {
						fwrite(dump, sizeof(char), strlen(dump), sctp->debug_dump);
						fflush(sctp->debug_dump);
						usrsctp_freedumpbuffer(dump);
					}
				}
#endif
				/* Encapsulate this data in DTLS and send it */
				janus_dtls_send_sctp_data((janus_dtls_srtp *)sctp->dtls, message->buffer, message->length);
				janus_sctp_message_destroy(message);
				message = NULL;
				if(!sent_data)
					sent_data = TRUE;
			}
		}
		janus_mutex_unlock(&sctp->mutex);
	}
	JANUS_LOG(LOG_INFO, "[%"SCNu64"] Leaving SCTP association thread\n", sctp->handle_id);
	/* This association has been destroyed, wait a bit and then free all the resources */
	g_usleep (1*G_USEC_PER_SEC);
	g_queue_free(sctp->in_messages);
	sctp->in_messages = NULL;
	g_queue_free(sctp->out_messages);
	sctp->out_messages = NULL;
	sctp->thread = NULL;
#ifdef DEBUG_SCTP
	if(sctp->debug_dump != NULL)
		fclose(sctp->debug_dump);
	sctp->debug_dump = NULL;
#endif
	g_free(sctp);
	sctp = NULL;
	g_thread_unref(g_thread_self());
	return NULL;
}