netwerk/sctp/src/netinet/sctp_pcb.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rwxr-xr-x

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial