Single thread (#339)
* single thread
Based on https://github.com/sctplab/usrsctp/pull/38/commits/010fcbc6f193152607dc267c7e7e573c9bffc111
from @ccaughie
* single thread: st_client.c. remove unused variables
* Revert "single thread: st_client.c. remove unused variables"
This reverts commit 1e240a954dcadf6296b9a0f2d1299e07a9e65ca8.
* single thread: st_client.c. remove unused variable
* single thread: s/usrsctp_fire_timer/usrsctp_handle_timers
* single thread: remove duplicated functions
* single thread: remove duplicate check for SCTP_SO_IS_NBIO(so)
* single thread: s/handle_packets/handle_events
* .gitignore: ignore programs/st_client binary
* user_socket.c: remove unnecessary SB_UPCALL check
* programs/client.c: make main() return(-1) after perror()
* programs/st_client.c: trying to make it work (it does not yet)
* programs/st_client.c: replace CLOCKS_PER_SEC with gettimeofday based code
* programs/client.c: revert cosmetic changes
* programs/st_client.c: clean debug prints
* programs/meson.build: add st_client
* Fix warnings in Windows
* programs/st_client.c: use snd 0 instead of 1.
* programs/st_client.c: add usrsctp_setsockopt(s, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int))
diff --git a/.gitignore b/.gitignore
index f1edda0..2fc78e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,6 +73,7 @@
programs/http_client
programs/http_client_upcall
programs/rtcweb
+programs/st_client
programs/tsctp
programs/test_libmgmt
programs/test_timer
diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt
index b99d181..45c772b 100644
--- a/programs/CMakeLists.txt
+++ b/programs/CMakeLists.txt
@@ -100,6 +100,7 @@
http_client.c
http_client_upcall.c
rtcweb.c
+ st_client.c
test_libmgmt.c
test_timer.c
tsctp.c
diff --git a/programs/Makefile.am b/programs/Makefile.am
index acb2168..794c32e 100644
--- a/programs/Makefile.am
+++ b/programs/Makefile.am
@@ -52,7 +52,8 @@
ekr_peer.c \
test_libmgmt.c \
http_client.c \
- http_client_upcall.c
+ http_client_upcall.c \
+ st_client.c
noinst_PROGRAMS = \
test_libmgmt \
@@ -76,7 +77,8 @@
ekr_peer \
test_libmgmt \
http_client \
- http_client_upcall
+ http_client_upcall \
+ st_client
test_libmgmt_SOURCES = programs_helper.c test_libmgmt.c
test_libmgmt_LDADD = ../usrsctplib/libusrsctp.la
@@ -120,3 +122,5 @@
http_client_LDADD = ../usrsctplib/libusrsctp.la
http_client_upcall_SOURCES = programs_helper.c http_client_upcall.c
http_client_upcall_LDADD = ../usrsctplib/libusrsctp.la
+st_client_SOURCES = programs_helper.c st_client.c
+st_client_LDADD = ../usrsctplib/libusrsctp.la
diff --git a/programs/Makefile.nmake b/programs/Makefile.nmake
index d426b24..24e9695 100644
--- a/programs/Makefile.nmake
+++ b/programs/Makefile.nmake
@@ -57,7 +57,8 @@
ekr_loop_upcall \
test_libmgmt \
http_client \
- http_client_upcall
+ http_client_upcall \
+ st_client
programs_helper.obj : programs_helper.c programs_helper.h
cl $(CVARSDLL) $(CFLAGS) -c programs_helper.c
@@ -138,6 +139,10 @@
$(CC) $(CFLAGS) $(CVARSDLL) -c http_client_upcall.c
link -out:http_client_upcall.exe http_client_upcall.obj programs_helper.obj $(LINKFLAGS)
+st_client:
+ $(CC) $(CFLAGS) $(CVARSDLL) -c st_client.c
+ link -out:st_client.exe st_client.obj programs_helper.obj $(LINKFLAGS)
+
clean:
del /F client.exe
del /F client.obj
@@ -177,3 +182,5 @@
del /F http_client.obj
del /F http_client_upcall.exe
del /F http_client_upcall.obj
+ del /F st_client.exe
+ del /F st_client.obj
diff --git a/programs/meson.build b/programs/meson.build
index daed941..9cbb0fb 100644
--- a/programs/meson.build
+++ b/programs/meson.build
@@ -5,6 +5,7 @@
programs = {
'chargen_server_upcall': files('chargen_server_upcall.c'),
'client': files('client.c'),
+ 'st_client': files('st_client.c'),
'client_upcall': files('client_upcall.c'),
'daytime_server': files('daytime_server.c'),
'daytime_server_upcall': files('daytime_server_upcall.c'),
diff --git a/programs/st_client.c b/programs/st_client.c
new file mode 100644
index 0000000..777e6d2
--- /dev/null
+++ b/programs/st_client.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2011-2013 Michael Tuexen
+ * Copyright (C) 2011-2015 Colin Caughie
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Usage: st_client local_addr local_port remote_addr remote_port remote_sctp_port
+ */
+
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#else
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#include <usrsctp.h>
+#include "programs_helper.h"
+
+#define MAX_PACKET_SIZE (1<<16)
+#define BUFFER_SIZE 80
+#define DISCARD_PPID 39
+
+#define TIMER_INTERVAL_MSECS 10
+
+static int connecting = 0;
+static int finish = 0;
+
+static unsigned get_tick_count(void)
+{
+#ifdef _WIN32
+ return GetTickCount();
+#else
+ struct timeval te;
+ gettimeofday(&te, NULL); // get current time
+ unsigned milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
+ return milliseconds;
+#endif
+}
+
+static void
+handle_events(int sock, struct socket* s, void* sconn_addr)
+{
+ char *dump_buf;
+ ssize_t length;
+ char buf[MAX_PACKET_SIZE];
+
+ fd_set rfds;
+ struct timeval tv;
+
+ unsigned next_fire_time = get_tick_count();
+ unsigned last_fire_time = next_fire_time;
+
+ while (!finish) {
+
+ unsigned now = get_tick_count();
+ int wait_time;
+
+ if ((int) (now - next_fire_time) > 0) {
+ usrsctp_handle_timers(now - last_fire_time);
+ last_fire_time = now;
+ next_fire_time = now + TIMER_INTERVAL_MSECS;
+ }
+
+ wait_time = next_fire_time - now;
+ tv.tv_sec = wait_time / 1000;
+ tv.tv_usec = (wait_time % 1000) * 1000;
+
+ FD_ZERO(&rfds);
+ FD_SET(sock, &rfds);
+
+ select(sock + 1, &rfds, NULL, NULL, &tv);
+
+ if (FD_ISSET(sock, &rfds)) {
+ length = recv(sock, 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(sconn_addr, buf, (size_t)length, 0);
+ }
+ }
+ }
+}
+
+static void on_connect(struct socket* s)
+{
+ struct sctp_sndinfo sndinfo;
+ char buffer[BUFFER_SIZE];
+
+ memset(buffer, 'A', BUFFER_SIZE);
+ sndinfo.snd_sid = 0;
+ sndinfo.snd_flags = 0;
+ sndinfo.snd_ppid = htonl(DISCARD_PPID);
+ sndinfo.snd_context = 0;
+ sndinfo.snd_assoc_id = 0;
+ if (usrsctp_sendv(s, buffer, BUFFER_SIZE, NULL, 0, (void *)&sndinfo,
+ (socklen_t)sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0) < 0) {
+ perror("usrsctp_sendv");
+ }
+}
+
+static void on_socket_readable(struct socket* s) {
+ char buffer[BUFFER_SIZE];
+ union sctp_sockstore addr;
+ socklen_t fromlen = sizeof(addr);
+ struct sctp_rcvinfo rcv_info;
+ socklen_t infolen = sizeof(rcv_info);
+ unsigned int infotype = 0;
+ int flags = 0;
+ ssize_t retval;
+
+ /* Keep reading until there is no more data */
+ for (;;) {
+ retval = usrsctp_recvv(s, buffer, sizeof(buffer), (struct sockaddr*) &addr,
+ &fromlen, &rcv_info, &infolen, &infotype, &flags);
+
+ if (retval < 0) {
+ if (errno != EWOULDBLOCK) {
+ perror("usrsctp_recvv");
+ finish = 1;
+ }
+ return;
+ } else if (retval == 0) {
+ printf("socket was disconnected\n");
+ finish = 1;
+ return;
+ }
+
+ if (flags & MSG_NOTIFICATION) {
+ printf("Notification of length %d received.\n", (int)retval);
+ } else {
+ printf("Msg of length %d received via %p:%u on stream %d with SSN %u and TSN %u, PPID %d, context %u.\n",
+ (int)retval,
+ addr.sconn.sconn_addr,
+ ntohs(addr.sconn.sconn_port),
+ rcv_info.rcv_sid,
+ rcv_info.rcv_ssn,
+ rcv_info.rcv_tsn,
+ ntohl(rcv_info.rcv_ppid),
+ rcv_info.rcv_context);
+ }
+ }
+}
+
+static void handle_upcall(struct socket *s, void *arg, int flags)
+{
+ int events = usrsctp_get_events(s);
+
+ if (connecting) {
+ if (events & SCTP_EVENT_ERROR) {
+ connecting = 0;
+ finish = 1;
+ } else if (events & SCTP_EVENT_WRITE) {
+ connecting = 0;
+ on_connect(s);
+ }
+
+ return;
+ }
+
+ if (events & SCTP_EVENT_READ) {
+ on_socket_readable(s);
+ }
+}
+
+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);
+ }
+}
+
+/* Usage: st_client local_addr local_port remote_addr remote_port remote_sctp_port */
+int
+main(int argc, char *argv[])
+{
+ struct sockaddr_in sin;
+ struct sockaddr_conn sconn;
+#ifdef _WIN32
+ SOCKET fd;
+#else
+ int fd;
+#endif
+ struct socket *s;
+ int retval;
+#ifdef _WIN32
+ WSADATA wsaData;
+#endif
+
+ if (argc < 6) {
+ printf("Usage: st_client local_addr local_port remote_addr remote_port remote_sctp_port\n");
+ return (-1);
+ }
+
+#ifdef _WIN32
+ if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
+ printf("WSAStartup failed\n");
+ return (-1);
+ }
+#endif
+ usrsctp_init_nothreads(0, conn_output, debug_printf);
+ /* set up a connected UDP socket */
+#ifdef _WIN32
+ if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
+ printf("socket() failed with error: %ld\n", WSAGetLastError());
+ return (-1);
+ }
+#else
+ if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("socket");
+ return (-1);
+ }
+#endif
+ memset(&sin, 0, sizeof(struct sockaddr_in));
+ sin.sin_family = AF_INET;
+#ifdef HAVE_SIN_LEN
+ sin.sin_len = sizeof(struct sockaddr_in);
+#endif
+ sin.sin_port = htons(atoi(argv[2]));
+ if (!inet_pton(AF_INET, argv[1], &sin.sin_addr.s_addr)){
+ printf("error: invalid address\n");
+ return (-1);
+ }
+#ifdef _WIN32
+ if (bind(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
+ printf("bind() failed with error: %ld\n", WSAGetLastError());
+ return (-1);
+ }
+#else
+ if (bind(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0) {
+ perror("bind");
+ return (-1);
+ }
+#endif
+ memset(&sin, 0, sizeof(struct sockaddr_in));
+ sin.sin_family = AF_INET;
+#ifdef HAVE_SIN_LEN
+ sin.sin_len = sizeof(struct sockaddr_in);
+#endif
+ sin.sin_port = htons(atoi(argv[4]));
+ if (!inet_pton(AF_INET, argv[3], &sin.sin_addr.s_addr)){
+ printf("error: invalid address\n");
+ return (-1);
+ }
+#ifdef _WIN32
+ if (connect(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
+ printf("connect() failed with error: %ld\n", WSAGetLastError());
+ return (-1);
+ }
+#else
+ if (connect(fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0) {
+ perror("connect");
+ return (-1);
+ }
+#endif
+#ifdef SCTP_DEBUG
+ usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
+#endif
+ usrsctp_sysctl_set_sctp_ecn_enable(0);
+ usrsctp_register_address((void *)&fd);
+
+ if ((s = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, NULL, NULL, 0, NULL)) == NULL) {
+ perror("usrsctp_socket");
+ return (-1);
+ }
+
+ const int on = 1;
+
+ usrsctp_setsockopt(s, IPPROTO_SCTP, SCTP_RECVRCVINFO, &on, sizeof(int));
+
+ usrsctp_set_non_blocking(s, 1);
+ usrsctp_set_upcall(s, handle_upcall, NULL);
+
+ memset(&sconn, 0, sizeof(struct sockaddr_conn));
+ sconn.sconn_family = AF_CONN;
+#ifdef HAVE_SCONN_LEN
+ sconn.sconn_len = sizeof(struct sockaddr_conn);
+#endif
+ sconn.sconn_port = htons(0);
+ sconn.sconn_addr = NULL;
+ if (usrsctp_bind(s, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn)) < 0) {
+ perror("usrsctp_bind");
+ return (-1);
+ }
+
+ memset(&sconn, 0, sizeof(struct sockaddr_conn));
+ sconn.sconn_family = AF_CONN;
+#ifdef HAVE_SCONN_LEN
+ sconn.sconn_len = sizeof(struct sockaddr_conn);
+#endif
+ sconn.sconn_port = htons(atoi(argv[5]));
+ sconn.sconn_addr = &fd;
+
+ retval = usrsctp_connect(s, (struct sockaddr *)&sconn, sizeof(struct sockaddr_conn));
+
+ if (retval < 0 && errno != EWOULDBLOCK && errno != EINPROGRESS) {
+ perror("usrsctp_connect");
+ return (-1);
+ }
+
+ connecting = 1;
+
+ handle_events(fd, s, sconn.sconn_addr);
+
+ return 0;
+}
diff --git a/usrsctplib/netinet/sctp_callout.c b/usrsctplib/netinet/sctp_callout.c
index b12b4b2..3ba5270 100755
--- a/usrsctplib/netinet/sctp_callout.c
+++ b/usrsctplib/netinet/sctp_callout.c
@@ -217,7 +217,7 @@
return (1);
}
-static void
+void
sctp_handle_tick(int delta)
{
sctp_os_timer_t *c;
diff --git a/usrsctplib/netinet/sctp_callout.h b/usrsctplib/netinet/sctp_callout.h
index 814bd06..3ac6c5b 100755
--- a/usrsctplib/netinet/sctp_callout.h
+++ b/usrsctplib/netinet/sctp_callout.h
@@ -103,6 +103,7 @@
void sctp_os_timer_init(sctp_os_timer_t *tmr);
void sctp_os_timer_start(sctp_os_timer_t *, int, void (*)(void *), void *);
int sctp_os_timer_stop(sctp_os_timer_t *);
+void sctp_handle_tick(int delta);
#define SCTP_OS_TIMER_INIT sctp_os_timer_init
#define SCTP_OS_TIMER_START sctp_os_timer_start
diff --git a/usrsctplib/netinet/sctp_pcb.c b/usrsctplib/netinet/sctp_pcb.c
index f5c4e3a..4ea0845 100755
--- a/usrsctplib/netinet/sctp_pcb.c
+++ b/usrsctplib/netinet/sctp_pcb.c
@@ -6635,7 +6635,7 @@
#endif
void
-sctp_pcb_init()
+sctp_pcb_init(int start_threads)
{
/*
* SCTP initialization for the PCB structures should be called by
@@ -6851,7 +6851,8 @@
mbuf_initialize(NULL);
atomic_init();
#if defined(INET) || defined(INET6)
- recv_thread_init();
+ if (start_threads)
+ recv_thread_init();
#endif
#endif
}
diff --git a/usrsctplib/netinet/sctp_pcb.h b/usrsctplib/netinet/sctp_pcb.h
index dad09e0..16b19c0 100755
--- a/usrsctplib/netinet/sctp_pcb.h
+++ b/usrsctplib/netinet/sctp_pcb.h
@@ -843,7 +843,7 @@
int sctp_del_remote_addr(struct sctp_tcb *, struct sockaddr *);
-void sctp_pcb_init(void);
+void sctp_pcb_init(int);
void sctp_pcb_finish(void);
diff --git a/usrsctplib/netinet/sctp_usrreq.c b/usrsctplib/netinet/sctp_usrreq.c
index 0912e3e..5ff7a2a 100755
--- a/usrsctplib/netinet/sctp_usrreq.c
+++ b/usrsctplib/netinet/sctp_usrreq.c
@@ -77,7 +77,7 @@
#if defined(__Userspace__)
sctp_init(uint16_t port,
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
- void (*debug_printf)(const char *format, ...))
+ void (*debug_printf)(const char *format, ...), int start_threads)
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
sctp_init(struct protosw *pp SCTP_UNUSED, struct domain *dp SCTP_UNUSED)
#else
@@ -151,9 +151,10 @@
SCTP_BASE_VAR(debug_printf) = debug_printf;
SCTP_BASE_VAR(crc32c_offloaded) = 0;
#endif
- sctp_pcb_init();
+ sctp_pcb_init(start_threads);
#if defined(__Userspace__)
- sctp_start_timer();
+ if (start_threads)
+ sctp_start_timer();
#endif
#if defined(SCTP_PACKET_LOGGING)
SCTP_BASE_VAR(packet_log_writers) = 0;
diff --git a/usrsctplib/netinet/sctp_var.h b/usrsctplib/netinet/sctp_var.h
index bc4afe9..ead9e9c 100755
--- a/usrsctplib/netinet/sctp_var.h
+++ b/usrsctplib/netinet/sctp_var.h
@@ -454,7 +454,7 @@
#if defined(__Userspace__)
void sctp_init(uint16_t,
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
- void (*)(const char *, ...));
+ void (*)(const char *, ...), int start_threads);
#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
void sctp_init __P((void));
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
diff --git a/usrsctplib/user_socket.c b/usrsctplib/user_socket.c
index bec0226..bde5428 100755
--- a/usrsctplib/user_socket.c
+++ b/usrsctplib/user_socket.c
@@ -39,6 +39,7 @@
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_input.h>
#include <netinet/sctp_peeloff.h>
+#include <netinet/sctp_callout.h>
#include <netinet/sctp_crc32.h>
#ifdef INET6
#include <netinet6/sctp6_var.h>
@@ -77,11 +78,7 @@
extern int sctp_attach(struct socket *so, int proto, uint32_t vrf_id);
extern int sctpconn_attach(struct socket *so, int proto, uint32_t vrf_id);
-void
-usrsctp_init(uint16_t port,
- int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
- void (*debug_printf)(const char *format, ...))
-{
+static void init_sync(void) {
#if defined(__Userspace_os_Windows)
#if defined(INET) || defined(INET6)
WSADATA wsaData;
@@ -104,7 +101,25 @@
pthread_mutexattr_destroy(&mutex_attr);
pthread_cond_init(&accept_cond, NULL);
#endif
- sctp_init(port, conn_output, debug_printf);
+}
+
+void
+usrsctp_init(uint16_t port,
+ int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
+ void (*debug_printf)(const char *format, ...))
+{
+ init_sync();
+ sctp_init(port, conn_output, debug_printf, 1);
+}
+
+
+void
+usrsctp_init_nothreads(uint16_t port,
+ int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
+ void (*debug_printf)(const char *format, ...))
+{
+ init_sync();
+ sctp_init(port, conn_output, debug_printf, 0);
}
@@ -1564,8 +1579,6 @@
#endif
}
SOCKBUF_UNLOCK(sb);
- /*__Userspace__ what todo about so_upcall?*/
-
}
#else /* kernel version for reference */
/*
@@ -3515,6 +3528,11 @@
return;
}
+void usrsctp_handle_timers(int delta)
+{
+ sctp_handle_tick(delta);
+}
+
int
usrsctp_get_events(struct socket *so)
{
diff --git a/usrsctplib/usrsctp.h b/usrsctplib/usrsctp.h
index 0533c49..d8b4593 100644
--- a/usrsctplib/usrsctp.h
+++ b/usrsctplib/usrsctp.h
@@ -892,6 +892,11 @@
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*)(const char *format, ...));
+void
+usrsctp_init_nothreads(uint16_t,
+ int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
+ void (*)(const char *format, ...));
+
struct socket *
usrsctp_socket(int domain, int type, int protocol,
int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
@@ -1034,6 +1039,9 @@
usrsctp_get_events(struct socket *so);
+void
+usrsctp_handle_timers(int delta);
+
#define SCTP_DUMP_OUTBOUND 1
#define SCTP_DUMP_INBOUND 0