diff options
author | Android Chromium Automerger <chromium-automerger@android> | 2014-10-14 15:22:07 +0000 |
---|---|---|
committer | Android Chromium Automerger <chromium-automerger@android> | 2014-10-14 15:22:07 +0000 |
commit | 8e827a5b64df1e9a502143dce09c490cb9a33abc (patch) | |
tree | d2fca47875f2bd7ebaf25630077b3b202bb6f8ae | |
parent | 7d03eb2a791714b19825146b6cb731ea10c9f4ca (diff) | |
parent | a11b3c55b730332ac33e9a81d053aca3bf813b93 (diff) | |
download | usrsctplib-8e827a5b64df1e9a502143dce09c490cb9a33abc.tar.gz |
Merge third_party/usrsctp/usrsctplib from https://chromium.googlesource.com/external/usrsctplib.git at a11b3c55b730332ac33e9a81d053aca3bf813b93
This commit was generated by merge_from_chromium.py.
Change-Id: I9db456b62724c4dd138eb2e19d4b6f670f1f34bb
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | Makefile.nmake | 4 | ||||
-rwxr-xr-x | netinet/sctp_callout.c | 89 | ||||
-rwxr-xr-x | netinet/sctp_callout.h | 6 | ||||
-rwxr-xr-x | netinet/sctp_input.c | 4 | ||||
-rwxr-xr-x | netinet/sctp_output.c | 63 | ||||
-rwxr-xr-x | netinet/sctp_output.h | 6 | ||||
-rwxr-xr-x | netinet/sctp_usrreq.c | 12 | ||||
-rwxr-xr-x | user_sctp_timer_iterate.c | 122 |
9 files changed, 131 insertions, 176 deletions
diff --git a/Makefile.am b/Makefile.am index d7f4f4a..85240b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,7 +42,6 @@ libusrsctp_la_SOURCES = user_atomic.h \ user_queue.h \ user_recv_thread.c user_recv_thread.h \ user_route.h \ - user_sctp_timer_iterate.c \ user_socket.c \ user_socketvar.h \ user_uma.h \ diff --git a/Makefile.nmake b/Makefile.nmake index 9be1077..48d2bd1 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -41,7 +41,6 @@ usrsctp_OBJECTS = \ user_environment.obj \
user_mbuf.obj \
user_recv_thread.obj \
- user_sctp_timer_iterate.obj \
user_socket.obj \
sctp_asconf.obj \
sctp_auth.obj \
@@ -115,9 +114,6 @@ user_mbuf.obj : user_mbuf.c $(usrsctp_HEADERS) user_recv_thread.obj: user_recv_thread.c $(usrsctp_HEADERS)
cl $(CVARSDLL) $(CFLAGS) -c user_recv_thread.c
-user_sctp_timer_iterate.obj : user_sctp_timer_iterate.c $(usrsctp_HEADERS)
- cl $(CVARSDLL) $(CFLAGS) -c user_sctp_timer_iterate.c
-
user_socket.obj : user_socket.c $(usrsctp_HEADERS)
cl $(CVARSDLL) $(CFLAGS) -c user_socket.c
diff --git a/netinet/sctp_callout.c b/netinet/sctp_callout.c index 67b7566..3174e3f 100755 --- a/netinet/sctp_callout.c +++ b/netinet/sctp_callout.c @@ -30,9 +30,27 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ +#if defined(__Userspace__) +#include <sys/types.h> +#if !defined (__Userspace_os_Windows) +#include <sys/wait.h> +#include <unistd.h> +#include <pthread.h> +#endif +#if defined(__Userspace_os_NaCl) +#include <sys/select.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <netinet/sctp_sysctl.h> +#include <netinet/sctp_pcb.h> +#else #include <netinet/sctp_os.h> #include <netinet/sctp_callout.h> #include <netinet/sctp_pcb.h> +#endif /* * Callout/Timer routines for OS that doesn't have them @@ -46,10 +64,8 @@ extern int ticks; /* * SCTP_TIMERQ_LOCK protects: * - SCTP_BASE_INFO(callqueue) - * - sctp_os_timer_current: current timer in process * - sctp_os_timer_next: next timer to check */ -static sctp_os_timer_t *sctp_os_timer_current = NULL; static sctp_os_timer_t *sctp_os_timer_next = NULL; void @@ -117,24 +133,16 @@ sctp_os_timer_stop(sctp_os_timer_t *c) return (1); } -#if defined(__APPLE__) -/* - * For __APPLE__, use a single main timer at a faster resolution than - * fastim. The timer just calls this existing callout infrastructure. - */ -#endif -void -sctp_timeout(void *arg SCTP_UNUSED) +static void +sctp_handle_tick(int delta) { sctp_os_timer_t *c; void (*c_func)(void *); void *c_arg; SCTP_TIMERQ_LOCK(); -#if defined(__APPLE__) /* update our tick count */ - ticks += SCTP_BASE_VAR(sctp_main_timer_ticks); -#endif + ticks += delta; c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue)); while (c) { if (c->c_time <= ticks) { @@ -143,11 +151,9 @@ sctp_timeout(void *arg SCTP_UNUSED) c_func = c->c_func; c_arg = c->c_arg; c->c_flags &= ~SCTP_CALLOUT_PENDING; - sctp_os_timer_current = c; SCTP_TIMERQ_UNLOCK(); c_func(c_arg); SCTP_TIMERQ_LOCK(); - sctp_os_timer_current = NULL; c = sctp_os_timer_next; } else { c = TAILQ_NEXT(c, tqe); @@ -155,9 +161,60 @@ sctp_timeout(void *arg SCTP_UNUSED) } sctp_os_timer_next = NULL; SCTP_TIMERQ_UNLOCK(); +} #if defined(__APPLE__) - /* restart the main timer */ +void +sctp_timeout(void *arg SCTP_UNUSED) +{ + sctp_handle_tick(SCTP_BASE_VAR(sctp_main_timer_ticks)); sctp_start_main_timer(); +} #endif + +#if defined(__Userspace__) +#define TIMEOUT_INTERVAL 10 + +void * +user_sctp_timer_iterate(void *arg) +{ + for (;;) { +#if defined (__Userspace_os_Windows) + Sleep(TIMEOUT_INTERVAL); +#else + struct timeval timeout; + + timeout.tv_sec = 0; + timeout.tv_usec = 1000 * TIMEOUT_INTERVAL; + select(0, NULL, NULL, NULL, &timeout); +#endif + if (SCTP_BASE_VAR(timer_thread_should_exit)) { + break; + } + sctp_handle_tick(MSEC_TO_TICKS(TIMEOUT_INTERVAL)); + } + return (NULL); } + +void +sctp_start_timer(void) +{ + /* + * No need to do SCTP_TIMERQ_LOCK_INIT(); + * here, it is being done in sctp_pcb_init() + */ +#if defined (__Userspace_os_Windows) + if ((SCTP_BASE_VAR(timer_thread) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)user_sctp_timer_iterate, NULL, 0, NULL)) == NULL) { + SCTP_PRINTF("ERROR; Creating ithread failed\n"); + } +#else + int rc; + + rc = pthread_create(&SCTP_BASE_VAR(timer_thread), NULL, user_sctp_timer_iterate, NULL); + if (rc) { + SCTP_PRINTF("ERROR; return code from pthread_create() is %d\n", rc); + } +#endif +} + +#endif diff --git a/netinet/sctp_callout.h b/netinet/sctp_callout.h index 2782945..c53c5a4 100755 --- a/netinet/sctp_callout.h +++ b/netinet/sctp_callout.h @@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$"); #endif extern int ticks; -extern void sctp_start_timer(); #endif TAILQ_HEAD(calloutlist, sctp_callout); @@ -94,6 +93,11 @@ int sctp_os_timer_stop(sctp_os_timer_t *); #define SCTP_OS_TIMER_ACTIVE(tmr) ((tmr)->c_flags & SCTP_CALLOUT_ACTIVE) #define SCTP_OS_TIMER_DEACTIVATE(tmr) ((tmr)->c_flags &= ~SCTP_CALLOUT_ACTIVE) +#if defined(__Userspace__) +void sctp_start_timer(void); +#endif +#if defined(__APPLE__) void sctp_timeout(void *); +#endif #endif diff --git a/netinet/sctp_input.c b/netinet/sctp_input.c index cb7968f..5302582 100755 --- a/netinet/sctp_input.c +++ b/netinet/sctp_input.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 271230 2014-09-07 18:05:37Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 272841 2014-10-09 20:08:12Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -4202,8 +4202,10 @@ sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset, if (chk == NULL) { return (ret_code); } + chk->copy_by_ref = 0; chk->rec.chunk_id.id = SCTP_STREAM_RESET; chk->rec.chunk_id.can_take_data = 0; + chk->flags = 0; chk->asoc = &stcb->asoc; chk->no_fr_allowed = 0; chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr); diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c index 9502cc6..07ae932 100755 --- a/netinet/sctp_output.c +++ b/netinet/sctp_output.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 272571 2014-10-05 20:30:49Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 272841 2014-10-09 20:08:12Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -9370,16 +9370,11 @@ sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err) return; } chk->send_size = 0; - mat = op_err; - while (mat != NULL) { + for (mat = op_err; mat != NULL; mat = SCTP_BUF_NEXT(mat)) { chk->send_size += SCTP_BUF_LEN(mat); - mat = SCTP_BUF_NEXT(mat); } - chk->rec.chunk_id.id = SCTP_OPERATION_ERROR; - chk->rec.chunk_id.can_take_data = 1; chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; - chk->flags = 0; chk->asoc = &stcb->asoc; chk->data = op_err; chk->whoTo = NULL; @@ -9467,12 +9462,12 @@ sctp_send_cookie_echo(struct mbuf *m, return (-5); } chk->copy_by_ref = 0; - chk->send_size = plen; chk->rec.chunk_id.id = SCTP_COOKIE_ECHO; chk->rec.chunk_id.can_take_data = 0; + chk->flags = CHUNK_FLAGS_FRAGMENT_OK; + chk->send_size = plen; chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; - chk->flags = CHUNK_FLAGS_FRAGMENT_OK; chk->asoc = &stcb->asoc; chk->data = cookie; chk->whoTo = net; @@ -9535,12 +9530,12 @@ sctp_send_heartbeat_ack(struct sctp_tcb *stcb, return; } chk->copy_by_ref = 0; - chk->send_size = chk_length; chk->rec.chunk_id.id = SCTP_HEARTBEAT_ACK; chk->rec.chunk_id.can_take_data = 1; + chk->flags = 0; + chk->send_size = chk_length; chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; - chk->flags = 0; chk->asoc = &stcb->asoc; chk->data = outchain; chk->whoTo = net; @@ -9572,12 +9567,12 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb) return; } chk->copy_by_ref = 0; - chk->send_size = sizeof(struct sctp_chunkhdr); chk->rec.chunk_id.id = SCTP_COOKIE_ACK; chk->rec.chunk_id.can_take_data = 1; + chk->flags = 0; + chk->send_size = sizeof(struct sctp_chunkhdr); chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; - chk->flags = 0; chk->asoc = &stcb->asoc; chk->data = cookie_ack; if (chk->asoc->last_control_chunk_from != NULL) { @@ -9618,9 +9613,10 @@ sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net) return; } chk->copy_by_ref = 0; - chk->send_size = sizeof(struct sctp_chunkhdr); chk->rec.chunk_id.id = SCTP_SHUTDOWN_ACK; chk->rec.chunk_id.can_take_data = 1; + chk->flags = 0; + chk->send_size = sizeof(struct sctp_chunkhdr); chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; chk->flags = 0; @@ -9661,9 +9657,10 @@ sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net) return; } chk->copy_by_ref = 0; - chk->send_size = sizeof(struct sctp_shutdown_chunk); chk->rec.chunk_id.id = SCTP_SHUTDOWN; chk->rec.chunk_id.can_take_data = 1; + chk->flags = 0; + chk->send_size = sizeof(struct sctp_shutdown_chunk); chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; chk->flags = 0; @@ -9717,13 +9714,13 @@ sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net, int addr_locked) } chk->copy_by_ref = 0; - chk->data = m_asconf; - chk->send_size = len; chk->rec.chunk_id.id = SCTP_ASCONF; chk->rec.chunk_id.can_take_data = 0; + chk->flags = CHUNK_FLAGS_FRAGMENT_OK; + chk->data = m_asconf; + chk->send_size = len; chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; - chk->flags = CHUNK_FLAGS_FRAGMENT_OK; chk->asoc = &stcb->asoc; chk->whoTo = net; if (chk->whoTo) { @@ -9813,7 +9810,9 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb) return; } chk->copy_by_ref = 0; - + chk->rec.chunk_id.id = SCTP_ASCONF_ACK; + chk->rec.chunk_id.can_take_data = 1; + chk->flags = CHUNK_FLAGS_FRAGMENT_OK; chk->whoTo = net; if (chk->whoTo) { atomic_add_int(&chk->whoTo->ref_count, 1); @@ -9822,11 +9821,8 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb) chk->send_size = 0; /* Get size */ chk->send_size = ack->len; - chk->rec.chunk_id.id = SCTP_ASCONF_ACK; - chk->rec.chunk_id.can_take_data = 1; chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; - chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; /* XXX */ chk->asoc = &stcb->asoc; TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next); @@ -10739,6 +10735,7 @@ send_forward_tsn(struct sctp_tcb *stcb, chk->copy_by_ref = 0; chk->rec.chunk_id.id = SCTP_FORWARD_CUM_TSN; chk->rec.chunk_id.can_take_data = 0; + chk->flags = 0; chk->asoc = asoc; chk->whoTo = NULL; chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA); @@ -10972,6 +10969,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked /* Clear our pkt counts */ asoc->data_pkts_seen = 0; + a_chk->flags = 0; a_chk->asoc = asoc; a_chk->snd_count = 0; a_chk->send_size = 0; /* fill in later */ @@ -11895,6 +11893,7 @@ sctp_send_hb(struct sctp_tcb *stcb, struct sctp_nets *net,int so_locked chk->copy_by_ref = 0; chk->rec.chunk_id.id = SCTP_HEARTBEAT_REQUEST; chk->rec.chunk_id.can_take_data = 1; + chk->flags = 0; chk->asoc = &stcb->asoc; chk->send_size = sizeof(struct sctp_heartbeat_chunk); @@ -12025,10 +12024,11 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, if (chk == NULL) { return; } - chk->copy_by_ref = 0; SCTP_STAT_INCR(sctps_queue_upd_ecne); + chk->copy_by_ref = 0; chk->rec.chunk_id.id = SCTP_ECN_ECHO; chk->rec.chunk_id.can_take_data = 0; + chk->flags = 0; chk->asoc = &stcb->asoc; chk->send_size = sizeof(struct sctp_ecne_chunk); chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER); @@ -12088,6 +12088,9 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net, return; } chk->copy_by_ref = 0; + chk->rec.chunk_id.id = SCTP_PACKET_DROPPED; + chk->rec.chunk_id.can_take_data = 1; + chk->flags = 0; len -= iphlen; chk->send_size = len; /* Validate that we do not have an ABORT in here. */ @@ -12173,8 +12176,6 @@ jump_out: } else { chk->whoTo = NULL; } - chk->rec.chunk_id.id = SCTP_PACKET_DROPPED; - chk->rec.chunk_id.can_take_data = 1; drp->ch.chunk_type = SCTP_PACKET_DROPPED; drp->ch.chunk_length = htons(chk->send_size); spc = SCTP_SB_LIMIT_RCV(stcb->sctp_socket); @@ -12236,6 +12237,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u chk->copy_by_ref = 0; chk->rec.chunk_id.id = SCTP_ECN_CWR; chk->rec.chunk_id.can_take_data = 1; + chk->flags = 0; chk->asoc = &stcb->asoc; chk->send_size = sizeof(struct sctp_cwr_chunk); chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER); @@ -12498,7 +12500,7 @@ sctp_add_an_in_stream(struct sctp_tmit_chunk *chk, int sctp_send_str_reset_req(struct sctp_tcb *stcb, - int number_entries, uint16_t *list, + uint16_t number_entries, uint16_t *list, uint8_t send_out_req, uint8_t send_in_req, uint8_t send_tsn_req, @@ -12531,6 +12533,14 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL); return (EINVAL); } + if (number_entries > (MCLBYTES - + SCTP_MIN_OVERHEAD - + sizeof(struct sctp_chunkhdr) - + sizeof(struct sctp_stream_reset_out_request)) / + sizeof(uint16_t)) { + SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); + return (ENOMEM); + } sctp_alloc_a_chunk(stcb, chk); if (chk == NULL) { SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM); @@ -12539,6 +12549,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, chk->copy_by_ref = 0; chk->rec.chunk_id.id = SCTP_STREAM_RESET; chk->rec.chunk_id.can_take_data = 0; + chk->flags = 0; chk->asoc = &stcb->asoc; chk->book_size = sizeof(struct sctp_chunkhdr); chk->send_size = SCTP_SIZE32(chk->book_size); diff --git a/netinet/sctp_output.h b/netinet/sctp_output.h index 808af1b..d03bead 100755 --- a/netinet/sctp_output.h +++ b/netinet/sctp_output.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 246595 2013-02-09 17:26:14Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.h 272751 2014-10-08 15:30:59Z tuexen $"); #endif #ifndef _NETINET_SCTP_OUTPUT_H_ @@ -208,8 +208,8 @@ sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *, uint32_t, uint32_t, uint32_t, uint32_t); int -sctp_send_str_reset_req(struct sctp_tcb *, int , uint16_t *, uint8_t, uint8_t, - uint8_t, uint8_t, uint16_t, uint16_t, uint8_t); +sctp_send_str_reset_req(struct sctp_tcb *, uint16_t , uint16_t *, uint8_t, + uint8_t, uint8_t, uint8_t, uint16_t, uint16_t, uint8_t); void sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *, diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c index e04e598..362d353 100755 --- a/netinet/sctp_usrreq.c +++ b/netinet/sctp_usrreq.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 271673 2014-09-16 14:20:33Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 272750 2014-10-08 15:29:49Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -56,7 +56,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 271673 2014-09-16 14:20:33Z t #include <netinet/sctp_timer.h> #include <netinet/sctp_auth.h> #include <netinet/sctp_bsd_addr.h> -#if !defined(__Userspace__) +#if defined(__Userspace__) +#include <netinet/sctp_callout.h> +#else #include <netinet/udp.h> #endif @@ -5252,6 +5254,12 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_TCB_UNLOCK(stcb); break; } + if (sizeof(struct sctp_reset_streams) + + strrst->srs_number_streams * sizeof(uint16_t) > optsize) { + error = EINVAL; + SCTP_TCB_UNLOCK(stcb); + break; + } if (stcb->asoc.stream_reset_outstanding) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); error = EALREADY; diff --git a/user_sctp_timer_iterate.c b/user_sctp_timer_iterate.c deleted file mode 100755 index 67684fd..0000000 --- a/user_sctp_timer_iterate.c +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * Copyright (c) 2012 Michael Tuexen - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - */ - -#include <sys/types.h> -#if !defined (__Userspace_os_Windows) -#include <sys/wait.h> -#include <unistd.h> -#include <pthread.h> -#endif -#if defined(__Userspace_os_NaCl) -#include <sys/select.h> -#endif -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> -#include <netinet/sctp_pcb.h> -#include <netinet/sctp_sysctl.h> -#include "netinet/sctp_callout.h" - -/* This is the polling time of callqueue in milliseconds - * 10ms seems to work well. 1ms was giving erratic behavior - */ -#define TIMEOUT_INTERVAL 10 - -extern int ticks; - -void * -user_sctp_timer_iterate(void *arg) -{ - sctp_os_timer_t *c; - void (*c_func)(void *); - void *c_arg; - sctp_os_timer_t *sctp_os_timer_next; - /* - * The MSEC_TO_TICKS conversion depends on hz. The to_ticks in - * sctp_os_timer_start also depends on hz. E.g. if hz=1000 then - * for multiple INIT the to_ticks is 2000, 4000, 8000, 16000, 32000, 60000 - * and further to_ticks level off at 60000 i.e. 60 seconds. - * If hz=100 then for multiple INIT the to_ticks are 200, 400, 800 and so-on. - */ - for (;;) { -#if defined (__Userspace_os_Windows) - Sleep(TIMEOUT_INTERVAL); -#else - struct timeval timeout; - - timeout.tv_sec = 0; - timeout.tv_usec = 1000 * TIMEOUT_INTERVAL; - select(0, NULL, NULL, NULL, &timeout); -#endif - if (SCTP_BASE_VAR(timer_thread_should_exit)) { - break; - } - SCTP_TIMERQ_LOCK(); - /* update our tick count */ - ticks += MSEC_TO_TICKS(TIMEOUT_INTERVAL); - c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue)); - while (c) { - if (c->c_time <= ticks) { - sctp_os_timer_next = TAILQ_NEXT(c, tqe); - TAILQ_REMOVE(&SCTP_BASE_INFO(callqueue), c, tqe); - c_func = c->c_func; - c_arg = c->c_arg; - c->c_flags &= ~SCTP_CALLOUT_PENDING; - SCTP_TIMERQ_UNLOCK(); - c_func(c_arg); - SCTP_TIMERQ_LOCK(); - c = sctp_os_timer_next; - } else { - c = TAILQ_NEXT(c, tqe); - } - } - SCTP_TIMERQ_UNLOCK(); - } - return (NULL); -} - -void -sctp_start_timer(void) -{ - /* - * No need to do SCTP_TIMERQ_LOCK_INIT(); - * here, it is being done in sctp_pcb_init() - */ -#if defined (__Userspace_os_Windows) - if ((SCTP_BASE_VAR(timer_thread) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)user_sctp_timer_iterate, NULL, 0, NULL)) == NULL) { - SCTP_PRINTF("ERROR; Creating ithread failed\n"); - } -#else - int rc; - - rc = pthread_create(&SCTP_BASE_VAR(timer_thread), NULL, user_sctp_timer_iterate, NULL); - if (rc) { - SCTP_PRINTF("ERROR; return code from pthread_create() is %d\n", rc); - } -#endif -} |