1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/sctp/src/netinet/sctp_structs.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1277 @@ 1.4 +/*- 1.5 + * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. 1.6 + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 1.7 + * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 1.8 + * 1.9 + * Redistribution and use in source and binary forms, with or without 1.10 + * modification, are permitted provided that the following conditions are met: 1.11 + * 1.12 + * a) Redistributions of source code must retain the above copyright notice, 1.13 + * this list of conditions and the following disclaimer. 1.14 + * 1.15 + * b) Redistributions in binary form must reproduce the above copyright 1.16 + * notice, this list of conditions and the following disclaimer in 1.17 + * the documentation and/or other materials provided with the distribution. 1.18 + * 1.19 + * c) Neither the name of Cisco Systems, Inc. nor the names of its 1.20 + * contributors may be used to endorse or promote products derived 1.21 + * from this software without specific prior written permission. 1.22 + * 1.23 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1.25 + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.26 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.27 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.28 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.29 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.30 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.31 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.32 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 1.33 + * THE POSSIBILITY OF SUCH DAMAGE. 1.34 + */ 1.35 + 1.36 +#ifdef __FreeBSD__ 1.37 +#include <sys/cdefs.h> 1.38 +__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 255190 2013-09-03 19:31:59Z tuexen $"); 1.39 +#endif 1.40 + 1.41 +#ifndef _NETINET_SCTP_STRUCTS_H_ 1.42 +#define _NETINET_SCTP_STRUCTS_H_ 1.43 + 1.44 +#include <netinet/sctp_os.h> 1.45 +#include <netinet/sctp_header.h> 1.46 +#include <netinet/sctp_auth.h> 1.47 + 1.48 +struct sctp_timer { 1.49 + sctp_os_timer_t timer; 1.50 + 1.51 + int type; 1.52 + /* 1.53 + * Depending on the timer type these will be setup and cast with the 1.54 + * appropriate entity. 1.55 + */ 1.56 + void *ep; 1.57 + void *tcb; 1.58 + void *net; 1.59 +#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 1.60 + void *vnet; 1.61 +#endif 1.62 + 1.63 + /* for sanity checking */ 1.64 + void *self; 1.65 + uint32_t ticks; 1.66 + uint32_t stopped_from; 1.67 +}; 1.68 + 1.69 + 1.70 +struct sctp_foo_stuff { 1.71 + struct sctp_inpcb *inp; 1.72 + uint32_t lineno; 1.73 + uint32_t ticks; 1.74 + int updown; 1.75 +}; 1.76 + 1.77 + 1.78 +/* 1.79 + * This is the information we track on each interface that we know about from 1.80 + * the distant end. 1.81 + */ 1.82 +TAILQ_HEAD(sctpnetlisthead, sctp_nets); 1.83 + 1.84 +struct sctp_stream_reset_list { 1.85 + TAILQ_ENTRY(sctp_stream_reset_list) next_resp; 1.86 + uint32_t tsn; 1.87 + uint32_t number_entries; 1.88 + uint16_t list_of_streams[]; 1.89 +}; 1.90 + 1.91 +TAILQ_HEAD(sctp_resethead, sctp_stream_reset_list); 1.92 + 1.93 +/* 1.94 + * Users of the iterator need to malloc a iterator with a call to 1.95 + * sctp_initiate_iterator(inp_func, assoc_func, inp_func, pcb_flags, pcb_features, 1.96 + * asoc_state, void-ptr-arg, uint32-arg, end_func, inp); 1.97 + * 1.98 + * Use the following two defines if you don't care what pcb flags are on the EP 1.99 + * and/or you don't care what state the association is in. 1.100 + * 1.101 + * Note that if you specify an INP as the last argument then ONLY each 1.102 + * association of that single INP will be executed upon. Note that the pcb 1.103 + * flags STILL apply so if the inp you specify has different pcb_flags then 1.104 + * what you put in pcb_flags nothing will happen. use SCTP_PCB_ANY_FLAGS to 1.105 + * assure the inp you specify gets treated. 1.106 + */ 1.107 +#define SCTP_PCB_ANY_FLAGS 0x00000000 1.108 +#define SCTP_PCB_ANY_FEATURES 0x00000000 1.109 +#define SCTP_ASOC_ANY_STATE 0x00000000 1.110 + 1.111 +typedef void (*asoc_func) (struct sctp_inpcb *, struct sctp_tcb *, void *ptr, 1.112 + uint32_t val); 1.113 +typedef int (*inp_func) (struct sctp_inpcb *, void *ptr, uint32_t val); 1.114 +typedef void (*end_func) (void *ptr, uint32_t val); 1.115 + 1.116 +#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) 1.117 +/* whats on the mcore control struct */ 1.118 +struct sctp_mcore_queue { 1.119 + TAILQ_ENTRY(sctp_mcore_queue) next; 1.120 +#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 1.121 + struct vnet *vn; 1.122 +#endif 1.123 + struct mbuf *m; 1.124 + int off; 1.125 + int v6; 1.126 +}; 1.127 + 1.128 +TAILQ_HEAD(sctp_mcore_qhead, sctp_mcore_queue); 1.129 + 1.130 +struct sctp_mcore_ctrl { 1.131 + SCTP_PROCESS_STRUCT thread_proc; 1.132 + struct sctp_mcore_qhead que; 1.133 + struct mtx core_mtx; 1.134 + struct mtx que_mtx; 1.135 + int running; 1.136 + int cpuid; 1.137 +}; 1.138 + 1.139 + 1.140 +#endif 1.141 + 1.142 + 1.143 +struct sctp_iterator { 1.144 + TAILQ_ENTRY(sctp_iterator) sctp_nxt_itr; 1.145 +#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 1.146 + struct vnet *vn; 1.147 +#endif 1.148 + struct sctp_timer tmr; 1.149 + struct sctp_inpcb *inp; /* current endpoint */ 1.150 + struct sctp_tcb *stcb; /* current* assoc */ 1.151 + struct sctp_inpcb *next_inp; /* special hook to skip to */ 1.152 + asoc_func function_assoc; /* per assoc function */ 1.153 + inp_func function_inp; /* per endpoint function */ 1.154 + inp_func function_inp_end; /* end INP function */ 1.155 + end_func function_atend; /* iterator completion function */ 1.156 + void *pointer; /* pointer for apply func to use */ 1.157 + uint32_t val; /* value for apply func to use */ 1.158 + uint32_t pcb_flags; /* endpoint flags being checked */ 1.159 + uint32_t pcb_features; /* endpoint features being checked */ 1.160 + uint32_t asoc_state; /* assoc state being checked */ 1.161 + uint32_t iterator_flags; 1.162 + uint8_t no_chunk_output; 1.163 + uint8_t done_current_ep; 1.164 +}; 1.165 +/* iterator_flags values */ 1.166 +#define SCTP_ITERATOR_DO_ALL_INP 0x00000001 1.167 +#define SCTP_ITERATOR_DO_SINGLE_INP 0x00000002 1.168 + 1.169 + 1.170 +TAILQ_HEAD(sctpiterators, sctp_iterator); 1.171 + 1.172 +struct sctp_copy_all { 1.173 + struct sctp_inpcb *inp; /* ep */ 1.174 + struct mbuf *m; 1.175 + struct sctp_sndrcvinfo sndrcv; 1.176 + int sndlen; 1.177 + int cnt_sent; 1.178 + int cnt_failed; 1.179 +}; 1.180 + 1.181 +struct sctp_asconf_iterator { 1.182 + struct sctpladdr list_of_work; 1.183 + int cnt; 1.184 +}; 1.185 + 1.186 +struct iterator_control { 1.187 +#if defined(__FreeBSD__) 1.188 + struct mtx ipi_iterator_wq_mtx; 1.189 + struct mtx it_mtx; 1.190 +#elif defined(__APPLE__) 1.191 + lck_mtx_t *ipi_iterator_wq_mtx; 1.192 + lck_mtx_t *it_mtx; 1.193 +#elif defined(SCTP_PROCESS_LEVEL_LOCKS) 1.194 +#if defined(__Userspace__) 1.195 + userland_mutex_t ipi_iterator_wq_mtx; 1.196 + userland_mutex_t it_mtx; 1.197 + userland_cond_t iterator_wakeup; 1.198 +#else 1.199 + pthread_mutex_t ipi_iterator_wq_mtx; 1.200 + pthread_mutex_t it_mtx; 1.201 + pthread_cond_t iterator_wakeup; 1.202 +#endif 1.203 +#elif defined(__Windows__) 1.204 + struct spinlock it_lock; 1.205 + struct spinlock ipi_iterator_wq_lock; 1.206 + KEVENT iterator_wakeup[2]; 1.207 + PFILE_OBJECT iterator_thread_obj; 1.208 +#else 1.209 + void *it_mtx; 1.210 +#endif 1.211 +#if !defined(__Windows__) 1.212 +#if !defined(__Userspace__) 1.213 + SCTP_PROCESS_STRUCT thread_proc; 1.214 +#else 1.215 + userland_thread_t thread_proc; 1.216 +#endif 1.217 +#endif 1.218 + struct sctpiterators iteratorhead; 1.219 + struct sctp_iterator *cur_it; 1.220 + uint32_t iterator_running; 1.221 + uint32_t iterator_flags; 1.222 +}; 1.223 +#if !defined(__FreeBSD__) 1.224 +#define SCTP_ITERATOR_MUST_EXIT 0x00000001 1.225 +#define SCTP_ITERATOR_EXITED 0x00000002 1.226 +#endif 1.227 +#define SCTP_ITERATOR_STOP_CUR_IT 0x00000004 1.228 +#define SCTP_ITERATOR_STOP_CUR_INP 0x00000008 1.229 + 1.230 +struct sctp_net_route { 1.231 + sctp_rtentry_t *ro_rt; 1.232 +#if defined(__FreeBSD__) 1.233 +#if __FreeBSD_version >= 800000 1.234 + void *ro_lle; 1.235 +#endif 1.236 +#if __FreeBSD_version >= 900000 1.237 + void *ro_ia; 1.238 + int ro_flags; 1.239 +#endif 1.240 +#endif 1.241 +#if defined(__APPLE__) 1.242 +#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) 1.243 + struct ifaddr *ro_srcia; 1.244 +#endif 1.245 +#if !defined(APPLE_LEOPARD) 1.246 + uint32_t ro_flags; 1.247 +#endif 1.248 +#endif 1.249 + union sctp_sockstore _l_addr; /* remote peer addr */ 1.250 + struct sctp_ifa *_s_addr; /* our selected src addr */ 1.251 +}; 1.252 + 1.253 +struct htcp { 1.254 + uint16_t alpha; /* Fixed point arith, << 7 */ 1.255 + uint8_t beta; /* Fixed point arith, << 7 */ 1.256 + uint8_t modeswitch; /* Delay modeswitch until we had at least one congestion event */ 1.257 + uint32_t last_cong; /* Time since last congestion event end */ 1.258 + uint32_t undo_last_cong; 1.259 + uint16_t bytes_acked; 1.260 + uint32_t bytecount; 1.261 + uint32_t minRTT; 1.262 + uint32_t maxRTT; 1.263 + 1.264 + uint32_t undo_maxRTT; 1.265 + uint32_t undo_old_maxB; 1.266 + 1.267 + /* Bandwidth estimation */ 1.268 + uint32_t minB; 1.269 + uint32_t maxB; 1.270 + uint32_t old_maxB; 1.271 + uint32_t Bi; 1.272 + uint32_t lasttime; 1.273 +}; 1.274 + 1.275 +struct rtcc_cc { 1.276 + struct timeval tls; /* The time we started the sending */ 1.277 + uint64_t lbw; /* Our last estimated bw */ 1.278 + uint64_t lbw_rtt; /* RTT at bw estimate */ 1.279 + uint64_t bw_bytes; /* The total bytes since this sending began */ 1.280 + uint64_t bw_tot_time; /* The total time since sending began */ 1.281 + uint64_t new_tot_time; /* temp holding the new value */ 1.282 + uint64_t bw_bytes_at_last_rttc; /* What bw_bytes was at last rtt calc */ 1.283 + uint32_t cwnd_at_bw_set; /* Cwnd at last bw saved - lbw */ 1.284 + uint32_t vol_reduce; /* cnt of voluntary reductions */ 1.285 + uint16_t steady_step; /* The number required to be in steady state*/ 1.286 + uint16_t step_cnt; /* The current number */ 1.287 + uint8_t ret_from_eq; /* When all things are equal what do I return 0/1 - 1 no cc advance */ 1.288 + uint8_t use_dccc_ecn; /* Flag to enable DCCC ECN */ 1.289 + uint8_t tls_needs_set; /* Flag to indicate we need to set tls 0 or 1 means set at send 2 not */ 1.290 + uint8_t last_step_state; /* Last state if steady state stepdown is on */ 1.291 + uint8_t rtt_set_this_sack; /* Flag saying this sack had RTT calc on it */ 1.292 + uint8_t last_inst_ind; /* Last saved inst indication */ 1.293 +}; 1.294 + 1.295 + 1.296 +struct sctp_nets { 1.297 + TAILQ_ENTRY(sctp_nets) sctp_next; /* next link */ 1.298 + 1.299 + /* 1.300 + * Things on the top half may be able to be split into a common 1.301 + * structure shared by all. 1.302 + */ 1.303 + struct sctp_timer pmtu_timer; 1.304 + struct sctp_timer hb_timer; 1.305 + 1.306 + /* 1.307 + * The following two in combination equate to a route entry for v6 1.308 + * or v4. 1.309 + */ 1.310 + struct sctp_net_route ro; 1.311 + 1.312 + /* mtu discovered so far */ 1.313 + uint32_t mtu; 1.314 + uint32_t ssthresh; /* not sure about this one for split */ 1.315 + uint32_t last_cwr_tsn; 1.316 + uint32_t cwr_window_tsn; 1.317 + uint32_t ecn_ce_pkt_cnt; 1.318 + uint32_t lost_cnt; 1.319 + /* smoothed average things for RTT and RTO itself */ 1.320 + int lastsa; 1.321 + int lastsv; 1.322 + uint64_t rtt; /* last measured rtt value in us */ 1.323 + unsigned int RTO; 1.324 + 1.325 + /* This is used for SHUTDOWN/SHUTDOWN-ACK/SEND or INIT timers */ 1.326 + struct sctp_timer rxt_timer; 1.327 + 1.328 + /* last time in seconds I sent to it */ 1.329 + struct timeval last_sent_time; 1.330 + union cc_control_data { 1.331 + struct htcp htcp_ca; /* JRS - struct used in HTCP algorithm */ 1.332 + struct rtcc_cc rtcc; /* rtcc module cc stuff */ 1.333 + } cc_mod; 1.334 + int ref_count; 1.335 + 1.336 + /* Congestion stats per destination */ 1.337 + /* 1.338 + * flight size variables and such, sorry Vern, I could not avoid 1.339 + * this if I wanted performance :> 1.340 + */ 1.341 + uint32_t flight_size; 1.342 + uint32_t cwnd; /* actual cwnd */ 1.343 + uint32_t prev_cwnd; /* cwnd before any processing */ 1.344 + uint32_t ecn_prev_cwnd; /* ECN prev cwnd at first ecn_echo seen in new window */ 1.345 + uint32_t partial_bytes_acked; /* in CA tracks when to incr a MTU */ 1.346 + /* tracking variables to avoid the aloc/free in sack processing */ 1.347 + unsigned int net_ack; 1.348 + unsigned int net_ack2; 1.349 + 1.350 + /* 1.351 + * JRS - 5/8/07 - Variable to track last time 1.352 + * a destination was active for CMT PF 1.353 + */ 1.354 + uint32_t last_active; 1.355 + 1.356 + /* 1.357 + * CMT variables (iyengar@cis.udel.edu) 1.358 + */ 1.359 + uint32_t this_sack_highest_newack; /* tracks highest TSN newly 1.360 + * acked for a given dest in 1.361 + * the current SACK. Used in 1.362 + * SFR and HTNA algos */ 1.363 + uint32_t pseudo_cumack; /* CMT CUC algorithm. Maintains next expected 1.364 + * pseudo-cumack for this destination */ 1.365 + uint32_t rtx_pseudo_cumack; /* CMT CUC algorithm. Maintains next 1.366 + * expected pseudo-cumack for this 1.367 + * destination */ 1.368 + 1.369 + /* CMT fast recovery variables */ 1.370 + uint32_t fast_recovery_tsn; 1.371 + uint32_t heartbeat_random1; 1.372 + uint32_t heartbeat_random2; 1.373 +#ifdef INET6 1.374 + uint32_t flowlabel; 1.375 +#endif 1.376 + uint8_t dscp; 1.377 + 1.378 + struct timeval start_time; /* time when this net was created */ 1.379 + uint32_t marked_retrans; /* number or DATA chunks marked for 1.380 + timer based retransmissions */ 1.381 + uint32_t marked_fastretrans; 1.382 + uint32_t heart_beat_delay; /* Heart Beat delay in ms */ 1.383 + 1.384 + /* if this guy is ok or not ... status */ 1.385 + uint16_t dest_state; 1.386 + /* number of timeouts to consider the destination unreachable */ 1.387 + uint16_t failure_threshold; 1.388 + /* number of timeouts to consider the destination potentially failed */ 1.389 + uint16_t pf_threshold; 1.390 + /* error stats on the destination */ 1.391 + uint16_t error_count; 1.392 + /* UDP port number in case of UDP tunneling */ 1.393 + uint16_t port; 1.394 + 1.395 + uint8_t fast_retran_loss_recovery; 1.396 + uint8_t will_exit_fast_recovery; 1.397 + /* Flags that probably can be combined into dest_state */ 1.398 + uint8_t fast_retran_ip; /* fast retransmit in progress */ 1.399 + uint8_t hb_responded; 1.400 + uint8_t saw_newack; /* CMT's SFR algorithm flag */ 1.401 + uint8_t src_addr_selected; /* if we split we move */ 1.402 + uint8_t indx_of_eligible_next_to_use; 1.403 + uint8_t addr_is_local; /* its a local address (if known) could move 1.404 + * in split */ 1.405 + 1.406 + /* 1.407 + * CMT variables (iyengar@cis.udel.edu) 1.408 + */ 1.409 + uint8_t find_pseudo_cumack; /* CMT CUC algorithm. Flag used to 1.410 + * find a new pseudocumack. This flag 1.411 + * is set after a new pseudo-cumack 1.412 + * has been received and indicates 1.413 + * that the sender should find the 1.414 + * next pseudo-cumack expected for 1.415 + * this destination */ 1.416 + uint8_t find_rtx_pseudo_cumack; /* CMT CUCv2 algorithm. Flag used to 1.417 + * find a new rtx-pseudocumack. This 1.418 + * flag is set after a new 1.419 + * rtx-pseudo-cumack has been received 1.420 + * and indicates that the sender 1.421 + * should find the next 1.422 + * rtx-pseudo-cumack expected for this 1.423 + * destination */ 1.424 + uint8_t new_pseudo_cumack; /* CMT CUC algorithm. Flag used to 1.425 + * indicate if a new pseudo-cumack or 1.426 + * rtx-pseudo-cumack has been received */ 1.427 + uint8_t window_probe; /* Doing a window probe? */ 1.428 + uint8_t RTO_measured; /* Have we done the first measure */ 1.429 + uint8_t last_hs_used; /* index into the last HS table entry we used */ 1.430 + uint8_t lan_type; 1.431 + uint8_t rto_needed; 1.432 +#if defined(__FreeBSD__) 1.433 + uint32_t flowid; 1.434 +#ifdef INVARIANTS 1.435 + uint8_t flowidset; 1.436 +#endif 1.437 +#endif 1.438 +}; 1.439 + 1.440 + 1.441 +struct sctp_data_chunkrec { 1.442 + uint32_t TSN_seq; /* the TSN of this transmit */ 1.443 + uint16_t stream_seq; /* the stream sequence number of this transmit */ 1.444 + uint16_t stream_number; /* the stream number of this guy */ 1.445 + uint32_t payloadtype; 1.446 + uint32_t context; /* from send */ 1.447 + uint32_t cwnd_at_send; 1.448 + /* 1.449 + * part of the Highest sacked algorithm to be able to stroke counts 1.450 + * on ones that are FR'd. 1.451 + */ 1.452 + uint32_t fast_retran_tsn; /* sending_seq at the time of FR */ 1.453 + struct timeval timetodrop; /* time we drop it from queue */ 1.454 + uint8_t doing_fast_retransmit; 1.455 + uint8_t rcv_flags; /* flags pulled from data chunk on inbound for 1.456 + * outbound holds sending flags for PR-SCTP. 1.457 + */ 1.458 + uint8_t state_flags; 1.459 + uint8_t chunk_was_revoked; 1.460 + uint8_t fwd_tsn_cnt; 1.461 +}; 1.462 + 1.463 +TAILQ_HEAD(sctpchunk_listhead, sctp_tmit_chunk); 1.464 + 1.465 +/* The lower byte is used to enumerate PR_SCTP policies */ 1.466 +#define CHUNK_FLAGS_PR_SCTP_TTL SCTP_PR_SCTP_TTL 1.467 +#define CHUNK_FLAGS_PR_SCTP_BUF SCTP_PR_SCTP_BUF 1.468 +#define CHUNK_FLAGS_PR_SCTP_RTX SCTP_PR_SCTP_RTX 1.469 + 1.470 +/* The upper byte is used as a bit mask */ 1.471 +#define CHUNK_FLAGS_FRAGMENT_OK 0x0100 1.472 + 1.473 +struct chk_id { 1.474 + uint16_t id; 1.475 + uint16_t can_take_data; 1.476 +}; 1.477 + 1.478 + 1.479 +struct sctp_tmit_chunk { 1.480 + union { 1.481 + struct sctp_data_chunkrec data; 1.482 + struct chk_id chunk_id; 1.483 + } rec; 1.484 + struct sctp_association *asoc; /* bp to asoc this belongs to */ 1.485 + struct timeval sent_rcv_time; /* filled in if RTT being calculated */ 1.486 + struct mbuf *data; /* pointer to mbuf chain of data */ 1.487 + struct mbuf *last_mbuf; /* pointer to last mbuf in chain */ 1.488 + struct sctp_nets *whoTo; 1.489 + TAILQ_ENTRY(sctp_tmit_chunk) sctp_next; /* next link */ 1.490 + int32_t sent; /* the send status */ 1.491 + uint16_t snd_count; /* number of times I sent */ 1.492 + uint16_t flags; /* flags, such as FRAGMENT_OK */ 1.493 + uint16_t send_size; 1.494 + uint16_t book_size; 1.495 + uint16_t mbcnt; 1.496 + uint16_t auth_keyid; 1.497 + uint8_t holds_key_ref; /* flag if auth keyid refcount is held */ 1.498 + uint8_t pad_inplace; 1.499 + uint8_t do_rtt; 1.500 + uint8_t book_size_scale; 1.501 + uint8_t no_fr_allowed; 1.502 + uint8_t copy_by_ref; 1.503 + uint8_t window_probe; 1.504 +}; 1.505 + 1.506 +/* 1.507 + * The first part of this structure MUST be the entire sinfo structure. Maybe 1.508 + * I should have made it a sub structure... we can circle back later and do 1.509 + * that if we want. 1.510 + */ 1.511 +struct sctp_queued_to_read { /* sinfo structure Pluse more */ 1.512 + uint16_t sinfo_stream; /* off the wire */ 1.513 + uint16_t sinfo_ssn; /* off the wire */ 1.514 + uint16_t sinfo_flags; /* SCTP_UNORDERED from wire use SCTP_EOF for 1.515 + * EOR */ 1.516 + uint32_t sinfo_ppid; /* off the wire */ 1.517 + uint32_t sinfo_context; /* pick this up from assoc def context? */ 1.518 + uint32_t sinfo_timetolive; /* not used by kernel */ 1.519 + uint32_t sinfo_tsn; /* Use this in reassembly as first TSN */ 1.520 + uint32_t sinfo_cumtsn; /* Use this in reassembly as last TSN */ 1.521 + sctp_assoc_t sinfo_assoc_id; /* our assoc id */ 1.522 + /* Non sinfo stuff */ 1.523 + uint32_t length; /* length of data */ 1.524 + uint32_t held_length; /* length held in sb */ 1.525 + struct sctp_nets *whoFrom; /* where it came from */ 1.526 + struct mbuf *data; /* front of the mbuf chain of data with 1.527 + * PKT_HDR */ 1.528 + struct mbuf *tail_mbuf; /* used for multi-part data */ 1.529 + struct mbuf *aux_data; /* used to hold/cache control if o/s does not take it from us */ 1.530 + struct sctp_tcb *stcb; /* assoc, used for window update */ 1.531 + TAILQ_ENTRY(sctp_queued_to_read) next; 1.532 + uint16_t port_from; 1.533 + uint16_t spec_flags; /* Flags to hold the notification field */ 1.534 + uint8_t do_not_ref_stcb; 1.535 + uint8_t end_added; 1.536 + uint8_t pdapi_aborted; 1.537 + uint8_t some_taken; 1.538 +}; 1.539 + 1.540 +/* This data structure will be on the outbound 1.541 + * stream queues. Data will be pulled off from 1.542 + * the front of the mbuf data and chunk-ified 1.543 + * by the output routines. We will custom 1.544 + * fit every chunk we pull to the send/sent 1.545 + * queue to make up the next full packet 1.546 + * if we can. An entry cannot be removed 1.547 + * from the stream_out queue until 1.548 + * the msg_is_complete flag is set. This 1.549 + * means at times data/tail_mbuf MIGHT 1.550 + * be NULL.. If that occurs it happens 1.551 + * for one of two reasons. Either the user 1.552 + * is blocked on a send() call and has not 1.553 + * awoken to copy more data down... OR 1.554 + * the user is in the explict MSG_EOR mode 1.555 + * and wrote some data, but has not completed 1.556 + * sending. 1.557 + */ 1.558 +struct sctp_stream_queue_pending { 1.559 + struct mbuf *data; 1.560 + struct mbuf *tail_mbuf; 1.561 + struct timeval ts; 1.562 + struct sctp_nets *net; 1.563 + TAILQ_ENTRY (sctp_stream_queue_pending) next; 1.564 + TAILQ_ENTRY (sctp_stream_queue_pending) ss_next; 1.565 + uint32_t length; 1.566 + uint32_t timetolive; 1.567 + uint32_t ppid; 1.568 + uint32_t context; 1.569 + uint16_t sinfo_flags; 1.570 + uint16_t stream; 1.571 + uint16_t act_flags; 1.572 + uint16_t auth_keyid; 1.573 + uint8_t holds_key_ref; 1.574 + uint8_t msg_is_complete; 1.575 + uint8_t some_taken; 1.576 + uint8_t sender_all_done; 1.577 + uint8_t put_last_out; 1.578 + uint8_t discard_rest; 1.579 +}; 1.580 + 1.581 +/* 1.582 + * this struct contains info that is used to track inbound stream data and 1.583 + * help with ordering. 1.584 + */ 1.585 +TAILQ_HEAD(sctpwheelunrel_listhead, sctp_stream_in); 1.586 +struct sctp_stream_in { 1.587 + struct sctp_readhead inqueue; 1.588 + uint16_t stream_no; 1.589 + uint16_t last_sequence_delivered; /* used for re-order */ 1.590 + uint8_t delivery_started; 1.591 +}; 1.592 + 1.593 +TAILQ_HEAD(sctpwheel_listhead, sctp_stream_out); 1.594 +TAILQ_HEAD(sctplist_listhead, sctp_stream_queue_pending); 1.595 + 1.596 +/* Round-robin schedulers */ 1.597 +struct ss_rr { 1.598 + /* next link in wheel */ 1.599 + TAILQ_ENTRY(sctp_stream_out) next_spoke; 1.600 +}; 1.601 + 1.602 +/* Priority scheduler */ 1.603 +struct ss_prio { 1.604 + /* next link in wheel */ 1.605 + TAILQ_ENTRY(sctp_stream_out) next_spoke; 1.606 + /* priority id */ 1.607 + uint16_t priority; 1.608 +}; 1.609 + 1.610 +/* Fair Bandwidth scheduler */ 1.611 +struct ss_fb { 1.612 + /* next link in wheel */ 1.613 + TAILQ_ENTRY(sctp_stream_out) next_spoke; 1.614 + /* stores message size */ 1.615 + int32_t rounds; 1.616 +}; 1.617 + 1.618 +/* 1.619 + * This union holds all data necessary for 1.620 + * different stream schedulers. 1.621 + */ 1.622 +union scheduling_data { 1.623 + struct sctpwheel_listhead out_wheel; 1.624 + struct sctplist_listhead out_list; 1.625 +}; 1.626 + 1.627 +/* 1.628 + * This union holds all parameters per stream 1.629 + * necessary for different stream schedulers. 1.630 + */ 1.631 +union scheduling_parameters { 1.632 + struct ss_rr rr; 1.633 + struct ss_prio prio; 1.634 + struct ss_fb fb; 1.635 +}; 1.636 + 1.637 +/* This struct is used to track the traffic on outbound streams */ 1.638 +struct sctp_stream_out { 1.639 + struct sctp_streamhead outqueue; 1.640 + union scheduling_parameters ss_params; 1.641 + uint32_t chunks_on_queues; 1.642 + uint16_t stream_no; 1.643 + uint16_t next_sequence_send; /* next one I expect to send out */ 1.644 + uint8_t last_msg_incomplete; 1.645 +}; 1.646 + 1.647 +/* used to keep track of the addresses yet to try to add/delete */ 1.648 +TAILQ_HEAD(sctp_asconf_addrhead, sctp_asconf_addr); 1.649 +struct sctp_asconf_addr { 1.650 + TAILQ_ENTRY(sctp_asconf_addr) next; 1.651 + struct sctp_asconf_addr_param ap; 1.652 + struct sctp_ifa *ifa; /* save the ifa for add/del ip */ 1.653 + uint8_t sent; /* has this been sent yet? */ 1.654 + uint8_t special_del; /* not to be used in lookup */ 1.655 +}; 1.656 + 1.657 +struct sctp_scoping { 1.658 + uint8_t ipv4_addr_legal; 1.659 + uint8_t ipv6_addr_legal; 1.660 +#if defined(__Userspace__) 1.661 + uint8_t conn_addr_legal; 1.662 +#endif 1.663 + uint8_t loopback_scope; 1.664 + uint8_t ipv4_local_scope; 1.665 + uint8_t local_scope; 1.666 + uint8_t site_scope; 1.667 +}; 1.668 + 1.669 +#define SCTP_TSN_LOG_SIZE 40 1.670 + 1.671 +struct sctp_tsn_log { 1.672 + void *stcb; 1.673 + uint32_t tsn; 1.674 + uint16_t strm; 1.675 + uint16_t seq; 1.676 + uint16_t sz; 1.677 + uint16_t flgs; 1.678 + uint16_t in_pos; 1.679 + uint16_t in_out; 1.680 +}; 1.681 + 1.682 +#define SCTP_FS_SPEC_LOG_SIZE 200 1.683 +struct sctp_fs_spec_log { 1.684 + uint32_t sent; 1.685 + uint32_t total_flight; 1.686 + uint32_t tsn; 1.687 + uint16_t book; 1.688 + uint8_t incr; 1.689 + uint8_t decr; 1.690 +}; 1.691 + 1.692 +/* This struct is here to cut out the compatiabilty 1.693 + * pad that bulks up both the inp and stcb. The non 1.694 + * pad portion MUST stay in complete sync with 1.695 + * sctp_sndrcvinfo... i.e. if sinfo_xxxx is added 1.696 + * this must be done here too. 1.697 + */ 1.698 +struct sctp_nonpad_sndrcvinfo { 1.699 + uint16_t sinfo_stream; 1.700 + uint16_t sinfo_ssn; 1.701 + uint16_t sinfo_flags; 1.702 + uint32_t sinfo_ppid; 1.703 + uint32_t sinfo_context; 1.704 + uint32_t sinfo_timetolive; 1.705 + uint32_t sinfo_tsn; 1.706 + uint32_t sinfo_cumtsn; 1.707 + sctp_assoc_t sinfo_assoc_id; 1.708 + uint16_t sinfo_keynumber; 1.709 + uint16_t sinfo_keynumber_valid; 1.710 +}; 1.711 + 1.712 +/* 1.713 + * JRS - Structure to hold function pointers to the functions responsible 1.714 + * for congestion control. 1.715 + */ 1.716 + 1.717 +struct sctp_cc_functions { 1.718 + void (*sctp_set_initial_cc_param)(struct sctp_tcb *stcb, struct sctp_nets *net); 1.719 + void (*sctp_cwnd_update_after_sack)(struct sctp_tcb *stcb, 1.720 + struct sctp_association *asoc, 1.721 + int accum_moved ,int reneged_all, int will_exit); 1.722 + void (*sctp_cwnd_update_exit_pf)(struct sctp_tcb *stcb, struct sctp_nets *net); 1.723 + void (*sctp_cwnd_update_after_fr)(struct sctp_tcb *stcb, 1.724 + struct sctp_association *asoc); 1.725 + void (*sctp_cwnd_update_after_timeout)(struct sctp_tcb *stcb, 1.726 + struct sctp_nets *net); 1.727 + void (*sctp_cwnd_update_after_ecn_echo)(struct sctp_tcb *stcb, 1.728 + struct sctp_nets *net, int in_window, int num_pkt_lost); 1.729 + void (*sctp_cwnd_update_after_packet_dropped)(struct sctp_tcb *stcb, 1.730 + struct sctp_nets *net, struct sctp_pktdrop_chunk *cp, 1.731 + uint32_t *bottle_bw, uint32_t *on_queue); 1.732 + void (*sctp_cwnd_update_after_output)(struct sctp_tcb *stcb, 1.733 + struct sctp_nets *net, int burst_limit); 1.734 + void (*sctp_cwnd_update_packet_transmitted)(struct sctp_tcb *stcb, 1.735 + struct sctp_nets *net); 1.736 + void (*sctp_cwnd_update_tsn_acknowledged)(struct sctp_nets *net, 1.737 + struct sctp_tmit_chunk *); 1.738 + void (*sctp_cwnd_new_transmission_begins)(struct sctp_tcb *stcb, 1.739 + struct sctp_nets *net); 1.740 + void (*sctp_cwnd_prepare_net_for_sack)(struct sctp_tcb *stcb, 1.741 + struct sctp_nets *net); 1.742 + int (*sctp_cwnd_socket_option)(struct sctp_tcb *stcb, int set, struct sctp_cc_option *); 1.743 + void (*sctp_rtt_calculated)(struct sctp_tcb *, struct sctp_nets *, struct timeval *); 1.744 +}; 1.745 + 1.746 +/* 1.747 + * RS - Structure to hold function pointers to the functions responsible 1.748 + * for stream scheduling. 1.749 + */ 1.750 +struct sctp_ss_functions { 1.751 + void (*sctp_ss_init)(struct sctp_tcb *stcb, struct sctp_association *asoc, 1.752 + int holds_lock); 1.753 + void (*sctp_ss_clear)(struct sctp_tcb *stcb, struct sctp_association *asoc, 1.754 + int clear_values, int holds_lock); 1.755 + void (*sctp_ss_init_stream)(struct sctp_stream_out *strq, struct sctp_stream_out *with_strq); 1.756 + void (*sctp_ss_add_to_stream)(struct sctp_tcb *stcb, struct sctp_association *asoc, 1.757 + struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp, int holds_lock); 1.758 + int (*sctp_ss_is_empty)(struct sctp_tcb *stcb, struct sctp_association *asoc); 1.759 + void (*sctp_ss_remove_from_stream)(struct sctp_tcb *stcb, struct sctp_association *asoc, 1.760 + struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp, int holds_lock); 1.761 + struct sctp_stream_out* (*sctp_ss_select_stream)(struct sctp_tcb *stcb, 1.762 + struct sctp_nets *net, struct sctp_association *asoc); 1.763 + void (*sctp_ss_scheduled)(struct sctp_tcb *stcb, struct sctp_nets *net, 1.764 + struct sctp_association *asoc, struct sctp_stream_out *strq, int moved_how_much); 1.765 + void (*sctp_ss_packet_done)(struct sctp_tcb *stcb, struct sctp_nets *net, 1.766 + struct sctp_association *asoc); 1.767 + int (*sctp_ss_get_value)(struct sctp_tcb *stcb, struct sctp_association *asoc, 1.768 + struct sctp_stream_out *strq, uint16_t *value); 1.769 + int (*sctp_ss_set_value)(struct sctp_tcb *stcb, struct sctp_association *asoc, 1.770 + struct sctp_stream_out *strq, uint16_t value); 1.771 +}; 1.772 + 1.773 +/* used to save ASCONF chunks for retransmission */ 1.774 +TAILQ_HEAD(sctp_asconf_head, sctp_asconf); 1.775 +struct sctp_asconf { 1.776 + TAILQ_ENTRY(sctp_asconf) next; 1.777 + uint32_t serial_number; 1.778 + uint16_t snd_count; 1.779 + struct mbuf *data; 1.780 + uint16_t len; 1.781 +}; 1.782 + 1.783 +/* used to save ASCONF-ACK chunks for retransmission */ 1.784 +TAILQ_HEAD(sctp_asconf_ackhead, sctp_asconf_ack); 1.785 +struct sctp_asconf_ack { 1.786 + TAILQ_ENTRY(sctp_asconf_ack) next; 1.787 + uint32_t serial_number; 1.788 + struct sctp_nets *last_sent_to; 1.789 + struct mbuf *data; 1.790 + uint16_t len; 1.791 +}; 1.792 + 1.793 +/* 1.794 + * Here we have information about each individual association that we track. 1.795 + * We probably in production would be more dynamic. But for ease of 1.796 + * implementation we will have a fixed array that we hunt for in a linear 1.797 + * fashion. 1.798 + */ 1.799 +struct sctp_association { 1.800 + /* association state */ 1.801 + int state; 1.802 + 1.803 + /* queue of pending addrs to add/delete */ 1.804 + struct sctp_asconf_addrhead asconf_queue; 1.805 + 1.806 + struct timeval time_entered; /* time we entered state */ 1.807 + struct timeval time_last_rcvd; 1.808 + struct timeval time_last_sent; 1.809 + struct timeval time_last_sat_advance; 1.810 + struct sctp_nonpad_sndrcvinfo def_send; 1.811 + 1.812 + /* timers and such */ 1.813 + struct sctp_timer dack_timer; /* Delayed ack timer */ 1.814 + struct sctp_timer asconf_timer; /* asconf */ 1.815 + struct sctp_timer strreset_timer; /* stream reset */ 1.816 + struct sctp_timer shut_guard_timer; /* shutdown guard */ 1.817 + struct sctp_timer autoclose_timer; /* automatic close timer */ 1.818 + struct sctp_timer delayed_event_timer; /* timer for delayed events */ 1.819 + struct sctp_timer delete_prim_timer; /* deleting primary dst */ 1.820 + 1.821 + /* list of restricted local addresses */ 1.822 + struct sctpladdr sctp_restricted_addrs; 1.823 + 1.824 + /* last local address pending deletion (waiting for an address add) */ 1.825 + struct sctp_ifa *asconf_addr_del_pending; 1.826 + /* Deleted primary destination (used to stop timer) */ 1.827 + struct sctp_nets *deleted_primary; 1.828 + 1.829 + struct sctpnetlisthead nets; /* remote address list */ 1.830 + 1.831 + /* Free chunk list */ 1.832 + struct sctpchunk_listhead free_chunks; 1.833 + 1.834 + /* Control chunk queue */ 1.835 + struct sctpchunk_listhead control_send_queue; 1.836 + 1.837 + /* ASCONF chunk queue */ 1.838 + struct sctpchunk_listhead asconf_send_queue; 1.839 + 1.840 + /* 1.841 + * Once a TSN hits the wire it is moved to the sent_queue. We 1.842 + * maintain two counts here (don't know if any but retran_cnt is 1.843 + * needed). The idea is that the sent_queue_retran_cnt reflects how 1.844 + * many chunks have been marked for retranmission by either T3-rxt 1.845 + * or FR. 1.846 + */ 1.847 + struct sctpchunk_listhead sent_queue; 1.848 + struct sctpchunk_listhead send_queue; 1.849 + 1.850 + /* re-assembly queue for fragmented chunks on the inbound path */ 1.851 + struct sctpchunk_listhead reasmqueue; 1.852 + 1.853 + /* Scheduling queues */ 1.854 + union scheduling_data ss_data; 1.855 + 1.856 + /* This pointer will be set to NULL 1.857 + * most of the time. But when we have 1.858 + * a fragmented message, where we could 1.859 + * not get out all of the message at 1.860 + * the last send then this will point 1.861 + * to the stream to go get data from. 1.862 + */ 1.863 + struct sctp_stream_out *locked_on_sending; 1.864 + 1.865 + /* If an iterator is looking at me, this is it */ 1.866 + struct sctp_iterator *stcb_starting_point_for_iterator; 1.867 + 1.868 + /* ASCONF save the last ASCONF-ACK so we can resend it if necessary */ 1.869 + struct sctp_asconf_ackhead asconf_ack_sent; 1.870 + 1.871 + /* 1.872 + * pointer to last stream reset queued to control queue by us with 1.873 + * requests. 1.874 + */ 1.875 + struct sctp_tmit_chunk *str_reset; 1.876 + /* 1.877 + * if Source Address Selection happening, this will rotate through 1.878 + * the link list. 1.879 + */ 1.880 + struct sctp_laddr *last_used_address; 1.881 + 1.882 + /* stream arrays */ 1.883 + struct sctp_stream_in *strmin; 1.884 + struct sctp_stream_out *strmout; 1.885 + uint8_t *mapping_array; 1.886 + /* primary destination to use */ 1.887 + struct sctp_nets *primary_destination; 1.888 + struct sctp_nets *alternate; /* If primary is down or PF */ 1.889 + /* For CMT */ 1.890 + struct sctp_nets *last_net_cmt_send_started; 1.891 + /* last place I got a data chunk from */ 1.892 + struct sctp_nets *last_data_chunk_from; 1.893 + /* last place I got a control from */ 1.894 + struct sctp_nets *last_control_chunk_from; 1.895 + 1.896 + /* circular looking for output selection */ 1.897 + struct sctp_stream_out *last_out_stream; 1.898 + 1.899 + /* 1.900 + * wait to the point the cum-ack passes req->send_reset_at_tsn for 1.901 + * any req on the list. 1.902 + */ 1.903 + struct sctp_resethead resetHead; 1.904 + 1.905 + /* queue of chunks waiting to be sent into the local stack */ 1.906 + struct sctp_readhead pending_reply_queue; 1.907 + 1.908 + /* JRS - the congestion control functions are in this struct */ 1.909 + struct sctp_cc_functions cc_functions; 1.910 + /* JRS - value to store the currently loaded congestion control module */ 1.911 + uint32_t congestion_control_module; 1.912 + /* RS - the stream scheduling functions are in this struct */ 1.913 + struct sctp_ss_functions ss_functions; 1.914 + /* RS - value to store the currently loaded stream scheduling module */ 1.915 + uint32_t stream_scheduling_module; 1.916 + 1.917 + uint32_t vrf_id; 1.918 + 1.919 + uint32_t cookie_preserve_req; 1.920 + /* ASCONF next seq I am sending out, inits at init-tsn */ 1.921 + uint32_t asconf_seq_out; 1.922 + uint32_t asconf_seq_out_acked; 1.923 + /* ASCONF last received ASCONF from peer, starts at peer's TSN-1 */ 1.924 + uint32_t asconf_seq_in; 1.925 + 1.926 + /* next seq I am sending in str reset messages */ 1.927 + uint32_t str_reset_seq_out; 1.928 + /* next seq I am expecting in str reset messages */ 1.929 + uint32_t str_reset_seq_in; 1.930 + 1.931 + /* various verification tag information */ 1.932 + uint32_t my_vtag; /* The tag to be used. if assoc is re-initited 1.933 + * by remote end, and I have unlocked this 1.934 + * will be regenerated to a new random value. */ 1.935 + uint32_t peer_vtag; /* The peers last tag */ 1.936 + 1.937 + uint32_t my_vtag_nonce; 1.938 + uint32_t peer_vtag_nonce; 1.939 + 1.940 + uint32_t assoc_id; 1.941 + 1.942 + /* This is the SCTP fragmentation threshold */ 1.943 + uint32_t smallest_mtu; 1.944 + 1.945 + /* 1.946 + * Special hook for Fast retransmit, allows us to track the highest 1.947 + * TSN that is NEW in this SACK if gap ack blocks are present. 1.948 + */ 1.949 + uint32_t this_sack_highest_gap; 1.950 + 1.951 + /* 1.952 + * The highest consecutive TSN that has been acked by peer on my 1.953 + * sends 1.954 + */ 1.955 + uint32_t last_acked_seq; 1.956 + 1.957 + /* The next TSN that I will use in sending. */ 1.958 + uint32_t sending_seq; 1.959 + 1.960 + /* Original seq number I used ??questionable to keep?? */ 1.961 + uint32_t init_seq_number; 1.962 + 1.963 + 1.964 + /* The Advanced Peer Ack Point, as required by the PR-SCTP */ 1.965 + /* (A1 in Section 4.2) */ 1.966 + uint32_t advanced_peer_ack_point; 1.967 + 1.968 + /* 1.969 + * The highest consequetive TSN at the bottom of the mapping array 1.970 + * (for his sends). 1.971 + */ 1.972 + uint32_t cumulative_tsn; 1.973 + /* 1.974 + * Used to track the mapping array and its offset bits. This MAY be 1.975 + * lower then cumulative_tsn. 1.976 + */ 1.977 + uint32_t mapping_array_base_tsn; 1.978 + /* 1.979 + * used to track highest TSN we have received and is listed in the 1.980 + * mapping array. 1.981 + */ 1.982 + uint32_t highest_tsn_inside_map; 1.983 + 1.984 + /* EY - new NR variables used for nr_sack based on mapping_array*/ 1.985 + uint8_t *nr_mapping_array; 1.986 + uint32_t highest_tsn_inside_nr_map; 1.987 + 1.988 + uint32_t fast_recovery_tsn; 1.989 + uint32_t sat_t3_recovery_tsn; 1.990 + uint32_t tsn_last_delivered; 1.991 + /* 1.992 + * For the pd-api we should re-write this a bit more efficent. We 1.993 + * could have multiple sctp_queued_to_read's that we are building at 1.994 + * once. Now we only do this when we get ready to deliver to the 1.995 + * socket buffer. Note that we depend on the fact that the struct is 1.996 + * "stuck" on the read queue until we finish all the pd-api. 1.997 + */ 1.998 + struct sctp_queued_to_read *control_pdapi; 1.999 + 1.1000 + uint32_t tsn_of_pdapi_last_delivered; 1.1001 + uint32_t pdapi_ppid; 1.1002 + uint32_t context; 1.1003 + uint32_t last_reset_action[SCTP_MAX_RESET_PARAMS]; 1.1004 + uint32_t last_sending_seq[SCTP_MAX_RESET_PARAMS]; 1.1005 + uint32_t last_base_tsnsent[SCTP_MAX_RESET_PARAMS]; 1.1006 +#ifdef SCTP_ASOCLOG_OF_TSNS 1.1007 + /* 1.1008 + * special log - This adds considerable size 1.1009 + * to the asoc, but provides a log that you 1.1010 + * can use to detect problems via kgdb. 1.1011 + */ 1.1012 + struct sctp_tsn_log in_tsnlog[SCTP_TSN_LOG_SIZE]; 1.1013 + struct sctp_tsn_log out_tsnlog[SCTP_TSN_LOG_SIZE]; 1.1014 + uint32_t cumack_log[SCTP_TSN_LOG_SIZE]; 1.1015 + uint32_t cumack_logsnt[SCTP_TSN_LOG_SIZE]; 1.1016 + uint16_t tsn_in_at; 1.1017 + uint16_t tsn_out_at; 1.1018 + uint16_t tsn_in_wrapped; 1.1019 + uint16_t tsn_out_wrapped; 1.1020 + uint16_t cumack_log_at; 1.1021 + uint16_t cumack_log_atsnt; 1.1022 +#endif /* SCTP_ASOCLOG_OF_TSNS */ 1.1023 +#ifdef SCTP_FS_SPEC_LOG 1.1024 + struct sctp_fs_spec_log fslog[SCTP_FS_SPEC_LOG_SIZE]; 1.1025 + uint16_t fs_index; 1.1026 +#endif 1.1027 + 1.1028 + /* 1.1029 + * window state information and smallest MTU that I use to bound 1.1030 + * segmentation 1.1031 + */ 1.1032 + uint32_t peers_rwnd; 1.1033 + uint32_t my_rwnd; 1.1034 + uint32_t my_last_reported_rwnd; 1.1035 + uint32_t sctp_frag_point; 1.1036 + 1.1037 + uint32_t total_output_queue_size; 1.1038 + 1.1039 + uint32_t sb_cc; /* shadow of sb_cc */ 1.1040 + uint32_t sb_send_resv; /* amount reserved on a send */ 1.1041 + uint32_t my_rwnd_control_len; /* shadow of sb_mbcnt used for rwnd control */ 1.1042 +#ifdef INET6 1.1043 + uint32_t default_flowlabel; 1.1044 +#endif 1.1045 + uint32_t pr_sctp_cnt; 1.1046 + int ctrl_queue_cnt; /* could be removed REM - NO IT CAN'T!! RRS */ 1.1047 + /* 1.1048 + * All outbound datagrams queue into this list from the individual 1.1049 + * stream queue. Here they get assigned a TSN and then await 1.1050 + * sending. The stream seq comes when it is first put in the 1.1051 + * individual str queue 1.1052 + */ 1.1053 + unsigned int stream_queue_cnt; 1.1054 + unsigned int send_queue_cnt; 1.1055 + unsigned int sent_queue_cnt; 1.1056 + unsigned int sent_queue_cnt_removeable; 1.1057 + /* 1.1058 + * Number on sent queue that are marked for retran until this value 1.1059 + * is 0 we only send one packet of retran'ed data. 1.1060 + */ 1.1061 + unsigned int sent_queue_retran_cnt; 1.1062 + 1.1063 + unsigned int size_on_reasm_queue; 1.1064 + unsigned int cnt_on_reasm_queue; 1.1065 + unsigned int fwd_tsn_cnt; 1.1066 + /* amount of data (bytes) currently in flight (on all destinations) */ 1.1067 + unsigned int total_flight; 1.1068 + /* Total book size in flight */ 1.1069 + unsigned int total_flight_count; /* count of chunks used with 1.1070 + * book total */ 1.1071 + /* count of destinaton nets and list of destination nets */ 1.1072 + unsigned int numnets; 1.1073 + 1.1074 + /* Total error count on this association */ 1.1075 + unsigned int overall_error_count; 1.1076 + 1.1077 + unsigned int cnt_msg_on_sb; 1.1078 + 1.1079 + /* All stream count of chunks for delivery */ 1.1080 + unsigned int size_on_all_streams; 1.1081 + unsigned int cnt_on_all_streams; 1.1082 + 1.1083 + /* Heart Beat delay in ms */ 1.1084 + uint32_t heart_beat_delay; 1.1085 + 1.1086 + /* autoclose */ 1.1087 + unsigned int sctp_autoclose_ticks; 1.1088 + 1.1089 + /* how many preopen streams we have */ 1.1090 + unsigned int pre_open_streams; 1.1091 + 1.1092 + /* How many streams I support coming into me */ 1.1093 + unsigned int max_inbound_streams; 1.1094 + 1.1095 + /* the cookie life I award for any cookie, in seconds */ 1.1096 + unsigned int cookie_life; 1.1097 + /* time to delay acks for */ 1.1098 + unsigned int delayed_ack; 1.1099 + unsigned int old_delayed_ack; 1.1100 + unsigned int sack_freq; 1.1101 + unsigned int data_pkts_seen; 1.1102 + 1.1103 + unsigned int numduptsns; 1.1104 + int dup_tsns[SCTP_MAX_DUP_TSNS]; 1.1105 + unsigned int initial_init_rto_max; /* initial RTO for INIT's */ 1.1106 + unsigned int initial_rto; /* initial send RTO */ 1.1107 + unsigned int minrto; /* per assoc RTO-MIN */ 1.1108 + unsigned int maxrto; /* per assoc RTO-MAX */ 1.1109 + 1.1110 + /* authentication fields */ 1.1111 + sctp_auth_chklist_t *local_auth_chunks; 1.1112 + sctp_auth_chklist_t *peer_auth_chunks; 1.1113 + sctp_hmaclist_t *local_hmacs; /* local HMACs supported */ 1.1114 + sctp_hmaclist_t *peer_hmacs; /* peer HMACs supported */ 1.1115 + struct sctp_keyhead shared_keys; /* assoc's shared keys */ 1.1116 + sctp_authinfo_t authinfo; /* randoms, cached keys */ 1.1117 + /* 1.1118 + * refcnt to block freeing when a sender or receiver is off coping 1.1119 + * user data in. 1.1120 + */ 1.1121 + uint32_t refcnt; 1.1122 + uint32_t chunks_on_out_queue; /* total chunks floating around, 1.1123 + * locked by send socket buffer */ 1.1124 + uint32_t peers_adaptation; 1.1125 + uint16_t peer_hmac_id; /* peer HMAC id to send */ 1.1126 + 1.1127 + /* 1.1128 + * Being that we have no bag to collect stale cookies, and that we 1.1129 + * really would not want to anyway.. we will count them in this 1.1130 + * counter. We of course feed them to the pigeons right away (I have 1.1131 + * always thought of pigeons as flying rats). 1.1132 + */ 1.1133 + uint16_t stale_cookie_count; 1.1134 + 1.1135 + /* 1.1136 + * For the partial delivery API, if up, invoked this is what last 1.1137 + * TSN I delivered 1.1138 + */ 1.1139 + uint16_t str_of_pdapi; 1.1140 + uint16_t ssn_of_pdapi; 1.1141 + 1.1142 + /* counts of actual built streams. Allocation may be more however */ 1.1143 + /* could re-arrange to optimize space here. */ 1.1144 + uint16_t streamincnt; 1.1145 + uint16_t streamoutcnt; 1.1146 + uint16_t strm_realoutsize; 1.1147 + uint16_t strm_pending_add_size; 1.1148 + /* my maximum number of retrans of INIT and SEND */ 1.1149 + /* copied from SCTP but should be individually setable */ 1.1150 + uint16_t max_init_times; 1.1151 + uint16_t max_send_times; 1.1152 + 1.1153 + uint16_t def_net_failure; 1.1154 + 1.1155 + uint16_t def_net_pf_threshold; 1.1156 + 1.1157 + /* 1.1158 + * lock flag: 0 is ok to send, 1+ (duals as a retran count) is 1.1159 + * awaiting ACK 1.1160 + */ 1.1161 + uint16_t mapping_array_size; 1.1162 + 1.1163 + uint16_t last_strm_seq_delivered; 1.1164 + uint16_t last_strm_no_delivered; 1.1165 + 1.1166 + uint16_t last_revoke_count; 1.1167 + int16_t num_send_timers_up; 1.1168 + 1.1169 + uint16_t stream_locked_on; 1.1170 + uint16_t ecn_echo_cnt_onq; 1.1171 + 1.1172 + uint16_t free_chunk_cnt; 1.1173 + uint8_t stream_locked; 1.1174 + uint8_t authenticated; /* packet authenticated ok */ 1.1175 + /* 1.1176 + * This flag indicates that a SACK need to be sent. 1.1177 + * Initially this is 1 to send the first sACK immediately. 1.1178 + */ 1.1179 + uint8_t send_sack; 1.1180 + 1.1181 + /* max burst of new packets into the network */ 1.1182 + uint32_t max_burst; 1.1183 + /* max burst of fast retransmit packets */ 1.1184 + uint32_t fr_max_burst; 1.1185 + 1.1186 + uint8_t sat_network; /* RTT is in range of sat net or greater */ 1.1187 + uint8_t sat_network_lockout; /* lockout code */ 1.1188 + uint8_t burst_limit_applied; /* Burst limit in effect at last send? */ 1.1189 + /* flag goes on when we are doing a partial delivery api */ 1.1190 + uint8_t hb_random_values[4]; 1.1191 + uint8_t fragmented_delivery_inprogress; 1.1192 + uint8_t fragment_flags; 1.1193 + uint8_t last_flags_delivered; 1.1194 + uint8_t hb_ect_randombit; 1.1195 + uint8_t hb_random_idx; 1.1196 + uint8_t default_dscp; 1.1197 + uint8_t asconf_del_pending; /* asconf delete last addr pending */ 1.1198 + 1.1199 + /* 1.1200 + * This value, plus all other ack'd but above cum-ack is added 1.1201 + * together to cross check against the bit that we have yet to 1.1202 + * define (probably in the SACK). When the cum-ack is updated, this 1.1203 + * sum is updated as well. 1.1204 + */ 1.1205 + 1.1206 + /* Flag to tell if ECN is allowed */ 1.1207 + uint8_t ecn_allowed; 1.1208 + 1.1209 + /* Did the peer make the stream config (add out) request */ 1.1210 + uint8_t peer_req_out; 1.1211 + 1.1212 + /* flag to indicate if peer can do asconf */ 1.1213 + uint8_t peer_supports_asconf; 1.1214 + /* EY - flag to indicate if peer can do nr_sack*/ 1.1215 + uint8_t peer_supports_nr_sack; 1.1216 + /* pr-sctp support flag */ 1.1217 + uint8_t peer_supports_prsctp; 1.1218 + /* peer authentication support flag */ 1.1219 + uint8_t peer_supports_auth; 1.1220 + /* stream resets are supported by the peer */ 1.1221 + uint8_t peer_supports_strreset; 1.1222 + uint8_t local_strreset_support; 1.1223 + 1.1224 + uint8_t peer_supports_nat; 1.1225 + /* 1.1226 + * packet drop's are supported by the peer, we don't really care 1.1227 + * about this but we bookkeep it anyway. 1.1228 + */ 1.1229 + uint8_t peer_supports_pktdrop; 1.1230 + 1.1231 + struct sctp_scoping scope; 1.1232 + /* flags to handle send alternate net tracking */ 1.1233 + uint8_t used_alt_onsack; 1.1234 + uint8_t used_alt_asconfack; 1.1235 + uint8_t fast_retran_loss_recovery; 1.1236 + uint8_t sat_t3_loss_recovery; 1.1237 + uint8_t dropped_special_cnt; 1.1238 + uint8_t seen_a_sack_this_pkt; 1.1239 + uint8_t stream_reset_outstanding; 1.1240 + uint8_t stream_reset_out_is_outstanding; 1.1241 + uint8_t delayed_connection; 1.1242 + uint8_t ifp_had_enobuf; 1.1243 + uint8_t saw_sack_with_frags; 1.1244 + uint8_t saw_sack_with_nr_frags; 1.1245 + uint8_t in_asocid_hash; 1.1246 + uint8_t assoc_up_sent; 1.1247 + uint8_t adaptation_needed; 1.1248 + uint8_t adaptation_sent; 1.1249 + /* CMT variables */ 1.1250 + uint8_t cmt_dac_pkts_rcvd; 1.1251 + uint8_t sctp_cmt_on_off; 1.1252 + uint8_t iam_blocking; 1.1253 + uint8_t cookie_how[8]; 1.1254 + /* EY 05/05/08 - NR_SACK variable*/ 1.1255 + uint8_t sctp_nr_sack_on_off; 1.1256 + /* JRS 5/21/07 - CMT PF variable */ 1.1257 + uint8_t sctp_cmt_pf; 1.1258 + uint8_t use_precise_time; 1.1259 + uint64_t sctp_features; 1.1260 + uint16_t port; /* remote UDP encapsulation port */ 1.1261 + /* 1.1262 + * The mapping array is used to track out of order sequences above 1.1263 + * last_acked_seq. 0 indicates packet missing 1 indicates packet 1.1264 + * rec'd. We slide it up every time we raise last_acked_seq and 0 1.1265 + * trailing locactions out. If I get a TSN above the array 1.1266 + * mappingArraySz, I discard the datagram and let retransmit happen. 1.1267 + */ 1.1268 + uint32_t marked_retrans; 1.1269 + uint32_t timoinit; 1.1270 + uint32_t timodata; 1.1271 + uint32_t timosack; 1.1272 + uint32_t timoshutdown; 1.1273 + uint32_t timoheartbeat; 1.1274 + uint32_t timocookie; 1.1275 + uint32_t timoshutdownack; 1.1276 + struct timeval start_time; 1.1277 + struct timeval discontinuity_time; 1.1278 +}; 1.1279 + 1.1280 +#endif