James Kuszmaul | 4cb043c | 2021-01-17 11:25:51 -0800 | [diff] [blame^] | 1 | /*- |
| 2 | * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. |
| 3 | * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. |
| 4 | * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions are met: |
| 8 | * |
| 9 | * a) Redistributions of source code must retain the above copyright notice, |
| 10 | * this list of conditions and the following disclaimer. |
| 11 | * |
| 12 | * b) Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in |
| 14 | * the documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * c) Neither the name of Cisco Systems, Inc. nor the names of its |
| 17 | * contributors may be used to endorse or promote products derived |
| 18 | * from this software without specific prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 22 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 30 | * THE POSSIBILITY OF SUCH DAMAGE. |
| 31 | */ |
| 32 | |
| 33 | #ifdef __FreeBSD__ |
| 34 | #include <sys/cdefs.h> |
| 35 | __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 310590 2016-12-26 11:06:41Z tuexen $"); |
| 36 | #endif |
| 37 | |
| 38 | #ifndef _NETINET_SCTP_PCB_H_ |
| 39 | #define _NETINET_SCTP_PCB_H_ |
| 40 | |
| 41 | #include <netinet/sctp_os.h> |
| 42 | #include <netinet/sctp.h> |
| 43 | #include <netinet/sctp_constants.h> |
| 44 | #include <netinet/sctp_sysctl.h> |
| 45 | |
| 46 | LIST_HEAD(sctppcbhead, sctp_inpcb); |
| 47 | LIST_HEAD(sctpasochead, sctp_tcb); |
| 48 | LIST_HEAD(sctpladdr, sctp_laddr); |
| 49 | LIST_HEAD(sctpvtaghead, sctp_tagblock); |
| 50 | LIST_HEAD(sctp_vrflist, sctp_vrf); |
| 51 | LIST_HEAD(sctp_ifnlist, sctp_ifn); |
| 52 | LIST_HEAD(sctp_ifalist, sctp_ifa); |
| 53 | TAILQ_HEAD(sctp_readhead, sctp_queued_to_read); |
| 54 | TAILQ_HEAD(sctp_streamhead, sctp_stream_queue_pending); |
| 55 | |
| 56 | #include <netinet/sctp_structs.h> |
| 57 | #include <netinet/sctp_auth.h> |
| 58 | |
| 59 | #define SCTP_PCBHASH_ALLADDR(port, mask) (port & mask) |
| 60 | #define SCTP_PCBHASH_ASOC(tag, mask) (tag & mask) |
| 61 | #define MAXLEN_MBUF_CHAIN 32 |
| 62 | |
| 63 | struct sctp_vrf { |
| 64 | LIST_ENTRY (sctp_vrf) next_vrf; |
| 65 | struct sctp_ifalist *vrf_addr_hash; |
| 66 | struct sctp_ifnlist ifnlist; |
| 67 | uint32_t vrf_id; |
| 68 | uint32_t tbl_id_v4; /* default v4 table id */ |
| 69 | uint32_t tbl_id_v6; /* default v6 table id */ |
| 70 | uint32_t total_ifa_count; |
| 71 | u_long vrf_addr_hashmark; |
| 72 | uint32_t refcount; |
| 73 | }; |
| 74 | |
| 75 | struct sctp_ifn { |
| 76 | struct sctp_ifalist ifalist; |
| 77 | struct sctp_vrf *vrf; |
| 78 | LIST_ENTRY(sctp_ifn) next_ifn; |
| 79 | LIST_ENTRY(sctp_ifn) next_bucket; |
| 80 | void *ifn_p; /* never access without appropriate lock */ |
| 81 | uint32_t ifn_mtu; |
| 82 | uint32_t ifn_type; |
| 83 | uint32_t ifn_index; /* shorthand way to look at ifn for reference */ |
| 84 | uint32_t refcount; /* number of reference held should be >= ifa_count */ |
| 85 | uint32_t ifa_count; /* IFA's we hold (in our list - ifalist)*/ |
| 86 | uint32_t num_v6; /* number of v6 addresses */ |
| 87 | uint32_t num_v4; /* number of v4 addresses */ |
| 88 | uint32_t registered_af; /* registered address family for i/f events */ |
| 89 | char ifn_name[SCTP_IFNAMSIZ]; |
| 90 | }; |
| 91 | |
| 92 | /* SCTP local IFA flags */ |
| 93 | #define SCTP_ADDR_VALID 0x00000001 /* its up and active */ |
| 94 | #define SCTP_BEING_DELETED 0x00000002 /* being deleted, |
| 95 | * when refcount = 0. Note |
| 96 | * that it is pulled from the ifn list |
| 97 | * and ifa_p is nulled right away but |
| 98 | * it cannot be freed until the last *net |
| 99 | * pointing to it is deleted. |
| 100 | */ |
| 101 | #define SCTP_ADDR_DEFER_USE 0x00000004 /* Hold off using this one */ |
| 102 | #define SCTP_ADDR_IFA_UNUSEABLE 0x00000008 |
| 103 | |
| 104 | struct sctp_ifa { |
| 105 | LIST_ENTRY(sctp_ifa) next_ifa; |
| 106 | LIST_ENTRY(sctp_ifa) next_bucket; |
| 107 | struct sctp_ifn *ifn_p; /* back pointer to parent ifn */ |
| 108 | void *ifa; /* pointer to ifa, needed for flag |
| 109 | * update for that we MUST lock |
| 110 | * appropriate locks. This is for V6. |
| 111 | */ |
| 112 | union sctp_sockstore address; |
| 113 | uint32_t refcount; /* number of folks referring to this */ |
| 114 | uint32_t flags; |
| 115 | uint32_t localifa_flags; |
| 116 | uint32_t vrf_id; /* vrf_id of this addr (for deleting) */ |
| 117 | uint8_t src_is_loop; |
| 118 | uint8_t src_is_priv; |
| 119 | uint8_t src_is_glob; |
| 120 | uint8_t resv; |
| 121 | }; |
| 122 | |
| 123 | struct sctp_laddr { |
| 124 | LIST_ENTRY(sctp_laddr) sctp_nxt_addr; /* next in list */ |
| 125 | struct sctp_ifa *ifa; |
| 126 | uint32_t action; /* Used during asconf and adding |
| 127 | * if no-zero src-addr selection will |
| 128 | * not consider this address. |
| 129 | */ |
| 130 | struct timeval start_time; /* time when this address was created */ |
| 131 | }; |
| 132 | |
| 133 | struct sctp_block_entry { |
| 134 | int error; |
| 135 | }; |
| 136 | |
| 137 | struct sctp_timewait { |
| 138 | uint32_t tv_sec_at_expire; /* the seconds from boot to expire */ |
| 139 | uint32_t v_tag; /* the vtag that can not be reused */ |
| 140 | uint16_t lport; /* the local port used in vtag */ |
| 141 | uint16_t rport; /* the remote port used in vtag */ |
| 142 | }; |
| 143 | |
| 144 | struct sctp_tagblock { |
| 145 | LIST_ENTRY(sctp_tagblock) sctp_nxt_tagblock; |
| 146 | struct sctp_timewait vtag_block[SCTP_NUMBER_IN_VTAG_BLOCK]; |
| 147 | }; |
| 148 | |
| 149 | |
| 150 | struct sctp_epinfo { |
| 151 | #if defined(__FreeBSD__) |
| 152 | #ifdef INET |
| 153 | struct socket *udp4_tun_socket; |
| 154 | #endif |
| 155 | #ifdef INET6 |
| 156 | struct socket *udp6_tun_socket; |
| 157 | #endif |
| 158 | #endif |
| 159 | struct sctpasochead *sctp_asochash; |
| 160 | u_long hashasocmark; |
| 161 | |
| 162 | struct sctppcbhead *sctp_ephash; |
| 163 | u_long hashmark; |
| 164 | |
| 165 | /*- |
| 166 | * The TCP model represents a substantial overhead in that we get an |
| 167 | * additional hash table to keep explicit connections in. The |
| 168 | * listening TCP endpoint will exist in the usual ephash above and |
| 169 | * accept only INIT's. It will be incapable of sending off an INIT. |
| 170 | * When a dg arrives we must look in the normal ephash. If we find a |
| 171 | * TCP endpoint that will tell us to go to the specific endpoint |
| 172 | * hash and re-hash to find the right assoc/socket. If we find a UDP |
| 173 | * model socket we then must complete the lookup. If this fails, |
| 174 | * i.e. no association can be found then we must continue to see if |
| 175 | * a sctp_peeloff()'d socket is in the tcpephash (a spun off socket |
| 176 | * acts like a TCP model connected socket). |
| 177 | */ |
| 178 | struct sctppcbhead *sctp_tcpephash; |
| 179 | u_long hashtcpmark; |
| 180 | uint32_t hashtblsize; |
| 181 | |
| 182 | struct sctp_vrflist *sctp_vrfhash; |
| 183 | u_long hashvrfmark; |
| 184 | |
| 185 | struct sctp_ifnlist *vrf_ifn_hash; |
| 186 | u_long vrf_ifn_hashmark; |
| 187 | |
| 188 | struct sctppcbhead listhead; |
| 189 | struct sctpladdr addr_wq; |
| 190 | |
| 191 | #if defined(__APPLE__) |
| 192 | struct inpcbhead inplisthead; |
| 193 | struct inpcbinfo sctbinfo; |
| 194 | #endif |
| 195 | /* ep zone info */ |
| 196 | sctp_zone_t ipi_zone_ep; |
| 197 | sctp_zone_t ipi_zone_asoc; |
| 198 | sctp_zone_t ipi_zone_laddr; |
| 199 | sctp_zone_t ipi_zone_net; |
| 200 | sctp_zone_t ipi_zone_chunk; |
| 201 | sctp_zone_t ipi_zone_readq; |
| 202 | sctp_zone_t ipi_zone_strmoq; |
| 203 | sctp_zone_t ipi_zone_asconf; |
| 204 | sctp_zone_t ipi_zone_asconf_ack; |
| 205 | |
| 206 | #if defined(__FreeBSD__) && __FreeBSD_version >= 503000 |
| 207 | #if __FreeBSD_version <= 602000 |
| 208 | struct mtx ipi_ep_mtx; |
| 209 | #else |
| 210 | struct rwlock ipi_ep_mtx; |
| 211 | #endif |
| 212 | struct mtx ipi_iterator_wq_mtx; |
| 213 | #if __FreeBSD_version <= 602000 |
| 214 | struct mtx ipi_addr_mtx; |
| 215 | #else |
| 216 | struct rwlock ipi_addr_mtx; |
| 217 | #endif |
| 218 | struct mtx ipi_pktlog_mtx; |
| 219 | struct mtx wq_addr_mtx; |
| 220 | #elif defined(SCTP_PROCESS_LEVEL_LOCKS) |
| 221 | userland_mutex_t ipi_ep_mtx; |
| 222 | userland_mutex_t ipi_addr_mtx; |
| 223 | userland_mutex_t ipi_count_mtx; |
| 224 | userland_mutex_t ipi_pktlog_mtx; |
| 225 | userland_mutex_t wq_addr_mtx; |
| 226 | #elif defined(__APPLE__) |
| 227 | #ifdef _KERN_LOCKS_H_ |
| 228 | lck_mtx_t *ipi_addr_mtx; |
| 229 | lck_mtx_t *ipi_count_mtx; |
| 230 | lck_mtx_t *ipi_pktlog_mtx; |
| 231 | lck_mtx_t *logging_mtx; |
| 232 | lck_mtx_t *wq_addr_mtx; |
| 233 | #else |
| 234 | void *ipi_count_mtx; |
| 235 | void *logging_mtx; |
| 236 | #endif /* _KERN_LOCKS_H_ */ |
| 237 | #elif defined(__Windows__) |
| 238 | struct rwlock ipi_ep_lock; |
| 239 | struct rwlock ipi_addr_lock; |
| 240 | struct spinlock ipi_pktlog_mtx; |
| 241 | struct rwlock wq_addr_mtx; |
| 242 | #elif defined(__Userspace__) |
| 243 | /* TODO decide on __Userspace__ locks */ |
| 244 | #endif |
| 245 | uint32_t ipi_count_ep; |
| 246 | |
| 247 | /* assoc/tcb zone info */ |
| 248 | uint32_t ipi_count_asoc; |
| 249 | |
| 250 | /* local addrlist zone info */ |
| 251 | uint32_t ipi_count_laddr; |
| 252 | |
| 253 | /* remote addrlist zone info */ |
| 254 | uint32_t ipi_count_raddr; |
| 255 | |
| 256 | /* chunk structure list for output */ |
| 257 | uint32_t ipi_count_chunk; |
| 258 | |
| 259 | /* socket queue zone info */ |
| 260 | uint32_t ipi_count_readq; |
| 261 | |
| 262 | /* socket queue zone info */ |
| 263 | uint32_t ipi_count_strmoq; |
| 264 | |
| 265 | /* Number of vrfs */ |
| 266 | uint32_t ipi_count_vrfs; |
| 267 | |
| 268 | /* Number of ifns */ |
| 269 | uint32_t ipi_count_ifns; |
| 270 | |
| 271 | /* Number of ifas */ |
| 272 | uint32_t ipi_count_ifas; |
| 273 | |
| 274 | /* system wide number of free chunks hanging around */ |
| 275 | uint32_t ipi_free_chunks; |
| 276 | uint32_t ipi_free_strmoq; |
| 277 | |
| 278 | struct sctpvtaghead vtag_timewait[SCTP_STACK_VTAG_HASH_SIZE]; |
| 279 | |
| 280 | /* address work queue handling */ |
| 281 | struct sctp_timer addr_wq_timer; |
| 282 | |
| 283 | #if defined(_SCTP_NEEDS_CALLOUT_) || defined(_USER_SCTP_NEEDS_CALLOUT_) |
| 284 | struct calloutlist callqueue; |
| 285 | #endif |
| 286 | }; |
| 287 | |
| 288 | |
| 289 | struct sctp_base_info { |
| 290 | /* All static structures that |
| 291 | * anchor the system must be here. |
| 292 | */ |
| 293 | struct sctp_epinfo sctppcbinfo; |
| 294 | #if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT) |
| 295 | struct sctpstat *sctpstat; |
| 296 | #else |
| 297 | struct sctpstat sctpstat; |
| 298 | #endif |
| 299 | struct sctp_sysctl sctpsysctl; |
| 300 | uint8_t first_time; |
| 301 | char sctp_pcb_initialized; |
| 302 | #if defined(SCTP_PACKET_LOGGING) |
| 303 | int packet_log_writers; |
| 304 | int packet_log_end; |
| 305 | uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE]; |
| 306 | #endif |
| 307 | #if defined(__APPLE__) |
| 308 | int sctp_main_timer_ticks; |
| 309 | #endif |
| 310 | #if defined(__Userspace__) |
| 311 | userland_mutex_t timer_mtx; |
| 312 | userland_thread_t timer_thread; |
| 313 | uint8_t timer_thread_should_exit; |
| 314 | #if !defined(__Userspace_os_Windows) |
| 315 | pthread_mutexattr_t mtx_attr; |
| 316 | #if defined(INET) || defined(INET6) |
| 317 | int userspace_route; |
| 318 | userland_thread_t recvthreadroute; |
| 319 | #endif |
| 320 | #endif |
| 321 | #ifdef INET |
| 322 | #if defined(__Userspace_os_Windows) |
| 323 | SOCKET userspace_rawsctp; |
| 324 | SOCKET userspace_udpsctp; |
| 325 | #else |
| 326 | int userspace_rawsctp; |
| 327 | int userspace_udpsctp; |
| 328 | #endif |
| 329 | userland_thread_t recvthreadraw; |
| 330 | userland_thread_t recvthreadudp; |
| 331 | #if !defined(THREAD_SUPPORT) |
| 332 | struct mbuf **recvmbuf4; |
| 333 | int to_fill4; |
| 334 | struct mbuf **recvmbuf6; |
| 335 | int to_fill6; |
| 336 | struct mbuf **udp_recvmbuf4; |
| 337 | int udp_to_fill4; |
| 338 | struct mbuf **udp_recvmbuf6; |
| 339 | int udp_to_fill6; |
| 340 | #if !defined(__Userspace_os_Windows) |
| 341 | struct iovec recv_iovec4[MAXLEN_MBUF_CHAIN]; |
| 342 | struct iovec recv_iovec6[MAXLEN_MBUF_CHAIN]; |
| 343 | struct iovec udp_recv_iovec4[MAXLEN_MBUF_CHAIN]; |
| 344 | struct iovec udp_recv_iovec6[MAXLEN_MBUF_CHAIN]; |
| 345 | #else |
| 346 | WSABUF *rcv_iovec4; |
| 347 | WSABUF *rcv_iovec6; |
| 348 | WSABUF *udp_rcv_iovec4; |
| 349 | WSABUF *udp_rcv_iovec6; |
| 350 | #endif |
| 351 | #endif |
| 352 | #endif |
| 353 | #ifdef INET6 |
| 354 | #if defined(__Userspace_os_Windows) |
| 355 | SOCKET userspace_rawsctp6; |
| 356 | SOCKET userspace_udpsctp6; |
| 357 | #else |
| 358 | int userspace_rawsctp6; |
| 359 | int userspace_udpsctp6; |
| 360 | #endif |
| 361 | userland_thread_t recvthreadraw6; |
| 362 | userland_thread_t recvthreadudp6; |
| 363 | #endif |
| 364 | int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df); |
| 365 | void (*debug_printf)(const char *format, ...); |
| 366 | int crc32c_offloaded; |
| 367 | #endif |
| 368 | }; |
| 369 | |
| 370 | /*- |
| 371 | * Here we have all the relevant information for each SCTP entity created. We |
| 372 | * will need to modify this as approprate. We also need to figure out how to |
| 373 | * access /dev/random. |
| 374 | */ |
| 375 | struct sctp_pcb { |
| 376 | unsigned int time_of_secret_change; /* number of seconds from |
| 377 | * timeval.tv_sec */ |
| 378 | uint32_t secret_key[SCTP_HOW_MANY_SECRETS][SCTP_NUMBER_OF_SECRETS]; |
| 379 | unsigned int size_of_a_cookie; |
| 380 | |
| 381 | unsigned int sctp_timeoutticks[SCTP_NUM_TMRS]; |
| 382 | unsigned int sctp_minrto; |
| 383 | unsigned int sctp_maxrto; |
| 384 | unsigned int initial_rto; |
| 385 | int initial_init_rto_max; |
| 386 | |
| 387 | unsigned int sctp_sack_freq; |
| 388 | uint32_t sctp_sws_sender; |
| 389 | uint32_t sctp_sws_receiver; |
| 390 | |
| 391 | uint32_t sctp_default_cc_module; |
| 392 | uint32_t sctp_default_ss_module; |
| 393 | /* authentication related fields */ |
| 394 | struct sctp_keyhead shared_keys; |
| 395 | sctp_auth_chklist_t *local_auth_chunks; |
| 396 | sctp_hmaclist_t *local_hmacs; |
| 397 | uint16_t default_keyid; |
| 398 | |
| 399 | /* various thresholds */ |
| 400 | /* Max times I will init at a guy */ |
| 401 | uint16_t max_init_times; |
| 402 | |
| 403 | /* Max times I will send before we consider someone dead */ |
| 404 | uint16_t max_send_times; |
| 405 | |
| 406 | uint16_t def_net_failure; |
| 407 | |
| 408 | uint16_t def_net_pf_threshold; |
| 409 | |
| 410 | /* number of streams to pre-open on a association */ |
| 411 | uint16_t pre_open_stream_count; |
| 412 | uint16_t max_open_streams_intome; |
| 413 | |
| 414 | /* random number generator */ |
| 415 | uint32_t random_counter; |
| 416 | uint8_t random_numbers[SCTP_SIGNATURE_ALOC_SIZE]; |
| 417 | uint8_t random_store[SCTP_SIGNATURE_ALOC_SIZE]; |
| 418 | |
| 419 | /* |
| 420 | * This timer is kept running per endpoint. When it fires it will |
| 421 | * change the secret key. The default is once a hour |
| 422 | */ |
| 423 | struct sctp_timer signature_change; |
| 424 | |
| 425 | /* Zero copy full buffer timer */ |
| 426 | struct sctp_timer zero_copy_timer; |
| 427 | /* Zero copy app to transport (sendq) read repulse timer */ |
| 428 | struct sctp_timer zero_copy_sendq_timer; |
| 429 | uint32_t def_cookie_life; |
| 430 | /* defaults to 0 */ |
| 431 | int auto_close_time; |
| 432 | uint32_t initial_sequence_debug; |
| 433 | uint32_t adaptation_layer_indicator; |
| 434 | uint8_t adaptation_layer_indicator_provided; |
| 435 | uint32_t store_at; |
| 436 | uint32_t max_burst; |
| 437 | uint32_t fr_max_burst; |
| 438 | #ifdef INET6 |
| 439 | uint32_t default_flowlabel; |
| 440 | #endif |
| 441 | uint8_t default_dscp; |
| 442 | char current_secret_number; |
| 443 | char last_secret_number; |
| 444 | uint16_t port; /* remote UDP encapsulation port */ |
| 445 | }; |
| 446 | |
| 447 | #ifndef SCTP_ALIGNMENT |
| 448 | #define SCTP_ALIGNMENT 32 |
| 449 | #endif |
| 450 | |
| 451 | #ifndef SCTP_ALIGNM1 |
| 452 | #define SCTP_ALIGNM1 (SCTP_ALIGNMENT-1) |
| 453 | #endif |
| 454 | |
| 455 | #define sctp_lport ip_inp.inp.inp_lport |
| 456 | |
| 457 | struct sctp_pcbtsn_rlog { |
| 458 | uint32_t vtag; |
| 459 | uint16_t strm; |
| 460 | uint16_t seq; |
| 461 | uint16_t sz; |
| 462 | uint16_t flgs; |
| 463 | }; |
| 464 | #define SCTP_READ_LOG_SIZE 135 /* we choose the number to make a pcb a page */ |
| 465 | |
| 466 | |
| 467 | struct sctp_inpcb { |
| 468 | /*- |
| 469 | * put an inpcb in front of it all, kind of a waste but we need to |
| 470 | * for compatibility with all the other stuff. |
| 471 | */ |
| 472 | union { |
| 473 | struct inpcb inp; |
| 474 | char align[(sizeof(struct in6pcb) + SCTP_ALIGNM1) & |
| 475 | ~SCTP_ALIGNM1]; |
| 476 | } ip_inp; |
| 477 | |
| 478 | #if defined(__APPLE__) |
| 479 | /* leave some space in case i386 inpcb is bigger than ppc */ |
| 480 | uint8_t padding[128]; |
| 481 | #endif |
| 482 | |
| 483 | /* Socket buffer lock protects read_queue and of course sb_cc */ |
| 484 | struct sctp_readhead read_queue; |
| 485 | |
| 486 | LIST_ENTRY(sctp_inpcb) sctp_list; /* lists all endpoints */ |
| 487 | /* hash of all endpoints for model */ |
| 488 | LIST_ENTRY(sctp_inpcb) sctp_hash; |
| 489 | /* count of local addresses bound, 0 if bound all */ |
| 490 | int laddr_count; |
| 491 | |
| 492 | /* list of addrs in use by the EP, NULL if bound-all */ |
| 493 | struct sctpladdr sctp_addr_list; |
| 494 | /* used for source address selection rotation when we are subset bound */ |
| 495 | struct sctp_laddr *next_addr_touse; |
| 496 | |
| 497 | /* back pointer to our socket */ |
| 498 | struct socket *sctp_socket; |
| 499 | uint64_t sctp_features; /* Feature flags */ |
| 500 | uint32_t sctp_flags; /* INP state flag set */ |
| 501 | uint32_t sctp_mobility_features; /* Mobility Feature flags */ |
| 502 | struct sctp_pcb sctp_ep;/* SCTP ep data */ |
| 503 | /* head of the hash of all associations */ |
| 504 | struct sctpasochead *sctp_tcbhash; |
| 505 | u_long sctp_hashmark; |
| 506 | /* head of the list of all associations */ |
| 507 | struct sctpasochead sctp_asoc_list; |
| 508 | #ifdef SCTP_TRACK_FREED_ASOCS |
| 509 | struct sctpasochead sctp_asoc_free_list; |
| 510 | #endif |
| 511 | struct sctp_iterator *inp_starting_point_for_iterator; |
| 512 | uint32_t sctp_frag_point; |
| 513 | uint32_t partial_delivery_point; |
| 514 | uint32_t sctp_context; |
| 515 | uint32_t max_cwnd; |
| 516 | uint8_t local_strreset_support; |
| 517 | uint32_t sctp_cmt_on_off; |
| 518 | uint8_t ecn_supported; |
| 519 | uint8_t prsctp_supported; |
| 520 | uint8_t auth_supported; |
| 521 | uint8_t idata_supported; |
| 522 | uint8_t asconf_supported; |
| 523 | uint8_t reconfig_supported; |
| 524 | uint8_t nrsack_supported; |
| 525 | uint8_t pktdrop_supported; |
| 526 | struct sctp_nonpad_sndrcvinfo def_send; |
| 527 | /*- |
| 528 | * These three are here for the sosend_dgram |
| 529 | * (pkt, pkt_last and control). |
| 530 | * routine. However, I don't think anyone in |
| 531 | * the current FreeBSD kernel calls this. So |
| 532 | * they are candidates with sctp_sendm for |
| 533 | * de-supporting. |
| 534 | */ |
| 535 | #ifdef __Panda__ |
| 536 | pakhandle_type pak_to_read; |
| 537 | pakhandle_type pak_to_read_sendq; |
| 538 | #endif |
| 539 | struct mbuf *pkt, *pkt_last; |
| 540 | struct mbuf *control; |
| 541 | #if !(defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__)) |
| 542 | #ifndef INP_IPV6 |
| 543 | #define INP_IPV6 0x1 |
| 544 | #endif |
| 545 | #ifndef INP_IPV4 |
| 546 | #define INP_IPV4 0x2 |
| 547 | #endif |
| 548 | uint8_t inp_vflag; |
| 549 | /* TODO __Userspace__ where is our inp_vlag going to be? */ |
| 550 | uint8_t inp_ip_ttl; |
| 551 | uint8_t inp_ip_tos; /* defined as macro in user_inpcb.h */ |
| 552 | uint8_t inp_ip_resv; |
| 553 | #endif |
| 554 | #if defined(__FreeBSD__) && __FreeBSD_version >= 503000 |
| 555 | struct mtx inp_mtx; |
| 556 | struct mtx inp_create_mtx; |
| 557 | struct mtx inp_rdata_mtx; |
| 558 | int32_t refcount; |
| 559 | #elif defined(SCTP_PROCESS_LEVEL_LOCKS) |
| 560 | userland_mutex_t inp_mtx; |
| 561 | userland_mutex_t inp_create_mtx; |
| 562 | userland_mutex_t inp_rdata_mtx; |
| 563 | int32_t refcount; |
| 564 | #elif defined(__APPLE__) |
| 565 | #if defined(SCTP_APPLE_RWLOCK) |
| 566 | lck_rw_t *inp_mtx; |
| 567 | #else |
| 568 | lck_mtx_t *inp_mtx; |
| 569 | #endif |
| 570 | lck_mtx_t *inp_create_mtx; |
| 571 | lck_mtx_t *inp_rdata_mtx; |
| 572 | #elif defined(__Windows__) |
| 573 | struct rwlock inp_lock; |
| 574 | struct spinlock inp_create_lock; |
| 575 | struct spinlock inp_rdata_lock; |
| 576 | int32_t refcount; |
| 577 | #elif defined(__Userspace__) |
| 578 | /* TODO decide on __Userspace__ locks */ |
| 579 | int32_t refcount; |
| 580 | #endif |
| 581 | #if defined(__APPLE__) |
| 582 | int32_t refcount; |
| 583 | |
| 584 | uint32_t lock_caller1; |
| 585 | uint32_t lock_caller2; |
| 586 | uint32_t lock_caller3; |
| 587 | uint32_t unlock_caller1; |
| 588 | uint32_t unlock_caller2; |
| 589 | uint32_t unlock_caller3; |
| 590 | uint32_t getlock_caller1; |
| 591 | uint32_t getlock_caller2; |
| 592 | uint32_t getlock_caller3; |
| 593 | uint32_t gen_count; |
| 594 | uint32_t lock_gen_count; |
| 595 | uint32_t unlock_gen_count; |
| 596 | uint32_t getlock_gen_count; |
| 597 | |
| 598 | uint32_t i_am_here_file; |
| 599 | uint32_t i_am_here_line; |
| 600 | #endif |
| 601 | uint32_t def_vrf_id; |
| 602 | uint16_t fibnum; |
| 603 | #ifdef SCTP_MVRF |
| 604 | uint32_t *m_vrf_ids; |
| 605 | uint32_t num_vrfs; |
| 606 | uint32_t vrf_size; |
| 607 | #endif |
| 608 | uint32_t total_sends; |
| 609 | uint32_t total_recvs; |
| 610 | uint32_t last_abort_code; |
| 611 | uint32_t total_nospaces; |
| 612 | struct sctpasochead *sctp_asocidhash; |
| 613 | u_long hashasocidmark; |
| 614 | uint32_t sctp_associd_counter; |
| 615 | |
| 616 | #ifdef SCTP_ASOCLOG_OF_TSNS |
| 617 | struct sctp_pcbtsn_rlog readlog[SCTP_READ_LOG_SIZE]; |
| 618 | uint32_t readlog_index; |
| 619 | #endif |
| 620 | #if defined(__Userspace__) |
| 621 | void *ulp_info; |
| 622 | int (*recv_callback)(struct socket *, union sctp_sockstore, void *, size_t, |
| 623 | struct sctp_rcvinfo, int, void *); |
| 624 | uint32_t send_sb_threshold; |
| 625 | int (*send_callback)(struct socket *, uint32_t); |
| 626 | #endif |
| 627 | }; |
| 628 | |
| 629 | #if defined(__Userspace__) |
| 630 | int register_recv_cb (struct socket *, |
| 631 | int (*)(struct socket *, union sctp_sockstore, void *, size_t, |
| 632 | struct sctp_rcvinfo, int, void *)); |
| 633 | int register_send_cb (struct socket *, uint32_t, int (*)(struct socket *, uint32_t)); |
| 634 | int register_ulp_info (struct socket *, void *); |
| 635 | |
| 636 | #endif |
| 637 | struct sctp_tcb { |
| 638 | struct socket *sctp_socket; /* back pointer to socket */ |
| 639 | struct sctp_inpcb *sctp_ep; /* back pointer to ep */ |
| 640 | LIST_ENTRY(sctp_tcb) sctp_tcbhash; /* next link in hash |
| 641 | * table */ |
| 642 | LIST_ENTRY(sctp_tcb) sctp_tcblist; /* list of all of the |
| 643 | * TCB's */ |
| 644 | LIST_ENTRY(sctp_tcb) sctp_tcbasocidhash; /* next link in asocid |
| 645 | * hash table |
| 646 | */ |
| 647 | LIST_ENTRY(sctp_tcb) sctp_asocs; /* vtag hash list */ |
| 648 | struct sctp_block_entry *block_entry; /* pointer locked by socket |
| 649 | * send buffer */ |
| 650 | struct sctp_association asoc; |
| 651 | /*- |
| 652 | * freed_by_sorcv_sincelast is protected by the sockbuf_lock NOT the |
| 653 | * tcb_lock. Its special in this way to help avoid extra mutex calls |
| 654 | * in the reading of data. |
| 655 | */ |
| 656 | uint32_t freed_by_sorcv_sincelast; |
| 657 | uint32_t total_sends; |
| 658 | uint32_t total_recvs; |
| 659 | int freed_from_where; |
| 660 | uint16_t rport; /* remote port in network format */ |
| 661 | uint16_t resv; |
| 662 | #if defined(__FreeBSD__) && __FreeBSD_version >= 503000 |
| 663 | struct mtx tcb_mtx; |
| 664 | struct mtx tcb_send_mtx; |
| 665 | #elif defined(SCTP_PROCESS_LEVEL_LOCKS) |
| 666 | userland_mutex_t tcb_mtx; |
| 667 | userland_mutex_t tcb_send_mtx; |
| 668 | #elif defined(__APPLE__) |
| 669 | lck_mtx_t* tcb_mtx; |
| 670 | lck_mtx_t* tcb_send_mtx; |
| 671 | #elif defined(__Windows__) |
| 672 | struct spinlock tcb_lock; |
| 673 | struct spinlock tcb_send_lock; |
| 674 | #elif defined(__Userspace__) |
| 675 | /* TODO decide on __Userspace__ locks */ |
| 676 | #endif |
| 677 | #if defined(__APPLE__) |
| 678 | uint32_t caller1; |
| 679 | uint32_t caller2; |
| 680 | uint32_t caller3; |
| 681 | #endif |
| 682 | }; |
| 683 | |
| 684 | |
| 685 | #if defined(__FreeBSD__) && __FreeBSD_version >= 503000 |
| 686 | |
| 687 | #include <netinet/sctp_lock_bsd.h> |
| 688 | |
| 689 | #elif defined(__APPLE__) |
| 690 | /* |
| 691 | * Apple MacOS X 10.4 "Tiger" |
| 692 | */ |
| 693 | |
| 694 | #include <netinet/sctp_lock_apple_fg.h> |
| 695 | |
| 696 | #elif defined(SCTP_PROCESS_LEVEL_LOCKS) |
| 697 | |
| 698 | #include <netinet/sctp_process_lock.h> |
| 699 | |
| 700 | #elif defined(__Windows__) |
| 701 | |
| 702 | #include <netinet/sctp_lock_windows.h> |
| 703 | |
| 704 | #elif defined(__Userspace__) |
| 705 | |
| 706 | #include <netinet/sctp_lock_userspace.h> |
| 707 | |
| 708 | #else |
| 709 | /* |
| 710 | * Pre-5.x FreeBSD, and others. |
| 711 | */ |
| 712 | #include <netinet/sctp_lock_empty.h> |
| 713 | #endif |
| 714 | |
| 715 | /* TODO where to put non-_KERNEL things for __Userspace__? */ |
| 716 | #if defined(_KERNEL) || defined(__Userspace__) |
| 717 | |
| 718 | /* Attention Julian, this is the extern that |
| 719 | * goes with the base info. sctp_pcb.c has |
| 720 | * the real definition. |
| 721 | */ |
| 722 | #if defined(__FreeBSD__) && __FreeBSD_version >= 801000 |
| 723 | VNET_DECLARE(struct sctp_base_info, system_base_info) ; |
| 724 | #else |
| 725 | extern struct sctp_base_info system_base_info; |
| 726 | #endif |
| 727 | |
| 728 | #ifdef INET6 |
| 729 | int SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b); |
| 730 | #endif |
| 731 | |
| 732 | void sctp_fill_pcbinfo(struct sctp_pcbinfo *); |
| 733 | |
| 734 | struct sctp_ifn * |
| 735 | sctp_find_ifn(void *ifn, uint32_t ifn_index); |
| 736 | |
| 737 | struct sctp_vrf *sctp_allocate_vrf(int vrfid); |
| 738 | struct sctp_vrf *sctp_find_vrf(uint32_t vrfid); |
| 739 | void sctp_free_vrf(struct sctp_vrf *vrf); |
| 740 | |
| 741 | /*- |
| 742 | * Change address state, can be used if |
| 743 | * O/S supports telling transports about |
| 744 | * changes to IFA/IFN's (link layer triggers). |
| 745 | * If a ifn goes down, we will do src-addr-selection |
| 746 | * and NOT use that, as a source address. This does |
| 747 | * not stop the routing system from routing out |
| 748 | * that interface, but we won't put it as a source. |
| 749 | */ |
| 750 | void sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index); |
| 751 | void sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index); |
| 752 | |
| 753 | struct sctp_ifa * |
| 754 | sctp_add_addr_to_vrf(uint32_t vrfid, |
| 755 | void *ifn, uint32_t ifn_index, uint32_t ifn_type, |
| 756 | const char *if_name, |
| 757 | void *ifa, struct sockaddr *addr, uint32_t ifa_flags, |
| 758 | int dynamic_add); |
| 759 | |
| 760 | void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu); |
| 761 | |
| 762 | void sctp_free_ifn(struct sctp_ifn *sctp_ifnp); |
| 763 | void sctp_free_ifa(struct sctp_ifa *sctp_ifap); |
| 764 | |
| 765 | |
| 766 | void sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr, |
| 767 | uint32_t ifn_index, const char *if_name); |
| 768 | |
| 769 | |
| 770 | |
| 771 | struct sctp_nets *sctp_findnet(struct sctp_tcb *, struct sockaddr *); |
| 772 | |
| 773 | struct sctp_inpcb *sctp_pcb_findep(struct sockaddr *, int, int, uint32_t); |
| 774 | |
| 775 | #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 |
| 776 | int sctp_inpcb_bind(struct socket *, struct sockaddr *, |
| 777 | struct sctp_ifa *,struct thread *); |
| 778 | #elif defined(__Windows__) |
| 779 | int sctp_inpcb_bind(struct socket *, struct sockaddr *, |
| 780 | struct sctp_ifa *,PKTHREAD); |
| 781 | #else |
| 782 | /* struct proc is a dummy for __Userspace__ */ |
| 783 | int sctp_inpcb_bind(struct socket *, struct sockaddr *, |
| 784 | struct sctp_ifa *, struct proc *); |
| 785 | #endif |
| 786 | |
| 787 | struct sctp_tcb * |
| 788 | sctp_findassociation_addr(struct mbuf *, int, |
| 789 | struct sockaddr *, struct sockaddr *, |
| 790 | struct sctphdr *, struct sctp_chunkhdr *, struct sctp_inpcb **, |
| 791 | struct sctp_nets **, uint32_t vrf_id); |
| 792 | |
| 793 | struct sctp_tcb * |
| 794 | sctp_findassociation_addr_sa(struct sockaddr *, |
| 795 | struct sockaddr *, struct sctp_inpcb **, struct sctp_nets **, int, uint32_t); |
| 796 | |
| 797 | void |
| 798 | sctp_move_pcb_and_assoc(struct sctp_inpcb *, struct sctp_inpcb *, |
| 799 | struct sctp_tcb *); |
| 800 | |
| 801 | /*- |
| 802 | * For this call ep_addr, the to is the destination endpoint address of the |
| 803 | * peer (relative to outbound). The from field is only used if the TCP model |
| 804 | * is enabled and helps distingush amongst the subset bound (non-boundall). |
| 805 | * The TCP model MAY change the actual ep field, this is why it is passed. |
| 806 | */ |
| 807 | struct sctp_tcb * |
| 808 | sctp_findassociation_ep_addr(struct sctp_inpcb **, |
| 809 | struct sockaddr *, struct sctp_nets **, struct sockaddr *, |
| 810 | struct sctp_tcb *); |
| 811 | |
| 812 | struct sctp_tcb * |
| 813 | sctp_findasoc_ep_asocid_locked(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock); |
| 814 | |
| 815 | struct sctp_tcb * |
| 816 | sctp_findassociation_ep_asocid(struct sctp_inpcb *, |
| 817 | sctp_assoc_t, int); |
| 818 | |
| 819 | struct sctp_tcb * |
| 820 | sctp_findassociation_ep_asconf(struct mbuf *, int, struct sockaddr *, |
| 821 | struct sctphdr *, struct sctp_inpcb **, struct sctp_nets **, uint32_t vrf_id); |
| 822 | |
| 823 | int sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id); |
| 824 | |
| 825 | int sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id); |
| 826 | |
| 827 | void sctp_inpcb_free(struct sctp_inpcb *, int, int); |
| 828 | |
| 829 | #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 |
| 830 | struct sctp_tcb * |
| 831 | sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, |
| 832 | int *, uint32_t, uint32_t, uint16_t, uint16_t, struct thread *); |
| 833 | #elif defined(__Windows__) |
| 834 | struct sctp_tcb * |
| 835 | sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, |
| 836 | int *, uint32_t, uint32_t, uint16_t, uint16_t, PKTHREAD); |
| 837 | #else |
| 838 | /* proc will be NULL for __Userspace__ */ |
| 839 | struct sctp_tcb * |
| 840 | sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *, |
| 841 | int *, uint32_t, uint32_t, uint16_t, uint16_t, struct proc *); |
| 842 | #endif |
| 843 | |
| 844 | int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int); |
| 845 | |
| 846 | |
| 847 | void sctp_delete_from_timewait(uint32_t, uint16_t, uint16_t); |
| 848 | |
| 849 | int sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport); |
| 850 | |
| 851 | void |
| 852 | sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t rport); |
| 853 | |
| 854 | void sctp_add_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *, uint32_t); |
| 855 | |
| 856 | void sctp_del_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *); |
| 857 | |
| 858 | int sctp_add_remote_addr(struct sctp_tcb *, struct sockaddr *, struct sctp_nets **, uint16_t, int, int); |
| 859 | |
| 860 | void sctp_remove_net(struct sctp_tcb *, struct sctp_nets *); |
| 861 | |
| 862 | int sctp_del_remote_addr(struct sctp_tcb *, struct sockaddr *); |
| 863 | |
| 864 | void sctp_pcb_init(void); |
| 865 | |
| 866 | void sctp_pcb_finish(void); |
| 867 | |
| 868 | void sctp_add_local_addr_restricted(struct sctp_tcb *, struct sctp_ifa *); |
| 869 | void sctp_del_local_addr_restricted(struct sctp_tcb *, struct sctp_ifa *); |
| 870 | |
| 871 | int |
| 872 | sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int, int, |
| 873 | struct sockaddr *, struct sockaddr *, struct sockaddr *, uint16_t); |
| 874 | |
| 875 | int |
| 876 | sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *, |
| 877 | struct sctp_nets *); |
| 878 | |
| 879 | int sctp_is_vtag_good(uint32_t, uint16_t lport, uint16_t rport, struct timeval *); |
| 880 | |
| 881 | /* void sctp_drain(void); */ |
| 882 | |
| 883 | int sctp_destination_is_reachable(struct sctp_tcb *, struct sockaddr *); |
| 884 | |
| 885 | int sctp_swap_inpcb_for_listen(struct sctp_inpcb *inp); |
| 886 | |
| 887 | void sctp_clean_up_stream(struct sctp_tcb *stcb, struct sctp_readhead *rh); |
| 888 | |
| 889 | /*- |
| 890 | * Null in last arg inpcb indicate run on ALL ep's. Specific inp in last arg |
| 891 | * indicates run on ONLY assoc's of the specified endpoint. |
| 892 | */ |
| 893 | int |
| 894 | sctp_initiate_iterator(inp_func inpf, |
| 895 | asoc_func af, |
| 896 | inp_func inpe, |
| 897 | uint32_t, uint32_t, |
| 898 | uint32_t, void *, |
| 899 | uint32_t, |
| 900 | end_func ef, |
| 901 | struct sctp_inpcb *, |
| 902 | uint8_t co_off); |
| 903 | #if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) |
| 904 | void |
| 905 | sctp_queue_to_mcore(struct mbuf *m, int off, int cpu_to_use); |
| 906 | |
| 907 | #endif |
| 908 | |
| 909 | #endif /* _KERNEL */ |
| 910 | #endif /* !__sctp_pcb_h__ */ |