1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. 5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * a) Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 14 * b) Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the distribution. 17 * 18 * c) Neither the name of Cisco Systems, Inc. nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 * THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __FBSDID("$FreeBSD$"); 37 38 #include <netinet/sctp_os.h> 39 #include <netinet/sctp_pcb.h> 40 #include <netinet/sctputil.h> 41 #include <netinet/sctp_var.h> 42 #include <netinet/sctp_sysctl.h> 43 #ifdef INET6 44 #include <netinet6/sctp6_var.h> 45 #endif 46 #include <netinet/sctp_header.h> 47 #include <netinet/sctp_output.h> 48 #include <netinet/sctp_uio.h> 49 #include <netinet/sctp_timer.h> 50 #include <netinet/sctp_indata.h>/* for sctp_deliver_data() */ 51 #include <netinet/sctp_auth.h> 52 #include <netinet/sctp_asconf.h> 53 #include <netinet/sctp_bsd_addr.h> 54 #if defined(INET6) || defined(INET) 55 #include <netinet/tcp_var.h> 56 #endif 57 #include <netinet/udp.h> 58 #include <netinet/udp_var.h> 59 #include <sys/proc.h> 60 #ifdef INET6 61 #include <netinet/icmp6.h> 62 #endif 63 64 65 #ifndef KTR_SCTP 66 #define KTR_SCTP KTR_SUBSYS 67 #endif 68 69 extern const struct sctp_cc_functions sctp_cc_functions[]; 70 extern const struct sctp_ss_functions sctp_ss_functions[]; 71 72 void 73 sctp_sblog(struct sockbuf *sb, struct sctp_tcb *stcb, int from, int incr) 74 { 75 struct sctp_cwnd_log sctp_clog; 76 77 sctp_clog.x.sb.stcb = stcb; 78 sctp_clog.x.sb.so_sbcc = sb->sb_cc; 79 if (stcb) 80 sctp_clog.x.sb.stcb_sbcc = stcb->asoc.sb_cc; 81 else 82 sctp_clog.x.sb.stcb_sbcc = 0; 83 sctp_clog.x.sb.incr = incr; 84 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 85 SCTP_LOG_EVENT_SB, 86 from, 87 sctp_clog.x.misc.log1, 88 sctp_clog.x.misc.log2, 89 sctp_clog.x.misc.log3, 90 sctp_clog.x.misc.log4); 91 } 92 93 void 94 sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc) 95 { 96 struct sctp_cwnd_log sctp_clog; 97 98 sctp_clog.x.close.inp = (void *)inp; 99 sctp_clog.x.close.sctp_flags = inp->sctp_flags; 100 if (stcb) { 101 sctp_clog.x.close.stcb = (void *)stcb; 102 sctp_clog.x.close.state = (uint16_t)stcb->asoc.state; 103 } else { 104 sctp_clog.x.close.stcb = 0; 105 sctp_clog.x.close.state = 0; 106 } 107 sctp_clog.x.close.loc = loc; 108 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 109 SCTP_LOG_EVENT_CLOSE, 110 0, 111 sctp_clog.x.misc.log1, 112 sctp_clog.x.misc.log2, 113 sctp_clog.x.misc.log3, 114 sctp_clog.x.misc.log4); 115 } 116 117 void 118 rto_logging(struct sctp_nets *net, int from) 119 { 120 struct sctp_cwnd_log sctp_clog; 121 122 memset(&sctp_clog, 0, sizeof(sctp_clog)); 123 sctp_clog.x.rto.net = (void *)net; 124 sctp_clog.x.rto.rtt = net->rtt / 1000; 125 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 126 SCTP_LOG_EVENT_RTT, 127 from, 128 sctp_clog.x.misc.log1, 129 sctp_clog.x.misc.log2, 130 sctp_clog.x.misc.log3, 131 sctp_clog.x.misc.log4); 132 } 133 134 void 135 sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t tsn, uint16_t sseq, uint16_t stream, int from) 136 { 137 struct sctp_cwnd_log sctp_clog; 138 139 sctp_clog.x.strlog.stcb = stcb; 140 sctp_clog.x.strlog.n_tsn = tsn; 141 sctp_clog.x.strlog.n_sseq = sseq; 142 sctp_clog.x.strlog.e_tsn = 0; 143 sctp_clog.x.strlog.e_sseq = 0; 144 sctp_clog.x.strlog.strm = stream; 145 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 146 SCTP_LOG_EVENT_STRM, 147 from, 148 sctp_clog.x.misc.log1, 149 sctp_clog.x.misc.log2, 150 sctp_clog.x.misc.log3, 151 sctp_clog.x.misc.log4); 152 } 153 154 void 155 sctp_log_nagle_event(struct sctp_tcb *stcb, int action) 156 { 157 struct sctp_cwnd_log sctp_clog; 158 159 sctp_clog.x.nagle.stcb = (void *)stcb; 160 sctp_clog.x.nagle.total_flight = stcb->asoc.total_flight; 161 sctp_clog.x.nagle.total_in_queue = stcb->asoc.total_output_queue_size; 162 sctp_clog.x.nagle.count_in_queue = stcb->asoc.chunks_on_out_queue; 163 sctp_clog.x.nagle.count_in_flight = stcb->asoc.total_flight_count; 164 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 165 SCTP_LOG_EVENT_NAGLE, 166 action, 167 sctp_clog.x.misc.log1, 168 sctp_clog.x.misc.log2, 169 sctp_clog.x.misc.log3, 170 sctp_clog.x.misc.log4); 171 } 172 173 void 174 sctp_log_sack(uint32_t old_cumack, uint32_t cumack, uint32_t tsn, uint16_t gaps, uint16_t dups, int from) 175 { 176 struct sctp_cwnd_log sctp_clog; 177 178 sctp_clog.x.sack.cumack = cumack; 179 sctp_clog.x.sack.oldcumack = old_cumack; 180 sctp_clog.x.sack.tsn = tsn; 181 sctp_clog.x.sack.numGaps = gaps; 182 sctp_clog.x.sack.numDups = dups; 183 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 184 SCTP_LOG_EVENT_SACK, 185 from, 186 sctp_clog.x.misc.log1, 187 sctp_clog.x.misc.log2, 188 sctp_clog.x.misc.log3, 189 sctp_clog.x.misc.log4); 190 } 191 192 void 193 sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from) 194 { 195 struct sctp_cwnd_log sctp_clog; 196 197 memset(&sctp_clog, 0, sizeof(sctp_clog)); 198 sctp_clog.x.map.base = map; 199 sctp_clog.x.map.cum = cum; 200 sctp_clog.x.map.high = high; 201 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 202 SCTP_LOG_EVENT_MAP, 203 from, 204 sctp_clog.x.misc.log1, 205 sctp_clog.x.misc.log2, 206 sctp_clog.x.misc.log3, 207 sctp_clog.x.misc.log4); 208 } 209 210 void 211 sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn, int from) 212 { 213 struct sctp_cwnd_log sctp_clog; 214 215 memset(&sctp_clog, 0, sizeof(sctp_clog)); 216 sctp_clog.x.fr.largest_tsn = biggest_tsn; 217 sctp_clog.x.fr.largest_new_tsn = biggest_new_tsn; 218 sctp_clog.x.fr.tsn = tsn; 219 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 220 SCTP_LOG_EVENT_FR, 221 from, 222 sctp_clog.x.misc.log1, 223 sctp_clog.x.misc.log2, 224 sctp_clog.x.misc.log3, 225 sctp_clog.x.misc.log4); 226 } 227 228 #ifdef SCTP_MBUF_LOGGING 229 void 230 sctp_log_mb(struct mbuf *m, int from) 231 { 232 struct sctp_cwnd_log sctp_clog; 233 234 sctp_clog.x.mb.mp = m; 235 sctp_clog.x.mb.mbuf_flags = (uint8_t)(SCTP_BUF_GET_FLAGS(m)); 236 sctp_clog.x.mb.size = (uint16_t)(SCTP_BUF_LEN(m)); 237 sctp_clog.x.mb.data = SCTP_BUF_AT(m, 0); 238 if (SCTP_BUF_IS_EXTENDED(m)) { 239 sctp_clog.x.mb.ext = SCTP_BUF_EXTEND_BASE(m); 240 sctp_clog.x.mb.refcnt = (uint8_t)(SCTP_BUF_EXTEND_REFCNT(m)); 241 } else { 242 sctp_clog.x.mb.ext = 0; 243 sctp_clog.x.mb.refcnt = 0; 244 } 245 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 246 SCTP_LOG_EVENT_MBUF, 247 from, 248 sctp_clog.x.misc.log1, 249 sctp_clog.x.misc.log2, 250 sctp_clog.x.misc.log3, 251 sctp_clog.x.misc.log4); 252 } 253 254 void 255 sctp_log_mbc(struct mbuf *m, int from) 256 { 257 struct mbuf *mat; 258 259 for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) { 260 sctp_log_mb(mat, from); 261 } 262 } 263 #endif 264 265 void 266 sctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_read *poschk, int from) 267 { 268 struct sctp_cwnd_log sctp_clog; 269 270 if (control == NULL) { 271 SCTP_PRINTF("Gak log of NULL?\n"); 272 return; 273 } 274 sctp_clog.x.strlog.stcb = control->stcb; 275 sctp_clog.x.strlog.n_tsn = control->sinfo_tsn; 276 sctp_clog.x.strlog.n_sseq = (uint16_t)control->mid; 277 sctp_clog.x.strlog.strm = control->sinfo_stream; 278 if (poschk != NULL) { 279 sctp_clog.x.strlog.e_tsn = poschk->sinfo_tsn; 280 sctp_clog.x.strlog.e_sseq = (uint16_t)poschk->mid; 281 } else { 282 sctp_clog.x.strlog.e_tsn = 0; 283 sctp_clog.x.strlog.e_sseq = 0; 284 } 285 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 286 SCTP_LOG_EVENT_STRM, 287 from, 288 sctp_clog.x.misc.log1, 289 sctp_clog.x.misc.log2, 290 sctp_clog.x.misc.log3, 291 sctp_clog.x.misc.log4); 292 } 293 294 void 295 sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from) 296 { 297 struct sctp_cwnd_log sctp_clog; 298 299 sctp_clog.x.cwnd.net = net; 300 if (stcb->asoc.send_queue_cnt > 255) 301 sctp_clog.x.cwnd.cnt_in_send = 255; 302 else 303 sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt; 304 if (stcb->asoc.stream_queue_cnt > 255) 305 sctp_clog.x.cwnd.cnt_in_str = 255; 306 else 307 sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt; 308 309 if (net) { 310 sctp_clog.x.cwnd.cwnd_new_value = net->cwnd; 311 sctp_clog.x.cwnd.inflight = net->flight_size; 312 sctp_clog.x.cwnd.pseudo_cumack = net->pseudo_cumack; 313 sctp_clog.x.cwnd.meets_pseudo_cumack = net->new_pseudo_cumack; 314 sctp_clog.x.cwnd.need_new_pseudo_cumack = net->find_pseudo_cumack; 315 } 316 if (SCTP_CWNDLOG_PRESEND == from) { 317 sctp_clog.x.cwnd.meets_pseudo_cumack = stcb->asoc.peers_rwnd; 318 } 319 sctp_clog.x.cwnd.cwnd_augment = augment; 320 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 321 SCTP_LOG_EVENT_CWND, 322 from, 323 sctp_clog.x.misc.log1, 324 sctp_clog.x.misc.log2, 325 sctp_clog.x.misc.log3, 326 sctp_clog.x.misc.log4); 327 } 328 329 void 330 sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from) 331 { 332 struct sctp_cwnd_log sctp_clog; 333 334 memset(&sctp_clog, 0, sizeof(sctp_clog)); 335 if (inp) { 336 sctp_clog.x.lock.sock = (void *)inp->sctp_socket; 337 338 } else { 339 sctp_clog.x.lock.sock = (void *)NULL; 340 } 341 sctp_clog.x.lock.inp = (void *)inp; 342 if (stcb) { 343 sctp_clog.x.lock.tcb_lock = mtx_owned(&stcb->tcb_mtx); 344 } else { 345 sctp_clog.x.lock.tcb_lock = SCTP_LOCK_UNKNOWN; 346 } 347 if (inp) { 348 sctp_clog.x.lock.inp_lock = mtx_owned(&inp->inp_mtx); 349 sctp_clog.x.lock.create_lock = mtx_owned(&inp->inp_create_mtx); 350 } else { 351 sctp_clog.x.lock.inp_lock = SCTP_LOCK_UNKNOWN; 352 sctp_clog.x.lock.create_lock = SCTP_LOCK_UNKNOWN; 353 } 354 sctp_clog.x.lock.info_lock = rw_wowned(&SCTP_BASE_INFO(ipi_ep_mtx)); 355 if (inp && (inp->sctp_socket)) { 356 sctp_clog.x.lock.sock_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx)); 357 sctp_clog.x.lock.sockrcvbuf_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx)); 358 sctp_clog.x.lock.socksndbuf_lock = mtx_owned(&(inp->sctp_socket->so_snd.sb_mtx)); 359 } else { 360 sctp_clog.x.lock.sock_lock = SCTP_LOCK_UNKNOWN; 361 sctp_clog.x.lock.sockrcvbuf_lock = SCTP_LOCK_UNKNOWN; 362 sctp_clog.x.lock.socksndbuf_lock = SCTP_LOCK_UNKNOWN; 363 } 364 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 365 SCTP_LOG_LOCK_EVENT, 366 from, 367 sctp_clog.x.misc.log1, 368 sctp_clog.x.misc.log2, 369 sctp_clog.x.misc.log3, 370 sctp_clog.x.misc.log4); 371 } 372 373 void 374 sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *net, int error, int burst, uint8_t from) 375 { 376 struct sctp_cwnd_log sctp_clog; 377 378 memset(&sctp_clog, 0, sizeof(sctp_clog)); 379 sctp_clog.x.cwnd.net = net; 380 sctp_clog.x.cwnd.cwnd_new_value = error; 381 sctp_clog.x.cwnd.inflight = net->flight_size; 382 sctp_clog.x.cwnd.cwnd_augment = burst; 383 if (stcb->asoc.send_queue_cnt > 255) 384 sctp_clog.x.cwnd.cnt_in_send = 255; 385 else 386 sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt; 387 if (stcb->asoc.stream_queue_cnt > 255) 388 sctp_clog.x.cwnd.cnt_in_str = 255; 389 else 390 sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt; 391 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 392 SCTP_LOG_EVENT_MAXBURST, 393 from, 394 sctp_clog.x.misc.log1, 395 sctp_clog.x.misc.log2, 396 sctp_clog.x.misc.log3, 397 sctp_clog.x.misc.log4); 398 } 399 400 void 401 sctp_log_rwnd(uint8_t from, uint32_t peers_rwnd, uint32_t snd_size, uint32_t overhead) 402 { 403 struct sctp_cwnd_log sctp_clog; 404 405 sctp_clog.x.rwnd.rwnd = peers_rwnd; 406 sctp_clog.x.rwnd.send_size = snd_size; 407 sctp_clog.x.rwnd.overhead = overhead; 408 sctp_clog.x.rwnd.new_rwnd = 0; 409 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 410 SCTP_LOG_EVENT_RWND, 411 from, 412 sctp_clog.x.misc.log1, 413 sctp_clog.x.misc.log2, 414 sctp_clog.x.misc.log3, 415 sctp_clog.x.misc.log4); 416 } 417 418 void 419 sctp_log_rwnd_set(uint8_t from, uint32_t peers_rwnd, uint32_t flight_size, uint32_t overhead, uint32_t a_rwndval) 420 { 421 struct sctp_cwnd_log sctp_clog; 422 423 sctp_clog.x.rwnd.rwnd = peers_rwnd; 424 sctp_clog.x.rwnd.send_size = flight_size; 425 sctp_clog.x.rwnd.overhead = overhead; 426 sctp_clog.x.rwnd.new_rwnd = a_rwndval; 427 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 428 SCTP_LOG_EVENT_RWND, 429 from, 430 sctp_clog.x.misc.log1, 431 sctp_clog.x.misc.log2, 432 sctp_clog.x.misc.log3, 433 sctp_clog.x.misc.log4); 434 } 435 436 #ifdef SCTP_MBCNT_LOGGING 437 static void 438 sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mbcnt_q, uint32_t mbcnt) 439 { 440 struct sctp_cwnd_log sctp_clog; 441 442 sctp_clog.x.mbcnt.total_queue_size = total_oq; 443 sctp_clog.x.mbcnt.size_change = book; 444 sctp_clog.x.mbcnt.total_queue_mb_size = total_mbcnt_q; 445 sctp_clog.x.mbcnt.mbcnt_change = mbcnt; 446 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 447 SCTP_LOG_EVENT_MBCNT, 448 from, 449 sctp_clog.x.misc.log1, 450 sctp_clog.x.misc.log2, 451 sctp_clog.x.misc.log3, 452 sctp_clog.x.misc.log4); 453 } 454 #endif 455 456 void 457 sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d) 458 { 459 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 460 SCTP_LOG_MISC_EVENT, 461 from, 462 a, b, c, d); 463 } 464 465 void 466 sctp_wakeup_log(struct sctp_tcb *stcb, uint32_t wake_cnt, int from) 467 { 468 struct sctp_cwnd_log sctp_clog; 469 470 sctp_clog.x.wake.stcb = (void *)stcb; 471 sctp_clog.x.wake.wake_cnt = wake_cnt; 472 sctp_clog.x.wake.flight = stcb->asoc.total_flight_count; 473 sctp_clog.x.wake.send_q = stcb->asoc.send_queue_cnt; 474 sctp_clog.x.wake.sent_q = stcb->asoc.sent_queue_cnt; 475 476 if (stcb->asoc.stream_queue_cnt < 0xff) 477 sctp_clog.x.wake.stream_qcnt = (uint8_t)stcb->asoc.stream_queue_cnt; 478 else 479 sctp_clog.x.wake.stream_qcnt = 0xff; 480 481 if (stcb->asoc.chunks_on_out_queue < 0xff) 482 sctp_clog.x.wake.chunks_on_oque = (uint8_t)stcb->asoc.chunks_on_out_queue; 483 else 484 sctp_clog.x.wake.chunks_on_oque = 0xff; 485 486 sctp_clog.x.wake.sctpflags = 0; 487 /* set in the defered mode stuff */ 488 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) 489 sctp_clog.x.wake.sctpflags |= 1; 490 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) 491 sctp_clog.x.wake.sctpflags |= 2; 492 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) 493 sctp_clog.x.wake.sctpflags |= 4; 494 /* what about the sb */ 495 if (stcb->sctp_socket) { 496 struct socket *so = stcb->sctp_socket; 497 498 sctp_clog.x.wake.sbflags = (uint8_t)((so->so_snd.sb_flags & 0x00ff)); 499 } else { 500 sctp_clog.x.wake.sbflags = 0xff; 501 } 502 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 503 SCTP_LOG_EVENT_WAKE, 504 from, 505 sctp_clog.x.misc.log1, 506 sctp_clog.x.misc.log2, 507 sctp_clog.x.misc.log3, 508 sctp_clog.x.misc.log4); 509 } 510 511 void 512 sctp_log_block(uint8_t from, struct sctp_association *asoc, size_t sendlen) 513 { 514 struct sctp_cwnd_log sctp_clog; 515 516 sctp_clog.x.blk.onsb = asoc->total_output_queue_size; 517 sctp_clog.x.blk.send_sent_qcnt = (uint16_t)(asoc->send_queue_cnt + asoc->sent_queue_cnt); 518 sctp_clog.x.blk.peer_rwnd = asoc->peers_rwnd; 519 sctp_clog.x.blk.stream_qcnt = (uint16_t)asoc->stream_queue_cnt; 520 sctp_clog.x.blk.chunks_on_oque = (uint16_t)asoc->chunks_on_out_queue; 521 sctp_clog.x.blk.flight_size = (uint16_t)(asoc->total_flight / 1024); 522 sctp_clog.x.blk.sndlen = (uint32_t)sendlen; 523 SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 524 SCTP_LOG_EVENT_BLOCK, 525 from, 526 sctp_clog.x.misc.log1, 527 sctp_clog.x.misc.log2, 528 sctp_clog.x.misc.log3, 529 sctp_clog.x.misc.log4); 530 } 531 532 int 533 sctp_fill_stat_log(void *optval SCTP_UNUSED, size_t *optsize SCTP_UNUSED) 534 { 535 /* May need to fix this if ktrdump does not work */ 536 return (0); 537 } 538 539 #ifdef SCTP_AUDITING_ENABLED 540 uint8_t sctp_audit_data[SCTP_AUDIT_SIZE][2]; 541 static int sctp_audit_indx = 0; 542 543 static 544 void 545 sctp_print_audit_report(void) 546 { 547 int i; 548 int cnt; 549 550 cnt = 0; 551 for (i = sctp_audit_indx; i < SCTP_AUDIT_SIZE; i++) { 552 if ((sctp_audit_data[i][0] == 0xe0) && 553 (sctp_audit_data[i][1] == 0x01)) { 554 cnt = 0; 555 SCTP_PRINTF("\n"); 556 } else if (sctp_audit_data[i][0] == 0xf0) { 557 cnt = 0; 558 SCTP_PRINTF("\n"); 559 } else if ((sctp_audit_data[i][0] == 0xc0) && 560 (sctp_audit_data[i][1] == 0x01)) { 561 SCTP_PRINTF("\n"); 562 cnt = 0; 563 } 564 SCTP_PRINTF("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0], 565 (uint32_t)sctp_audit_data[i][1]); 566 cnt++; 567 if ((cnt % 14) == 0) 568 SCTP_PRINTF("\n"); 569 } 570 for (i = 0; i < sctp_audit_indx; i++) { 571 if ((sctp_audit_data[i][0] == 0xe0) && 572 (sctp_audit_data[i][1] == 0x01)) { 573 cnt = 0; 574 SCTP_PRINTF("\n"); 575 } else if (sctp_audit_data[i][0] == 0xf0) { 576 cnt = 0; 577 SCTP_PRINTF("\n"); 578 } else if ((sctp_audit_data[i][0] == 0xc0) && 579 (sctp_audit_data[i][1] == 0x01)) { 580 SCTP_PRINTF("\n"); 581 cnt = 0; 582 } 583 SCTP_PRINTF("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0], 584 (uint32_t)sctp_audit_data[i][1]); 585 cnt++; 586 if ((cnt % 14) == 0) 587 SCTP_PRINTF("\n"); 588 } 589 SCTP_PRINTF("\n"); 590 } 591 592 void 593 sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 594 struct sctp_nets *net) 595 { 596 int resend_cnt, tot_out, rep, tot_book_cnt; 597 struct sctp_nets *lnet; 598 struct sctp_tmit_chunk *chk; 599 600 sctp_audit_data[sctp_audit_indx][0] = 0xAA; 601 sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from; 602 sctp_audit_indx++; 603 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 604 sctp_audit_indx = 0; 605 } 606 if (inp == NULL) { 607 sctp_audit_data[sctp_audit_indx][0] = 0xAF; 608 sctp_audit_data[sctp_audit_indx][1] = 0x01; 609 sctp_audit_indx++; 610 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 611 sctp_audit_indx = 0; 612 } 613 return; 614 } 615 if (stcb == NULL) { 616 sctp_audit_data[sctp_audit_indx][0] = 0xAF; 617 sctp_audit_data[sctp_audit_indx][1] = 0x02; 618 sctp_audit_indx++; 619 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 620 sctp_audit_indx = 0; 621 } 622 return; 623 } 624 sctp_audit_data[sctp_audit_indx][0] = 0xA1; 625 sctp_audit_data[sctp_audit_indx][1] = 626 (0x000000ff & stcb->asoc.sent_queue_retran_cnt); 627 sctp_audit_indx++; 628 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 629 sctp_audit_indx = 0; 630 } 631 rep = 0; 632 tot_book_cnt = 0; 633 resend_cnt = tot_out = 0; 634 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 635 if (chk->sent == SCTP_DATAGRAM_RESEND) { 636 resend_cnt++; 637 } else if (chk->sent < SCTP_DATAGRAM_RESEND) { 638 tot_out += chk->book_size; 639 tot_book_cnt++; 640 } 641 } 642 if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) { 643 sctp_audit_data[sctp_audit_indx][0] = 0xAF; 644 sctp_audit_data[sctp_audit_indx][1] = 0xA1; 645 sctp_audit_indx++; 646 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 647 sctp_audit_indx = 0; 648 } 649 SCTP_PRINTF("resend_cnt:%d asoc-tot:%d\n", 650 resend_cnt, stcb->asoc.sent_queue_retran_cnt); 651 rep = 1; 652 stcb->asoc.sent_queue_retran_cnt = resend_cnt; 653 sctp_audit_data[sctp_audit_indx][0] = 0xA2; 654 sctp_audit_data[sctp_audit_indx][1] = 655 (0x000000ff & stcb->asoc.sent_queue_retran_cnt); 656 sctp_audit_indx++; 657 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 658 sctp_audit_indx = 0; 659 } 660 } 661 if (tot_out != stcb->asoc.total_flight) { 662 sctp_audit_data[sctp_audit_indx][0] = 0xAF; 663 sctp_audit_data[sctp_audit_indx][1] = 0xA2; 664 sctp_audit_indx++; 665 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 666 sctp_audit_indx = 0; 667 } 668 rep = 1; 669 SCTP_PRINTF("tot_flt:%d asoc_tot:%d\n", tot_out, 670 (int)stcb->asoc.total_flight); 671 stcb->asoc.total_flight = tot_out; 672 } 673 if (tot_book_cnt != stcb->asoc.total_flight_count) { 674 sctp_audit_data[sctp_audit_indx][0] = 0xAF; 675 sctp_audit_data[sctp_audit_indx][1] = 0xA5; 676 sctp_audit_indx++; 677 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 678 sctp_audit_indx = 0; 679 } 680 rep = 1; 681 SCTP_PRINTF("tot_flt_book:%d\n", tot_book_cnt); 682 683 stcb->asoc.total_flight_count = tot_book_cnt; 684 } 685 tot_out = 0; 686 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 687 tot_out += lnet->flight_size; 688 } 689 if (tot_out != stcb->asoc.total_flight) { 690 sctp_audit_data[sctp_audit_indx][0] = 0xAF; 691 sctp_audit_data[sctp_audit_indx][1] = 0xA3; 692 sctp_audit_indx++; 693 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 694 sctp_audit_indx = 0; 695 } 696 rep = 1; 697 SCTP_PRINTF("real flight:%d net total was %d\n", 698 stcb->asoc.total_flight, tot_out); 699 /* now corrective action */ 700 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 701 702 tot_out = 0; 703 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 704 if ((chk->whoTo == lnet) && 705 (chk->sent < SCTP_DATAGRAM_RESEND)) { 706 tot_out += chk->book_size; 707 } 708 } 709 if (lnet->flight_size != tot_out) { 710 SCTP_PRINTF("net:%p flight was %d corrected to %d\n", 711 (void *)lnet, lnet->flight_size, 712 tot_out); 713 lnet->flight_size = tot_out; 714 } 715 } 716 } 717 if (rep) { 718 sctp_print_audit_report(); 719 } 720 } 721 722 void 723 sctp_audit_log(uint8_t ev, uint8_t fd) 724 { 725 726 sctp_audit_data[sctp_audit_indx][0] = ev; 727 sctp_audit_data[sctp_audit_indx][1] = fd; 728 sctp_audit_indx++; 729 if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 730 sctp_audit_indx = 0; 731 } 732 } 733 734 #endif 735 736 /* 737 * sctp_stop_timers_for_shutdown() should be called 738 * when entering the SHUTDOWN_SENT or SHUTDOWN_ACK_SENT 739 * state to make sure that all timers are stopped. 740 */ 741 void 742 sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb) 743 { 744 struct sctp_association *asoc; 745 struct sctp_nets *net; 746 747 asoc = &stcb->asoc; 748 749 (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer); 750 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer); 751 (void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer); 752 (void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer); 753 (void)SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer); 754 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 755 (void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer); 756 (void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer); 757 } 758 } 759 760 /* 761 * a list of sizes based on typical mtu's, used only if next hop size not 762 * returned. 763 */ 764 static uint32_t sctp_mtu_sizes[] = { 765 68, 766 296, 767 508, 768 512, 769 544, 770 576, 771 1006, 772 1492, 773 1500, 774 1536, 775 2002, 776 2048, 777 4352, 778 4464, 779 8166, 780 17914, 781 32000, 782 65535 783 }; 784 785 /* 786 * Return the largest MTU smaller than val. If there is no 787 * entry, just return val. 788 */ 789 uint32_t 790 sctp_get_prev_mtu(uint32_t val) 791 { 792 uint32_t i; 793 794 if (val <= sctp_mtu_sizes[0]) { 795 return (val); 796 } 797 for (i = 1; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) { 798 if (val <= sctp_mtu_sizes[i]) { 799 break; 800 } 801 } 802 return (sctp_mtu_sizes[i - 1]); 803 } 804 805 /* 806 * Return the smallest MTU larger than val. If there is no 807 * entry, just return val. 808 */ 809 uint32_t 810 sctp_get_next_mtu(uint32_t val) 811 { 812 /* select another MTU that is just bigger than this one */ 813 uint32_t i; 814 815 for (i = 0; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) { 816 if (val < sctp_mtu_sizes[i]) { 817 return (sctp_mtu_sizes[i]); 818 } 819 } 820 return (val); 821 } 822 823 void 824 sctp_fill_random_store(struct sctp_pcb *m) 825 { 826 /* 827 * Here we use the MD5/SHA-1 to hash with our good randomNumbers and 828 * our counter. The result becomes our good random numbers and we 829 * then setup to give these out. Note that we do no locking to 830 * protect this. This is ok, since if competing folks call this we 831 * will get more gobbled gook in the random store which is what we 832 * want. There is a danger that two guys will use the same random 833 * numbers, but thats ok too since that is random as well :-> 834 */ 835 m->store_at = 0; 836 (void)sctp_hmac(SCTP_HMAC, (uint8_t *)m->random_numbers, 837 sizeof(m->random_numbers), (uint8_t *)&m->random_counter, 838 sizeof(m->random_counter), (uint8_t *)m->random_store); 839 m->random_counter++; 840 } 841 842 uint32_t 843 sctp_select_initial_TSN(struct sctp_pcb *inp) 844 { 845 /* 846 * A true implementation should use random selection process to get 847 * the initial stream sequence number, using RFC1750 as a good 848 * guideline 849 */ 850 uint32_t x, *xp; 851 uint8_t *p; 852 int store_at, new_store; 853 854 if (inp->initial_sequence_debug != 0) { 855 uint32_t ret; 856 857 ret = inp->initial_sequence_debug; 858 inp->initial_sequence_debug++; 859 return (ret); 860 } 861 retry: 862 store_at = inp->store_at; 863 new_store = store_at + sizeof(uint32_t); 864 if (new_store >= (SCTP_SIGNATURE_SIZE - 3)) { 865 new_store = 0; 866 } 867 if (!atomic_cmpset_int(&inp->store_at, store_at, new_store)) { 868 goto retry; 869 } 870 if (new_store == 0) { 871 /* Refill the random store */ 872 sctp_fill_random_store(inp); 873 } 874 p = &inp->random_store[store_at]; 875 xp = (uint32_t *)p; 876 x = *xp; 877 return (x); 878 } 879 880 uint32_t 881 sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int check) 882 { 883 uint32_t x; 884 struct timeval now; 885 886 if (check) { 887 (void)SCTP_GETTIME_TIMEVAL(&now); 888 } 889 for (;;) { 890 x = sctp_select_initial_TSN(&inp->sctp_ep); 891 if (x == 0) { 892 /* we never use 0 */ 893 continue; 894 } 895 if (!check || sctp_is_vtag_good(x, lport, rport, &now)) { 896 break; 897 } 898 } 899 return (x); 900 } 901 902 int32_t 903 sctp_map_assoc_state(int kernel_state) 904 { 905 int32_t user_state; 906 907 if (kernel_state & SCTP_STATE_WAS_ABORTED) { 908 user_state = SCTP_CLOSED; 909 } else if (kernel_state & SCTP_STATE_SHUTDOWN_PENDING) { 910 user_state = SCTP_SHUTDOWN_PENDING; 911 } else { 912 switch (kernel_state & SCTP_STATE_MASK) { 913 case SCTP_STATE_EMPTY: 914 user_state = SCTP_CLOSED; 915 break; 916 case SCTP_STATE_INUSE: 917 user_state = SCTP_CLOSED; 918 break; 919 case SCTP_STATE_COOKIE_WAIT: 920 user_state = SCTP_COOKIE_WAIT; 921 break; 922 case SCTP_STATE_COOKIE_ECHOED: 923 user_state = SCTP_COOKIE_ECHOED; 924 break; 925 case SCTP_STATE_OPEN: 926 user_state = SCTP_ESTABLISHED; 927 break; 928 case SCTP_STATE_SHUTDOWN_SENT: 929 user_state = SCTP_SHUTDOWN_SENT; 930 break; 931 case SCTP_STATE_SHUTDOWN_RECEIVED: 932 user_state = SCTP_SHUTDOWN_RECEIVED; 933 break; 934 case SCTP_STATE_SHUTDOWN_ACK_SENT: 935 user_state = SCTP_SHUTDOWN_ACK_SENT; 936 break; 937 default: 938 user_state = SCTP_CLOSED; 939 break; 940 } 941 } 942 return (user_state); 943 } 944 945 int 946 sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 947 uint32_t override_tag, uint32_t vrf_id, uint16_t o_strms) 948 { 949 struct sctp_association *asoc; 950 951 /* 952 * Anything set to zero is taken care of by the allocation routine's 953 * bzero 954 */ 955 956 /* 957 * Up front select what scoping to apply on addresses I tell my peer 958 * Not sure what to do with these right now, we will need to come up 959 * with a way to set them. We may need to pass them through from the 960 * caller in the sctp_aloc_assoc() function. 961 */ 962 int i; 963 #if defined(SCTP_DETAILED_STR_STATS) 964 int j; 965 #endif 966 967 asoc = &stcb->asoc; 968 /* init all variables to a known value. */ 969 SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE); 970 asoc->max_burst = inp->sctp_ep.max_burst; 971 asoc->fr_max_burst = inp->sctp_ep.fr_max_burst; 972 asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 973 asoc->cookie_life = inp->sctp_ep.def_cookie_life; 974 asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off; 975 asoc->ecn_supported = inp->ecn_supported; 976 asoc->prsctp_supported = inp->prsctp_supported; 977 asoc->idata_supported = inp->idata_supported; 978 asoc->auth_supported = inp->auth_supported; 979 asoc->asconf_supported = inp->asconf_supported; 980 asoc->reconfig_supported = inp->reconfig_supported; 981 asoc->nrsack_supported = inp->nrsack_supported; 982 asoc->pktdrop_supported = inp->pktdrop_supported; 983 asoc->idata_supported = inp->idata_supported; 984 asoc->sctp_cmt_pf = (uint8_t)0; 985 asoc->sctp_frag_point = inp->sctp_frag_point; 986 asoc->sctp_features = inp->sctp_features; 987 asoc->default_dscp = inp->sctp_ep.default_dscp; 988 asoc->max_cwnd = inp->max_cwnd; 989 #ifdef INET6 990 if (inp->sctp_ep.default_flowlabel) { 991 asoc->default_flowlabel = inp->sctp_ep.default_flowlabel; 992 } else { 993 if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) { 994 asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep); 995 asoc->default_flowlabel &= 0x000fffff; 996 asoc->default_flowlabel |= 0x80000000; 997 } else { 998 asoc->default_flowlabel = 0; 999 } 1000 } 1001 #endif 1002 asoc->sb_send_resv = 0; 1003 if (override_tag) { 1004 asoc->my_vtag = override_tag; 1005 } else { 1006 asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 1); 1007 } 1008 /* Get the nonce tags */ 1009 asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0); 1010 asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0); 1011 asoc->vrf_id = vrf_id; 1012 1013 #ifdef SCTP_ASOCLOG_OF_TSNS 1014 asoc->tsn_in_at = 0; 1015 asoc->tsn_out_at = 0; 1016 asoc->tsn_in_wrapped = 0; 1017 asoc->tsn_out_wrapped = 0; 1018 asoc->cumack_log_at = 0; 1019 asoc->cumack_log_atsnt = 0; 1020 #endif 1021 #ifdef SCTP_FS_SPEC_LOG 1022 asoc->fs_index = 0; 1023 #endif 1024 asoc->refcnt = 0; 1025 asoc->assoc_up_sent = 0; 1026 asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq = 1027 sctp_select_initial_TSN(&inp->sctp_ep); 1028 asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1; 1029 /* we are optimisitic here */ 1030 asoc->peer_supports_nat = 0; 1031 asoc->sent_queue_retran_cnt = 0; 1032 1033 /* for CMT */ 1034 asoc->last_net_cmt_send_started = NULL; 1035 1036 /* This will need to be adjusted */ 1037 asoc->last_acked_seq = asoc->init_seq_number - 1; 1038 asoc->advanced_peer_ack_point = asoc->last_acked_seq; 1039 asoc->asconf_seq_in = asoc->last_acked_seq; 1040 1041 /* here we are different, we hold the next one we expect */ 1042 asoc->str_reset_seq_in = asoc->last_acked_seq + 1; 1043 1044 asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max; 1045 asoc->initial_rto = inp->sctp_ep.initial_rto; 1046 1047 asoc->default_mtu = inp->sctp_ep.default_mtu; 1048 asoc->max_init_times = inp->sctp_ep.max_init_times; 1049 asoc->max_send_times = inp->sctp_ep.max_send_times; 1050 asoc->def_net_failure = inp->sctp_ep.def_net_failure; 1051 asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold; 1052 asoc->free_chunk_cnt = 0; 1053 1054 asoc->iam_blocking = 0; 1055 asoc->context = inp->sctp_context; 1056 asoc->local_strreset_support = inp->local_strreset_support; 1057 asoc->def_send = inp->def_send; 1058 asoc->delayed_ack = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 1059 asoc->sack_freq = inp->sctp_ep.sctp_sack_freq; 1060 asoc->pr_sctp_cnt = 0; 1061 asoc->total_output_queue_size = 0; 1062 1063 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1064 asoc->scope.ipv6_addr_legal = 1; 1065 if (SCTP_IPV6_V6ONLY(inp) == 0) { 1066 asoc->scope.ipv4_addr_legal = 1; 1067 } else { 1068 asoc->scope.ipv4_addr_legal = 0; 1069 } 1070 } else { 1071 asoc->scope.ipv6_addr_legal = 0; 1072 asoc->scope.ipv4_addr_legal = 1; 1073 } 1074 1075 asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND); 1076 asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket); 1077 1078 asoc->smallest_mtu = inp->sctp_frag_point; 1079 asoc->minrto = inp->sctp_ep.sctp_minrto; 1080 asoc->maxrto = inp->sctp_ep.sctp_maxrto; 1081 1082 asoc->stream_locked_on = 0; 1083 asoc->ecn_echo_cnt_onq = 0; 1084 asoc->stream_locked = 0; 1085 1086 asoc->send_sack = 1; 1087 1088 LIST_INIT(&asoc->sctp_restricted_addrs); 1089 1090 TAILQ_INIT(&asoc->nets); 1091 TAILQ_INIT(&asoc->pending_reply_queue); 1092 TAILQ_INIT(&asoc->asconf_ack_sent); 1093 /* Setup to fill the hb random cache at first HB */ 1094 asoc->hb_random_idx = 4; 1095 1096 asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time; 1097 1098 stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module; 1099 stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module]; 1100 1101 stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module; 1102 stcb->asoc.ss_functions = sctp_ss_functions[inp->sctp_ep.sctp_default_ss_module]; 1103 1104 /* 1105 * Now the stream parameters, here we allocate space for all streams 1106 * that we request by default. 1107 */ 1108 asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams = 1109 o_strms; 1110 SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *, 1111 asoc->streamoutcnt * sizeof(struct sctp_stream_out), 1112 SCTP_M_STRMO); 1113 if (asoc->strmout == NULL) { 1114 /* big trouble no memory */ 1115 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 1116 return (ENOMEM); 1117 } 1118 for (i = 0; i < asoc->streamoutcnt; i++) { 1119 /* 1120 * inbound side must be set to 0xffff, also NOTE when we get 1121 * the INIT-ACK back (for INIT sender) we MUST reduce the 1122 * count (streamoutcnt) but first check if we sent to any of 1123 * the upper streams that were dropped (if some were). Those 1124 * that were dropped must be notified to the upper layer as 1125 * failed to send. 1126 */ 1127 asoc->strmout[i].next_mid_ordered = 0; 1128 asoc->strmout[i].next_mid_unordered = 0; 1129 TAILQ_INIT(&asoc->strmout[i].outqueue); 1130 asoc->strmout[i].chunks_on_queues = 0; 1131 #if defined(SCTP_DETAILED_STR_STATS) 1132 for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) { 1133 asoc->strmout[i].abandoned_sent[j] = 0; 1134 asoc->strmout[i].abandoned_unsent[j] = 0; 1135 } 1136 #else 1137 asoc->strmout[i].abandoned_sent[0] = 0; 1138 asoc->strmout[i].abandoned_unsent[0] = 0; 1139 #endif 1140 asoc->strmout[i].sid = i; 1141 asoc->strmout[i].last_msg_incomplete = 0; 1142 asoc->strmout[i].state = SCTP_STREAM_OPENING; 1143 asoc->ss_functions.sctp_ss_init_stream(stcb, &asoc->strmout[i], NULL); 1144 } 1145 asoc->ss_functions.sctp_ss_init(stcb, asoc, 0); 1146 1147 /* Now the mapping array */ 1148 asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY; 1149 SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size, 1150 SCTP_M_MAP); 1151 if (asoc->mapping_array == NULL) { 1152 SCTP_FREE(asoc->strmout, SCTP_M_STRMO); 1153 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 1154 return (ENOMEM); 1155 } 1156 memset(asoc->mapping_array, 0, asoc->mapping_array_size); 1157 SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size, 1158 SCTP_M_MAP); 1159 if (asoc->nr_mapping_array == NULL) { 1160 SCTP_FREE(asoc->strmout, SCTP_M_STRMO); 1161 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP); 1162 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 1163 return (ENOMEM); 1164 } 1165 memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size); 1166 1167 /* Now the init of the other outqueues */ 1168 TAILQ_INIT(&asoc->free_chunks); 1169 TAILQ_INIT(&asoc->control_send_queue); 1170 TAILQ_INIT(&asoc->asconf_send_queue); 1171 TAILQ_INIT(&asoc->send_queue); 1172 TAILQ_INIT(&asoc->sent_queue); 1173 TAILQ_INIT(&asoc->resetHead); 1174 asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome; 1175 TAILQ_INIT(&asoc->asconf_queue); 1176 /* authentication fields */ 1177 asoc->authinfo.random = NULL; 1178 asoc->authinfo.active_keyid = 0; 1179 asoc->authinfo.assoc_key = NULL; 1180 asoc->authinfo.assoc_keyid = 0; 1181 asoc->authinfo.recv_key = NULL; 1182 asoc->authinfo.recv_keyid = 0; 1183 LIST_INIT(&asoc->shared_keys); 1184 asoc->marked_retrans = 0; 1185 asoc->port = inp->sctp_ep.port; 1186 asoc->timoinit = 0; 1187 asoc->timodata = 0; 1188 asoc->timosack = 0; 1189 asoc->timoshutdown = 0; 1190 asoc->timoheartbeat = 0; 1191 asoc->timocookie = 0; 1192 asoc->timoshutdownack = 0; 1193 (void)SCTP_GETTIME_TIMEVAL(&asoc->start_time); 1194 asoc->discontinuity_time = asoc->start_time; 1195 for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) { 1196 asoc->abandoned_unsent[i] = 0; 1197 asoc->abandoned_sent[i] = 0; 1198 } 1199 /* 1200 * sa_ignore MEMLEAK {memory is put in the assoc mapping array and 1201 * freed later when the association is freed. 1202 */ 1203 return (0); 1204 } 1205 1206 void 1207 sctp_print_mapping_array(struct sctp_association *asoc) 1208 { 1209 unsigned int i, limit; 1210 1211 SCTP_PRINTF("Mapping array size: %d, baseTSN: %8.8x, cumAck: %8.8x, highestTSN: (%8.8x, %8.8x).\n", 1212 asoc->mapping_array_size, 1213 asoc->mapping_array_base_tsn, 1214 asoc->cumulative_tsn, 1215 asoc->highest_tsn_inside_map, 1216 asoc->highest_tsn_inside_nr_map); 1217 for (limit = asoc->mapping_array_size; limit > 1; limit--) { 1218 if (asoc->mapping_array[limit - 1] != 0) { 1219 break; 1220 } 1221 } 1222 SCTP_PRINTF("Renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit); 1223 for (i = 0; i < limit; i++) { 1224 SCTP_PRINTF("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n'); 1225 } 1226 if (limit % 16) 1227 SCTP_PRINTF("\n"); 1228 for (limit = asoc->mapping_array_size; limit > 1; limit--) { 1229 if (asoc->nr_mapping_array[limit - 1]) { 1230 break; 1231 } 1232 } 1233 SCTP_PRINTF("Non renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit); 1234 for (i = 0; i < limit; i++) { 1235 SCTP_PRINTF("%2.2x%c", asoc->nr_mapping_array[i], ((i + 1) % 16) ? ' ' : '\n'); 1236 } 1237 if (limit % 16) 1238 SCTP_PRINTF("\n"); 1239 } 1240 1241 int 1242 sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed) 1243 { 1244 /* mapping array needs to grow */ 1245 uint8_t *new_array1, *new_array2; 1246 uint32_t new_size; 1247 1248 new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR); 1249 SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP); 1250 SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP); 1251 if ((new_array1 == NULL) || (new_array2 == NULL)) { 1252 /* can't get more, forget it */ 1253 SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n", new_size); 1254 if (new_array1) { 1255 SCTP_FREE(new_array1, SCTP_M_MAP); 1256 } 1257 if (new_array2) { 1258 SCTP_FREE(new_array2, SCTP_M_MAP); 1259 } 1260 return (-1); 1261 } 1262 memset(new_array1, 0, new_size); 1263 memset(new_array2, 0, new_size); 1264 memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size); 1265 memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size); 1266 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP); 1267 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP); 1268 asoc->mapping_array = new_array1; 1269 asoc->nr_mapping_array = new_array2; 1270 asoc->mapping_array_size = new_size; 1271 return (0); 1272 } 1273 1274 1275 static void 1276 sctp_iterator_work(struct sctp_iterator *it) 1277 { 1278 int iteration_count = 0; 1279 int inp_skip = 0; 1280 int first_in = 1; 1281 struct sctp_inpcb *tinp; 1282 1283 SCTP_INP_INFO_RLOCK(); 1284 SCTP_ITERATOR_LOCK(); 1285 sctp_it_ctl.cur_it = it; 1286 if (it->inp) { 1287 SCTP_INP_RLOCK(it->inp); 1288 SCTP_INP_DECR_REF(it->inp); 1289 } 1290 if (it->inp == NULL) { 1291 /* iterator is complete */ 1292 done_with_iterator: 1293 sctp_it_ctl.cur_it = NULL; 1294 SCTP_ITERATOR_UNLOCK(); 1295 SCTP_INP_INFO_RUNLOCK(); 1296 if (it->function_atend != NULL) { 1297 (*it->function_atend) (it->pointer, it->val); 1298 } 1299 SCTP_FREE(it, SCTP_M_ITER); 1300 return; 1301 } 1302 select_a_new_ep: 1303 if (first_in) { 1304 first_in = 0; 1305 } else { 1306 SCTP_INP_RLOCK(it->inp); 1307 } 1308 while (((it->pcb_flags) && 1309 ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) || 1310 ((it->pcb_features) && 1311 ((it->inp->sctp_features & it->pcb_features) != it->pcb_features))) { 1312 /* endpoint flags or features don't match, so keep looking */ 1313 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { 1314 SCTP_INP_RUNLOCK(it->inp); 1315 goto done_with_iterator; 1316 } 1317 tinp = it->inp; 1318 it->inp = LIST_NEXT(it->inp, sctp_list); 1319 SCTP_INP_RUNLOCK(tinp); 1320 if (it->inp == NULL) { 1321 goto done_with_iterator; 1322 } 1323 SCTP_INP_RLOCK(it->inp); 1324 } 1325 /* now go through each assoc which is in the desired state */ 1326 if (it->done_current_ep == 0) { 1327 if (it->function_inp != NULL) 1328 inp_skip = (*it->function_inp) (it->inp, it->pointer, it->val); 1329 it->done_current_ep = 1; 1330 } 1331 if (it->stcb == NULL) { 1332 /* run the per instance function */ 1333 it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list); 1334 } 1335 if ((inp_skip) || it->stcb == NULL) { 1336 if (it->function_inp_end != NULL) { 1337 inp_skip = (*it->function_inp_end) (it->inp, 1338 it->pointer, 1339 it->val); 1340 } 1341 SCTP_INP_RUNLOCK(it->inp); 1342 goto no_stcb; 1343 } 1344 while (it->stcb) { 1345 SCTP_TCB_LOCK(it->stcb); 1346 if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) { 1347 /* not in the right state... keep looking */ 1348 SCTP_TCB_UNLOCK(it->stcb); 1349 goto next_assoc; 1350 } 1351 /* see if we have limited out the iterator loop */ 1352 iteration_count++; 1353 if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) { 1354 /* Pause to let others grab the lock */ 1355 atomic_add_int(&it->stcb->asoc.refcnt, 1); 1356 SCTP_TCB_UNLOCK(it->stcb); 1357 SCTP_INP_INCR_REF(it->inp); 1358 SCTP_INP_RUNLOCK(it->inp); 1359 SCTP_ITERATOR_UNLOCK(); 1360 SCTP_INP_INFO_RUNLOCK(); 1361 SCTP_INP_INFO_RLOCK(); 1362 SCTP_ITERATOR_LOCK(); 1363 if (sctp_it_ctl.iterator_flags) { 1364 /* We won't be staying here */ 1365 SCTP_INP_DECR_REF(it->inp); 1366 atomic_add_int(&it->stcb->asoc.refcnt, -1); 1367 if (sctp_it_ctl.iterator_flags & 1368 SCTP_ITERATOR_STOP_CUR_IT) { 1369 sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_IT; 1370 goto done_with_iterator; 1371 } 1372 if (sctp_it_ctl.iterator_flags & 1373 SCTP_ITERATOR_STOP_CUR_INP) { 1374 sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_INP; 1375 goto no_stcb; 1376 } 1377 /* If we reach here huh? */ 1378 SCTP_PRINTF("Unknown it ctl flag %x\n", 1379 sctp_it_ctl.iterator_flags); 1380 sctp_it_ctl.iterator_flags = 0; 1381 } 1382 SCTP_INP_RLOCK(it->inp); 1383 SCTP_INP_DECR_REF(it->inp); 1384 SCTP_TCB_LOCK(it->stcb); 1385 atomic_add_int(&it->stcb->asoc.refcnt, -1); 1386 iteration_count = 0; 1387 } 1388 /* run function on this one */ 1389 (*it->function_assoc) (it->inp, it->stcb, it->pointer, it->val); 1390 1391 /* 1392 * we lie here, it really needs to have its own type but 1393 * first I must verify that this won't effect things :-0 1394 */ 1395 if (it->no_chunk_output == 0) 1396 sctp_chunk_output(it->inp, it->stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED); 1397 1398 SCTP_TCB_UNLOCK(it->stcb); 1399 next_assoc: 1400 it->stcb = LIST_NEXT(it->stcb, sctp_tcblist); 1401 if (it->stcb == NULL) { 1402 /* Run last function */ 1403 if (it->function_inp_end != NULL) { 1404 inp_skip = (*it->function_inp_end) (it->inp, 1405 it->pointer, 1406 it->val); 1407 } 1408 } 1409 } 1410 SCTP_INP_RUNLOCK(it->inp); 1411 no_stcb: 1412 /* done with all assocs on this endpoint, move on to next endpoint */ 1413 it->done_current_ep = 0; 1414 if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { 1415 it->inp = NULL; 1416 } else { 1417 it->inp = LIST_NEXT(it->inp, sctp_list); 1418 } 1419 if (it->inp == NULL) { 1420 goto done_with_iterator; 1421 } 1422 goto select_a_new_ep; 1423 } 1424 1425 void 1426 sctp_iterator_worker(void) 1427 { 1428 struct sctp_iterator *it, *nit; 1429 1430 /* This function is called with the WQ lock in place */ 1431 1432 sctp_it_ctl.iterator_running = 1; 1433 TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { 1434 /* now lets work on this one */ 1435 TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); 1436 SCTP_IPI_ITERATOR_WQ_UNLOCK(); 1437 CURVNET_SET(it->vn); 1438 sctp_iterator_work(it); 1439 CURVNET_RESTORE(); 1440 SCTP_IPI_ITERATOR_WQ_LOCK(); 1441 /* sa_ignore FREED_MEMORY */ 1442 } 1443 sctp_it_ctl.iterator_running = 0; 1444 return; 1445 } 1446 1447 1448 static void 1449 sctp_handle_addr_wq(void) 1450 { 1451 /* deal with the ADDR wq from the rtsock calls */ 1452 struct sctp_laddr *wi, *nwi; 1453 struct sctp_asconf_iterator *asc; 1454 1455 SCTP_MALLOC(asc, struct sctp_asconf_iterator *, 1456 sizeof(struct sctp_asconf_iterator), SCTP_M_ASC_IT); 1457 if (asc == NULL) { 1458 /* Try later, no memory */ 1459 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, 1460 (struct sctp_inpcb *)NULL, 1461 (struct sctp_tcb *)NULL, 1462 (struct sctp_nets *)NULL); 1463 return; 1464 } 1465 LIST_INIT(&asc->list_of_work); 1466 asc->cnt = 0; 1467 1468 LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { 1469 LIST_REMOVE(wi, sctp_nxt_addr); 1470 LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr); 1471 asc->cnt++; 1472 } 1473 1474 if (asc->cnt == 0) { 1475 SCTP_FREE(asc, SCTP_M_ASC_IT); 1476 } else { 1477 int ret; 1478 1479 ret = sctp_initiate_iterator(sctp_asconf_iterator_ep, 1480 sctp_asconf_iterator_stcb, 1481 NULL, /* No ep end for boundall */ 1482 SCTP_PCB_FLAGS_BOUNDALL, 1483 SCTP_PCB_ANY_FEATURES, 1484 SCTP_ASOC_ANY_STATE, 1485 (void *)asc, 0, 1486 sctp_asconf_iterator_end, NULL, 0); 1487 if (ret) { 1488 SCTP_PRINTF("Failed to initiate iterator for handle_addr_wq\n"); 1489 /* 1490 * Freeing if we are stopping or put back on the 1491 * addr_wq. 1492 */ 1493 if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) { 1494 sctp_asconf_iterator_end(asc, 0); 1495 } else { 1496 LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) { 1497 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); 1498 } 1499 SCTP_FREE(asc, SCTP_M_ASC_IT); 1500 } 1501 } 1502 } 1503 } 1504 1505 void 1506 sctp_timeout_handler(void *t) 1507 { 1508 struct sctp_inpcb *inp; 1509 struct sctp_tcb *stcb; 1510 struct sctp_nets *net; 1511 struct sctp_timer *tmr; 1512 struct mbuf *op_err; 1513 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 1514 struct socket *so; 1515 #endif 1516 int did_output; 1517 int type; 1518 1519 tmr = (struct sctp_timer *)t; 1520 inp = (struct sctp_inpcb *)tmr->ep; 1521 stcb = (struct sctp_tcb *)tmr->tcb; 1522 net = (struct sctp_nets *)tmr->net; 1523 CURVNET_SET((struct vnet *)tmr->vnet); 1524 did_output = 1; 1525 1526 #ifdef SCTP_AUDITING_ENABLED 1527 sctp_audit_log(0xF0, (uint8_t)tmr->type); 1528 sctp_auditing(3, inp, stcb, net); 1529 #endif 1530 1531 /* sanity checks... */ 1532 if (tmr->self != (void *)tmr) { 1533 /* 1534 * SCTP_PRINTF("Stale SCTP timer fired (%p), ignoring...\n", 1535 * (void *)tmr); 1536 */ 1537 CURVNET_RESTORE(); 1538 return; 1539 } 1540 tmr->stopped_from = 0xa001; 1541 if (!SCTP_IS_TIMER_TYPE_VALID(tmr->type)) { 1542 /* 1543 * SCTP_PRINTF("SCTP timer fired with invalid type: 0x%x\n", 1544 * tmr->type); 1545 */ 1546 CURVNET_RESTORE(); 1547 return; 1548 } 1549 tmr->stopped_from = 0xa002; 1550 if ((tmr->type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) { 1551 CURVNET_RESTORE(); 1552 return; 1553 } 1554 /* if this is an iterator timeout, get the struct and clear inp */ 1555 tmr->stopped_from = 0xa003; 1556 if (inp) { 1557 SCTP_INP_INCR_REF(inp); 1558 if ((inp->sctp_socket == NULL) && 1559 ((tmr->type != SCTP_TIMER_TYPE_INPKILL) && 1560 (tmr->type != SCTP_TIMER_TYPE_INIT) && 1561 (tmr->type != SCTP_TIMER_TYPE_SEND) && 1562 (tmr->type != SCTP_TIMER_TYPE_RECV) && 1563 (tmr->type != SCTP_TIMER_TYPE_HEARTBEAT) && 1564 (tmr->type != SCTP_TIMER_TYPE_SHUTDOWN) && 1565 (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNACK) && 1566 (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNGUARD) && 1567 (tmr->type != SCTP_TIMER_TYPE_ASOCKILL))) { 1568 SCTP_INP_DECR_REF(inp); 1569 CURVNET_RESTORE(); 1570 return; 1571 } 1572 } 1573 tmr->stopped_from = 0xa004; 1574 if (stcb) { 1575 atomic_add_int(&stcb->asoc.refcnt, 1); 1576 if (stcb->asoc.state == 0) { 1577 atomic_add_int(&stcb->asoc.refcnt, -1); 1578 if (inp) { 1579 SCTP_INP_DECR_REF(inp); 1580 } 1581 CURVNET_RESTORE(); 1582 return; 1583 } 1584 } 1585 type = tmr->type; 1586 tmr->stopped_from = 0xa005; 1587 SCTPDBG(SCTP_DEBUG_TIMER1, "Timer type %d goes off\n", type); 1588 if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) { 1589 if (inp) { 1590 SCTP_INP_DECR_REF(inp); 1591 } 1592 if (stcb) { 1593 atomic_add_int(&stcb->asoc.refcnt, -1); 1594 } 1595 CURVNET_RESTORE(); 1596 return; 1597 } 1598 tmr->stopped_from = 0xa006; 1599 1600 if (stcb) { 1601 SCTP_TCB_LOCK(stcb); 1602 atomic_add_int(&stcb->asoc.refcnt, -1); 1603 if ((type != SCTP_TIMER_TYPE_ASOCKILL) && 1604 ((stcb->asoc.state == 0) || 1605 (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED))) { 1606 SCTP_TCB_UNLOCK(stcb); 1607 if (inp) { 1608 SCTP_INP_DECR_REF(inp); 1609 } 1610 CURVNET_RESTORE(); 1611 return; 1612 } 1613 } else if (inp != NULL) { 1614 if (type != SCTP_TIMER_TYPE_INPKILL) { 1615 SCTP_INP_WLOCK(inp); 1616 } 1617 } else { 1618 SCTP_WQ_ADDR_LOCK(); 1619 } 1620 /* record in stopped what t-o occurred */ 1621 tmr->stopped_from = type; 1622 1623 /* mark as being serviced now */ 1624 if (SCTP_OS_TIMER_PENDING(&tmr->timer)) { 1625 /* 1626 * Callout has been rescheduled. 1627 */ 1628 goto get_out; 1629 } 1630 if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) { 1631 /* 1632 * Not active, so no action. 1633 */ 1634 goto get_out; 1635 } 1636 SCTP_OS_TIMER_DEACTIVATE(&tmr->timer); 1637 1638 /* call the handler for the appropriate timer type */ 1639 switch (type) { 1640 case SCTP_TIMER_TYPE_ADDR_WQ: 1641 sctp_handle_addr_wq(); 1642 break; 1643 case SCTP_TIMER_TYPE_SEND: 1644 if ((stcb == NULL) || (inp == NULL)) { 1645 break; 1646 } 1647 SCTP_STAT_INCR(sctps_timodata); 1648 stcb->asoc.timodata++; 1649 stcb->asoc.num_send_timers_up--; 1650 if (stcb->asoc.num_send_timers_up < 0) { 1651 stcb->asoc.num_send_timers_up = 0; 1652 } 1653 SCTP_TCB_LOCK_ASSERT(stcb); 1654 if (sctp_t3rxt_timer(inp, stcb, net)) { 1655 /* no need to unlock on tcb its gone */ 1656 1657 goto out_decr; 1658 } 1659 SCTP_TCB_LOCK_ASSERT(stcb); 1660 #ifdef SCTP_AUDITING_ENABLED 1661 sctp_auditing(4, inp, stcb, net); 1662 #endif 1663 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED); 1664 if ((stcb->asoc.num_send_timers_up == 0) && 1665 (stcb->asoc.sent_queue_cnt > 0)) { 1666 struct sctp_tmit_chunk *chk; 1667 1668 /* 1669 * safeguard. If there on some on the sent queue 1670 * somewhere but no timers running something is 1671 * wrong... so we start a timer on the first chunk 1672 * on the send queue on whatever net it is sent to. 1673 */ 1674 chk = TAILQ_FIRST(&stcb->asoc.sent_queue); 1675 sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, 1676 chk->whoTo); 1677 } 1678 break; 1679 case SCTP_TIMER_TYPE_INIT: 1680 if ((stcb == NULL) || (inp == NULL)) { 1681 break; 1682 } 1683 SCTP_STAT_INCR(sctps_timoinit); 1684 stcb->asoc.timoinit++; 1685 if (sctp_t1init_timer(inp, stcb, net)) { 1686 /* no need to unlock on tcb its gone */ 1687 goto out_decr; 1688 } 1689 /* We do output but not here */ 1690 did_output = 0; 1691 break; 1692 case SCTP_TIMER_TYPE_RECV: 1693 if ((stcb == NULL) || (inp == NULL)) { 1694 break; 1695 } 1696 SCTP_STAT_INCR(sctps_timosack); 1697 stcb->asoc.timosack++; 1698 sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); 1699 #ifdef SCTP_AUDITING_ENABLED 1700 sctp_auditing(4, inp, stcb, net); 1701 #endif 1702 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SACK_TMR, SCTP_SO_NOT_LOCKED); 1703 break; 1704 case SCTP_TIMER_TYPE_SHUTDOWN: 1705 if ((stcb == NULL) || (inp == NULL)) { 1706 break; 1707 } 1708 if (sctp_shutdown_timer(inp, stcb, net)) { 1709 /* no need to unlock on tcb its gone */ 1710 goto out_decr; 1711 } 1712 SCTP_STAT_INCR(sctps_timoshutdown); 1713 stcb->asoc.timoshutdown++; 1714 #ifdef SCTP_AUDITING_ENABLED 1715 sctp_auditing(4, inp, stcb, net); 1716 #endif 1717 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_TMR, SCTP_SO_NOT_LOCKED); 1718 break; 1719 case SCTP_TIMER_TYPE_HEARTBEAT: 1720 if ((stcb == NULL) || (inp == NULL) || (net == NULL)) { 1721 break; 1722 } 1723 SCTP_STAT_INCR(sctps_timoheartbeat); 1724 stcb->asoc.timoheartbeat++; 1725 if (sctp_heartbeat_timer(inp, stcb, net)) { 1726 /* no need to unlock on tcb its gone */ 1727 goto out_decr; 1728 } 1729 #ifdef SCTP_AUDITING_ENABLED 1730 sctp_auditing(4, inp, stcb, net); 1731 #endif 1732 if (!(net->dest_state & SCTP_ADDR_NOHB)) { 1733 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 1734 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_HB_TMR, SCTP_SO_NOT_LOCKED); 1735 } 1736 break; 1737 case SCTP_TIMER_TYPE_COOKIE: 1738 if ((stcb == NULL) || (inp == NULL)) { 1739 break; 1740 } 1741 if (sctp_cookie_timer(inp, stcb, net)) { 1742 /* no need to unlock on tcb its gone */ 1743 goto out_decr; 1744 } 1745 SCTP_STAT_INCR(sctps_timocookie); 1746 stcb->asoc.timocookie++; 1747 #ifdef SCTP_AUDITING_ENABLED 1748 sctp_auditing(4, inp, stcb, net); 1749 #endif 1750 /* 1751 * We consider T3 and Cookie timer pretty much the same with 1752 * respect to where from in chunk_output. 1753 */ 1754 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED); 1755 break; 1756 case SCTP_TIMER_TYPE_NEWCOOKIE: 1757 { 1758 struct timeval tv; 1759 int i, secret; 1760 1761 if (inp == NULL) { 1762 break; 1763 } 1764 SCTP_STAT_INCR(sctps_timosecret); 1765 (void)SCTP_GETTIME_TIMEVAL(&tv); 1766 inp->sctp_ep.time_of_secret_change = tv.tv_sec; 1767 inp->sctp_ep.last_secret_number = 1768 inp->sctp_ep.current_secret_number; 1769 inp->sctp_ep.current_secret_number++; 1770 if (inp->sctp_ep.current_secret_number >= 1771 SCTP_HOW_MANY_SECRETS) { 1772 inp->sctp_ep.current_secret_number = 0; 1773 } 1774 secret = (int)inp->sctp_ep.current_secret_number; 1775 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) { 1776 inp->sctp_ep.secret_key[secret][i] = 1777 sctp_select_initial_TSN(&inp->sctp_ep); 1778 } 1779 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net); 1780 } 1781 did_output = 0; 1782 break; 1783 case SCTP_TIMER_TYPE_PATHMTURAISE: 1784 if ((stcb == NULL) || (inp == NULL)) { 1785 break; 1786 } 1787 SCTP_STAT_INCR(sctps_timopathmtu); 1788 sctp_pathmtu_timer(inp, stcb, net); 1789 did_output = 0; 1790 break; 1791 case SCTP_TIMER_TYPE_SHUTDOWNACK: 1792 if ((stcb == NULL) || (inp == NULL)) { 1793 break; 1794 } 1795 if (sctp_shutdownack_timer(inp, stcb, net)) { 1796 /* no need to unlock on tcb its gone */ 1797 goto out_decr; 1798 } 1799 SCTP_STAT_INCR(sctps_timoshutdownack); 1800 stcb->asoc.timoshutdownack++; 1801 #ifdef SCTP_AUDITING_ENABLED 1802 sctp_auditing(4, inp, stcb, net); 1803 #endif 1804 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_ACK_TMR, SCTP_SO_NOT_LOCKED); 1805 break; 1806 case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 1807 if ((stcb == NULL) || (inp == NULL)) { 1808 break; 1809 } 1810 SCTP_STAT_INCR(sctps_timoshutdownguard); 1811 op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), 1812 "Shutdown guard timer expired"); 1813 sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED); 1814 /* no need to unlock on tcb its gone */ 1815 goto out_decr; 1816 1817 case SCTP_TIMER_TYPE_STRRESET: 1818 if ((stcb == NULL) || (inp == NULL)) { 1819 break; 1820 } 1821 if (sctp_strreset_timer(inp, stcb, net)) { 1822 /* no need to unlock on tcb its gone */ 1823 goto out_decr; 1824 } 1825 SCTP_STAT_INCR(sctps_timostrmrst); 1826 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_TMR, SCTP_SO_NOT_LOCKED); 1827 break; 1828 case SCTP_TIMER_TYPE_ASCONF: 1829 if ((stcb == NULL) || (inp == NULL)) { 1830 break; 1831 } 1832 if (sctp_asconf_timer(inp, stcb, net)) { 1833 /* no need to unlock on tcb its gone */ 1834 goto out_decr; 1835 } 1836 SCTP_STAT_INCR(sctps_timoasconf); 1837 #ifdef SCTP_AUDITING_ENABLED 1838 sctp_auditing(4, inp, stcb, net); 1839 #endif 1840 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_ASCONF_TMR, SCTP_SO_NOT_LOCKED); 1841 break; 1842 case SCTP_TIMER_TYPE_PRIM_DELETED: 1843 if ((stcb == NULL) || (inp == NULL)) { 1844 break; 1845 } 1846 sctp_delete_prim_timer(inp, stcb, net); 1847 SCTP_STAT_INCR(sctps_timodelprim); 1848 break; 1849 1850 case SCTP_TIMER_TYPE_AUTOCLOSE: 1851 if ((stcb == NULL) || (inp == NULL)) { 1852 break; 1853 } 1854 SCTP_STAT_INCR(sctps_timoautoclose); 1855 sctp_autoclose_timer(inp, stcb, net); 1856 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR, SCTP_SO_NOT_LOCKED); 1857 did_output = 0; 1858 break; 1859 case SCTP_TIMER_TYPE_ASOCKILL: 1860 if ((stcb == NULL) || (inp == NULL)) { 1861 break; 1862 } 1863 SCTP_STAT_INCR(sctps_timoassockill); 1864 /* Can we free it yet? */ 1865 SCTP_INP_DECR_REF(inp); 1866 sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL, 1867 SCTP_FROM_SCTPUTIL + SCTP_LOC_1); 1868 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 1869 so = SCTP_INP_SO(inp); 1870 atomic_add_int(&stcb->asoc.refcnt, 1); 1871 SCTP_TCB_UNLOCK(stcb); 1872 SCTP_SOCKET_LOCK(so, 1); 1873 SCTP_TCB_LOCK(stcb); 1874 atomic_subtract_int(&stcb->asoc.refcnt, 1); 1875 #endif 1876 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 1877 SCTP_FROM_SCTPUTIL + SCTP_LOC_2); 1878 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 1879 SCTP_SOCKET_UNLOCK(so, 1); 1880 #endif 1881 /* 1882 * free asoc, always unlocks (or destroy's) so prevent 1883 * duplicate unlock or unlock of a free mtx :-0 1884 */ 1885 stcb = NULL; 1886 goto out_no_decr; 1887 case SCTP_TIMER_TYPE_INPKILL: 1888 SCTP_STAT_INCR(sctps_timoinpkill); 1889 if (inp == NULL) { 1890 break; 1891 } 1892 /* 1893 * special case, take away our increment since WE are the 1894 * killer 1895 */ 1896 SCTP_INP_DECR_REF(inp); 1897 sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL, 1898 SCTP_FROM_SCTPUTIL + SCTP_LOC_3); 1899 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 1900 SCTP_CALLED_FROM_INPKILL_TIMER); 1901 inp = NULL; 1902 goto out_no_decr; 1903 default: 1904 SCTPDBG(SCTP_DEBUG_TIMER1, "sctp_timeout_handler:unknown timer %d\n", 1905 type); 1906 break; 1907 } 1908 #ifdef SCTP_AUDITING_ENABLED 1909 sctp_audit_log(0xF1, (uint8_t)type); 1910 if (inp) 1911 sctp_auditing(5, inp, stcb, net); 1912 #endif 1913 if ((did_output) && stcb) { 1914 /* 1915 * Now we need to clean up the control chunk chain if an 1916 * ECNE is on it. It must be marked as UNSENT again so next 1917 * call will continue to send it until such time that we get 1918 * a CWR, to remove it. It is, however, less likely that we 1919 * will find a ecn echo on the chain though. 1920 */ 1921 sctp_fix_ecn_echo(&stcb->asoc); 1922 } 1923 get_out: 1924 if (stcb) { 1925 SCTP_TCB_UNLOCK(stcb); 1926 } else if (inp != NULL) { 1927 SCTP_INP_WUNLOCK(inp); 1928 } else { 1929 SCTP_WQ_ADDR_UNLOCK(); 1930 } 1931 1932 out_decr: 1933 if (inp) { 1934 SCTP_INP_DECR_REF(inp); 1935 } 1936 out_no_decr: 1937 SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type = %d)\n", type); 1938 CURVNET_RESTORE(); 1939 } 1940 1941 void 1942 sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1943 struct sctp_nets *net) 1944 { 1945 uint32_t to_ticks; 1946 struct sctp_timer *tmr; 1947 1948 if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) 1949 return; 1950 1951 tmr = NULL; 1952 if (stcb) { 1953 SCTP_TCB_LOCK_ASSERT(stcb); 1954 } 1955 switch (t_type) { 1956 case SCTP_TIMER_TYPE_ADDR_WQ: 1957 /* Only 1 tick away :-) */ 1958 tmr = &SCTP_BASE_INFO(addr_wq_timer); 1959 to_ticks = SCTP_ADDRESS_TICK_DELAY; 1960 break; 1961 case SCTP_TIMER_TYPE_SEND: 1962 /* Here we use the RTO timer */ 1963 { 1964 int rto_val; 1965 1966 if ((stcb == NULL) || (net == NULL)) { 1967 return; 1968 } 1969 tmr = &net->rxt_timer; 1970 if (net->RTO == 0) { 1971 rto_val = stcb->asoc.initial_rto; 1972 } else { 1973 rto_val = net->RTO; 1974 } 1975 to_ticks = MSEC_TO_TICKS(rto_val); 1976 } 1977 break; 1978 case SCTP_TIMER_TYPE_INIT: 1979 /* 1980 * Here we use the INIT timer default usually about 1 1981 * minute. 1982 */ 1983 if ((stcb == NULL) || (net == NULL)) { 1984 return; 1985 } 1986 tmr = &net->rxt_timer; 1987 if (net->RTO == 0) { 1988 to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 1989 } else { 1990 to_ticks = MSEC_TO_TICKS(net->RTO); 1991 } 1992 break; 1993 case SCTP_TIMER_TYPE_RECV: 1994 /* 1995 * Here we use the Delayed-Ack timer value from the inp 1996 * ususually about 200ms. 1997 */ 1998 if (stcb == NULL) { 1999 return; 2000 } 2001 tmr = &stcb->asoc.dack_timer; 2002 to_ticks = MSEC_TO_TICKS(stcb->asoc.delayed_ack); 2003 break; 2004 case SCTP_TIMER_TYPE_SHUTDOWN: 2005 /* Here we use the RTO of the destination. */ 2006 if ((stcb == NULL) || (net == NULL)) { 2007 return; 2008 } 2009 if (net->RTO == 0) { 2010 to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 2011 } else { 2012 to_ticks = MSEC_TO_TICKS(net->RTO); 2013 } 2014 tmr = &net->rxt_timer; 2015 break; 2016 case SCTP_TIMER_TYPE_HEARTBEAT: 2017 /* 2018 * the net is used here so that we can add in the RTO. Even 2019 * though we use a different timer. We also add the HB timer 2020 * PLUS a random jitter. 2021 */ 2022 if ((stcb == NULL) || (net == NULL)) { 2023 return; 2024 } else { 2025 uint32_t rndval; 2026 uint32_t jitter; 2027 2028 if ((net->dest_state & SCTP_ADDR_NOHB) && 2029 !(net->dest_state & SCTP_ADDR_UNCONFIRMED)) { 2030 return; 2031 } 2032 if (net->RTO == 0) { 2033 to_ticks = stcb->asoc.initial_rto; 2034 } else { 2035 to_ticks = net->RTO; 2036 } 2037 rndval = sctp_select_initial_TSN(&inp->sctp_ep); 2038 jitter = rndval % to_ticks; 2039 if (jitter >= (to_ticks >> 1)) { 2040 to_ticks = to_ticks + (jitter - (to_ticks >> 1)); 2041 } else { 2042 to_ticks = to_ticks - jitter; 2043 } 2044 if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) && 2045 !(net->dest_state & SCTP_ADDR_PF)) { 2046 to_ticks += net->heart_beat_delay; 2047 } 2048 /* 2049 * Now we must convert the to_ticks that are now in 2050 * ms to ticks. 2051 */ 2052 to_ticks = MSEC_TO_TICKS(to_ticks); 2053 tmr = &net->hb_timer; 2054 } 2055 break; 2056 case SCTP_TIMER_TYPE_COOKIE: 2057 /* 2058 * Here we can use the RTO timer from the network since one 2059 * RTT was compelete. If a retran happened then we will be 2060 * using the RTO initial value. 2061 */ 2062 if ((stcb == NULL) || (net == NULL)) { 2063 return; 2064 } 2065 if (net->RTO == 0) { 2066 to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 2067 } else { 2068 to_ticks = MSEC_TO_TICKS(net->RTO); 2069 } 2070 tmr = &net->rxt_timer; 2071 break; 2072 case SCTP_TIMER_TYPE_NEWCOOKIE: 2073 /* 2074 * nothing needed but the endpoint here ususually about 60 2075 * minutes. 2076 */ 2077 tmr = &inp->sctp_ep.signature_change; 2078 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE]; 2079 break; 2080 case SCTP_TIMER_TYPE_ASOCKILL: 2081 if (stcb == NULL) { 2082 return; 2083 } 2084 tmr = &stcb->asoc.strreset_timer; 2085 to_ticks = MSEC_TO_TICKS(SCTP_ASOC_KILL_TIMEOUT); 2086 break; 2087 case SCTP_TIMER_TYPE_INPKILL: 2088 /* 2089 * The inp is setup to die. We re-use the signature_chage 2090 * timer since that has stopped and we are in the GONE 2091 * state. 2092 */ 2093 tmr = &inp->sctp_ep.signature_change; 2094 to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT); 2095 break; 2096 case SCTP_TIMER_TYPE_PATHMTURAISE: 2097 /* 2098 * Here we use the value found in the EP for PMTU ususually 2099 * about 10 minutes. 2100 */ 2101 if ((stcb == NULL) || (net == NULL)) { 2102 return; 2103 } 2104 if (net->dest_state & SCTP_ADDR_NO_PMTUD) { 2105 return; 2106 } 2107 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU]; 2108 tmr = &net->pmtu_timer; 2109 break; 2110 case SCTP_TIMER_TYPE_SHUTDOWNACK: 2111 /* Here we use the RTO of the destination */ 2112 if ((stcb == NULL) || (net == NULL)) { 2113 return; 2114 } 2115 if (net->RTO == 0) { 2116 to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 2117 } else { 2118 to_ticks = MSEC_TO_TICKS(net->RTO); 2119 } 2120 tmr = &net->rxt_timer; 2121 break; 2122 case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 2123 /* 2124 * Here we use the endpoints shutdown guard timer usually 2125 * about 3 minutes. 2126 */ 2127 if (stcb == NULL) { 2128 return; 2129 } 2130 if (inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] == 0) { 2131 to_ticks = 5 * MSEC_TO_TICKS(stcb->asoc.maxrto); 2132 } else { 2133 to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN]; 2134 } 2135 tmr = &stcb->asoc.shut_guard_timer; 2136 break; 2137 case SCTP_TIMER_TYPE_STRRESET: 2138 /* 2139 * Here the timer comes from the stcb but its value is from 2140 * the net's RTO. 2141 */ 2142 if ((stcb == NULL) || (net == NULL)) { 2143 return; 2144 } 2145 if (net->RTO == 0) { 2146 to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 2147 } else { 2148 to_ticks = MSEC_TO_TICKS(net->RTO); 2149 } 2150 tmr = &stcb->asoc.strreset_timer; 2151 break; 2152 case SCTP_TIMER_TYPE_ASCONF: 2153 /* 2154 * Here the timer comes from the stcb but its value is from 2155 * the net's RTO. 2156 */ 2157 if ((stcb == NULL) || (net == NULL)) { 2158 return; 2159 } 2160 if (net->RTO == 0) { 2161 to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 2162 } else { 2163 to_ticks = MSEC_TO_TICKS(net->RTO); 2164 } 2165 tmr = &stcb->asoc.asconf_timer; 2166 break; 2167 case SCTP_TIMER_TYPE_PRIM_DELETED: 2168 if ((stcb == NULL) || (net != NULL)) { 2169 return; 2170 } 2171 to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 2172 tmr = &stcb->asoc.delete_prim_timer; 2173 break; 2174 case SCTP_TIMER_TYPE_AUTOCLOSE: 2175 if (stcb == NULL) { 2176 return; 2177 } 2178 if (stcb->asoc.sctp_autoclose_ticks == 0) { 2179 /* 2180 * Really an error since stcb is NOT set to 2181 * autoclose 2182 */ 2183 return; 2184 } 2185 to_ticks = stcb->asoc.sctp_autoclose_ticks; 2186 tmr = &stcb->asoc.autoclose_timer; 2187 break; 2188 default: 2189 SCTPDBG(SCTP_DEBUG_TIMER1, "%s: Unknown timer type %d\n", 2190 __func__, t_type); 2191 return; 2192 break; 2193 } 2194 if ((to_ticks <= 0) || (tmr == NULL)) { 2195 SCTPDBG(SCTP_DEBUG_TIMER1, "%s: %d:software error to_ticks:%d tmr:%p not set ??\n", 2196 __func__, t_type, to_ticks, (void *)tmr); 2197 return; 2198 } 2199 if (SCTP_OS_TIMER_PENDING(&tmr->timer)) { 2200 /* 2201 * we do NOT allow you to have it already running. if it is 2202 * we leave the current one up unchanged 2203 */ 2204 return; 2205 } 2206 /* At this point we can proceed */ 2207 if (t_type == SCTP_TIMER_TYPE_SEND) { 2208 stcb->asoc.num_send_timers_up++; 2209 } 2210 tmr->stopped_from = 0; 2211 tmr->type = t_type; 2212 tmr->ep = (void *)inp; 2213 tmr->tcb = (void *)stcb; 2214 tmr->net = (void *)net; 2215 tmr->self = (void *)tmr; 2216 tmr->vnet = (void *)curvnet; 2217 tmr->ticks = sctp_get_tick_count(); 2218 (void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr); 2219 return; 2220 } 2221 2222 void 2223 sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 2224 struct sctp_nets *net, uint32_t from) 2225 { 2226 struct sctp_timer *tmr; 2227 2228 if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) && 2229 (inp == NULL)) 2230 return; 2231 2232 tmr = NULL; 2233 if (stcb) { 2234 SCTP_TCB_LOCK_ASSERT(stcb); 2235 } 2236 switch (t_type) { 2237 case SCTP_TIMER_TYPE_ADDR_WQ: 2238 tmr = &SCTP_BASE_INFO(addr_wq_timer); 2239 break; 2240 case SCTP_TIMER_TYPE_SEND: 2241 if ((stcb == NULL) || (net == NULL)) { 2242 return; 2243 } 2244 tmr = &net->rxt_timer; 2245 break; 2246 case SCTP_TIMER_TYPE_INIT: 2247 if ((stcb == NULL) || (net == NULL)) { 2248 return; 2249 } 2250 tmr = &net->rxt_timer; 2251 break; 2252 case SCTP_TIMER_TYPE_RECV: 2253 if (stcb == NULL) { 2254 return; 2255 } 2256 tmr = &stcb->asoc.dack_timer; 2257 break; 2258 case SCTP_TIMER_TYPE_SHUTDOWN: 2259 if ((stcb == NULL) || (net == NULL)) { 2260 return; 2261 } 2262 tmr = &net->rxt_timer; 2263 break; 2264 case SCTP_TIMER_TYPE_HEARTBEAT: 2265 if ((stcb == NULL) || (net == NULL)) { 2266 return; 2267 } 2268 tmr = &net->hb_timer; 2269 break; 2270 case SCTP_TIMER_TYPE_COOKIE: 2271 if ((stcb == NULL) || (net == NULL)) { 2272 return; 2273 } 2274 tmr = &net->rxt_timer; 2275 break; 2276 case SCTP_TIMER_TYPE_NEWCOOKIE: 2277 /* nothing needed but the endpoint here */ 2278 tmr = &inp->sctp_ep.signature_change; 2279 /* 2280 * We re-use the newcookie timer for the INP kill timer. We 2281 * must assure that we do not kill it by accident. 2282 */ 2283 break; 2284 case SCTP_TIMER_TYPE_ASOCKILL: 2285 /* 2286 * Stop the asoc kill timer. 2287 */ 2288 if (stcb == NULL) { 2289 return; 2290 } 2291 tmr = &stcb->asoc.strreset_timer; 2292 break; 2293 2294 case SCTP_TIMER_TYPE_INPKILL: 2295 /* 2296 * The inp is setup to die. We re-use the signature_chage 2297 * timer since that has stopped and we are in the GONE 2298 * state. 2299 */ 2300 tmr = &inp->sctp_ep.signature_change; 2301 break; 2302 case SCTP_TIMER_TYPE_PATHMTURAISE: 2303 if ((stcb == NULL) || (net == NULL)) { 2304 return; 2305 } 2306 tmr = &net->pmtu_timer; 2307 break; 2308 case SCTP_TIMER_TYPE_SHUTDOWNACK: 2309 if ((stcb == NULL) || (net == NULL)) { 2310 return; 2311 } 2312 tmr = &net->rxt_timer; 2313 break; 2314 case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 2315 if (stcb == NULL) { 2316 return; 2317 } 2318 tmr = &stcb->asoc.shut_guard_timer; 2319 break; 2320 case SCTP_TIMER_TYPE_STRRESET: 2321 if (stcb == NULL) { 2322 return; 2323 } 2324 tmr = &stcb->asoc.strreset_timer; 2325 break; 2326 case SCTP_TIMER_TYPE_ASCONF: 2327 if (stcb == NULL) { 2328 return; 2329 } 2330 tmr = &stcb->asoc.asconf_timer; 2331 break; 2332 case SCTP_TIMER_TYPE_PRIM_DELETED: 2333 if (stcb == NULL) { 2334 return; 2335 } 2336 tmr = &stcb->asoc.delete_prim_timer; 2337 break; 2338 case SCTP_TIMER_TYPE_AUTOCLOSE: 2339 if (stcb == NULL) { 2340 return; 2341 } 2342 tmr = &stcb->asoc.autoclose_timer; 2343 break; 2344 default: 2345 SCTPDBG(SCTP_DEBUG_TIMER1, "%s: Unknown timer type %d\n", 2346 __func__, t_type); 2347 break; 2348 } 2349 if (tmr == NULL) { 2350 return; 2351 } 2352 if ((tmr->type != t_type) && tmr->type) { 2353 /* 2354 * Ok we have a timer that is under joint use. Cookie timer 2355 * per chance with the SEND timer. We therefore are NOT 2356 * running the timer that the caller wants stopped. So just 2357 * return. 2358 */ 2359 return; 2360 } 2361 if ((t_type == SCTP_TIMER_TYPE_SEND) && (stcb != NULL)) { 2362 stcb->asoc.num_send_timers_up--; 2363 if (stcb->asoc.num_send_timers_up < 0) { 2364 stcb->asoc.num_send_timers_up = 0; 2365 } 2366 } 2367 tmr->self = NULL; 2368 tmr->stopped_from = from; 2369 (void)SCTP_OS_TIMER_STOP(&tmr->timer); 2370 return; 2371 } 2372 2373 uint32_t 2374 sctp_calculate_len(struct mbuf *m) 2375 { 2376 uint32_t tlen = 0; 2377 struct mbuf *at; 2378 2379 at = m; 2380 while (at) { 2381 tlen += SCTP_BUF_LEN(at); 2382 at = SCTP_BUF_NEXT(at); 2383 } 2384 return (tlen); 2385 } 2386 2387 void 2388 sctp_mtu_size_reset(struct sctp_inpcb *inp, 2389 struct sctp_association *asoc, uint32_t mtu) 2390 { 2391 /* 2392 * Reset the P-MTU size on this association, this involves changing 2393 * the asoc MTU, going through ANY chunk+overhead larger than mtu to 2394 * allow the DF flag to be cleared. 2395 */ 2396 struct sctp_tmit_chunk *chk; 2397 unsigned int eff_mtu, ovh; 2398 2399 asoc->smallest_mtu = mtu; 2400 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 2401 ovh = SCTP_MIN_OVERHEAD; 2402 } else { 2403 ovh = SCTP_MIN_V4_OVERHEAD; 2404 } 2405 eff_mtu = mtu - ovh; 2406 TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) { 2407 if (chk->send_size > eff_mtu) { 2408 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 2409 } 2410 } 2411 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { 2412 if (chk->send_size > eff_mtu) { 2413 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 2414 } 2415 } 2416 } 2417 2418 2419 /* 2420 * given an association and starting time of the current RTT period return 2421 * RTO in number of msecs net should point to the current network 2422 */ 2423 2424 uint32_t 2425 sctp_calculate_rto(struct sctp_tcb *stcb, 2426 struct sctp_association *asoc, 2427 struct sctp_nets *net, 2428 struct timeval *old, 2429 int rtt_from_sack) 2430 { 2431 /*- 2432 * given an association and the starting time of the current RTT 2433 * period (in value1/value2) return RTO in number of msecs. 2434 */ 2435 int32_t rtt; /* RTT in ms */ 2436 uint32_t new_rto; 2437 int first_measure = 0; 2438 struct timeval now; 2439 2440 /************************/ 2441 /* 1. calculate new RTT */ 2442 /************************/ 2443 /* get the current time */ 2444 if (stcb->asoc.use_precise_time) { 2445 (void)SCTP_GETPTIME_TIMEVAL(&now); 2446 } else { 2447 (void)SCTP_GETTIME_TIMEVAL(&now); 2448 } 2449 timevalsub(&now, old); 2450 /* store the current RTT in us */ 2451 net->rtt = (uint64_t)1000000 *(uint64_t)now.tv_sec + 2452 (uint64_t)now.tv_usec; 2453 2454 /* compute rtt in ms */ 2455 rtt = (int32_t)(net->rtt / 1000); 2456 if ((asoc->cc_functions.sctp_rtt_calculated) && (rtt_from_sack == SCTP_RTT_FROM_DATA)) { 2457 /* 2458 * Tell the CC module that a new update has just occurred 2459 * from a sack 2460 */ 2461 (*asoc->cc_functions.sctp_rtt_calculated) (stcb, net, &now); 2462 } 2463 /* 2464 * Do we need to determine the lan? We do this only on sacks i.e. 2465 * RTT being determined from data not non-data (HB/INIT->INITACK). 2466 */ 2467 if ((rtt_from_sack == SCTP_RTT_FROM_DATA) && 2468 (net->lan_type == SCTP_LAN_UNKNOWN)) { 2469 if (net->rtt > SCTP_LOCAL_LAN_RTT) { 2470 net->lan_type = SCTP_LAN_INTERNET; 2471 } else { 2472 net->lan_type = SCTP_LAN_LOCAL; 2473 } 2474 } 2475 /***************************/ 2476 /* 2. update RTTVAR & SRTT */ 2477 /***************************/ 2478 /*- 2479 * Compute the scaled average lastsa and the 2480 * scaled variance lastsv as described in van Jacobson 2481 * Paper "Congestion Avoidance and Control", Annex A. 2482 * 2483 * (net->lastsa >> SCTP_RTT_SHIFT) is the srtt 2484 * (net->lastsa >> SCTP_RTT_VAR_SHIFT) is the rttvar 2485 */ 2486 if (net->RTO_measured) { 2487 rtt -= (net->lastsa >> SCTP_RTT_SHIFT); 2488 net->lastsa += rtt; 2489 if (rtt < 0) { 2490 rtt = -rtt; 2491 } 2492 rtt -= (net->lastsv >> SCTP_RTT_VAR_SHIFT); 2493 net->lastsv += rtt; 2494 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) { 2495 rto_logging(net, SCTP_LOG_RTTVAR); 2496 } 2497 } else { 2498 /* First RTO measurment */ 2499 net->RTO_measured = 1; 2500 first_measure = 1; 2501 net->lastsa = rtt << SCTP_RTT_SHIFT; 2502 net->lastsv = (rtt / 2) << SCTP_RTT_VAR_SHIFT; 2503 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) { 2504 rto_logging(net, SCTP_LOG_INITIAL_RTT); 2505 } 2506 } 2507 if (net->lastsv == 0) { 2508 net->lastsv = SCTP_CLOCK_GRANULARITY; 2509 } 2510 new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv; 2511 if ((new_rto > SCTP_SAT_NETWORK_MIN) && 2512 (stcb->asoc.sat_network_lockout == 0)) { 2513 stcb->asoc.sat_network = 1; 2514 } else if ((!first_measure) && stcb->asoc.sat_network) { 2515 stcb->asoc.sat_network = 0; 2516 stcb->asoc.sat_network_lockout = 1; 2517 } 2518 /* bound it, per C6/C7 in Section 5.3.1 */ 2519 if (new_rto < stcb->asoc.minrto) { 2520 new_rto = stcb->asoc.minrto; 2521 } 2522 if (new_rto > stcb->asoc.maxrto) { 2523 new_rto = stcb->asoc.maxrto; 2524 } 2525 /* we are now returning the RTO */ 2526 return (new_rto); 2527 } 2528 2529 /* 2530 * return a pointer to a contiguous piece of data from the given mbuf chain 2531 * starting at 'off' for 'len' bytes. If the desired piece spans more than 2532 * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size 2533 * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain. 2534 */ 2535 caddr_t 2536 sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t *in_ptr) 2537 { 2538 uint32_t count; 2539 uint8_t *ptr; 2540 2541 ptr = in_ptr; 2542 if ((off < 0) || (len <= 0)) 2543 return (NULL); 2544 2545 /* find the desired start location */ 2546 while ((m != NULL) && (off > 0)) { 2547 if (off < SCTP_BUF_LEN(m)) 2548 break; 2549 off -= SCTP_BUF_LEN(m); 2550 m = SCTP_BUF_NEXT(m); 2551 } 2552 if (m == NULL) 2553 return (NULL); 2554 2555 /* is the current mbuf large enough (eg. contiguous)? */ 2556 if ((SCTP_BUF_LEN(m) - off) >= len) { 2557 return (mtod(m, caddr_t)+off); 2558 } else { 2559 /* else, it spans more than one mbuf, so save a temp copy... */ 2560 while ((m != NULL) && (len > 0)) { 2561 count = min(SCTP_BUF_LEN(m) - off, len); 2562 memcpy(ptr, mtod(m, caddr_t)+off, count); 2563 len -= count; 2564 ptr += count; 2565 off = 0; 2566 m = SCTP_BUF_NEXT(m); 2567 } 2568 if ((m == NULL) && (len > 0)) 2569 return (NULL); 2570 else 2571 return ((caddr_t)in_ptr); 2572 } 2573 } 2574 2575 2576 2577 struct sctp_paramhdr * 2578 sctp_get_next_param(struct mbuf *m, 2579 int offset, 2580 struct sctp_paramhdr *pull, 2581 int pull_limit) 2582 { 2583 /* This just provides a typed signature to Peter's Pull routine */ 2584 return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit, 2585 (uint8_t *)pull)); 2586 } 2587 2588 2589 struct mbuf * 2590 sctp_add_pad_tombuf(struct mbuf *m, int padlen) 2591 { 2592 struct mbuf *m_last; 2593 caddr_t dp; 2594 2595 if (padlen > 3) { 2596 return (NULL); 2597 } 2598 if (padlen <= M_TRAILINGSPACE(m)) { 2599 /* 2600 * The easy way. We hope the majority of the time we hit 2601 * here :) 2602 */ 2603 m_last = m; 2604 } else { 2605 /* Hard way we must grow the mbuf chain */ 2606 m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA); 2607 if (m_last == NULL) { 2608 return (NULL); 2609 } 2610 SCTP_BUF_LEN(m_last) = 0; 2611 SCTP_BUF_NEXT(m_last) = NULL; 2612 SCTP_BUF_NEXT(m) = m_last; 2613 } 2614 dp = mtod(m_last, caddr_t)+SCTP_BUF_LEN(m_last); 2615 SCTP_BUF_LEN(m_last) += padlen; 2616 memset(dp, 0, padlen); 2617 return (m_last); 2618 } 2619 2620 struct mbuf * 2621 sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf) 2622 { 2623 /* find the last mbuf in chain and pad it */ 2624 struct mbuf *m_at; 2625 2626 if (last_mbuf != NULL) { 2627 return (sctp_add_pad_tombuf(last_mbuf, padval)); 2628 } else { 2629 for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) { 2630 if (SCTP_BUF_NEXT(m_at) == NULL) { 2631 return (sctp_add_pad_tombuf(m_at, padval)); 2632 } 2633 } 2634 } 2635 return (NULL); 2636 } 2637 2638 static void 2639 sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, 2640 uint16_t error, struct sctp_abort_chunk *abort, uint8_t from_peer, int so_locked 2641 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 2642 SCTP_UNUSED 2643 #endif 2644 ) 2645 { 2646 struct mbuf *m_notify; 2647 struct sctp_assoc_change *sac; 2648 struct sctp_queued_to_read *control; 2649 unsigned int notif_len; 2650 uint16_t abort_len; 2651 unsigned int i; 2652 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 2653 struct socket *so; 2654 #endif 2655 2656 if (stcb == NULL) { 2657 return; 2658 } 2659 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) { 2660 notif_len = (unsigned int)sizeof(struct sctp_assoc_change); 2661 if (abort != NULL) { 2662 abort_len = ntohs(abort->ch.chunk_length); 2663 } else { 2664 abort_len = 0; 2665 } 2666 if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) { 2667 notif_len += SCTP_ASSOC_SUPPORTS_MAX; 2668 } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) { 2669 notif_len += abort_len; 2670 } 2671 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 2672 if (m_notify == NULL) { 2673 /* Retry with smaller value. */ 2674 notif_len = (unsigned int)sizeof(struct sctp_assoc_change); 2675 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 2676 if (m_notify == NULL) { 2677 goto set_error; 2678 } 2679 } 2680 SCTP_BUF_NEXT(m_notify) = NULL; 2681 sac = mtod(m_notify, struct sctp_assoc_change *); 2682 memset(sac, 0, notif_len); 2683 sac->sac_type = SCTP_ASSOC_CHANGE; 2684 sac->sac_flags = 0; 2685 sac->sac_length = sizeof(struct sctp_assoc_change); 2686 sac->sac_state = state; 2687 sac->sac_error = error; 2688 /* XXX verify these stream counts */ 2689 sac->sac_outbound_streams = stcb->asoc.streamoutcnt; 2690 sac->sac_inbound_streams = stcb->asoc.streamincnt; 2691 sac->sac_assoc_id = sctp_get_associd(stcb); 2692 if (notif_len > sizeof(struct sctp_assoc_change)) { 2693 if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) { 2694 i = 0; 2695 if (stcb->asoc.prsctp_supported == 1) { 2696 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR; 2697 } 2698 if (stcb->asoc.auth_supported == 1) { 2699 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH; 2700 } 2701 if (stcb->asoc.asconf_supported == 1) { 2702 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF; 2703 } 2704 if (stcb->asoc.idata_supported == 1) { 2705 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_INTERLEAVING; 2706 } 2707 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF; 2708 if (stcb->asoc.reconfig_supported == 1) { 2709 sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG; 2710 } 2711 sac->sac_length += i; 2712 } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) { 2713 memcpy(sac->sac_info, abort, abort_len); 2714 sac->sac_length += abort_len; 2715 } 2716 } 2717 SCTP_BUF_LEN(m_notify) = sac->sac_length; 2718 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 2719 0, 0, stcb->asoc.context, 0, 0, 0, 2720 m_notify); 2721 if (control != NULL) { 2722 control->length = SCTP_BUF_LEN(m_notify); 2723 control->spec_flags = M_NOTIFICATION; 2724 /* not that we need this */ 2725 control->tail_mbuf = m_notify; 2726 sctp_add_to_readq(stcb->sctp_ep, stcb, 2727 control, 2728 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, 2729 so_locked); 2730 } else { 2731 sctp_m_freem(m_notify); 2732 } 2733 } 2734 /* 2735 * For 1-to-1 style sockets, we send up and error when an ABORT 2736 * comes in. 2737 */ 2738 set_error: 2739 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2740 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && 2741 ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) { 2742 SOCK_LOCK(stcb->sctp_socket); 2743 if (from_peer) { 2744 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) { 2745 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED); 2746 stcb->sctp_socket->so_error = ECONNREFUSED; 2747 } else { 2748 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET); 2749 stcb->sctp_socket->so_error = ECONNRESET; 2750 } 2751 } else { 2752 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) || 2753 (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) { 2754 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT); 2755 stcb->sctp_socket->so_error = ETIMEDOUT; 2756 } else { 2757 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED); 2758 stcb->sctp_socket->so_error = ECONNABORTED; 2759 } 2760 } 2761 SOCK_UNLOCK(stcb->sctp_socket); 2762 } 2763 /* Wake ANY sleepers */ 2764 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 2765 so = SCTP_INP_SO(stcb->sctp_ep); 2766 if (!so_locked) { 2767 atomic_add_int(&stcb->asoc.refcnt, 1); 2768 SCTP_TCB_UNLOCK(stcb); 2769 SCTP_SOCKET_LOCK(so, 1); 2770 SCTP_TCB_LOCK(stcb); 2771 atomic_subtract_int(&stcb->asoc.refcnt, 1); 2772 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { 2773 SCTP_SOCKET_UNLOCK(so, 1); 2774 return; 2775 } 2776 } 2777 #endif 2778 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2779 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && 2780 ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) { 2781 socantrcvmore(stcb->sctp_socket); 2782 } 2783 sorwakeup(stcb->sctp_socket); 2784 sowwakeup(stcb->sctp_socket); 2785 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 2786 if (!so_locked) { 2787 SCTP_SOCKET_UNLOCK(so, 1); 2788 } 2789 #endif 2790 } 2791 2792 static void 2793 sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state, 2794 struct sockaddr *sa, uint32_t error, int so_locked 2795 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 2796 SCTP_UNUSED 2797 #endif 2798 ) 2799 { 2800 struct mbuf *m_notify; 2801 struct sctp_paddr_change *spc; 2802 struct sctp_queued_to_read *control; 2803 2804 if ((stcb == NULL) || 2805 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) { 2806 /* event not enabled */ 2807 return; 2808 } 2809 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_NOWAIT, 1, MT_DATA); 2810 if (m_notify == NULL) 2811 return; 2812 SCTP_BUF_LEN(m_notify) = 0; 2813 spc = mtod(m_notify, struct sctp_paddr_change *); 2814 memset(spc, 0, sizeof(struct sctp_paddr_change)); 2815 spc->spc_type = SCTP_PEER_ADDR_CHANGE; 2816 spc->spc_flags = 0; 2817 spc->spc_length = sizeof(struct sctp_paddr_change); 2818 switch (sa->sa_family) { 2819 #ifdef INET 2820 case AF_INET: 2821 #ifdef INET6 2822 if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 2823 in6_sin_2_v4mapsin6((struct sockaddr_in *)sa, 2824 (struct sockaddr_in6 *)&spc->spc_aaddr); 2825 } else { 2826 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in)); 2827 } 2828 #else 2829 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in)); 2830 #endif 2831 break; 2832 #endif 2833 #ifdef INET6 2834 case AF_INET6: 2835 { 2836 struct sockaddr_in6 *sin6; 2837 2838 memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6)); 2839 2840 sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr; 2841 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) { 2842 if (sin6->sin6_scope_id == 0) { 2843 /* recover scope_id for user */ 2844 (void)sa6_recoverscope(sin6); 2845 } else { 2846 /* clear embedded scope_id for user */ 2847 in6_clearscope(&sin6->sin6_addr); 2848 } 2849 } 2850 break; 2851 } 2852 #endif 2853 default: 2854 /* TSNH */ 2855 break; 2856 } 2857 spc->spc_state = state; 2858 spc->spc_error = error; 2859 spc->spc_assoc_id = sctp_get_associd(stcb); 2860 2861 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_paddr_change); 2862 SCTP_BUF_NEXT(m_notify) = NULL; 2863 2864 /* append to socket */ 2865 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 2866 0, 0, stcb->asoc.context, 0, 0, 0, 2867 m_notify); 2868 if (control == NULL) { 2869 /* no memory */ 2870 sctp_m_freem(m_notify); 2871 return; 2872 } 2873 control->length = SCTP_BUF_LEN(m_notify); 2874 control->spec_flags = M_NOTIFICATION; 2875 /* not that we need this */ 2876 control->tail_mbuf = m_notify; 2877 sctp_add_to_readq(stcb->sctp_ep, stcb, 2878 control, 2879 &stcb->sctp_socket->so_rcv, 1, 2880 SCTP_READ_LOCK_NOT_HELD, 2881 so_locked); 2882 } 2883 2884 2885 static void 2886 sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, 2887 struct sctp_tmit_chunk *chk, int so_locked 2888 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 2889 SCTP_UNUSED 2890 #endif 2891 ) 2892 { 2893 struct mbuf *m_notify; 2894 struct sctp_send_failed *ssf; 2895 struct sctp_send_failed_event *ssfe; 2896 struct sctp_queued_to_read *control; 2897 struct sctp_chunkhdr *chkhdr; 2898 int notifhdr_len, chk_len, chkhdr_len, padding_len, payload_len; 2899 2900 if ((stcb == NULL) || 2901 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && 2902 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) { 2903 /* event not enabled */ 2904 return; 2905 } 2906 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 2907 notifhdr_len = sizeof(struct sctp_send_failed_event); 2908 } else { 2909 notifhdr_len = sizeof(struct sctp_send_failed); 2910 } 2911 m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA); 2912 if (m_notify == NULL) 2913 /* no space left */ 2914 return; 2915 SCTP_BUF_LEN(m_notify) = notifhdr_len; 2916 if (stcb->asoc.idata_supported) { 2917 chkhdr_len = sizeof(struct sctp_idata_chunk); 2918 } else { 2919 chkhdr_len = sizeof(struct sctp_data_chunk); 2920 } 2921 /* Use some defaults in case we can't access the chunk header */ 2922 if (chk->send_size >= chkhdr_len) { 2923 payload_len = chk->send_size - chkhdr_len; 2924 } else { 2925 payload_len = 0; 2926 } 2927 padding_len = 0; 2928 if (chk->data != NULL) { 2929 chkhdr = mtod(chk->data, struct sctp_chunkhdr *); 2930 if (chkhdr != NULL) { 2931 chk_len = ntohs(chkhdr->chunk_length); 2932 if ((chk_len >= chkhdr_len) && 2933 (chk->send_size >= chk_len) && 2934 (chk->send_size - chk_len < 4)) { 2935 padding_len = chk->send_size - chk_len; 2936 payload_len = chk->send_size - chkhdr_len - padding_len; 2937 } 2938 } 2939 } 2940 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 2941 ssfe = mtod(m_notify, struct sctp_send_failed_event *); 2942 memset(ssfe, 0, notifhdr_len); 2943 ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT; 2944 if (sent) { 2945 ssfe->ssfe_flags = SCTP_DATA_SENT; 2946 } else { 2947 ssfe->ssfe_flags = SCTP_DATA_UNSENT; 2948 } 2949 ssfe->ssfe_length = (uint32_t)(notifhdr_len + payload_len); 2950 ssfe->ssfe_error = error; 2951 /* not exactly what the user sent in, but should be close :) */ 2952 ssfe->ssfe_info.snd_sid = chk->rec.data.sid; 2953 ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags; 2954 ssfe->ssfe_info.snd_ppid = chk->rec.data.ppid; 2955 ssfe->ssfe_info.snd_context = chk->rec.data.context; 2956 ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb); 2957 ssfe->ssfe_assoc_id = sctp_get_associd(stcb); 2958 } else { 2959 ssf = mtod(m_notify, struct sctp_send_failed *); 2960 memset(ssf, 0, notifhdr_len); 2961 ssf->ssf_type = SCTP_SEND_FAILED; 2962 if (sent) { 2963 ssf->ssf_flags = SCTP_DATA_SENT; 2964 } else { 2965 ssf->ssf_flags = SCTP_DATA_UNSENT; 2966 } 2967 ssf->ssf_length = (uint32_t)(notifhdr_len + payload_len); 2968 ssf->ssf_error = error; 2969 /* not exactly what the user sent in, but should be close :) */ 2970 ssf->ssf_info.sinfo_stream = chk->rec.data.sid; 2971 ssf->ssf_info.sinfo_ssn = (uint16_t)chk->rec.data.mid; 2972 ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags; 2973 ssf->ssf_info.sinfo_ppid = chk->rec.data.ppid; 2974 ssf->ssf_info.sinfo_context = chk->rec.data.context; 2975 ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb); 2976 ssf->ssf_assoc_id = sctp_get_associd(stcb); 2977 } 2978 if (chk->data != NULL) { 2979 /* Trim off the sctp chunk header (it should be there) */ 2980 if (chk->send_size == chkhdr_len + payload_len + padding_len) { 2981 m_adj(chk->data, chkhdr_len); 2982 m_adj(chk->data, -padding_len); 2983 sctp_mbuf_crush(chk->data); 2984 chk->send_size -= (chkhdr_len + padding_len); 2985 } 2986 } 2987 SCTP_BUF_NEXT(m_notify) = chk->data; 2988 /* Steal off the mbuf */ 2989 chk->data = NULL; 2990 /* 2991 * For this case, we check the actual socket buffer, since the assoc 2992 * is going away we don't want to overfill the socket buffer for a 2993 * non-reader 2994 */ 2995 if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 2996 sctp_m_freem(m_notify); 2997 return; 2998 } 2999 /* append to socket */ 3000 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3001 0, 0, stcb->asoc.context, 0, 0, 0, 3002 m_notify); 3003 if (control == NULL) { 3004 /* no memory */ 3005 sctp_m_freem(m_notify); 3006 return; 3007 } 3008 control->length = SCTP_BUF_LEN(m_notify); 3009 control->spec_flags = M_NOTIFICATION; 3010 /* not that we need this */ 3011 control->tail_mbuf = m_notify; 3012 sctp_add_to_readq(stcb->sctp_ep, stcb, 3013 control, 3014 &stcb->sctp_socket->so_rcv, 1, 3015 SCTP_READ_LOCK_NOT_HELD, 3016 so_locked); 3017 } 3018 3019 3020 static void 3021 sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error, 3022 struct sctp_stream_queue_pending *sp, int so_locked 3023 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 3024 SCTP_UNUSED 3025 #endif 3026 ) 3027 { 3028 struct mbuf *m_notify; 3029 struct sctp_send_failed *ssf; 3030 struct sctp_send_failed_event *ssfe; 3031 struct sctp_queued_to_read *control; 3032 int notifhdr_len; 3033 3034 if ((stcb == NULL) || 3035 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && 3036 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) { 3037 /* event not enabled */ 3038 return; 3039 } 3040 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 3041 notifhdr_len = sizeof(struct sctp_send_failed_event); 3042 } else { 3043 notifhdr_len = sizeof(struct sctp_send_failed); 3044 } 3045 m_notify = sctp_get_mbuf_for_msg(notifhdr_len, 0, M_NOWAIT, 1, MT_DATA); 3046 if (m_notify == NULL) { 3047 /* no space left */ 3048 return; 3049 } 3050 SCTP_BUF_LEN(m_notify) = notifhdr_len; 3051 if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 3052 ssfe = mtod(m_notify, struct sctp_send_failed_event *); 3053 memset(ssfe, 0, notifhdr_len); 3054 ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT; 3055 ssfe->ssfe_flags = SCTP_DATA_UNSENT; 3056 ssfe->ssfe_length = (uint32_t)(notifhdr_len + sp->length); 3057 ssfe->ssfe_error = error; 3058 /* not exactly what the user sent in, but should be close :) */ 3059 ssfe->ssfe_info.snd_sid = sp->sid; 3060 if (sp->some_taken) { 3061 ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG; 3062 } else { 3063 ssfe->ssfe_info.snd_flags = SCTP_DATA_NOT_FRAG; 3064 } 3065 ssfe->ssfe_info.snd_ppid = sp->ppid; 3066 ssfe->ssfe_info.snd_context = sp->context; 3067 ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb); 3068 ssfe->ssfe_assoc_id = sctp_get_associd(stcb); 3069 } else { 3070 ssf = mtod(m_notify, struct sctp_send_failed *); 3071 memset(ssf, 0, notifhdr_len); 3072 ssf->ssf_type = SCTP_SEND_FAILED; 3073 ssf->ssf_flags = SCTP_DATA_UNSENT; 3074 ssf->ssf_length = (uint32_t)(notifhdr_len + sp->length); 3075 ssf->ssf_error = error; 3076 /* not exactly what the user sent in, but should be close :) */ 3077 ssf->ssf_info.sinfo_stream = sp->sid; 3078 ssf->ssf_info.sinfo_ssn = 0; 3079 if (sp->some_taken) { 3080 ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG; 3081 } else { 3082 ssf->ssf_info.sinfo_flags = SCTP_DATA_NOT_FRAG; 3083 } 3084 ssf->ssf_info.sinfo_ppid = sp->ppid; 3085 ssf->ssf_info.sinfo_context = sp->context; 3086 ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb); 3087 ssf->ssf_assoc_id = sctp_get_associd(stcb); 3088 } 3089 SCTP_BUF_NEXT(m_notify) = sp->data; 3090 3091 /* Steal off the mbuf */ 3092 sp->data = NULL; 3093 /* 3094 * For this case, we check the actual socket buffer, since the assoc 3095 * is going away we don't want to overfill the socket buffer for a 3096 * non-reader 3097 */ 3098 if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 3099 sctp_m_freem(m_notify); 3100 return; 3101 } 3102 /* append to socket */ 3103 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3104 0, 0, stcb->asoc.context, 0, 0, 0, 3105 m_notify); 3106 if (control == NULL) { 3107 /* no memory */ 3108 sctp_m_freem(m_notify); 3109 return; 3110 } 3111 control->length = SCTP_BUF_LEN(m_notify); 3112 control->spec_flags = M_NOTIFICATION; 3113 /* not that we need this */ 3114 control->tail_mbuf = m_notify; 3115 sctp_add_to_readq(stcb->sctp_ep, stcb, 3116 control, 3117 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked); 3118 } 3119 3120 3121 3122 static void 3123 sctp_notify_adaptation_layer(struct sctp_tcb *stcb) 3124 { 3125 struct mbuf *m_notify; 3126 struct sctp_adaptation_event *sai; 3127 struct sctp_queued_to_read *control; 3128 3129 if ((stcb == NULL) || 3130 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) { 3131 /* event not enabled */ 3132 return; 3133 } 3134 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_NOWAIT, 1, MT_DATA); 3135 if (m_notify == NULL) 3136 /* no space left */ 3137 return; 3138 SCTP_BUF_LEN(m_notify) = 0; 3139 sai = mtod(m_notify, struct sctp_adaptation_event *); 3140 memset(sai, 0, sizeof(struct sctp_adaptation_event)); 3141 sai->sai_type = SCTP_ADAPTATION_INDICATION; 3142 sai->sai_flags = 0; 3143 sai->sai_length = sizeof(struct sctp_adaptation_event); 3144 sai->sai_adaptation_ind = stcb->asoc.peers_adaptation; 3145 sai->sai_assoc_id = sctp_get_associd(stcb); 3146 3147 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_adaptation_event); 3148 SCTP_BUF_NEXT(m_notify) = NULL; 3149 3150 /* append to socket */ 3151 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3152 0, 0, stcb->asoc.context, 0, 0, 0, 3153 m_notify); 3154 if (control == NULL) { 3155 /* no memory */ 3156 sctp_m_freem(m_notify); 3157 return; 3158 } 3159 control->length = SCTP_BUF_LEN(m_notify); 3160 control->spec_flags = M_NOTIFICATION; 3161 /* not that we need this */ 3162 control->tail_mbuf = m_notify; 3163 sctp_add_to_readq(stcb->sctp_ep, stcb, 3164 control, 3165 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 3166 } 3167 3168 /* This always must be called with the read-queue LOCKED in the INP */ 3169 static void 3170 sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error, 3171 uint32_t val, int so_locked 3172 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 3173 SCTP_UNUSED 3174 #endif 3175 ) 3176 { 3177 struct mbuf *m_notify; 3178 struct sctp_pdapi_event *pdapi; 3179 struct sctp_queued_to_read *control; 3180 struct sockbuf *sb; 3181 3182 if ((stcb == NULL) || 3183 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) { 3184 /* event not enabled */ 3185 return; 3186 } 3187 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { 3188 return; 3189 } 3190 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_NOWAIT, 1, MT_DATA); 3191 if (m_notify == NULL) 3192 /* no space left */ 3193 return; 3194 SCTP_BUF_LEN(m_notify) = 0; 3195 pdapi = mtod(m_notify, struct sctp_pdapi_event *); 3196 memset(pdapi, 0, sizeof(struct sctp_pdapi_event)); 3197 pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT; 3198 pdapi->pdapi_flags = 0; 3199 pdapi->pdapi_length = sizeof(struct sctp_pdapi_event); 3200 pdapi->pdapi_indication = error; 3201 pdapi->pdapi_stream = (val >> 16); 3202 pdapi->pdapi_seq = (val & 0x0000ffff); 3203 pdapi->pdapi_assoc_id = sctp_get_associd(stcb); 3204 3205 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event); 3206 SCTP_BUF_NEXT(m_notify) = NULL; 3207 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3208 0, 0, stcb->asoc.context, 0, 0, 0, 3209 m_notify); 3210 if (control == NULL) { 3211 /* no memory */ 3212 sctp_m_freem(m_notify); 3213 return; 3214 } 3215 control->length = SCTP_BUF_LEN(m_notify); 3216 control->spec_flags = M_NOTIFICATION; 3217 /* not that we need this */ 3218 control->tail_mbuf = m_notify; 3219 sb = &stcb->sctp_socket->so_rcv; 3220 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 3221 sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify)); 3222 } 3223 sctp_sballoc(stcb, sb, m_notify); 3224 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 3225 sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0); 3226 } 3227 control->end_added = 1; 3228 if (stcb->asoc.control_pdapi) 3229 TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi, control, next); 3230 else { 3231 /* we really should not see this case */ 3232 TAILQ_INSERT_TAIL(&stcb->sctp_ep->read_queue, control, next); 3233 } 3234 if (stcb->sctp_ep && stcb->sctp_socket) { 3235 /* This should always be the case */ 3236 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 3237 struct socket *so; 3238 3239 so = SCTP_INP_SO(stcb->sctp_ep); 3240 if (!so_locked) { 3241 atomic_add_int(&stcb->asoc.refcnt, 1); 3242 SCTP_TCB_UNLOCK(stcb); 3243 SCTP_SOCKET_LOCK(so, 1); 3244 SCTP_TCB_LOCK(stcb); 3245 atomic_subtract_int(&stcb->asoc.refcnt, 1); 3246 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 3247 SCTP_SOCKET_UNLOCK(so, 1); 3248 return; 3249 } 3250 } 3251 #endif 3252 sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 3253 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 3254 if (!so_locked) { 3255 SCTP_SOCKET_UNLOCK(so, 1); 3256 } 3257 #endif 3258 } 3259 } 3260 3261 static void 3262 sctp_notify_shutdown_event(struct sctp_tcb *stcb) 3263 { 3264 struct mbuf *m_notify; 3265 struct sctp_shutdown_event *sse; 3266 struct sctp_queued_to_read *control; 3267 3268 /* 3269 * For TCP model AND UDP connected sockets we will send an error up 3270 * when an SHUTDOWN completes 3271 */ 3272 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3273 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 3274 /* mark socket closed for read/write and wakeup! */ 3275 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 3276 struct socket *so; 3277 3278 so = SCTP_INP_SO(stcb->sctp_ep); 3279 atomic_add_int(&stcb->asoc.refcnt, 1); 3280 SCTP_TCB_UNLOCK(stcb); 3281 SCTP_SOCKET_LOCK(so, 1); 3282 SCTP_TCB_LOCK(stcb); 3283 atomic_subtract_int(&stcb->asoc.refcnt, 1); 3284 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { 3285 SCTP_SOCKET_UNLOCK(so, 1); 3286 return; 3287 } 3288 #endif 3289 socantsendmore(stcb->sctp_socket); 3290 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 3291 SCTP_SOCKET_UNLOCK(so, 1); 3292 #endif 3293 } 3294 if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) { 3295 /* event not enabled */ 3296 return; 3297 } 3298 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 0, M_NOWAIT, 1, MT_DATA); 3299 if (m_notify == NULL) 3300 /* no space left */ 3301 return; 3302 sse = mtod(m_notify, struct sctp_shutdown_event *); 3303 memset(sse, 0, sizeof(struct sctp_shutdown_event)); 3304 sse->sse_type = SCTP_SHUTDOWN_EVENT; 3305 sse->sse_flags = 0; 3306 sse->sse_length = sizeof(struct sctp_shutdown_event); 3307 sse->sse_assoc_id = sctp_get_associd(stcb); 3308 3309 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_shutdown_event); 3310 SCTP_BUF_NEXT(m_notify) = NULL; 3311 3312 /* append to socket */ 3313 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3314 0, 0, stcb->asoc.context, 0, 0, 0, 3315 m_notify); 3316 if (control == NULL) { 3317 /* no memory */ 3318 sctp_m_freem(m_notify); 3319 return; 3320 } 3321 control->length = SCTP_BUF_LEN(m_notify); 3322 control->spec_flags = M_NOTIFICATION; 3323 /* not that we need this */ 3324 control->tail_mbuf = m_notify; 3325 sctp_add_to_readq(stcb->sctp_ep, stcb, 3326 control, 3327 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 3328 } 3329 3330 static void 3331 sctp_notify_sender_dry_event(struct sctp_tcb *stcb, 3332 int so_locked 3333 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 3334 SCTP_UNUSED 3335 #endif 3336 ) 3337 { 3338 struct mbuf *m_notify; 3339 struct sctp_sender_dry_event *event; 3340 struct sctp_queued_to_read *control; 3341 3342 if ((stcb == NULL) || 3343 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) { 3344 /* event not enabled */ 3345 return; 3346 } 3347 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_sender_dry_event), 0, M_NOWAIT, 1, MT_DATA); 3348 if (m_notify == NULL) { 3349 /* no space left */ 3350 return; 3351 } 3352 SCTP_BUF_LEN(m_notify) = 0; 3353 event = mtod(m_notify, struct sctp_sender_dry_event *); 3354 memset(event, 0, sizeof(struct sctp_sender_dry_event)); 3355 event->sender_dry_type = SCTP_SENDER_DRY_EVENT; 3356 event->sender_dry_flags = 0; 3357 event->sender_dry_length = sizeof(struct sctp_sender_dry_event); 3358 event->sender_dry_assoc_id = sctp_get_associd(stcb); 3359 3360 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_sender_dry_event); 3361 SCTP_BUF_NEXT(m_notify) = NULL; 3362 3363 /* append to socket */ 3364 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3365 0, 0, stcb->asoc.context, 0, 0, 0, 3366 m_notify); 3367 if (control == NULL) { 3368 /* no memory */ 3369 sctp_m_freem(m_notify); 3370 return; 3371 } 3372 control->length = SCTP_BUF_LEN(m_notify); 3373 control->spec_flags = M_NOTIFICATION; 3374 /* not that we need this */ 3375 control->tail_mbuf = m_notify; 3376 sctp_add_to_readq(stcb->sctp_ep, stcb, control, 3377 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked); 3378 } 3379 3380 3381 void 3382 sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t numberout, int flag) 3383 { 3384 struct mbuf *m_notify; 3385 struct sctp_queued_to_read *control; 3386 struct sctp_stream_change_event *stradd; 3387 3388 if ((stcb == NULL) || 3389 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) { 3390 /* event not enabled */ 3391 return; 3392 } 3393 if ((stcb->asoc.peer_req_out) && flag) { 3394 /* Peer made the request, don't tell the local user */ 3395 stcb->asoc.peer_req_out = 0; 3396 return; 3397 } 3398 stcb->asoc.peer_req_out = 0; 3399 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA); 3400 if (m_notify == NULL) 3401 /* no space left */ 3402 return; 3403 SCTP_BUF_LEN(m_notify) = 0; 3404 stradd = mtod(m_notify, struct sctp_stream_change_event *); 3405 memset(stradd, 0, sizeof(struct sctp_stream_change_event)); 3406 stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT; 3407 stradd->strchange_flags = flag; 3408 stradd->strchange_length = sizeof(struct sctp_stream_change_event); 3409 stradd->strchange_assoc_id = sctp_get_associd(stcb); 3410 stradd->strchange_instrms = numberin; 3411 stradd->strchange_outstrms = numberout; 3412 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event); 3413 SCTP_BUF_NEXT(m_notify) = NULL; 3414 if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 3415 /* no space */ 3416 sctp_m_freem(m_notify); 3417 return; 3418 } 3419 /* append to socket */ 3420 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3421 0, 0, stcb->asoc.context, 0, 0, 0, 3422 m_notify); 3423 if (control == NULL) { 3424 /* no memory */ 3425 sctp_m_freem(m_notify); 3426 return; 3427 } 3428 control->length = SCTP_BUF_LEN(m_notify); 3429 control->spec_flags = M_NOTIFICATION; 3430 /* not that we need this */ 3431 control->tail_mbuf = m_notify; 3432 sctp_add_to_readq(stcb->sctp_ep, stcb, 3433 control, 3434 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 3435 } 3436 3437 void 3438 sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag) 3439 { 3440 struct mbuf *m_notify; 3441 struct sctp_queued_to_read *control; 3442 struct sctp_assoc_reset_event *strasoc; 3443 3444 if ((stcb == NULL) || 3445 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) { 3446 /* event not enabled */ 3447 return; 3448 } 3449 m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA); 3450 if (m_notify == NULL) 3451 /* no space left */ 3452 return; 3453 SCTP_BUF_LEN(m_notify) = 0; 3454 strasoc = mtod(m_notify, struct sctp_assoc_reset_event *); 3455 memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event)); 3456 strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT; 3457 strasoc->assocreset_flags = flag; 3458 strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event); 3459 strasoc->assocreset_assoc_id = sctp_get_associd(stcb); 3460 strasoc->assocreset_local_tsn = sending_tsn; 3461 strasoc->assocreset_remote_tsn = recv_tsn; 3462 SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event); 3463 SCTP_BUF_NEXT(m_notify) = NULL; 3464 if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 3465 /* no space */ 3466 sctp_m_freem(m_notify); 3467 return; 3468 } 3469 /* append to socket */ 3470 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3471 0, 0, stcb->asoc.context, 0, 0, 0, 3472 m_notify); 3473 if (control == NULL) { 3474 /* no memory */ 3475 sctp_m_freem(m_notify); 3476 return; 3477 } 3478 control->length = SCTP_BUF_LEN(m_notify); 3479 control->spec_flags = M_NOTIFICATION; 3480 /* not that we need this */ 3481 control->tail_mbuf = m_notify; 3482 sctp_add_to_readq(stcb->sctp_ep, stcb, 3483 control, 3484 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 3485 } 3486 3487 3488 3489 static void 3490 sctp_notify_stream_reset(struct sctp_tcb *stcb, 3491 int number_entries, uint16_t *list, int flag) 3492 { 3493 struct mbuf *m_notify; 3494 struct sctp_queued_to_read *control; 3495 struct sctp_stream_reset_event *strreset; 3496 int len; 3497 3498 if ((stcb == NULL) || 3499 (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT))) { 3500 /* event not enabled */ 3501 return; 3502 } 3503 m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA); 3504 if (m_notify == NULL) 3505 /* no space left */ 3506 return; 3507 SCTP_BUF_LEN(m_notify) = 0; 3508 len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t)); 3509 if (len > M_TRAILINGSPACE(m_notify)) { 3510 /* never enough room */ 3511 sctp_m_freem(m_notify); 3512 return; 3513 } 3514 strreset = mtod(m_notify, struct sctp_stream_reset_event *); 3515 memset(strreset, 0, len); 3516 strreset->strreset_type = SCTP_STREAM_RESET_EVENT; 3517 strreset->strreset_flags = flag; 3518 strreset->strreset_length = len; 3519 strreset->strreset_assoc_id = sctp_get_associd(stcb); 3520 if (number_entries) { 3521 int i; 3522 3523 for (i = 0; i < number_entries; i++) { 3524 strreset->strreset_stream_list[i] = ntohs(list[i]); 3525 } 3526 } 3527 SCTP_BUF_LEN(m_notify) = len; 3528 SCTP_BUF_NEXT(m_notify) = NULL; 3529 if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 3530 /* no space */ 3531 sctp_m_freem(m_notify); 3532 return; 3533 } 3534 /* append to socket */ 3535 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3536 0, 0, stcb->asoc.context, 0, 0, 0, 3537 m_notify); 3538 if (control == NULL) { 3539 /* no memory */ 3540 sctp_m_freem(m_notify); 3541 return; 3542 } 3543 control->length = SCTP_BUF_LEN(m_notify); 3544 control->spec_flags = M_NOTIFICATION; 3545 /* not that we need this */ 3546 control->tail_mbuf = m_notify; 3547 sctp_add_to_readq(stcb->sctp_ep, stcb, 3548 control, 3549 &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 3550 } 3551 3552 3553 static void 3554 sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_error_chunk *chunk) 3555 { 3556 struct mbuf *m_notify; 3557 struct sctp_remote_error *sre; 3558 struct sctp_queued_to_read *control; 3559 unsigned int notif_len; 3560 uint16_t chunk_len; 3561 3562 if ((stcb == NULL) || 3563 sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) { 3564 return; 3565 } 3566 if (chunk != NULL) { 3567 chunk_len = ntohs(chunk->ch.chunk_length); 3568 } else { 3569 chunk_len = 0; 3570 } 3571 notif_len = (unsigned int)(sizeof(struct sctp_remote_error) + chunk_len); 3572 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 3573 if (m_notify == NULL) { 3574 /* Retry with smaller value. */ 3575 notif_len = (unsigned int)sizeof(struct sctp_remote_error); 3576 m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 3577 if (m_notify == NULL) { 3578 return; 3579 } 3580 } 3581 SCTP_BUF_NEXT(m_notify) = NULL; 3582 sre = mtod(m_notify, struct sctp_remote_error *); 3583 memset(sre, 0, notif_len); 3584 sre->sre_type = SCTP_REMOTE_ERROR; 3585 sre->sre_flags = 0; 3586 sre->sre_length = sizeof(struct sctp_remote_error); 3587 sre->sre_error = error; 3588 sre->sre_assoc_id = sctp_get_associd(stcb); 3589 if (notif_len > sizeof(struct sctp_remote_error)) { 3590 memcpy(sre->sre_data, chunk, chunk_len); 3591 sre->sre_length += chunk_len; 3592 } 3593 SCTP_BUF_LEN(m_notify) = sre->sre_length; 3594 control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3595 0, 0, stcb->asoc.context, 0, 0, 0, 3596 m_notify); 3597 if (control != NULL) { 3598 control->length = SCTP_BUF_LEN(m_notify); 3599 control->spec_flags = M_NOTIFICATION; 3600 /* not that we need this */ 3601 control->tail_mbuf = m_notify; 3602 sctp_add_to_readq(stcb->sctp_ep, stcb, 3603 control, 3604 &stcb->sctp_socket->so_rcv, 1, 3605 SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 3606 } else { 3607 sctp_m_freem(m_notify); 3608 } 3609 } 3610 3611 3612 void 3613 sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, 3614 uint32_t error, void *data, int so_locked 3615 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 3616 SCTP_UNUSED 3617 #endif 3618 ) 3619 { 3620 if ((stcb == NULL) || 3621 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 3622 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 3623 (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { 3624 /* If the socket is gone we are out of here */ 3625 return; 3626 } 3627 if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) { 3628 return; 3629 } 3630 if ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) || 3631 (stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED)) { 3632 if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) || 3633 (notification == SCTP_NOTIFY_INTERFACE_UP) || 3634 (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) { 3635 /* Don't report these in front states */ 3636 return; 3637 } 3638 } 3639 switch (notification) { 3640 case SCTP_NOTIFY_ASSOC_UP: 3641 if (stcb->asoc.assoc_up_sent == 0) { 3642 sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, 0, so_locked); 3643 stcb->asoc.assoc_up_sent = 1; 3644 } 3645 if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) { 3646 sctp_notify_adaptation_layer(stcb); 3647 } 3648 if (stcb->asoc.auth_supported == 0) { 3649 sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0, 3650 NULL, so_locked); 3651 } 3652 break; 3653 case SCTP_NOTIFY_ASSOC_DOWN: 3654 sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, 0, so_locked); 3655 break; 3656 case SCTP_NOTIFY_INTERFACE_DOWN: 3657 { 3658 struct sctp_nets *net; 3659 3660 net = (struct sctp_nets *)data; 3661 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE, 3662 (struct sockaddr *)&net->ro._l_addr, error, so_locked); 3663 break; 3664 } 3665 case SCTP_NOTIFY_INTERFACE_UP: 3666 { 3667 struct sctp_nets *net; 3668 3669 net = (struct sctp_nets *)data; 3670 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE, 3671 (struct sockaddr *)&net->ro._l_addr, error, so_locked); 3672 break; 3673 } 3674 case SCTP_NOTIFY_INTERFACE_CONFIRMED: 3675 { 3676 struct sctp_nets *net; 3677 3678 net = (struct sctp_nets *)data; 3679 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED, 3680 (struct sockaddr *)&net->ro._l_addr, error, so_locked); 3681 break; 3682 } 3683 case SCTP_NOTIFY_SPECIAL_SP_FAIL: 3684 sctp_notify_send_failed2(stcb, error, 3685 (struct sctp_stream_queue_pending *)data, so_locked); 3686 break; 3687 case SCTP_NOTIFY_SENT_DG_FAIL: 3688 sctp_notify_send_failed(stcb, 1, error, 3689 (struct sctp_tmit_chunk *)data, so_locked); 3690 break; 3691 case SCTP_NOTIFY_UNSENT_DG_FAIL: 3692 sctp_notify_send_failed(stcb, 0, error, 3693 (struct sctp_tmit_chunk *)data, so_locked); 3694 break; 3695 case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION: 3696 { 3697 uint32_t val; 3698 3699 val = *((uint32_t *)data); 3700 3701 sctp_notify_partial_delivery_indication(stcb, error, val, so_locked); 3702 break; 3703 } 3704 case SCTP_NOTIFY_ASSOC_LOC_ABORTED: 3705 if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) || 3706 ((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) { 3707 sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked); 3708 } else { 3709 sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked); 3710 } 3711 break; 3712 case SCTP_NOTIFY_ASSOC_REM_ABORTED: 3713 if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) || 3714 ((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) { 3715 sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked); 3716 } else { 3717 sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked); 3718 } 3719 break; 3720 case SCTP_NOTIFY_ASSOC_RESTART: 3721 sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked); 3722 if (stcb->asoc.auth_supported == 0) { 3723 sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0, 3724 NULL, so_locked); 3725 } 3726 break; 3727 case SCTP_NOTIFY_STR_RESET_SEND: 3728 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STREAM_RESET_OUTGOING_SSN); 3729 break; 3730 case SCTP_NOTIFY_STR_RESET_RECV: 3731 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STREAM_RESET_INCOMING); 3732 break; 3733 case SCTP_NOTIFY_STR_RESET_FAILED_OUT: 3734 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), 3735 (SCTP_STREAM_RESET_OUTGOING_SSN | SCTP_STREAM_RESET_FAILED)); 3736 break; 3737 case SCTP_NOTIFY_STR_RESET_DENIED_OUT: 3738 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), 3739 (SCTP_STREAM_RESET_OUTGOING_SSN | SCTP_STREAM_RESET_DENIED)); 3740 break; 3741 case SCTP_NOTIFY_STR_RESET_FAILED_IN: 3742 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), 3743 (SCTP_STREAM_RESET_INCOMING | SCTP_STREAM_RESET_FAILED)); 3744 break; 3745 case SCTP_NOTIFY_STR_RESET_DENIED_IN: 3746 sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), 3747 (SCTP_STREAM_RESET_INCOMING | SCTP_STREAM_RESET_DENIED)); 3748 break; 3749 case SCTP_NOTIFY_ASCONF_ADD_IP: 3750 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data, 3751 error, so_locked); 3752 break; 3753 case SCTP_NOTIFY_ASCONF_DELETE_IP: 3754 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data, 3755 error, so_locked); 3756 break; 3757 case SCTP_NOTIFY_ASCONF_SET_PRIMARY: 3758 sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data, 3759 error, so_locked); 3760 break; 3761 case SCTP_NOTIFY_PEER_SHUTDOWN: 3762 sctp_notify_shutdown_event(stcb); 3763 break; 3764 case SCTP_NOTIFY_AUTH_NEW_KEY: 3765 sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error, 3766 (uint16_t)(uintptr_t)data, 3767 so_locked); 3768 break; 3769 case SCTP_NOTIFY_AUTH_FREE_KEY: 3770 sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY, error, 3771 (uint16_t)(uintptr_t)data, 3772 so_locked); 3773 break; 3774 case SCTP_NOTIFY_NO_PEER_AUTH: 3775 sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, error, 3776 (uint16_t)(uintptr_t)data, 3777 so_locked); 3778 break; 3779 case SCTP_NOTIFY_SENDER_DRY: 3780 sctp_notify_sender_dry_event(stcb, so_locked); 3781 break; 3782 case SCTP_NOTIFY_REMOTE_ERROR: 3783 sctp_notify_remote_error(stcb, error, data); 3784 break; 3785 default: 3786 SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n", 3787 __func__, notification, notification); 3788 break; 3789 } /* end switch */ 3790 } 3791 3792 void 3793 sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked 3794 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 3795 SCTP_UNUSED 3796 #endif 3797 ) 3798 { 3799 struct sctp_association *asoc; 3800 struct sctp_stream_out *outs; 3801 struct sctp_tmit_chunk *chk, *nchk; 3802 struct sctp_stream_queue_pending *sp, *nsp; 3803 int i; 3804 3805 if (stcb == NULL) { 3806 return; 3807 } 3808 asoc = &stcb->asoc; 3809 if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) { 3810 /* already being freed */ 3811 return; 3812 } 3813 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 3814 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 3815 (asoc->state & SCTP_STATE_CLOSED_SOCKET)) { 3816 return; 3817 } 3818 /* now through all the gunk freeing chunks */ 3819 if (holds_lock == 0) { 3820 SCTP_TCB_SEND_LOCK(stcb); 3821 } 3822 /* sent queue SHOULD be empty */ 3823 TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { 3824 TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); 3825 asoc->sent_queue_cnt--; 3826 if (chk->sent != SCTP_DATAGRAM_NR_ACKED) { 3827 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) { 3828 asoc->strmout[chk->rec.data.sid].chunks_on_queues--; 3829 #ifdef INVARIANTS 3830 } else { 3831 panic("No chunks on the queues for sid %u.", chk->rec.data.sid); 3832 #endif 3833 } 3834 } 3835 if (chk->data != NULL) { 3836 sctp_free_bufspace(stcb, asoc, chk, 1); 3837 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 3838 error, chk, so_locked); 3839 if (chk->data) { 3840 sctp_m_freem(chk->data); 3841 chk->data = NULL; 3842 } 3843 } 3844 sctp_free_a_chunk(stcb, chk, so_locked); 3845 /* sa_ignore FREED_MEMORY */ 3846 } 3847 /* pending send queue SHOULD be empty */ 3848 TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { 3849 TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); 3850 asoc->send_queue_cnt--; 3851 if (asoc->strmout[chk->rec.data.sid].chunks_on_queues > 0) { 3852 asoc->strmout[chk->rec.data.sid].chunks_on_queues--; 3853 #ifdef INVARIANTS 3854 } else { 3855 panic("No chunks on the queues for sid %u.", chk->rec.data.sid); 3856 #endif 3857 } 3858 if (chk->data != NULL) { 3859 sctp_free_bufspace(stcb, asoc, chk, 1); 3860 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 3861 error, chk, so_locked); 3862 if (chk->data) { 3863 sctp_m_freem(chk->data); 3864 chk->data = NULL; 3865 } 3866 } 3867 sctp_free_a_chunk(stcb, chk, so_locked); 3868 /* sa_ignore FREED_MEMORY */ 3869 } 3870 for (i = 0; i < asoc->streamoutcnt; i++) { 3871 /* For each stream */ 3872 outs = &asoc->strmout[i]; 3873 /* clean up any sends there */ 3874 TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { 3875 atomic_subtract_int(&asoc->stream_queue_cnt, 1); 3876 TAILQ_REMOVE(&outs->outqueue, sp, next); 3877 stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, holds_lock); 3878 sctp_free_spbufspace(stcb, asoc, sp); 3879 if (sp->data) { 3880 sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb, 3881 error, (void *)sp, so_locked); 3882 if (sp->data) { 3883 sctp_m_freem(sp->data); 3884 sp->data = NULL; 3885 sp->tail_mbuf = NULL; 3886 sp->length = 0; 3887 } 3888 } 3889 if (sp->net) { 3890 sctp_free_remote_addr(sp->net); 3891 sp->net = NULL; 3892 } 3893 /* Free the chunk */ 3894 sctp_free_a_strmoq(stcb, sp, so_locked); 3895 /* sa_ignore FREED_MEMORY */ 3896 } 3897 } 3898 3899 if (holds_lock == 0) { 3900 SCTP_TCB_SEND_UNLOCK(stcb); 3901 } 3902 } 3903 3904 void 3905 sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error, 3906 struct sctp_abort_chunk *abort, int so_locked 3907 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 3908 SCTP_UNUSED 3909 #endif 3910 ) 3911 { 3912 if (stcb == NULL) { 3913 return; 3914 } 3915 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3916 ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 3917 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) { 3918 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED; 3919 } 3920 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 3921 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 3922 (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { 3923 return; 3924 } 3925 /* Tell them we lost the asoc */ 3926 sctp_report_all_outbound(stcb, error, 1, so_locked); 3927 if (from_peer) { 3928 sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked); 3929 } else { 3930 sctp_ulp_notify(SCTP_NOTIFY_ASSOC_LOC_ABORTED, stcb, error, abort, so_locked); 3931 } 3932 } 3933 3934 void 3935 sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 3936 struct mbuf *m, int iphlen, 3937 struct sockaddr *src, struct sockaddr *dst, 3938 struct sctphdr *sh, struct mbuf *op_err, 3939 uint8_t mflowtype, uint32_t mflowid, 3940 uint32_t vrf_id, uint16_t port) 3941 { 3942 uint32_t vtag; 3943 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 3944 struct socket *so; 3945 #endif 3946 3947 vtag = 0; 3948 if (stcb != NULL) { 3949 vtag = stcb->asoc.peer_vtag; 3950 vrf_id = stcb->asoc.vrf_id; 3951 } 3952 sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err, 3953 mflowtype, mflowid, inp->fibnum, 3954 vrf_id, port); 3955 if (stcb != NULL) { 3956 /* We have a TCB to abort, send notification too */ 3957 sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED); 3958 stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; 3959 /* Ok, now lets free it */ 3960 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 3961 so = SCTP_INP_SO(inp); 3962 atomic_add_int(&stcb->asoc.refcnt, 1); 3963 SCTP_TCB_UNLOCK(stcb); 3964 SCTP_SOCKET_LOCK(so, 1); 3965 SCTP_TCB_LOCK(stcb); 3966 atomic_subtract_int(&stcb->asoc.refcnt, 1); 3967 #endif 3968 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 3969 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 3970 (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 3971 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 3972 } 3973 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 3974 SCTP_FROM_SCTPUTIL + SCTP_LOC_4); 3975 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 3976 SCTP_SOCKET_UNLOCK(so, 1); 3977 #endif 3978 } 3979 } 3980 #ifdef SCTP_ASOCLOG_OF_TSNS 3981 void 3982 sctp_print_out_track_log(struct sctp_tcb *stcb) 3983 { 3984 #ifdef NOSIY_PRINTS 3985 int i; 3986 3987 SCTP_PRINTF("Last ep reason:%x\n", stcb->sctp_ep->last_abort_code); 3988 SCTP_PRINTF("IN bound TSN log-aaa\n"); 3989 if ((stcb->asoc.tsn_in_at == 0) && (stcb->asoc.tsn_in_wrapped == 0)) { 3990 SCTP_PRINTF("None rcvd\n"); 3991 goto none_in; 3992 } 3993 if (stcb->asoc.tsn_in_wrapped) { 3994 for (i = stcb->asoc.tsn_in_at; i < SCTP_TSN_LOG_SIZE; i++) { 3995 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 3996 stcb->asoc.in_tsnlog[i].tsn, 3997 stcb->asoc.in_tsnlog[i].strm, 3998 stcb->asoc.in_tsnlog[i].seq, 3999 stcb->asoc.in_tsnlog[i].flgs, 4000 stcb->asoc.in_tsnlog[i].sz); 4001 } 4002 } 4003 if (stcb->asoc.tsn_in_at) { 4004 for (i = 0; i < stcb->asoc.tsn_in_at; i++) { 4005 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 4006 stcb->asoc.in_tsnlog[i].tsn, 4007 stcb->asoc.in_tsnlog[i].strm, 4008 stcb->asoc.in_tsnlog[i].seq, 4009 stcb->asoc.in_tsnlog[i].flgs, 4010 stcb->asoc.in_tsnlog[i].sz); 4011 } 4012 } 4013 none_in: 4014 SCTP_PRINTF("OUT bound TSN log-aaa\n"); 4015 if ((stcb->asoc.tsn_out_at == 0) && 4016 (stcb->asoc.tsn_out_wrapped == 0)) { 4017 SCTP_PRINTF("None sent\n"); 4018 } 4019 if (stcb->asoc.tsn_out_wrapped) { 4020 for (i = stcb->asoc.tsn_out_at; i < SCTP_TSN_LOG_SIZE; i++) { 4021 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 4022 stcb->asoc.out_tsnlog[i].tsn, 4023 stcb->asoc.out_tsnlog[i].strm, 4024 stcb->asoc.out_tsnlog[i].seq, 4025 stcb->asoc.out_tsnlog[i].flgs, 4026 stcb->asoc.out_tsnlog[i].sz); 4027 } 4028 } 4029 if (stcb->asoc.tsn_out_at) { 4030 for (i = 0; i < stcb->asoc.tsn_out_at; i++) { 4031 SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 4032 stcb->asoc.out_tsnlog[i].tsn, 4033 stcb->asoc.out_tsnlog[i].strm, 4034 stcb->asoc.out_tsnlog[i].seq, 4035 stcb->asoc.out_tsnlog[i].flgs, 4036 stcb->asoc.out_tsnlog[i].sz); 4037 } 4038 } 4039 #endif 4040 } 4041 #endif 4042 4043 void 4044 sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 4045 struct mbuf *op_err, 4046 int so_locked 4047 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 4048 SCTP_UNUSED 4049 #endif 4050 ) 4051 { 4052 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4053 struct socket *so; 4054 #endif 4055 4056 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4057 so = SCTP_INP_SO(inp); 4058 #endif 4059 if (stcb == NULL) { 4060 /* Got to have a TCB */ 4061 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 4062 if (LIST_EMPTY(&inp->sctp_asoc_list)) { 4063 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 4064 SCTP_CALLED_DIRECTLY_NOCMPSET); 4065 } 4066 } 4067 return; 4068 } else { 4069 stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; 4070 } 4071 /* notify the peer */ 4072 sctp_send_abort_tcb(stcb, op_err, so_locked); 4073 SCTP_STAT_INCR_COUNTER32(sctps_aborted); 4074 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 4075 (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 4076 SCTP_STAT_DECR_GAUGE32(sctps_currestab); 4077 } 4078 /* notify the ulp */ 4079 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 4080 sctp_abort_notification(stcb, 0, 0, NULL, so_locked); 4081 } 4082 /* now free the asoc */ 4083 #ifdef SCTP_ASOCLOG_OF_TSNS 4084 sctp_print_out_track_log(stcb); 4085 #endif 4086 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4087 if (!so_locked) { 4088 atomic_add_int(&stcb->asoc.refcnt, 1); 4089 SCTP_TCB_UNLOCK(stcb); 4090 SCTP_SOCKET_LOCK(so, 1); 4091 SCTP_TCB_LOCK(stcb); 4092 atomic_subtract_int(&stcb->asoc.refcnt, 1); 4093 } 4094 #endif 4095 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 4096 SCTP_FROM_SCTPUTIL + SCTP_LOC_5); 4097 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4098 if (!so_locked) { 4099 SCTP_SOCKET_UNLOCK(so, 1); 4100 } 4101 #endif 4102 } 4103 4104 void 4105 sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, 4106 struct sockaddr *src, struct sockaddr *dst, 4107 struct sctphdr *sh, struct sctp_inpcb *inp, 4108 struct mbuf *cause, 4109 uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, 4110 uint32_t vrf_id, uint16_t port) 4111 { 4112 struct sctp_chunkhdr *ch, chunk_buf; 4113 unsigned int chk_length; 4114 int contains_init_chunk; 4115 4116 SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue); 4117 /* Generate a TO address for future reference */ 4118 if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 4119 if (LIST_EMPTY(&inp->sctp_asoc_list)) { 4120 sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 4121 SCTP_CALLED_DIRECTLY_NOCMPSET); 4122 } 4123 } 4124 contains_init_chunk = 0; 4125 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 4126 sizeof(*ch), (uint8_t *)&chunk_buf); 4127 while (ch != NULL) { 4128 chk_length = ntohs(ch->chunk_length); 4129 if (chk_length < sizeof(*ch)) { 4130 /* break to abort land */ 4131 break; 4132 } 4133 switch (ch->chunk_type) { 4134 case SCTP_INIT: 4135 contains_init_chunk = 1; 4136 break; 4137 case SCTP_PACKET_DROPPED: 4138 /* we don't respond to pkt-dropped */ 4139 return; 4140 case SCTP_ABORT_ASSOCIATION: 4141 /* we don't respond with an ABORT to an ABORT */ 4142 return; 4143 case SCTP_SHUTDOWN_COMPLETE: 4144 /* 4145 * we ignore it since we are not waiting for it and 4146 * peer is gone 4147 */ 4148 return; 4149 case SCTP_SHUTDOWN_ACK: 4150 sctp_send_shutdown_complete2(src, dst, sh, 4151 mflowtype, mflowid, fibnum, 4152 vrf_id, port); 4153 return; 4154 default: 4155 break; 4156 } 4157 offset += SCTP_SIZE32(chk_length); 4158 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 4159 sizeof(*ch), (uint8_t *)&chunk_buf); 4160 } 4161 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 4162 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 4163 (contains_init_chunk == 0))) { 4164 sctp_send_abort(m, iphlen, src, dst, sh, 0, cause, 4165 mflowtype, mflowid, fibnum, 4166 vrf_id, port); 4167 } 4168 } 4169 4170 /* 4171 * check the inbound datagram to make sure there is not an abort inside it, 4172 * if there is return 1, else return 0. 4173 */ 4174 int 4175 sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, uint32_t *vtagfill) 4176 { 4177 struct sctp_chunkhdr *ch; 4178 struct sctp_init_chunk *init_chk, chunk_buf; 4179 int offset; 4180 unsigned int chk_length; 4181 4182 offset = iphlen + sizeof(struct sctphdr); 4183 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch), 4184 (uint8_t *)&chunk_buf); 4185 while (ch != NULL) { 4186 chk_length = ntohs(ch->chunk_length); 4187 if (chk_length < sizeof(*ch)) { 4188 /* packet is probably corrupt */ 4189 break; 4190 } 4191 /* we seem to be ok, is it an abort? */ 4192 if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) { 4193 /* yep, tell them */ 4194 return (1); 4195 } 4196 if (ch->chunk_type == SCTP_INITIATION) { 4197 /* need to update the Vtag */ 4198 init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m, 4199 offset, sizeof(*init_chk), (uint8_t *)&chunk_buf); 4200 if (init_chk != NULL) { 4201 *vtagfill = ntohl(init_chk->init.initiate_tag); 4202 } 4203 } 4204 /* Nope, move to the next chunk */ 4205 offset += SCTP_SIZE32(chk_length); 4206 ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 4207 sizeof(*ch), (uint8_t *)&chunk_buf); 4208 } 4209 return (0); 4210 } 4211 4212 /* 4213 * currently (2/02), ifa_addr embeds scope_id's and don't have sin6_scope_id 4214 * set (i.e. it's 0) so, create this function to compare link local scopes 4215 */ 4216 #ifdef INET6 4217 uint32_t 4218 sctp_is_same_scope(struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2) 4219 { 4220 struct sockaddr_in6 a, b; 4221 4222 /* save copies */ 4223 a = *addr1; 4224 b = *addr2; 4225 4226 if (a.sin6_scope_id == 0) 4227 if (sa6_recoverscope(&a)) { 4228 /* can't get scope, so can't match */ 4229 return (0); 4230 } 4231 if (b.sin6_scope_id == 0) 4232 if (sa6_recoverscope(&b)) { 4233 /* can't get scope, so can't match */ 4234 return (0); 4235 } 4236 if (a.sin6_scope_id != b.sin6_scope_id) 4237 return (0); 4238 4239 return (1); 4240 } 4241 4242 /* 4243 * returns a sockaddr_in6 with embedded scope recovered and removed 4244 */ 4245 struct sockaddr_in6 * 4246 sctp_recover_scope(struct sockaddr_in6 *addr, struct sockaddr_in6 *store) 4247 { 4248 /* check and strip embedded scope junk */ 4249 if (addr->sin6_family == AF_INET6) { 4250 if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) { 4251 if (addr->sin6_scope_id == 0) { 4252 *store = *addr; 4253 if (!sa6_recoverscope(store)) { 4254 /* use the recovered scope */ 4255 addr = store; 4256 } 4257 } else { 4258 /* else, return the original "to" addr */ 4259 in6_clearscope(&addr->sin6_addr); 4260 } 4261 } 4262 } 4263 return (addr); 4264 } 4265 #endif 4266 4267 /* 4268 * are the two addresses the same? currently a "scopeless" check returns: 1 4269 * if same, 0 if not 4270 */ 4271 int 4272 sctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2) 4273 { 4274 4275 /* must be valid */ 4276 if (sa1 == NULL || sa2 == NULL) 4277 return (0); 4278 4279 /* must be the same family */ 4280 if (sa1->sa_family != sa2->sa_family) 4281 return (0); 4282 4283 switch (sa1->sa_family) { 4284 #ifdef INET6 4285 case AF_INET6: 4286 { 4287 /* IPv6 addresses */ 4288 struct sockaddr_in6 *sin6_1, *sin6_2; 4289 4290 sin6_1 = (struct sockaddr_in6 *)sa1; 4291 sin6_2 = (struct sockaddr_in6 *)sa2; 4292 return (SCTP6_ARE_ADDR_EQUAL(sin6_1, 4293 sin6_2)); 4294 } 4295 #endif 4296 #ifdef INET 4297 case AF_INET: 4298 { 4299 /* IPv4 addresses */ 4300 struct sockaddr_in *sin_1, *sin_2; 4301 4302 sin_1 = (struct sockaddr_in *)sa1; 4303 sin_2 = (struct sockaddr_in *)sa2; 4304 return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr); 4305 } 4306 #endif 4307 default: 4308 /* we don't do these... */ 4309 return (0); 4310 } 4311 } 4312 4313 void 4314 sctp_print_address(struct sockaddr *sa) 4315 { 4316 #ifdef INET6 4317 char ip6buf[INET6_ADDRSTRLEN]; 4318 #endif 4319 4320 switch (sa->sa_family) { 4321 #ifdef INET6 4322 case AF_INET6: 4323 { 4324 struct sockaddr_in6 *sin6; 4325 4326 sin6 = (struct sockaddr_in6 *)sa; 4327 SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n", 4328 ip6_sprintf(ip6buf, &sin6->sin6_addr), 4329 ntohs(sin6->sin6_port), 4330 sin6->sin6_scope_id); 4331 break; 4332 } 4333 #endif 4334 #ifdef INET 4335 case AF_INET: 4336 { 4337 struct sockaddr_in *sin; 4338 unsigned char *p; 4339 4340 sin = (struct sockaddr_in *)sa; 4341 p = (unsigned char *)&sin->sin_addr; 4342 SCTP_PRINTF("IPv4 address: %u.%u.%u.%u:%d\n", 4343 p[0], p[1], p[2], p[3], ntohs(sin->sin_port)); 4344 break; 4345 } 4346 #endif 4347 default: 4348 SCTP_PRINTF("?\n"); 4349 break; 4350 } 4351 } 4352 4353 void 4354 sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, 4355 struct sctp_inpcb *new_inp, 4356 struct sctp_tcb *stcb, 4357 int waitflags) 4358 { 4359 /* 4360 * go through our old INP and pull off any control structures that 4361 * belong to stcb and move then to the new inp. 4362 */ 4363 struct socket *old_so, *new_so; 4364 struct sctp_queued_to_read *control, *nctl; 4365 struct sctp_readhead tmp_queue; 4366 struct mbuf *m; 4367 int error = 0; 4368 4369 old_so = old_inp->sctp_socket; 4370 new_so = new_inp->sctp_socket; 4371 TAILQ_INIT(&tmp_queue); 4372 error = sblock(&old_so->so_rcv, waitflags); 4373 if (error) { 4374 /* 4375 * Gak, can't get sblock, we have a problem. data will be 4376 * left stranded.. and we don't dare look at it since the 4377 * other thread may be reading something. Oh well, its a 4378 * screwed up app that does a peeloff OR a accept while 4379 * reading from the main socket... actually its only the 4380 * peeloff() case, since I think read will fail on a 4381 * listening socket.. 4382 */ 4383 return; 4384 } 4385 /* lock the socket buffers */ 4386 SCTP_INP_READ_LOCK(old_inp); 4387 TAILQ_FOREACH_SAFE(control, &old_inp->read_queue, next, nctl) { 4388 /* Pull off all for out target stcb */ 4389 if (control->stcb == stcb) { 4390 /* remove it we want it */ 4391 TAILQ_REMOVE(&old_inp->read_queue, control, next); 4392 TAILQ_INSERT_TAIL(&tmp_queue, control, next); 4393 m = control->data; 4394 while (m) { 4395 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 4396 sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m)); 4397 } 4398 sctp_sbfree(control, stcb, &old_so->so_rcv, m); 4399 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 4400 sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0); 4401 } 4402 m = SCTP_BUF_NEXT(m); 4403 } 4404 } 4405 } 4406 SCTP_INP_READ_UNLOCK(old_inp); 4407 /* Remove the sb-lock on the old socket */ 4408 4409 sbunlock(&old_so->so_rcv); 4410 /* Now we move them over to the new socket buffer */ 4411 SCTP_INP_READ_LOCK(new_inp); 4412 TAILQ_FOREACH_SAFE(control, &tmp_queue, next, nctl) { 4413 TAILQ_INSERT_TAIL(&new_inp->read_queue, control, next); 4414 m = control->data; 4415 while (m) { 4416 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 4417 sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m)); 4418 } 4419 sctp_sballoc(stcb, &new_so->so_rcv, m); 4420 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 4421 sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0); 4422 } 4423 m = SCTP_BUF_NEXT(m); 4424 } 4425 } 4426 SCTP_INP_READ_UNLOCK(new_inp); 4427 } 4428 4429 void 4430 sctp_wakeup_the_read_socket(struct sctp_inpcb *inp, 4431 struct sctp_tcb *stcb, 4432 int so_locked 4433 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 4434 SCTP_UNUSED 4435 #endif 4436 ) 4437 { 4438 if ((inp != NULL) && (inp->sctp_socket != NULL)) { 4439 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4440 struct socket *so; 4441 4442 so = SCTP_INP_SO(inp); 4443 if (!so_locked) { 4444 if (stcb) { 4445 atomic_add_int(&stcb->asoc.refcnt, 1); 4446 SCTP_TCB_UNLOCK(stcb); 4447 } 4448 SCTP_SOCKET_LOCK(so, 1); 4449 if (stcb) { 4450 SCTP_TCB_LOCK(stcb); 4451 atomic_subtract_int(&stcb->asoc.refcnt, 1); 4452 } 4453 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 4454 SCTP_SOCKET_UNLOCK(so, 1); 4455 return; 4456 } 4457 } 4458 #endif 4459 sctp_sorwakeup(inp, inp->sctp_socket); 4460 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4461 if (!so_locked) { 4462 SCTP_SOCKET_UNLOCK(so, 1); 4463 } 4464 #endif 4465 } 4466 } 4467 4468 void 4469 sctp_add_to_readq(struct sctp_inpcb *inp, 4470 struct sctp_tcb *stcb, 4471 struct sctp_queued_to_read *control, 4472 struct sockbuf *sb, 4473 int end, 4474 int inp_read_lock_held, 4475 int so_locked 4476 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 4477 SCTP_UNUSED 4478 #endif 4479 ) 4480 { 4481 /* 4482 * Here we must place the control on the end of the socket read 4483 * queue AND increment sb_cc so that select will work properly on 4484 * read. 4485 */ 4486 struct mbuf *m, *prev = NULL; 4487 4488 if (inp == NULL) { 4489 /* Gak, TSNH!! */ 4490 #ifdef INVARIANTS 4491 panic("Gak, inp NULL on add_to_readq"); 4492 #endif 4493 return; 4494 } 4495 if (inp_read_lock_held == 0) 4496 SCTP_INP_READ_LOCK(inp); 4497 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { 4498 sctp_free_remote_addr(control->whoFrom); 4499 if (control->data) { 4500 sctp_m_freem(control->data); 4501 control->data = NULL; 4502 } 4503 sctp_free_a_readq(stcb, control); 4504 if (inp_read_lock_held == 0) 4505 SCTP_INP_READ_UNLOCK(inp); 4506 return; 4507 } 4508 if (!(control->spec_flags & M_NOTIFICATION)) { 4509 atomic_add_int(&inp->total_recvs, 1); 4510 if (!control->do_not_ref_stcb) { 4511 atomic_add_int(&stcb->total_recvs, 1); 4512 } 4513 } 4514 m = control->data; 4515 control->held_length = 0; 4516 control->length = 0; 4517 while (m) { 4518 if (SCTP_BUF_LEN(m) == 0) { 4519 /* Skip mbufs with NO length */ 4520 if (prev == NULL) { 4521 /* First one */ 4522 control->data = sctp_m_free(m); 4523 m = control->data; 4524 } else { 4525 SCTP_BUF_NEXT(prev) = sctp_m_free(m); 4526 m = SCTP_BUF_NEXT(prev); 4527 } 4528 if (m == NULL) { 4529 control->tail_mbuf = prev; 4530 } 4531 continue; 4532 } 4533 prev = m; 4534 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 4535 sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m)); 4536 } 4537 sctp_sballoc(stcb, sb, m); 4538 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 4539 sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0); 4540 } 4541 atomic_add_int(&control->length, SCTP_BUF_LEN(m)); 4542 m = SCTP_BUF_NEXT(m); 4543 } 4544 if (prev != NULL) { 4545 control->tail_mbuf = prev; 4546 } else { 4547 /* Everything got collapsed out?? */ 4548 sctp_free_remote_addr(control->whoFrom); 4549 sctp_free_a_readq(stcb, control); 4550 if (inp_read_lock_held == 0) 4551 SCTP_INP_READ_UNLOCK(inp); 4552 return; 4553 } 4554 if (end) { 4555 control->end_added = 1; 4556 } 4557 TAILQ_INSERT_TAIL(&inp->read_queue, control, next); 4558 control->on_read_q = 1; 4559 if (inp_read_lock_held == 0) 4560 SCTP_INP_READ_UNLOCK(inp); 4561 if (inp && inp->sctp_socket) { 4562 sctp_wakeup_the_read_socket(inp, stcb, so_locked); 4563 } 4564 } 4565 4566 /*************HOLD THIS COMMENT FOR PATCH FILE OF 4567 *************ALTERNATE ROUTING CODE 4568 */ 4569 4570 /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF 4571 *************ALTERNATE ROUTING CODE 4572 */ 4573 4574 struct mbuf * 4575 sctp_generate_cause(uint16_t code, char *info) 4576 { 4577 struct mbuf *m; 4578 struct sctp_gen_error_cause *cause; 4579 size_t info_len; 4580 uint16_t len; 4581 4582 if ((code == 0) || (info == NULL)) { 4583 return (NULL); 4584 } 4585 info_len = strlen(info); 4586 if (info_len > (SCTP_MAX_CAUSE_LENGTH - sizeof(struct sctp_paramhdr))) { 4587 return (NULL); 4588 } 4589 len = (uint16_t)(sizeof(struct sctp_paramhdr) + info_len); 4590 m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); 4591 if (m != NULL) { 4592 SCTP_BUF_LEN(m) = len; 4593 cause = mtod(m, struct sctp_gen_error_cause *); 4594 cause->code = htons(code); 4595 cause->length = htons(len); 4596 memcpy(cause->info, info, info_len); 4597 } 4598 return (m); 4599 } 4600 4601 struct mbuf * 4602 sctp_generate_no_user_data_cause(uint32_t tsn) 4603 { 4604 struct mbuf *m; 4605 struct sctp_error_no_user_data *no_user_data_cause; 4606 uint16_t len; 4607 4608 len = (uint16_t)sizeof(struct sctp_error_no_user_data); 4609 m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); 4610 if (m != NULL) { 4611 SCTP_BUF_LEN(m) = len; 4612 no_user_data_cause = mtod(m, struct sctp_error_no_user_data *); 4613 no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA); 4614 no_user_data_cause->cause.length = htons(len); 4615 no_user_data_cause->tsn = htonl(tsn); 4616 } 4617 return (m); 4618 } 4619 4620 #ifdef SCTP_MBCNT_LOGGING 4621 void 4622 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc, 4623 struct sctp_tmit_chunk *tp1, int chk_cnt) 4624 { 4625 if (tp1->data == NULL) { 4626 return; 4627 } 4628 asoc->chunks_on_out_queue -= chk_cnt; 4629 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBCNT_LOGGING_ENABLE) { 4630 sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE, 4631 asoc->total_output_queue_size, 4632 tp1->book_size, 4633 0, 4634 tp1->mbcnt); 4635 } 4636 if (asoc->total_output_queue_size >= tp1->book_size) { 4637 atomic_add_int(&asoc->total_output_queue_size, -tp1->book_size); 4638 } else { 4639 asoc->total_output_queue_size = 0; 4640 } 4641 4642 if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) || 4643 ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) { 4644 if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { 4645 stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size; 4646 } else { 4647 stcb->sctp_socket->so_snd.sb_cc = 0; 4648 4649 } 4650 } 4651 } 4652 4653 #endif 4654 4655 int 4656 sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, 4657 uint8_t sent, int so_locked 4658 #if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 4659 SCTP_UNUSED 4660 #endif 4661 ) 4662 { 4663 struct sctp_stream_out *strq; 4664 struct sctp_tmit_chunk *chk = NULL, *tp2; 4665 struct sctp_stream_queue_pending *sp; 4666 uint32_t mid; 4667 uint16_t sid; 4668 uint8_t foundeom = 0; 4669 int ret_sz = 0; 4670 int notdone; 4671 int do_wakeup_routine = 0; 4672 4673 sid = tp1->rec.data.sid; 4674 mid = tp1->rec.data.mid; 4675 if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) { 4676 stcb->asoc.abandoned_sent[0]++; 4677 stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++; 4678 stcb->asoc.strmout[sid].abandoned_sent[0]++; 4679 #if defined(SCTP_DETAILED_STR_STATS) 4680 stcb->asoc.strmout[sid].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++; 4681 #endif 4682 } else { 4683 stcb->asoc.abandoned_unsent[0]++; 4684 stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++; 4685 stcb->asoc.strmout[sid].abandoned_unsent[0]++; 4686 #if defined(SCTP_DETAILED_STR_STATS) 4687 stcb->asoc.strmout[sid].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++; 4688 #endif 4689 } 4690 do { 4691 ret_sz += tp1->book_size; 4692 if (tp1->data != NULL) { 4693 if (tp1->sent < SCTP_DATAGRAM_RESEND) { 4694 sctp_flight_size_decrease(tp1); 4695 sctp_total_flight_decrease(stcb, tp1); 4696 } 4697 sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1); 4698 stcb->asoc.peers_rwnd += tp1->send_size; 4699 stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh); 4700 if (sent) { 4701 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked); 4702 } else { 4703 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked); 4704 } 4705 if (tp1->data) { 4706 sctp_m_freem(tp1->data); 4707 tp1->data = NULL; 4708 } 4709 do_wakeup_routine = 1; 4710 if (PR_SCTP_BUF_ENABLED(tp1->flags)) { 4711 stcb->asoc.sent_queue_cnt_removeable--; 4712 } 4713 } 4714 tp1->sent = SCTP_FORWARD_TSN_SKIP; 4715 if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) == 4716 SCTP_DATA_NOT_FRAG) { 4717 /* not frag'ed we ae done */ 4718 notdone = 0; 4719 foundeom = 1; 4720 } else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { 4721 /* end of frag, we are done */ 4722 notdone = 0; 4723 foundeom = 1; 4724 } else { 4725 /* 4726 * Its a begin or middle piece, we must mark all of 4727 * it 4728 */ 4729 notdone = 1; 4730 tp1 = TAILQ_NEXT(tp1, sctp_next); 4731 } 4732 } while (tp1 && notdone); 4733 if (foundeom == 0) { 4734 /* 4735 * The multi-part message was scattered across the send and 4736 * sent queue. 4737 */ 4738 TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) { 4739 if ((tp1->rec.data.sid != sid) || 4740 (!SCTP_MID_EQ(stcb->asoc.idata_supported, tp1->rec.data.mid, mid))) { 4741 break; 4742 } 4743 /* 4744 * save to chk in case we have some on stream out 4745 * queue. If so and we have an un-transmitted one we 4746 * don't have to fudge the TSN. 4747 */ 4748 chk = tp1; 4749 ret_sz += tp1->book_size; 4750 sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1); 4751 if (sent) { 4752 sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked); 4753 } else { 4754 sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked); 4755 } 4756 if (tp1->data) { 4757 sctp_m_freem(tp1->data); 4758 tp1->data = NULL; 4759 } 4760 /* No flight involved here book the size to 0 */ 4761 tp1->book_size = 0; 4762 if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { 4763 foundeom = 1; 4764 } 4765 do_wakeup_routine = 1; 4766 tp1->sent = SCTP_FORWARD_TSN_SKIP; 4767 TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next); 4768 /* 4769 * on to the sent queue so we can wait for it to be 4770 * passed by. 4771 */ 4772 TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1, 4773 sctp_next); 4774 stcb->asoc.send_queue_cnt--; 4775 stcb->asoc.sent_queue_cnt++; 4776 } 4777 } 4778 if (foundeom == 0) { 4779 /* 4780 * Still no eom found. That means there is stuff left on the 4781 * stream out queue.. yuck. 4782 */ 4783 SCTP_TCB_SEND_LOCK(stcb); 4784 strq = &stcb->asoc.strmout[sid]; 4785 sp = TAILQ_FIRST(&strq->outqueue); 4786 if (sp != NULL) { 4787 sp->discard_rest = 1; 4788 /* 4789 * We may need to put a chunk on the queue that 4790 * holds the TSN that would have been sent with the 4791 * LAST bit. 4792 */ 4793 if (chk == NULL) { 4794 /* Yep, we have to */ 4795 sctp_alloc_a_chunk(stcb, chk); 4796 if (chk == NULL) { 4797 /* 4798 * we are hosed. All we can do is 4799 * nothing.. which will cause an 4800 * abort if the peer is paying 4801 * attention. 4802 */ 4803 goto oh_well; 4804 } 4805 memset(chk, 0, sizeof(*chk)); 4806 chk->rec.data.rcv_flags = 0; 4807 chk->sent = SCTP_FORWARD_TSN_SKIP; 4808 chk->asoc = &stcb->asoc; 4809 if (stcb->asoc.idata_supported == 0) { 4810 if (sp->sinfo_flags & SCTP_UNORDERED) { 4811 chk->rec.data.mid = 0; 4812 } else { 4813 chk->rec.data.mid = strq->next_mid_ordered; 4814 } 4815 } else { 4816 if (sp->sinfo_flags & SCTP_UNORDERED) { 4817 chk->rec.data.mid = strq->next_mid_unordered; 4818 } else { 4819 chk->rec.data.mid = strq->next_mid_ordered; 4820 } 4821 } 4822 chk->rec.data.sid = sp->sid; 4823 chk->rec.data.ppid = sp->ppid; 4824 chk->rec.data.context = sp->context; 4825 chk->flags = sp->act_flags; 4826 chk->whoTo = NULL; 4827 chk->rec.data.tsn = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1); 4828 strq->chunks_on_queues++; 4829 TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next); 4830 stcb->asoc.sent_queue_cnt++; 4831 stcb->asoc.pr_sctp_cnt++; 4832 } 4833 chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG; 4834 if (sp->sinfo_flags & SCTP_UNORDERED) { 4835 chk->rec.data.rcv_flags |= SCTP_DATA_UNORDERED; 4836 } 4837 if (stcb->asoc.idata_supported == 0) { 4838 if ((sp->sinfo_flags & SCTP_UNORDERED) == 0) { 4839 strq->next_mid_ordered++; 4840 } 4841 } else { 4842 if (sp->sinfo_flags & SCTP_UNORDERED) { 4843 strq->next_mid_unordered++; 4844 } else { 4845 strq->next_mid_ordered++; 4846 } 4847 } 4848 oh_well: 4849 if (sp->data) { 4850 /* 4851 * Pull any data to free up the SB and allow 4852 * sender to "add more" while we will throw 4853 * away :-) 4854 */ 4855 sctp_free_spbufspace(stcb, &stcb->asoc, sp); 4856 ret_sz += sp->length; 4857 do_wakeup_routine = 1; 4858 sp->some_taken = 1; 4859 sctp_m_freem(sp->data); 4860 sp->data = NULL; 4861 sp->tail_mbuf = NULL; 4862 sp->length = 0; 4863 } 4864 } 4865 SCTP_TCB_SEND_UNLOCK(stcb); 4866 } 4867 if (do_wakeup_routine) { 4868 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4869 struct socket *so; 4870 4871 so = SCTP_INP_SO(stcb->sctp_ep); 4872 if (!so_locked) { 4873 atomic_add_int(&stcb->asoc.refcnt, 1); 4874 SCTP_TCB_UNLOCK(stcb); 4875 SCTP_SOCKET_LOCK(so, 1); 4876 SCTP_TCB_LOCK(stcb); 4877 atomic_subtract_int(&stcb->asoc.refcnt, 1); 4878 if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { 4879 /* assoc was freed while we were unlocked */ 4880 SCTP_SOCKET_UNLOCK(so, 1); 4881 return (ret_sz); 4882 } 4883 } 4884 #endif 4885 sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket); 4886 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4887 if (!so_locked) { 4888 SCTP_SOCKET_UNLOCK(so, 1); 4889 } 4890 #endif 4891 } 4892 return (ret_sz); 4893 } 4894 4895 /* 4896 * checks to see if the given address, sa, is one that is currently known by 4897 * the kernel note: can't distinguish the same address on multiple interfaces 4898 * and doesn't handle multiple addresses with different zone/scope id's note: 4899 * ifa_ifwithaddr() compares the entire sockaddr struct 4900 */ 4901 struct sctp_ifa * 4902 sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr, 4903 int holds_lock) 4904 { 4905 struct sctp_laddr *laddr; 4906 4907 if (holds_lock == 0) { 4908 SCTP_INP_RLOCK(inp); 4909 } 4910 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 4911 if (laddr->ifa == NULL) 4912 continue; 4913 if (addr->sa_family != laddr->ifa->address.sa.sa_family) 4914 continue; 4915 #ifdef INET 4916 if (addr->sa_family == AF_INET) { 4917 if (((struct sockaddr_in *)addr)->sin_addr.s_addr == 4918 laddr->ifa->address.sin.sin_addr.s_addr) { 4919 /* found him. */ 4920 if (holds_lock == 0) { 4921 SCTP_INP_RUNLOCK(inp); 4922 } 4923 return (laddr->ifa); 4924 break; 4925 } 4926 } 4927 #endif 4928 #ifdef INET6 4929 if (addr->sa_family == AF_INET6) { 4930 if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr, 4931 &laddr->ifa->address.sin6)) { 4932 /* found him. */ 4933 if (holds_lock == 0) { 4934 SCTP_INP_RUNLOCK(inp); 4935 } 4936 return (laddr->ifa); 4937 break; 4938 } 4939 } 4940 #endif 4941 } 4942 if (holds_lock == 0) { 4943 SCTP_INP_RUNLOCK(inp); 4944 } 4945 return (NULL); 4946 } 4947 4948 uint32_t 4949 sctp_get_ifa_hash_val(struct sockaddr *addr) 4950 { 4951 switch (addr->sa_family) { 4952 #ifdef INET 4953 case AF_INET: 4954 { 4955 struct sockaddr_in *sin; 4956 4957 sin = (struct sockaddr_in *)addr; 4958 return (sin->sin_addr.s_addr ^ (sin->sin_addr.s_addr >> 16)); 4959 } 4960 #endif 4961 #ifdef INET6 4962 case AF_INET6: 4963 { 4964 struct sockaddr_in6 *sin6; 4965 uint32_t hash_of_addr; 4966 4967 sin6 = (struct sockaddr_in6 *)addr; 4968 hash_of_addr = (sin6->sin6_addr.s6_addr32[0] + 4969 sin6->sin6_addr.s6_addr32[1] + 4970 sin6->sin6_addr.s6_addr32[2] + 4971 sin6->sin6_addr.s6_addr32[3]); 4972 hash_of_addr = (hash_of_addr ^ (hash_of_addr >> 16)); 4973 return (hash_of_addr); 4974 } 4975 #endif 4976 default: 4977 break; 4978 } 4979 return (0); 4980 } 4981 4982 struct sctp_ifa * 4983 sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock) 4984 { 4985 struct sctp_ifa *sctp_ifap; 4986 struct sctp_vrf *vrf; 4987 struct sctp_ifalist *hash_head; 4988 uint32_t hash_of_addr; 4989 4990 if (holds_lock == 0) 4991 SCTP_IPI_ADDR_RLOCK(); 4992 4993 vrf = sctp_find_vrf(vrf_id); 4994 if (vrf == NULL) { 4995 if (holds_lock == 0) 4996 SCTP_IPI_ADDR_RUNLOCK(); 4997 return (NULL); 4998 } 4999 hash_of_addr = sctp_get_ifa_hash_val(addr); 5000 5001 hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)]; 5002 if (hash_head == NULL) { 5003 SCTP_PRINTF("hash_of_addr:%x mask:%x table:%x - ", 5004 hash_of_addr, (uint32_t)vrf->vrf_addr_hashmark, 5005 (uint32_t)(hash_of_addr & vrf->vrf_addr_hashmark)); 5006 sctp_print_address(addr); 5007 SCTP_PRINTF("No such bucket for address\n"); 5008 if (holds_lock == 0) 5009 SCTP_IPI_ADDR_RUNLOCK(); 5010 5011 return (NULL); 5012 } 5013 LIST_FOREACH(sctp_ifap, hash_head, next_bucket) { 5014 if (addr->sa_family != sctp_ifap->address.sa.sa_family) 5015 continue; 5016 #ifdef INET 5017 if (addr->sa_family == AF_INET) { 5018 if (((struct sockaddr_in *)addr)->sin_addr.s_addr == 5019 sctp_ifap->address.sin.sin_addr.s_addr) { 5020 /* found him. */ 5021 if (holds_lock == 0) 5022 SCTP_IPI_ADDR_RUNLOCK(); 5023 return (sctp_ifap); 5024 break; 5025 } 5026 } 5027 #endif 5028 #ifdef INET6 5029 if (addr->sa_family == AF_INET6) { 5030 if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr, 5031 &sctp_ifap->address.sin6)) { 5032 /* found him. */ 5033 if (holds_lock == 0) 5034 SCTP_IPI_ADDR_RUNLOCK(); 5035 return (sctp_ifap); 5036 break; 5037 } 5038 } 5039 #endif 5040 } 5041 if (holds_lock == 0) 5042 SCTP_IPI_ADDR_RUNLOCK(); 5043 return (NULL); 5044 } 5045 5046 static void 5047 sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t *freed_so_far, int hold_rlock, 5048 uint32_t rwnd_req) 5049 { 5050 /* User pulled some data, do we need a rwnd update? */ 5051 int r_unlocked = 0; 5052 uint32_t dif, rwnd; 5053 struct socket *so = NULL; 5054 5055 if (stcb == NULL) 5056 return; 5057 5058 atomic_add_int(&stcb->asoc.refcnt, 1); 5059 5060 if (stcb->asoc.state & (SCTP_STATE_ABOUT_TO_BE_FREED | 5061 SCTP_STATE_SHUTDOWN_RECEIVED | 5062 SCTP_STATE_SHUTDOWN_ACK_SENT)) { 5063 /* Pre-check If we are freeing no update */ 5064 goto no_lock; 5065 } 5066 SCTP_INP_INCR_REF(stcb->sctp_ep); 5067 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 5068 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { 5069 goto out; 5070 } 5071 so = stcb->sctp_socket; 5072 if (so == NULL) { 5073 goto out; 5074 } 5075 atomic_add_int(&stcb->freed_by_sorcv_sincelast, *freed_so_far); 5076 /* Have you have freed enough to look */ 5077 *freed_so_far = 0; 5078 /* Yep, its worth a look and the lock overhead */ 5079 5080 /* Figure out what the rwnd would be */ 5081 rwnd = sctp_calc_rwnd(stcb, &stcb->asoc); 5082 if (rwnd >= stcb->asoc.my_last_reported_rwnd) { 5083 dif = rwnd - stcb->asoc.my_last_reported_rwnd; 5084 } else { 5085 dif = 0; 5086 } 5087 if (dif >= rwnd_req) { 5088 if (hold_rlock) { 5089 SCTP_INP_READ_UNLOCK(stcb->sctp_ep); 5090 r_unlocked = 1; 5091 } 5092 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 5093 /* 5094 * One last check before we allow the guy possibly 5095 * to get in. There is a race, where the guy has not 5096 * reached the gate. In that case 5097 */ 5098 goto out; 5099 } 5100 SCTP_TCB_LOCK(stcb); 5101 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 5102 /* No reports here */ 5103 SCTP_TCB_UNLOCK(stcb); 5104 goto out; 5105 } 5106 SCTP_STAT_INCR(sctps_wu_sacks_sent); 5107 sctp_send_sack(stcb, SCTP_SO_LOCKED); 5108 5109 sctp_chunk_output(stcb->sctp_ep, stcb, 5110 SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED); 5111 /* make sure no timer is running */ 5112 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, 5113 SCTP_FROM_SCTPUTIL + SCTP_LOC_6); 5114 SCTP_TCB_UNLOCK(stcb); 5115 } else { 5116 /* Update how much we have pending */ 5117 stcb->freed_by_sorcv_sincelast = dif; 5118 } 5119 out: 5120 if (so && r_unlocked && hold_rlock) { 5121 SCTP_INP_READ_LOCK(stcb->sctp_ep); 5122 } 5123 SCTP_INP_DECR_REF(stcb->sctp_ep); 5124 no_lock: 5125 atomic_add_int(&stcb->asoc.refcnt, -1); 5126 return; 5127 } 5128 5129 int 5130 sctp_sorecvmsg(struct socket *so, 5131 struct uio *uio, 5132 struct mbuf **mp, 5133 struct sockaddr *from, 5134 int fromlen, 5135 int *msg_flags, 5136 struct sctp_sndrcvinfo *sinfo, 5137 int filling_sinfo) 5138 { 5139 /* 5140 * MSG flags we will look at MSG_DONTWAIT - non-blocking IO. 5141 * MSG_PEEK - Look don't touch :-D (only valid with OUT mbuf copy 5142 * mp=NULL thus uio is the copy method to userland) MSG_WAITALL - ?? 5143 * On the way out we may send out any combination of: 5144 * MSG_NOTIFICATION MSG_EOR 5145 * 5146 */ 5147 struct sctp_inpcb *inp = NULL; 5148 int my_len = 0; 5149 int cp_len = 0, error = 0; 5150 struct sctp_queued_to_read *control = NULL, *ctl = NULL, *nxt = NULL; 5151 struct mbuf *m = NULL; 5152 struct sctp_tcb *stcb = NULL; 5153 int wakeup_read_socket = 0; 5154 int freecnt_applied = 0; 5155 int out_flags = 0, in_flags = 0; 5156 int block_allowed = 1; 5157 uint32_t freed_so_far = 0; 5158 uint32_t copied_so_far = 0; 5159 int in_eeor_mode = 0; 5160 int no_rcv_needed = 0; 5161 uint32_t rwnd_req = 0; 5162 int hold_sblock = 0; 5163 int hold_rlock = 0; 5164 ssize_t slen = 0; 5165 uint32_t held_length = 0; 5166 int sockbuf_lock = 0; 5167 5168 if (uio == NULL) { 5169 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 5170 return (EINVAL); 5171 } 5172 if (msg_flags) { 5173 in_flags = *msg_flags; 5174 if (in_flags & MSG_PEEK) 5175 SCTP_STAT_INCR(sctps_read_peeks); 5176 } else { 5177 in_flags = 0; 5178 } 5179 slen = uio->uio_resid; 5180 5181 /* Pull in and set up our int flags */ 5182 if (in_flags & MSG_OOB) { 5183 /* Out of band's NOT supported */ 5184 return (EOPNOTSUPP); 5185 } 5186 if ((in_flags & MSG_PEEK) && (mp != NULL)) { 5187 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 5188 return (EINVAL); 5189 } 5190 if ((in_flags & (MSG_DONTWAIT 5191 | MSG_NBIO 5192 )) || 5193 SCTP_SO_IS_NBIO(so)) { 5194 block_allowed = 0; 5195 } 5196 /* setup the endpoint */ 5197 inp = (struct sctp_inpcb *)so->so_pcb; 5198 if (inp == NULL) { 5199 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT); 5200 return (EFAULT); 5201 } 5202 rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT); 5203 /* Must be at least a MTU's worth */ 5204 if (rwnd_req < SCTP_MIN_RWND) 5205 rwnd_req = SCTP_MIN_RWND; 5206 in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); 5207 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) { 5208 sctp_misc_ints(SCTP_SORECV_ENTER, 5209 rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, (uint32_t)uio->uio_resid); 5210 } 5211 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) { 5212 sctp_misc_ints(SCTP_SORECV_ENTERPL, 5213 rwnd_req, block_allowed, so->so_rcv.sb_cc, (uint32_t)uio->uio_resid); 5214 } 5215 error = sblock(&so->so_rcv, (block_allowed ? SBL_WAIT : 0)); 5216 if (error) { 5217 goto release_unlocked; 5218 } 5219 sockbuf_lock = 1; 5220 restart: 5221 5222 5223 restart_nosblocks: 5224 if (hold_sblock == 0) { 5225 SOCKBUF_LOCK(&so->so_rcv); 5226 hold_sblock = 1; 5227 } 5228 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 5229 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { 5230 goto out; 5231 } 5232 if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) { 5233 if (so->so_error) { 5234 error = so->so_error; 5235 if ((in_flags & MSG_PEEK) == 0) 5236 so->so_error = 0; 5237 goto out; 5238 } else { 5239 if (so->so_rcv.sb_cc == 0) { 5240 /* indicate EOF */ 5241 error = 0; 5242 goto out; 5243 } 5244 } 5245 } 5246 if (so->so_rcv.sb_cc <= held_length) { 5247 if (so->so_error) { 5248 error = so->so_error; 5249 if ((in_flags & MSG_PEEK) == 0) { 5250 so->so_error = 0; 5251 } 5252 goto out; 5253 } 5254 if ((so->so_rcv.sb_cc == 0) && 5255 ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5256 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { 5257 if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) { 5258 /* 5259 * For active open side clear flags for 5260 * re-use passive open is blocked by 5261 * connect. 5262 */ 5263 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) { 5264 /* 5265 * You were aborted, passive side 5266 * always hits here 5267 */ 5268 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET); 5269 error = ECONNRESET; 5270 } 5271 so->so_state &= ~(SS_ISCONNECTING | 5272 SS_ISDISCONNECTING | 5273 SS_ISCONFIRMING | 5274 SS_ISCONNECTED); 5275 if (error == 0) { 5276 if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) { 5277 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN); 5278 error = ENOTCONN; 5279 } 5280 } 5281 goto out; 5282 } 5283 } 5284 if (block_allowed) { 5285 error = sbwait(&so->so_rcv); 5286 if (error) { 5287 goto out; 5288 } 5289 held_length = 0; 5290 goto restart_nosblocks; 5291 } else { 5292 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EWOULDBLOCK); 5293 error = EWOULDBLOCK; 5294 goto out; 5295 } 5296 } 5297 if (hold_sblock == 1) { 5298 SOCKBUF_UNLOCK(&so->so_rcv); 5299 hold_sblock = 0; 5300 } 5301 /* we possibly have data we can read */ 5302 /* sa_ignore FREED_MEMORY */ 5303 control = TAILQ_FIRST(&inp->read_queue); 5304 if (control == NULL) { 5305 /* 5306 * This could be happening since the appender did the 5307 * increment but as not yet did the tailq insert onto the 5308 * read_queue 5309 */ 5310 if (hold_rlock == 0) { 5311 SCTP_INP_READ_LOCK(inp); 5312 } 5313 control = TAILQ_FIRST(&inp->read_queue); 5314 if ((control == NULL) && (so->so_rcv.sb_cc != 0)) { 5315 #ifdef INVARIANTS 5316 panic("Huh, its non zero and nothing on control?"); 5317 #endif 5318 so->so_rcv.sb_cc = 0; 5319 } 5320 SCTP_INP_READ_UNLOCK(inp); 5321 hold_rlock = 0; 5322 goto restart; 5323 } 5324 if ((control->length == 0) && 5325 (control->do_not_ref_stcb)) { 5326 /* 5327 * Clean up code for freeing assoc that left behind a 5328 * pdapi.. maybe a peer in EEOR that just closed after 5329 * sending and never indicated a EOR. 5330 */ 5331 if (hold_rlock == 0) { 5332 hold_rlock = 1; 5333 SCTP_INP_READ_LOCK(inp); 5334 } 5335 control->held_length = 0; 5336 if (control->data) { 5337 /* Hmm there is data here .. fix */ 5338 struct mbuf *m_tmp; 5339 int cnt = 0; 5340 5341 m_tmp = control->data; 5342 while (m_tmp) { 5343 cnt += SCTP_BUF_LEN(m_tmp); 5344 if (SCTP_BUF_NEXT(m_tmp) == NULL) { 5345 control->tail_mbuf = m_tmp; 5346 control->end_added = 1; 5347 } 5348 m_tmp = SCTP_BUF_NEXT(m_tmp); 5349 } 5350 control->length = cnt; 5351 } else { 5352 /* remove it */ 5353 TAILQ_REMOVE(&inp->read_queue, control, next); 5354 /* Add back any hiddend data */ 5355 sctp_free_remote_addr(control->whoFrom); 5356 sctp_free_a_readq(stcb, control); 5357 } 5358 if (hold_rlock) { 5359 hold_rlock = 0; 5360 SCTP_INP_READ_UNLOCK(inp); 5361 } 5362 goto restart; 5363 } 5364 if ((control->length == 0) && 5365 (control->end_added == 1)) { 5366 /* 5367 * Do we also need to check for (control->pdapi_aborted == 5368 * 1)? 5369 */ 5370 if (hold_rlock == 0) { 5371 hold_rlock = 1; 5372 SCTP_INP_READ_LOCK(inp); 5373 } 5374 TAILQ_REMOVE(&inp->read_queue, control, next); 5375 if (control->data) { 5376 #ifdef INVARIANTS 5377 panic("control->data not null but control->length == 0"); 5378 #else 5379 SCTP_PRINTF("Strange, data left in the control buffer. Cleaning up.\n"); 5380 sctp_m_freem(control->data); 5381 control->data = NULL; 5382 #endif 5383 } 5384 if (control->aux_data) { 5385 sctp_m_free(control->aux_data); 5386 control->aux_data = NULL; 5387 } 5388 #ifdef INVARIANTS 5389 if (control->on_strm_q) { 5390 panic("About to free ctl:%p so:%p and its in %d", 5391 control, so, control->on_strm_q); 5392 } 5393 #endif 5394 sctp_free_remote_addr(control->whoFrom); 5395 sctp_free_a_readq(stcb, control); 5396 if (hold_rlock) { 5397 hold_rlock = 0; 5398 SCTP_INP_READ_UNLOCK(inp); 5399 } 5400 goto restart; 5401 } 5402 if (control->length == 0) { 5403 if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) && 5404 (filling_sinfo)) { 5405 /* find a more suitable one then this */ 5406 ctl = TAILQ_NEXT(control, next); 5407 while (ctl) { 5408 if ((ctl->stcb != control->stcb) && (ctl->length) && 5409 (ctl->some_taken || 5410 (ctl->spec_flags & M_NOTIFICATION) || 5411 ((ctl->do_not_ref_stcb == 0) && 5412 (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0))) 5413 ) { 5414 /*- 5415 * If we have a different TCB next, and there is data 5416 * present. If we have already taken some (pdapi), OR we can 5417 * ref the tcb and no delivery as started on this stream, we 5418 * take it. Note we allow a notification on a different 5419 * assoc to be delivered.. 5420 */ 5421 control = ctl; 5422 goto found_one; 5423 } else if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) && 5424 (ctl->length) && 5425 ((ctl->some_taken) || 5426 ((ctl->do_not_ref_stcb == 0) && 5427 ((ctl->spec_flags & M_NOTIFICATION) == 0) && 5428 (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))) { 5429 /*- 5430 * If we have the same tcb, and there is data present, and we 5431 * have the strm interleave feature present. Then if we have 5432 * taken some (pdapi) or we can refer to tht tcb AND we have 5433 * not started a delivery for this stream, we can take it. 5434 * Note we do NOT allow a notificaiton on the same assoc to 5435 * be delivered. 5436 */ 5437 control = ctl; 5438 goto found_one; 5439 } 5440 ctl = TAILQ_NEXT(ctl, next); 5441 } 5442 } 5443 /* 5444 * if we reach here, not suitable replacement is available 5445 * <or> fragment interleave is NOT on. So stuff the sb_cc 5446 * into the our held count, and its time to sleep again. 5447 */ 5448 held_length = so->so_rcv.sb_cc; 5449 control->held_length = so->so_rcv.sb_cc; 5450 goto restart; 5451 } 5452 /* Clear the held length since there is something to read */ 5453 control->held_length = 0; 5454 found_one: 5455 /* 5456 * If we reach here, control has a some data for us to read off. 5457 * Note that stcb COULD be NULL. 5458 */ 5459 if (hold_rlock == 0) { 5460 hold_rlock = 1; 5461 SCTP_INP_READ_LOCK(inp); 5462 } 5463 control->some_taken++; 5464 stcb = control->stcb; 5465 if (stcb) { 5466 if ((control->do_not_ref_stcb == 0) && 5467 (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) { 5468 if (freecnt_applied == 0) 5469 stcb = NULL; 5470 } else if (control->do_not_ref_stcb == 0) { 5471 /* you can't free it on me please */ 5472 /* 5473 * The lock on the socket buffer protects us so the 5474 * free code will stop. But since we used the 5475 * socketbuf lock and the sender uses the tcb_lock 5476 * to increment, we need to use the atomic add to 5477 * the refcnt 5478 */ 5479 if (freecnt_applied) { 5480 #ifdef INVARIANTS 5481 panic("refcnt already incremented"); 5482 #else 5483 SCTP_PRINTF("refcnt already incremented?\n"); 5484 #endif 5485 } else { 5486 atomic_add_int(&stcb->asoc.refcnt, 1); 5487 freecnt_applied = 1; 5488 } 5489 /* 5490 * Setup to remember how much we have not yet told 5491 * the peer our rwnd has opened up. Note we grab the 5492 * value from the tcb from last time. Note too that 5493 * sack sending clears this when a sack is sent, 5494 * which is fine. Once we hit the rwnd_req, we then 5495 * will go to the sctp_user_rcvd() that will not 5496 * lock until it KNOWs it MUST send a WUP-SACK. 5497 */ 5498 freed_so_far = stcb->freed_by_sorcv_sincelast; 5499 stcb->freed_by_sorcv_sincelast = 0; 5500 } 5501 } 5502 if (stcb && 5503 ((control->spec_flags & M_NOTIFICATION) == 0) && 5504 control->do_not_ref_stcb == 0) { 5505 stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1; 5506 } 5507 /* First lets get off the sinfo and sockaddr info */ 5508 if ((sinfo != NULL) && (filling_sinfo != 0)) { 5509 sinfo->sinfo_stream = control->sinfo_stream; 5510 sinfo->sinfo_ssn = (uint16_t)control->mid; 5511 sinfo->sinfo_flags = control->sinfo_flags; 5512 sinfo->sinfo_ppid = control->sinfo_ppid; 5513 sinfo->sinfo_context = control->sinfo_context; 5514 sinfo->sinfo_timetolive = control->sinfo_timetolive; 5515 sinfo->sinfo_tsn = control->sinfo_tsn; 5516 sinfo->sinfo_cumtsn = control->sinfo_cumtsn; 5517 sinfo->sinfo_assoc_id = control->sinfo_assoc_id; 5518 nxt = TAILQ_NEXT(control, next); 5519 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) || 5520 sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) { 5521 struct sctp_extrcvinfo *s_extra; 5522 5523 s_extra = (struct sctp_extrcvinfo *)sinfo; 5524 if ((nxt) && 5525 (nxt->length)) { 5526 s_extra->serinfo_next_flags = SCTP_NEXT_MSG_AVAIL; 5527 if (nxt->sinfo_flags & SCTP_UNORDERED) { 5528 s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED; 5529 } 5530 if (nxt->spec_flags & M_NOTIFICATION) { 5531 s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION; 5532 } 5533 s_extra->serinfo_next_aid = nxt->sinfo_assoc_id; 5534 s_extra->serinfo_next_length = nxt->length; 5535 s_extra->serinfo_next_ppid = nxt->sinfo_ppid; 5536 s_extra->serinfo_next_stream = nxt->sinfo_stream; 5537 if (nxt->tail_mbuf != NULL) { 5538 if (nxt->end_added) { 5539 s_extra->serinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE; 5540 } 5541 } 5542 } else { 5543 /* 5544 * we explicitly 0 this, since the memcpy 5545 * got some other things beyond the older 5546 * sinfo_ that is on the control's structure 5547 * :-D 5548 */ 5549 nxt = NULL; 5550 s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG; 5551 s_extra->serinfo_next_aid = 0; 5552 s_extra->serinfo_next_length = 0; 5553 s_extra->serinfo_next_ppid = 0; 5554 s_extra->serinfo_next_stream = 0; 5555 } 5556 } 5557 /* 5558 * update off the real current cum-ack, if we have an stcb. 5559 */ 5560 if ((control->do_not_ref_stcb == 0) && stcb) 5561 sinfo->sinfo_cumtsn = stcb->asoc.cumulative_tsn; 5562 /* 5563 * mask off the high bits, we keep the actual chunk bits in 5564 * there. 5565 */ 5566 sinfo->sinfo_flags &= 0x00ff; 5567 if ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) { 5568 sinfo->sinfo_flags |= SCTP_UNORDERED; 5569 } 5570 } 5571 #ifdef SCTP_ASOCLOG_OF_TSNS 5572 { 5573 int index, newindex; 5574 struct sctp_pcbtsn_rlog *entry; 5575 5576 do { 5577 index = inp->readlog_index; 5578 newindex = index + 1; 5579 if (newindex >= SCTP_READ_LOG_SIZE) { 5580 newindex = 0; 5581 } 5582 } while (atomic_cmpset_int(&inp->readlog_index, index, newindex) == 0); 5583 entry = &inp->readlog[index]; 5584 entry->vtag = control->sinfo_assoc_id; 5585 entry->strm = control->sinfo_stream; 5586 entry->seq = (uint16_t)control->mid; 5587 entry->sz = control->length; 5588 entry->flgs = control->sinfo_flags; 5589 } 5590 #endif 5591 if ((fromlen > 0) && (from != NULL)) { 5592 union sctp_sockstore store; 5593 size_t len; 5594 5595 switch (control->whoFrom->ro._l_addr.sa.sa_family) { 5596 #ifdef INET6 5597 case AF_INET6: 5598 len = sizeof(struct sockaddr_in6); 5599 store.sin6 = control->whoFrom->ro._l_addr.sin6; 5600 store.sin6.sin6_port = control->port_from; 5601 break; 5602 #endif 5603 #ifdef INET 5604 case AF_INET: 5605 #ifdef INET6 5606 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 5607 len = sizeof(struct sockaddr_in6); 5608 in6_sin_2_v4mapsin6(&control->whoFrom->ro._l_addr.sin, 5609 &store.sin6); 5610 store.sin6.sin6_port = control->port_from; 5611 } else { 5612 len = sizeof(struct sockaddr_in); 5613 store.sin = control->whoFrom->ro._l_addr.sin; 5614 store.sin.sin_port = control->port_from; 5615 } 5616 #else 5617 len = sizeof(struct sockaddr_in); 5618 store.sin = control->whoFrom->ro._l_addr.sin; 5619 store.sin.sin_port = control->port_from; 5620 #endif 5621 break; 5622 #endif 5623 default: 5624 len = 0; 5625 break; 5626 } 5627 memcpy(from, &store, min((size_t)fromlen, len)); 5628 #ifdef INET6 5629 { 5630 struct sockaddr_in6 lsa6, *from6; 5631 5632 from6 = (struct sockaddr_in6 *)from; 5633 sctp_recover_scope_mac(from6, (&lsa6)); 5634 } 5635 #endif 5636 } 5637 if (hold_rlock) { 5638 SCTP_INP_READ_UNLOCK(inp); 5639 hold_rlock = 0; 5640 } 5641 if (hold_sblock) { 5642 SOCKBUF_UNLOCK(&so->so_rcv); 5643 hold_sblock = 0; 5644 } 5645 /* now copy out what data we can */ 5646 if (mp == NULL) { 5647 /* copy out each mbuf in the chain up to length */ 5648 get_more_data: 5649 m = control->data; 5650 while (m) { 5651 /* Move out all we can */ 5652 cp_len = (int)uio->uio_resid; 5653 my_len = (int)SCTP_BUF_LEN(m); 5654 if (cp_len > my_len) { 5655 /* not enough in this buf */ 5656 cp_len = my_len; 5657 } 5658 if (hold_rlock) { 5659 SCTP_INP_READ_UNLOCK(inp); 5660 hold_rlock = 0; 5661 } 5662 if (cp_len > 0) 5663 error = uiomove(mtod(m, char *), cp_len, uio); 5664 /* re-read */ 5665 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 5666 goto release; 5667 } 5668 if ((control->do_not_ref_stcb == 0) && stcb && 5669 stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 5670 no_rcv_needed = 1; 5671 } 5672 if (error) { 5673 /* error we are out of here */ 5674 goto release; 5675 } 5676 SCTP_INP_READ_LOCK(inp); 5677 hold_rlock = 1; 5678 if (cp_len == SCTP_BUF_LEN(m)) { 5679 if ((SCTP_BUF_NEXT(m) == NULL) && 5680 (control->end_added)) { 5681 out_flags |= MSG_EOR; 5682 if ((control->do_not_ref_stcb == 0) && 5683 (control->stcb != NULL) && 5684 ((control->spec_flags & M_NOTIFICATION) == 0)) 5685 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 5686 } 5687 if (control->spec_flags & M_NOTIFICATION) { 5688 out_flags |= MSG_NOTIFICATION; 5689 } 5690 /* we ate up the mbuf */ 5691 if (in_flags & MSG_PEEK) { 5692 /* just looking */ 5693 m = SCTP_BUF_NEXT(m); 5694 copied_so_far += cp_len; 5695 } else { 5696 /* dispose of the mbuf */ 5697 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 5698 sctp_sblog(&so->so_rcv, 5699 control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m)); 5700 } 5701 sctp_sbfree(control, stcb, &so->so_rcv, m); 5702 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 5703 sctp_sblog(&so->so_rcv, 5704 control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0); 5705 } 5706 copied_so_far += cp_len; 5707 freed_so_far += cp_len; 5708 freed_so_far += MSIZE; 5709 atomic_subtract_int(&control->length, cp_len); 5710 control->data = sctp_m_free(m); 5711 m = control->data; 5712 /* 5713 * been through it all, must hold sb 5714 * lock ok to null tail 5715 */ 5716 if (control->data == NULL) { 5717 #ifdef INVARIANTS 5718 if ((control->end_added == 0) || 5719 (TAILQ_NEXT(control, next) == NULL)) { 5720 /* 5721 * If the end is not 5722 * added, OR the 5723 * next is NOT null 5724 * we MUST have the 5725 * lock. 5726 */ 5727 if (mtx_owned(&inp->inp_rdata_mtx) == 0) { 5728 panic("Hmm we don't own the lock?"); 5729 } 5730 } 5731 #endif 5732 control->tail_mbuf = NULL; 5733 #ifdef INVARIANTS 5734 if ((control->end_added) && ((out_flags & MSG_EOR) == 0)) { 5735 panic("end_added, nothing left and no MSG_EOR"); 5736 } 5737 #endif 5738 } 5739 } 5740 } else { 5741 /* Do we need to trim the mbuf? */ 5742 if (control->spec_flags & M_NOTIFICATION) { 5743 out_flags |= MSG_NOTIFICATION; 5744 } 5745 if ((in_flags & MSG_PEEK) == 0) { 5746 SCTP_BUF_RESV_UF(m, cp_len); 5747 SCTP_BUF_LEN(m) -= cp_len; 5748 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 5749 sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, cp_len); 5750 } 5751 atomic_subtract_int(&so->so_rcv.sb_cc, cp_len); 5752 if ((control->do_not_ref_stcb == 0) && 5753 stcb) { 5754 atomic_subtract_int(&stcb->asoc.sb_cc, cp_len); 5755 } 5756 copied_so_far += cp_len; 5757 freed_so_far += cp_len; 5758 freed_so_far += MSIZE; 5759 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 5760 sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, 5761 SCTP_LOG_SBRESULT, 0); 5762 } 5763 atomic_subtract_int(&control->length, cp_len); 5764 } else { 5765 copied_so_far += cp_len; 5766 } 5767 } 5768 if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) { 5769 break; 5770 } 5771 if (((stcb) && (in_flags & MSG_PEEK) == 0) && 5772 (control->do_not_ref_stcb == 0) && 5773 (freed_so_far >= rwnd_req)) { 5774 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 5775 } 5776 } /* end while(m) */ 5777 /* 5778 * At this point we have looked at it all and we either have 5779 * a MSG_EOR/or read all the user wants... <OR> 5780 * control->length == 0. 5781 */ 5782 if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) { 5783 /* we are done with this control */ 5784 if (control->length == 0) { 5785 if (control->data) { 5786 #ifdef INVARIANTS 5787 panic("control->data not null at read eor?"); 5788 #else 5789 SCTP_PRINTF("Strange, data left in the control buffer .. invarients would panic?\n"); 5790 sctp_m_freem(control->data); 5791 control->data = NULL; 5792 #endif 5793 } 5794 done_with_control: 5795 if (hold_rlock == 0) { 5796 SCTP_INP_READ_LOCK(inp); 5797 hold_rlock = 1; 5798 } 5799 TAILQ_REMOVE(&inp->read_queue, control, next); 5800 /* Add back any hiddend data */ 5801 if (control->held_length) { 5802 held_length = 0; 5803 control->held_length = 0; 5804 wakeup_read_socket = 1; 5805 } 5806 if (control->aux_data) { 5807 sctp_m_free(control->aux_data); 5808 control->aux_data = NULL; 5809 } 5810 no_rcv_needed = control->do_not_ref_stcb; 5811 sctp_free_remote_addr(control->whoFrom); 5812 control->data = NULL; 5813 #ifdef INVARIANTS 5814 if (control->on_strm_q) { 5815 panic("About to free ctl:%p so:%p and its in %d", 5816 control, so, control->on_strm_q); 5817 } 5818 #endif 5819 sctp_free_a_readq(stcb, control); 5820 control = NULL; 5821 if ((freed_so_far >= rwnd_req) && 5822 (no_rcv_needed == 0)) 5823 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 5824 5825 } else { 5826 /* 5827 * The user did not read all of this 5828 * message, turn off the returned MSG_EOR 5829 * since we are leaving more behind on the 5830 * control to read. 5831 */ 5832 #ifdef INVARIANTS 5833 if (control->end_added && 5834 (control->data == NULL) && 5835 (control->tail_mbuf == NULL)) { 5836 panic("Gak, control->length is corrupt?"); 5837 } 5838 #endif 5839 no_rcv_needed = control->do_not_ref_stcb; 5840 out_flags &= ~MSG_EOR; 5841 } 5842 } 5843 if (out_flags & MSG_EOR) { 5844 goto release; 5845 } 5846 if ((uio->uio_resid == 0) || 5847 ((in_eeor_mode) && 5848 (copied_so_far >= (uint32_t)max(so->so_rcv.sb_lowat, 1)))) { 5849 goto release; 5850 } 5851 /* 5852 * If I hit here the receiver wants more and this message is 5853 * NOT done (pd-api). So two questions. Can we block? if not 5854 * we are done. Did the user NOT set MSG_WAITALL? 5855 */ 5856 if (block_allowed == 0) { 5857 goto release; 5858 } 5859 /* 5860 * We need to wait for more data a few things: - We don't 5861 * sbunlock() so we don't get someone else reading. - We 5862 * must be sure to account for the case where what is added 5863 * is NOT to our control when we wakeup. 5864 */ 5865 5866 /* 5867 * Do we need to tell the transport a rwnd update might be 5868 * needed before we go to sleep? 5869 */ 5870 if (((stcb) && (in_flags & MSG_PEEK) == 0) && 5871 ((freed_so_far >= rwnd_req) && 5872 (control->do_not_ref_stcb == 0) && 5873 (no_rcv_needed == 0))) { 5874 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 5875 } 5876 wait_some_more: 5877 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { 5878 goto release; 5879 } 5880 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) 5881 goto release; 5882 5883 if (hold_rlock == 1) { 5884 SCTP_INP_READ_UNLOCK(inp); 5885 hold_rlock = 0; 5886 } 5887 if (hold_sblock == 0) { 5888 SOCKBUF_LOCK(&so->so_rcv); 5889 hold_sblock = 1; 5890 } 5891 if ((copied_so_far) && (control->length == 0) && 5892 (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) { 5893 goto release; 5894 } 5895 if (so->so_rcv.sb_cc <= control->held_length) { 5896 error = sbwait(&so->so_rcv); 5897 if (error) { 5898 goto release; 5899 } 5900 control->held_length = 0; 5901 } 5902 if (hold_sblock) { 5903 SOCKBUF_UNLOCK(&so->so_rcv); 5904 hold_sblock = 0; 5905 } 5906 if (control->length == 0) { 5907 /* still nothing here */ 5908 if (control->end_added == 1) { 5909 /* he aborted, or is done i.e.did a shutdown */ 5910 out_flags |= MSG_EOR; 5911 if (control->pdapi_aborted) { 5912 if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0)) 5913 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 5914 5915 out_flags |= MSG_TRUNC; 5916 } else { 5917 if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0)) 5918 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 5919 } 5920 goto done_with_control; 5921 } 5922 if (so->so_rcv.sb_cc > held_length) { 5923 control->held_length = so->so_rcv.sb_cc; 5924 held_length = 0; 5925 } 5926 goto wait_some_more; 5927 } else if (control->data == NULL) { 5928 /* 5929 * we must re-sync since data is probably being 5930 * added 5931 */ 5932 SCTP_INP_READ_LOCK(inp); 5933 if ((control->length > 0) && (control->data == NULL)) { 5934 /* 5935 * big trouble.. we have the lock and its 5936 * corrupt? 5937 */ 5938 #ifdef INVARIANTS 5939 panic("Impossible data==NULL length !=0"); 5940 #endif 5941 out_flags |= MSG_EOR; 5942 out_flags |= MSG_TRUNC; 5943 control->length = 0; 5944 SCTP_INP_READ_UNLOCK(inp); 5945 goto done_with_control; 5946 } 5947 SCTP_INP_READ_UNLOCK(inp); 5948 /* We will fall around to get more data */ 5949 } 5950 goto get_more_data; 5951 } else { 5952 /*- 5953 * Give caller back the mbuf chain, 5954 * store in uio_resid the length 5955 */ 5956 wakeup_read_socket = 0; 5957 if ((control->end_added == 0) || 5958 (TAILQ_NEXT(control, next) == NULL)) { 5959 /* Need to get rlock */ 5960 if (hold_rlock == 0) { 5961 SCTP_INP_READ_LOCK(inp); 5962 hold_rlock = 1; 5963 } 5964 } 5965 if (control->end_added) { 5966 out_flags |= MSG_EOR; 5967 if ((control->do_not_ref_stcb == 0) && 5968 (control->stcb != NULL) && 5969 ((control->spec_flags & M_NOTIFICATION) == 0)) 5970 control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 5971 } 5972 if (control->spec_flags & M_NOTIFICATION) { 5973 out_flags |= MSG_NOTIFICATION; 5974 } 5975 uio->uio_resid = control->length; 5976 *mp = control->data; 5977 m = control->data; 5978 while (m) { 5979 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 5980 sctp_sblog(&so->so_rcv, 5981 control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m)); 5982 } 5983 sctp_sbfree(control, stcb, &so->so_rcv, m); 5984 freed_so_far += SCTP_BUF_LEN(m); 5985 freed_so_far += MSIZE; 5986 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 5987 sctp_sblog(&so->so_rcv, 5988 control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0); 5989 } 5990 m = SCTP_BUF_NEXT(m); 5991 } 5992 control->data = control->tail_mbuf = NULL; 5993 control->length = 0; 5994 if (out_flags & MSG_EOR) { 5995 /* Done with this control */ 5996 goto done_with_control; 5997 } 5998 } 5999 release: 6000 if (hold_rlock == 1) { 6001 SCTP_INP_READ_UNLOCK(inp); 6002 hold_rlock = 0; 6003 } 6004 if (hold_sblock == 1) { 6005 SOCKBUF_UNLOCK(&so->so_rcv); 6006 hold_sblock = 0; 6007 } 6008 sbunlock(&so->so_rcv); 6009 sockbuf_lock = 0; 6010 6011 release_unlocked: 6012 if (hold_sblock) { 6013 SOCKBUF_UNLOCK(&so->so_rcv); 6014 hold_sblock = 0; 6015 } 6016 if ((stcb) && (in_flags & MSG_PEEK) == 0) { 6017 if ((freed_so_far >= rwnd_req) && 6018 (control && (control->do_not_ref_stcb == 0)) && 6019 (no_rcv_needed == 0)) 6020 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 6021 } 6022 out: 6023 if (msg_flags) { 6024 *msg_flags = out_flags; 6025 } 6026 if (((out_flags & MSG_EOR) == 0) && 6027 ((in_flags & MSG_PEEK) == 0) && 6028 (sinfo) && 6029 (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) || 6030 sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO))) { 6031 struct sctp_extrcvinfo *s_extra; 6032 6033 s_extra = (struct sctp_extrcvinfo *)sinfo; 6034 s_extra->serinfo_next_flags = SCTP_NO_NEXT_MSG; 6035 } 6036 if (hold_rlock == 1) { 6037 SCTP_INP_READ_UNLOCK(inp); 6038 } 6039 if (hold_sblock) { 6040 SOCKBUF_UNLOCK(&so->so_rcv); 6041 } 6042 if (sockbuf_lock) { 6043 sbunlock(&so->so_rcv); 6044 } 6045 if (freecnt_applied) { 6046 /* 6047 * The lock on the socket buffer protects us so the free 6048 * code will stop. But since we used the socketbuf lock and 6049 * the sender uses the tcb_lock to increment, we need to use 6050 * the atomic add to the refcnt. 6051 */ 6052 if (stcb == NULL) { 6053 #ifdef INVARIANTS 6054 panic("stcb for refcnt has gone NULL?"); 6055 goto stage_left; 6056 #else 6057 goto stage_left; 6058 #endif 6059 } 6060 /* Save the value back for next time */ 6061 stcb->freed_by_sorcv_sincelast = freed_so_far; 6062 atomic_add_int(&stcb->asoc.refcnt, -1); 6063 } 6064 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) { 6065 if (stcb) { 6066 sctp_misc_ints(SCTP_SORECV_DONE, 6067 freed_so_far, 6068 (uint32_t)((uio) ? (slen - uio->uio_resid) : slen), 6069 stcb->asoc.my_rwnd, 6070 so->so_rcv.sb_cc); 6071 } else { 6072 sctp_misc_ints(SCTP_SORECV_DONE, 6073 freed_so_far, 6074 (uint32_t)((uio) ? (slen - uio->uio_resid) : slen), 6075 0, 6076 so->so_rcv.sb_cc); 6077 } 6078 } 6079 stage_left: 6080 if (wakeup_read_socket) { 6081 sctp_sorwakeup(inp, so); 6082 } 6083 return (error); 6084 } 6085 6086 6087 #ifdef SCTP_MBUF_LOGGING 6088 struct mbuf * 6089 sctp_m_free(struct mbuf *m) 6090 { 6091 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { 6092 sctp_log_mb(m, SCTP_MBUF_IFREE); 6093 } 6094 return (m_free(m)); 6095 } 6096 6097 void 6098 sctp_m_freem(struct mbuf *mb) 6099 { 6100 while (mb != NULL) 6101 mb = sctp_m_free(mb); 6102 } 6103 6104 #endif 6105 6106 int 6107 sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id) 6108 { 6109 /* 6110 * Given a local address. For all associations that holds the 6111 * address, request a peer-set-primary. 6112 */ 6113 struct sctp_ifa *ifa; 6114 struct sctp_laddr *wi; 6115 6116 ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0); 6117 if (ifa == NULL) { 6118 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EADDRNOTAVAIL); 6119 return (EADDRNOTAVAIL); 6120 } 6121 /* 6122 * Now that we have the ifa we must awaken the iterator with this 6123 * message. 6124 */ 6125 wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr); 6126 if (wi == NULL) { 6127 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 6128 return (ENOMEM); 6129 } 6130 /* Now incr the count and int wi structure */ 6131 SCTP_INCR_LADDR_COUNT(); 6132 memset(wi, 0, sizeof(*wi)); 6133 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); 6134 wi->ifa = ifa; 6135 wi->action = SCTP_SET_PRIM_ADDR; 6136 atomic_add_int(&ifa->refcount, 1); 6137 6138 /* Now add it to the work queue */ 6139 SCTP_WQ_ADDR_LOCK(); 6140 /* 6141 * Should this really be a tailq? As it is we will process the 6142 * newest first :-0 6143 */ 6144 LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); 6145 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, 6146 (struct sctp_inpcb *)NULL, 6147 (struct sctp_tcb *)NULL, 6148 (struct sctp_nets *)NULL); 6149 SCTP_WQ_ADDR_UNLOCK(); 6150 return (0); 6151 } 6152 6153 6154 int 6155 sctp_soreceive(struct socket *so, 6156 struct sockaddr **psa, 6157 struct uio *uio, 6158 struct mbuf **mp0, 6159 struct mbuf **controlp, 6160 int *flagsp) 6161 { 6162 int error, fromlen; 6163 uint8_t sockbuf[256]; 6164 struct sockaddr *from; 6165 struct sctp_extrcvinfo sinfo; 6166 int filling_sinfo = 1; 6167 struct sctp_inpcb *inp; 6168 6169 inp = (struct sctp_inpcb *)so->so_pcb; 6170 /* pickup the assoc we are reading from */ 6171 if (inp == NULL) { 6172 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6173 return (EINVAL); 6174 } 6175 if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT) && 6176 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO) && 6177 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) || 6178 (controlp == NULL)) { 6179 /* user does not want the sndrcv ctl */ 6180 filling_sinfo = 0; 6181 } 6182 if (psa) { 6183 from = (struct sockaddr *)sockbuf; 6184 fromlen = sizeof(sockbuf); 6185 from->sa_len = 0; 6186 } else { 6187 from = NULL; 6188 fromlen = 0; 6189 } 6190 6191 if (filling_sinfo) { 6192 memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo)); 6193 } 6194 error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp, 6195 (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo); 6196 if (controlp != NULL) { 6197 /* copy back the sinfo in a CMSG format */ 6198 if (filling_sinfo) 6199 *controlp = sctp_build_ctl_nchunk(inp, 6200 (struct sctp_sndrcvinfo *)&sinfo); 6201 else 6202 *controlp = NULL; 6203 } 6204 if (psa) { 6205 /* copy back the address info */ 6206 if (from && from->sa_len) { 6207 *psa = sodupsockaddr(from, M_NOWAIT); 6208 } else { 6209 *psa = NULL; 6210 } 6211 } 6212 return (error); 6213 } 6214 6215 6216 6217 6218 6219 int 6220 sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, 6221 int totaddr, int *error) 6222 { 6223 int added = 0; 6224 int i; 6225 struct sctp_inpcb *inp; 6226 struct sockaddr *sa; 6227 size_t incr = 0; 6228 #ifdef INET 6229 struct sockaddr_in *sin; 6230 #endif 6231 #ifdef INET6 6232 struct sockaddr_in6 *sin6; 6233 #endif 6234 6235 sa = addr; 6236 inp = stcb->sctp_ep; 6237 *error = 0; 6238 for (i = 0; i < totaddr; i++) { 6239 switch (sa->sa_family) { 6240 #ifdef INET 6241 case AF_INET: 6242 incr = sizeof(struct sockaddr_in); 6243 sin = (struct sockaddr_in *)sa; 6244 if ((sin->sin_addr.s_addr == INADDR_ANY) || 6245 (sin->sin_addr.s_addr == INADDR_BROADCAST) || 6246 IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 6247 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6248 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 6249 SCTP_FROM_SCTPUTIL + SCTP_LOC_7); 6250 *error = EINVAL; 6251 goto out_now; 6252 } 6253 if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port, 6254 SCTP_DONOT_SETSCOPE, 6255 SCTP_ADDR_IS_CONFIRMED)) { 6256 /* assoc gone no un-lock */ 6257 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS); 6258 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 6259 SCTP_FROM_SCTPUTIL + SCTP_LOC_8); 6260 *error = ENOBUFS; 6261 goto out_now; 6262 } 6263 added++; 6264 break; 6265 #endif 6266 #ifdef INET6 6267 case AF_INET6: 6268 incr = sizeof(struct sockaddr_in6); 6269 sin6 = (struct sockaddr_in6 *)sa; 6270 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 6271 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 6272 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6273 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 6274 SCTP_FROM_SCTPUTIL + SCTP_LOC_9); 6275 *error = EINVAL; 6276 goto out_now; 6277 } 6278 if (sctp_add_remote_addr(stcb, sa, NULL, stcb->asoc.port, 6279 SCTP_DONOT_SETSCOPE, 6280 SCTP_ADDR_IS_CONFIRMED)) { 6281 /* assoc gone no un-lock */ 6282 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS); 6283 (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, 6284 SCTP_FROM_SCTPUTIL + SCTP_LOC_10); 6285 *error = ENOBUFS; 6286 goto out_now; 6287 } 6288 added++; 6289 break; 6290 #endif 6291 default: 6292 break; 6293 } 6294 sa = (struct sockaddr *)((caddr_t)sa + incr); 6295 } 6296 out_now: 6297 return (added); 6298 } 6299 6300 struct sctp_tcb * 6301 sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, 6302 unsigned int *totaddr, 6303 unsigned int *num_v4, unsigned int *num_v6, int *error, 6304 unsigned int limit, int *bad_addr) 6305 { 6306 struct sockaddr *sa; 6307 struct sctp_tcb *stcb = NULL; 6308 unsigned int incr, at, i; 6309 6310 at = 0; 6311 sa = addr; 6312 *error = *num_v6 = *num_v4 = 0; 6313 /* account and validate addresses */ 6314 for (i = 0; i < *totaddr; i++) { 6315 switch (sa->sa_family) { 6316 #ifdef INET 6317 case AF_INET: 6318 incr = (unsigned int)sizeof(struct sockaddr_in); 6319 if (sa->sa_len != incr) { 6320 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6321 *error = EINVAL; 6322 *bad_addr = 1; 6323 return (NULL); 6324 } 6325 (*num_v4) += 1; 6326 break; 6327 #endif 6328 #ifdef INET6 6329 case AF_INET6: 6330 { 6331 struct sockaddr_in6 *sin6; 6332 6333 sin6 = (struct sockaddr_in6 *)sa; 6334 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 6335 /* Must be non-mapped for connectx */ 6336 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6337 *error = EINVAL; 6338 *bad_addr = 1; 6339 return (NULL); 6340 } 6341 incr = (unsigned int)sizeof(struct sockaddr_in6); 6342 if (sa->sa_len != incr) { 6343 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6344 *error = EINVAL; 6345 *bad_addr = 1; 6346 return (NULL); 6347 } 6348 (*num_v6) += 1; 6349 break; 6350 } 6351 #endif 6352 default: 6353 *totaddr = i; 6354 incr = 0; 6355 /* we are done */ 6356 break; 6357 } 6358 if (i == *totaddr) { 6359 break; 6360 } 6361 SCTP_INP_INCR_REF(inp); 6362 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL); 6363 if (stcb != NULL) { 6364 /* Already have or am bring up an association */ 6365 return (stcb); 6366 } else { 6367 SCTP_INP_DECR_REF(inp); 6368 } 6369 if ((at + incr) > limit) { 6370 *totaddr = i; 6371 break; 6372 } 6373 sa = (struct sockaddr *)((caddr_t)sa + incr); 6374 } 6375 return ((struct sctp_tcb *)NULL); 6376 } 6377 6378 /* 6379 * sctp_bindx(ADD) for one address. 6380 * assumes all arguments are valid/checked by caller. 6381 */ 6382 void 6383 sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, 6384 struct sockaddr *sa, sctp_assoc_t assoc_id, 6385 uint32_t vrf_id, int *error, void *p) 6386 { 6387 struct sockaddr *addr_touse; 6388 #if defined(INET) && defined(INET6) 6389 struct sockaddr_in sin; 6390 #endif 6391 6392 /* see if we're bound all already! */ 6393 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 6394 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6395 *error = EINVAL; 6396 return; 6397 } 6398 addr_touse = sa; 6399 #ifdef INET6 6400 if (sa->sa_family == AF_INET6) { 6401 #ifdef INET 6402 struct sockaddr_in6 *sin6; 6403 6404 #endif 6405 if (sa->sa_len != sizeof(struct sockaddr_in6)) { 6406 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6407 *error = EINVAL; 6408 return; 6409 } 6410 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 6411 /* can only bind v6 on PF_INET6 sockets */ 6412 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6413 *error = EINVAL; 6414 return; 6415 } 6416 #ifdef INET 6417 sin6 = (struct sockaddr_in6 *)addr_touse; 6418 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 6419 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 6420 SCTP_IPV6_V6ONLY(inp)) { 6421 /* can't bind v4-mapped on PF_INET sockets */ 6422 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6423 *error = EINVAL; 6424 return; 6425 } 6426 in6_sin6_2_sin(&sin, sin6); 6427 addr_touse = (struct sockaddr *)&sin; 6428 } 6429 #endif 6430 } 6431 #endif 6432 #ifdef INET 6433 if (sa->sa_family == AF_INET) { 6434 if (sa->sa_len != sizeof(struct sockaddr_in)) { 6435 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6436 *error = EINVAL; 6437 return; 6438 } 6439 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 6440 SCTP_IPV6_V6ONLY(inp)) { 6441 /* can't bind v4 on PF_INET sockets */ 6442 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6443 *error = EINVAL; 6444 return; 6445 } 6446 } 6447 #endif 6448 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 6449 if (p == NULL) { 6450 /* Can't get proc for Net/Open BSD */ 6451 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6452 *error = EINVAL; 6453 return; 6454 } 6455 *error = sctp_inpcb_bind(so, addr_touse, NULL, p); 6456 return; 6457 } 6458 /* 6459 * No locks required here since bind and mgmt_ep_sa all do their own 6460 * locking. If we do something for the FIX: below we may need to 6461 * lock in that case. 6462 */ 6463 if (assoc_id == 0) { 6464 /* add the address */ 6465 struct sctp_inpcb *lep; 6466 struct sockaddr_in *lsin = (struct sockaddr_in *)addr_touse; 6467 6468 /* validate the incoming port */ 6469 if ((lsin->sin_port != 0) && 6470 (lsin->sin_port != inp->sctp_lport)) { 6471 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6472 *error = EINVAL; 6473 return; 6474 } else { 6475 /* user specified 0 port, set it to existing port */ 6476 lsin->sin_port = inp->sctp_lport; 6477 } 6478 6479 lep = sctp_pcb_findep(addr_touse, 1, 0, vrf_id); 6480 if (lep != NULL) { 6481 /* 6482 * We must decrement the refcount since we have the 6483 * ep already and are binding. No remove going on 6484 * here. 6485 */ 6486 SCTP_INP_DECR_REF(lep); 6487 } 6488 if (lep == inp) { 6489 /* already bound to it.. ok */ 6490 return; 6491 } else if (lep == NULL) { 6492 ((struct sockaddr_in *)addr_touse)->sin_port = 0; 6493 *error = sctp_addr_mgmt_ep_sa(inp, addr_touse, 6494 SCTP_ADD_IP_ADDRESS, 6495 vrf_id, NULL); 6496 } else { 6497 *error = EADDRINUSE; 6498 } 6499 if (*error) 6500 return; 6501 } else { 6502 /* 6503 * FIX: decide whether we allow assoc based bindx 6504 */ 6505 } 6506 } 6507 6508 /* 6509 * sctp_bindx(DELETE) for one address. 6510 * assumes all arguments are valid/checked by caller. 6511 */ 6512 void 6513 sctp_bindx_delete_address(struct sctp_inpcb *inp, 6514 struct sockaddr *sa, sctp_assoc_t assoc_id, 6515 uint32_t vrf_id, int *error) 6516 { 6517 struct sockaddr *addr_touse; 6518 #if defined(INET) && defined(INET6) 6519 struct sockaddr_in sin; 6520 #endif 6521 6522 /* see if we're bound all already! */ 6523 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 6524 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6525 *error = EINVAL; 6526 return; 6527 } 6528 addr_touse = sa; 6529 #ifdef INET6 6530 if (sa->sa_family == AF_INET6) { 6531 #ifdef INET 6532 struct sockaddr_in6 *sin6; 6533 #endif 6534 6535 if (sa->sa_len != sizeof(struct sockaddr_in6)) { 6536 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6537 *error = EINVAL; 6538 return; 6539 } 6540 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 6541 /* can only bind v6 on PF_INET6 sockets */ 6542 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6543 *error = EINVAL; 6544 return; 6545 } 6546 #ifdef INET 6547 sin6 = (struct sockaddr_in6 *)addr_touse; 6548 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 6549 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 6550 SCTP_IPV6_V6ONLY(inp)) { 6551 /* can't bind mapped-v4 on PF_INET sockets */ 6552 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6553 *error = EINVAL; 6554 return; 6555 } 6556 in6_sin6_2_sin(&sin, sin6); 6557 addr_touse = (struct sockaddr *)&sin; 6558 } 6559 #endif 6560 } 6561 #endif 6562 #ifdef INET 6563 if (sa->sa_family == AF_INET) { 6564 if (sa->sa_len != sizeof(struct sockaddr_in)) { 6565 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6566 *error = EINVAL; 6567 return; 6568 } 6569 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 6570 SCTP_IPV6_V6ONLY(inp)) { 6571 /* can't bind v4 on PF_INET sockets */ 6572 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 6573 *error = EINVAL; 6574 return; 6575 } 6576 } 6577 #endif 6578 /* 6579 * No lock required mgmt_ep_sa does its own locking. If the FIX: 6580 * below is ever changed we may need to lock before calling 6581 * association level binding. 6582 */ 6583 if (assoc_id == 0) { 6584 /* delete the address */ 6585 *error = sctp_addr_mgmt_ep_sa(inp, addr_touse, 6586 SCTP_DEL_IP_ADDRESS, 6587 vrf_id, NULL); 6588 } else { 6589 /* 6590 * FIX: decide whether we allow assoc based bindx 6591 */ 6592 } 6593 } 6594 6595 /* 6596 * returns the valid local address count for an assoc, taking into account 6597 * all scoping rules 6598 */ 6599 int 6600 sctp_local_addr_count(struct sctp_tcb *stcb) 6601 { 6602 int loopback_scope; 6603 #if defined(INET) 6604 int ipv4_local_scope, ipv4_addr_legal; 6605 #endif 6606 #if defined (INET6) 6607 int local_scope, site_scope, ipv6_addr_legal; 6608 #endif 6609 struct sctp_vrf *vrf; 6610 struct sctp_ifn *sctp_ifn; 6611 struct sctp_ifa *sctp_ifa; 6612 int count = 0; 6613 6614 /* Turn on all the appropriate scopes */ 6615 loopback_scope = stcb->asoc.scope.loopback_scope; 6616 #if defined(INET) 6617 ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; 6618 ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; 6619 #endif 6620 #if defined(INET6) 6621 local_scope = stcb->asoc.scope.local_scope; 6622 site_scope = stcb->asoc.scope.site_scope; 6623 ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; 6624 #endif 6625 SCTP_IPI_ADDR_RLOCK(); 6626 vrf = sctp_find_vrf(stcb->asoc.vrf_id); 6627 if (vrf == NULL) { 6628 /* no vrf, no addresses */ 6629 SCTP_IPI_ADDR_RUNLOCK(); 6630 return (0); 6631 } 6632 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 6633 /* 6634 * bound all case: go through all ifns on the vrf 6635 */ 6636 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 6637 if ((loopback_scope == 0) && 6638 SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { 6639 continue; 6640 } 6641 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 6642 if (sctp_is_addr_restricted(stcb, sctp_ifa)) 6643 continue; 6644 switch (sctp_ifa->address.sa.sa_family) { 6645 #ifdef INET 6646 case AF_INET: 6647 if (ipv4_addr_legal) { 6648 struct sockaddr_in *sin; 6649 6650 sin = &sctp_ifa->address.sin; 6651 if (sin->sin_addr.s_addr == 0) { 6652 /* 6653 * skip unspecified 6654 * addrs 6655 */ 6656 continue; 6657 } 6658 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, 6659 &sin->sin_addr) != 0) { 6660 continue; 6661 } 6662 if ((ipv4_local_scope == 0) && 6663 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 6664 continue; 6665 } 6666 /* count this one */ 6667 count++; 6668 } else { 6669 continue; 6670 } 6671 break; 6672 #endif 6673 #ifdef INET6 6674 case AF_INET6: 6675 if (ipv6_addr_legal) { 6676 struct sockaddr_in6 *sin6; 6677 6678 sin6 = &sctp_ifa->address.sin6; 6679 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 6680 continue; 6681 } 6682 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, 6683 &sin6->sin6_addr) != 0) { 6684 continue; 6685 } 6686 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 6687 if (local_scope == 0) 6688 continue; 6689 if (sin6->sin6_scope_id == 0) { 6690 if (sa6_recoverscope(sin6) != 0) 6691 /* 6692 * 6693 * bad 6694 * link 6695 * 6696 * local 6697 * 6698 * address 6699 */ 6700 continue; 6701 } 6702 } 6703 if ((site_scope == 0) && 6704 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 6705 continue; 6706 } 6707 /* count this one */ 6708 count++; 6709 } 6710 break; 6711 #endif 6712 default: 6713 /* TSNH */ 6714 break; 6715 } 6716 } 6717 } 6718 } else { 6719 /* 6720 * subset bound case 6721 */ 6722 struct sctp_laddr *laddr; 6723 6724 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, 6725 sctp_nxt_addr) { 6726 if (sctp_is_addr_restricted(stcb, laddr->ifa)) { 6727 continue; 6728 } 6729 /* count this one */ 6730 count++; 6731 } 6732 } 6733 SCTP_IPI_ADDR_RUNLOCK(); 6734 return (count); 6735 } 6736 6737 #if defined(SCTP_LOCAL_TRACE_BUF) 6738 6739 void 6740 sctp_log_trace(uint32_t subsys, const char *str SCTP_UNUSED, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f) 6741 { 6742 uint32_t saveindex, newindex; 6743 6744 do { 6745 saveindex = SCTP_BASE_SYSCTL(sctp_log).index; 6746 if (saveindex >= SCTP_MAX_LOGGING_SIZE) { 6747 newindex = 1; 6748 } else { 6749 newindex = saveindex + 1; 6750 } 6751 } while (atomic_cmpset_int(&SCTP_BASE_SYSCTL(sctp_log).index, saveindex, newindex) == 0); 6752 if (saveindex >= SCTP_MAX_LOGGING_SIZE) { 6753 saveindex = 0; 6754 } 6755 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT; 6756 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].subsys = subsys; 6757 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[0] = a; 6758 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[1] = b; 6759 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[2] = c; 6760 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[3] = d; 6761 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[4] = e; 6762 SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[5] = f; 6763 } 6764 6765 #endif 6766 static void 6767 sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *inp, 6768 const struct sockaddr *sa SCTP_UNUSED, void *ctx SCTP_UNUSED) 6769 { 6770 struct ip *iph; 6771 #ifdef INET6 6772 struct ip6_hdr *ip6; 6773 #endif 6774 struct mbuf *sp, *last; 6775 struct udphdr *uhdr; 6776 uint16_t port; 6777 6778 if ((m->m_flags & M_PKTHDR) == 0) { 6779 /* Can't handle one that is not a pkt hdr */ 6780 goto out; 6781 } 6782 /* Pull the src port */ 6783 iph = mtod(m, struct ip *); 6784 uhdr = (struct udphdr *)((caddr_t)iph + off); 6785 port = uhdr->uh_sport; 6786 /* 6787 * Split out the mbuf chain. Leave the IP header in m, place the 6788 * rest in the sp. 6789 */ 6790 sp = m_split(m, off, M_NOWAIT); 6791 if (sp == NULL) { 6792 /* Gak, drop packet, we can't do a split */ 6793 goto out; 6794 } 6795 if (sp->m_pkthdr.len < sizeof(struct udphdr) + sizeof(struct sctphdr)) { 6796 /* Gak, packet can't have an SCTP header in it - too small */ 6797 m_freem(sp); 6798 goto out; 6799 } 6800 /* Now pull up the UDP header and SCTP header together */ 6801 sp = m_pullup(sp, sizeof(struct udphdr) + sizeof(struct sctphdr)); 6802 if (sp == NULL) { 6803 /* Gak pullup failed */ 6804 goto out; 6805 } 6806 /* Trim out the UDP header */ 6807 m_adj(sp, sizeof(struct udphdr)); 6808 6809 /* Now reconstruct the mbuf chain */ 6810 for (last = m; last->m_next; last = last->m_next); 6811 last->m_next = sp; 6812 m->m_pkthdr.len += sp->m_pkthdr.len; 6813 /* 6814 * The CSUM_DATA_VALID flags indicates that the HW checked the UDP 6815 * checksum and it was valid. Since CSUM_DATA_VALID == 6816 * CSUM_SCTP_VALID this would imply that the HW also verified the 6817 * SCTP checksum. Therefore, clear the bit. 6818 */ 6819 SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 6820 "sctp_recv_udp_tunneled_packet(): Packet of length %d received on %s with csum_flags 0x%b.\n", 6821 m->m_pkthdr.len, 6822 if_name(m->m_pkthdr.rcvif), 6823 (int)m->m_pkthdr.csum_flags, CSUM_BITS); 6824 m->m_pkthdr.csum_flags &= ~CSUM_DATA_VALID; 6825 iph = mtod(m, struct ip *); 6826 switch (iph->ip_v) { 6827 #ifdef INET 6828 case IPVERSION: 6829 iph->ip_len = htons(ntohs(iph->ip_len) - sizeof(struct udphdr)); 6830 sctp_input_with_port(m, off, port); 6831 break; 6832 #endif 6833 #ifdef INET6 6834 case IPV6_VERSION >> 4: 6835 ip6 = mtod(m, struct ip6_hdr *); 6836 ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(struct udphdr)); 6837 sctp6_input_with_port(&m, &off, port); 6838 break; 6839 #endif 6840 default: 6841 goto out; 6842 break; 6843 } 6844 return; 6845 out: 6846 m_freem(m); 6847 } 6848 6849 #ifdef INET 6850 static void 6851 sctp_recv_icmp_tunneled_packet(int cmd, struct sockaddr *sa, void *vip, void *ctx SCTP_UNUSED) 6852 { 6853 struct ip *outer_ip, *inner_ip; 6854 struct sctphdr *sh; 6855 struct icmp *icmp; 6856 struct udphdr *udp; 6857 struct sctp_inpcb *inp; 6858 struct sctp_tcb *stcb; 6859 struct sctp_nets *net; 6860 struct sctp_init_chunk *ch; 6861 struct sockaddr_in src, dst; 6862 uint8_t type, code; 6863 6864 inner_ip = (struct ip *)vip; 6865 icmp = (struct icmp *)((caddr_t)inner_ip - 6866 (sizeof(struct icmp) - sizeof(struct ip))); 6867 outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip)); 6868 if (ntohs(outer_ip->ip_len) < 6869 sizeof(struct ip) + 8 + (inner_ip->ip_hl << 2) + sizeof(struct udphdr) + 8) { 6870 return; 6871 } 6872 udp = (struct udphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2)); 6873 sh = (struct sctphdr *)(udp + 1); 6874 memset(&src, 0, sizeof(struct sockaddr_in)); 6875 src.sin_family = AF_INET; 6876 src.sin_len = sizeof(struct sockaddr_in); 6877 src.sin_port = sh->src_port; 6878 src.sin_addr = inner_ip->ip_src; 6879 memset(&dst, 0, sizeof(struct sockaddr_in)); 6880 dst.sin_family = AF_INET; 6881 dst.sin_len = sizeof(struct sockaddr_in); 6882 dst.sin_port = sh->dest_port; 6883 dst.sin_addr = inner_ip->ip_dst; 6884 /* 6885 * 'dst' holds the dest of the packet that failed to be sent. 'src' 6886 * holds our local endpoint address. Thus we reverse the dst and the 6887 * src in the lookup. 6888 */ 6889 inp = NULL; 6890 net = NULL; 6891 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst, 6892 (struct sockaddr *)&src, 6893 &inp, &net, 1, 6894 SCTP_DEFAULT_VRFID); 6895 if ((stcb != NULL) && 6896 (net != NULL) && 6897 (inp != NULL)) { 6898 /* Check the UDP port numbers */ 6899 if ((udp->uh_dport != net->port) || 6900 (udp->uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) { 6901 SCTP_TCB_UNLOCK(stcb); 6902 return; 6903 } 6904 /* Check the verification tag */ 6905 if (ntohl(sh->v_tag) != 0) { 6906 /* 6907 * This must be the verification tag used for 6908 * sending out packets. We don't consider packets 6909 * reflecting the verification tag. 6910 */ 6911 if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) { 6912 SCTP_TCB_UNLOCK(stcb); 6913 return; 6914 } 6915 } else { 6916 if (ntohs(outer_ip->ip_len) >= 6917 sizeof(struct ip) + 6918 8 + (inner_ip->ip_hl << 2) + 8 + 20) { 6919 /* 6920 * In this case we can check if we got an 6921 * INIT chunk and if the initiate tag 6922 * matches. 6923 */ 6924 ch = (struct sctp_init_chunk *)(sh + 1); 6925 if ((ch->ch.chunk_type != SCTP_INITIATION) || 6926 (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) { 6927 SCTP_TCB_UNLOCK(stcb); 6928 return; 6929 } 6930 } else { 6931 SCTP_TCB_UNLOCK(stcb); 6932 return; 6933 } 6934 } 6935 type = icmp->icmp_type; 6936 code = icmp->icmp_code; 6937 if ((type == ICMP_UNREACH) && 6938 (code == ICMP_UNREACH_PORT)) { 6939 code = ICMP_UNREACH_PROTOCOL; 6940 } 6941 sctp_notify(inp, stcb, net, type, code, 6942 ntohs(inner_ip->ip_len), 6943 (uint32_t)ntohs(icmp->icmp_nextmtu)); 6944 } else { 6945 if ((stcb == NULL) && (inp != NULL)) { 6946 /* reduce ref-count */ 6947 SCTP_INP_WLOCK(inp); 6948 SCTP_INP_DECR_REF(inp); 6949 SCTP_INP_WUNLOCK(inp); 6950 } 6951 if (stcb) { 6952 SCTP_TCB_UNLOCK(stcb); 6953 } 6954 } 6955 return; 6956 } 6957 #endif 6958 6959 #ifdef INET6 6960 static void 6961 sctp_recv_icmp6_tunneled_packet(int cmd, struct sockaddr *sa, void *d, void *ctx SCTP_UNUSED) 6962 { 6963 struct ip6ctlparam *ip6cp; 6964 struct sctp_inpcb *inp; 6965 struct sctp_tcb *stcb; 6966 struct sctp_nets *net; 6967 struct sctphdr sh; 6968 struct udphdr udp; 6969 struct sockaddr_in6 src, dst; 6970 uint8_t type, code; 6971 6972 ip6cp = (struct ip6ctlparam *)d; 6973 /* 6974 * XXX: We assume that when IPV6 is non NULL, M and OFF are valid. 6975 */ 6976 if (ip6cp->ip6c_m == NULL) { 6977 return; 6978 } 6979 /* 6980 * Check if we can safely examine the ports and the verification tag 6981 * of the SCTP common header. 6982 */ 6983 if (ip6cp->ip6c_m->m_pkthdr.len < 6984 ip6cp->ip6c_off + sizeof(struct udphdr) + offsetof(struct sctphdr, checksum)) { 6985 return; 6986 } 6987 /* Copy out the UDP header. */ 6988 memset(&udp, 0, sizeof(struct udphdr)); 6989 m_copydata(ip6cp->ip6c_m, 6990 ip6cp->ip6c_off, 6991 sizeof(struct udphdr), 6992 (caddr_t)&udp); 6993 /* Copy out the port numbers and the verification tag. */ 6994 memset(&sh, 0, sizeof(struct sctphdr)); 6995 m_copydata(ip6cp->ip6c_m, 6996 ip6cp->ip6c_off + sizeof(struct udphdr), 6997 sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t), 6998 (caddr_t)&sh); 6999 memset(&src, 0, sizeof(struct sockaddr_in6)); 7000 src.sin6_family = AF_INET6; 7001 src.sin6_len = sizeof(struct sockaddr_in6); 7002 src.sin6_port = sh.src_port; 7003 src.sin6_addr = ip6cp->ip6c_ip6->ip6_src; 7004 if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) { 7005 return; 7006 } 7007 memset(&dst, 0, sizeof(struct sockaddr_in6)); 7008 dst.sin6_family = AF_INET6; 7009 dst.sin6_len = sizeof(struct sockaddr_in6); 7010 dst.sin6_port = sh.dest_port; 7011 dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst; 7012 if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) { 7013 return; 7014 } 7015 inp = NULL; 7016 net = NULL; 7017 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst, 7018 (struct sockaddr *)&src, 7019 &inp, &net, 1, SCTP_DEFAULT_VRFID); 7020 if ((stcb != NULL) && 7021 (net != NULL) && 7022 (inp != NULL)) { 7023 /* Check the UDP port numbers */ 7024 if ((udp.uh_dport != net->port) || 7025 (udp.uh_sport != htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)))) { 7026 SCTP_TCB_UNLOCK(stcb); 7027 return; 7028 } 7029 /* Check the verification tag */ 7030 if (ntohl(sh.v_tag) != 0) { 7031 /* 7032 * This must be the verification tag used for 7033 * sending out packets. We don't consider packets 7034 * reflecting the verification tag. 7035 */ 7036 if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) { 7037 SCTP_TCB_UNLOCK(stcb); 7038 return; 7039 } 7040 } else { 7041 if (ip6cp->ip6c_m->m_pkthdr.len >= 7042 ip6cp->ip6c_off + sizeof(struct udphdr) + 7043 sizeof(struct sctphdr) + 7044 sizeof(struct sctp_chunkhdr) + 7045 offsetof(struct sctp_init, a_rwnd)) { 7046 /* 7047 * In this case we can check if we got an 7048 * INIT chunk and if the initiate tag 7049 * matches. 7050 */ 7051 uint32_t initiate_tag; 7052 uint8_t chunk_type; 7053 7054 m_copydata(ip6cp->ip6c_m, 7055 ip6cp->ip6c_off + 7056 sizeof(struct udphdr) + 7057 sizeof(struct sctphdr), 7058 sizeof(uint8_t), 7059 (caddr_t)&chunk_type); 7060 m_copydata(ip6cp->ip6c_m, 7061 ip6cp->ip6c_off + 7062 sizeof(struct udphdr) + 7063 sizeof(struct sctphdr) + 7064 sizeof(struct sctp_chunkhdr), 7065 sizeof(uint32_t), 7066 (caddr_t)&initiate_tag); 7067 if ((chunk_type != SCTP_INITIATION) || 7068 (ntohl(initiate_tag) != stcb->asoc.my_vtag)) { 7069 SCTP_TCB_UNLOCK(stcb); 7070 return; 7071 } 7072 } else { 7073 SCTP_TCB_UNLOCK(stcb); 7074 return; 7075 } 7076 } 7077 type = ip6cp->ip6c_icmp6->icmp6_type; 7078 code = ip6cp->ip6c_icmp6->icmp6_code; 7079 if ((type == ICMP6_DST_UNREACH) && 7080 (code == ICMP6_DST_UNREACH_NOPORT)) { 7081 type = ICMP6_PARAM_PROB; 7082 code = ICMP6_PARAMPROB_NEXTHEADER; 7083 } 7084 sctp6_notify(inp, stcb, net, type, code, 7085 ntohl(ip6cp->ip6c_icmp6->icmp6_mtu)); 7086 } else { 7087 if ((stcb == NULL) && (inp != NULL)) { 7088 /* reduce inp's ref-count */ 7089 SCTP_INP_WLOCK(inp); 7090 SCTP_INP_DECR_REF(inp); 7091 SCTP_INP_WUNLOCK(inp); 7092 } 7093 if (stcb) { 7094 SCTP_TCB_UNLOCK(stcb); 7095 } 7096 } 7097 } 7098 #endif 7099 7100 void 7101 sctp_over_udp_stop(void) 7102 { 7103 /* 7104 * This function assumes sysctl caller holds sctp_sysctl_info_lock() 7105 * for writting! 7106 */ 7107 #ifdef INET 7108 if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) { 7109 soclose(SCTP_BASE_INFO(udp4_tun_socket)); 7110 SCTP_BASE_INFO(udp4_tun_socket) = NULL; 7111 } 7112 #endif 7113 #ifdef INET6 7114 if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) { 7115 soclose(SCTP_BASE_INFO(udp6_tun_socket)); 7116 SCTP_BASE_INFO(udp6_tun_socket) = NULL; 7117 } 7118 #endif 7119 } 7120 7121 int 7122 sctp_over_udp_start(void) 7123 { 7124 uint16_t port; 7125 int ret; 7126 #ifdef INET 7127 struct sockaddr_in sin; 7128 #endif 7129 #ifdef INET6 7130 struct sockaddr_in6 sin6; 7131 #endif 7132 /* 7133 * This function assumes sysctl caller holds sctp_sysctl_info_lock() 7134 * for writting! 7135 */ 7136 port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port); 7137 if (ntohs(port) == 0) { 7138 /* Must have a port set */ 7139 return (EINVAL); 7140 } 7141 #ifdef INET 7142 if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) { 7143 /* Already running -- must stop first */ 7144 return (EALREADY); 7145 } 7146 #endif 7147 #ifdef INET6 7148 if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) { 7149 /* Already running -- must stop first */ 7150 return (EALREADY); 7151 } 7152 #endif 7153 #ifdef INET 7154 if ((ret = socreate(PF_INET, &SCTP_BASE_INFO(udp4_tun_socket), 7155 SOCK_DGRAM, IPPROTO_UDP, 7156 curthread->td_ucred, curthread))) { 7157 sctp_over_udp_stop(); 7158 return (ret); 7159 } 7160 /* Call the special UDP hook. */ 7161 if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket), 7162 sctp_recv_udp_tunneled_packet, 7163 sctp_recv_icmp_tunneled_packet, 7164 NULL))) { 7165 sctp_over_udp_stop(); 7166 return (ret); 7167 } 7168 /* Ok, we have a socket, bind it to the port. */ 7169 memset(&sin, 0, sizeof(struct sockaddr_in)); 7170 sin.sin_len = sizeof(struct sockaddr_in); 7171 sin.sin_family = AF_INET; 7172 sin.sin_port = htons(port); 7173 if ((ret = sobind(SCTP_BASE_INFO(udp4_tun_socket), 7174 (struct sockaddr *)&sin, curthread))) { 7175 sctp_over_udp_stop(); 7176 return (ret); 7177 } 7178 #endif 7179 #ifdef INET6 7180 if ((ret = socreate(PF_INET6, &SCTP_BASE_INFO(udp6_tun_socket), 7181 SOCK_DGRAM, IPPROTO_UDP, 7182 curthread->td_ucred, curthread))) { 7183 sctp_over_udp_stop(); 7184 return (ret); 7185 } 7186 /* Call the special UDP hook. */ 7187 if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket), 7188 sctp_recv_udp_tunneled_packet, 7189 sctp_recv_icmp6_tunneled_packet, 7190 NULL))) { 7191 sctp_over_udp_stop(); 7192 return (ret); 7193 } 7194 /* Ok, we have a socket, bind it to the port. */ 7195 memset(&sin6, 0, sizeof(struct sockaddr_in6)); 7196 sin6.sin6_len = sizeof(struct sockaddr_in6); 7197 sin6.sin6_family = AF_INET6; 7198 sin6.sin6_port = htons(port); 7199 if ((ret = sobind(SCTP_BASE_INFO(udp6_tun_socket), 7200 (struct sockaddr *)&sin6, curthread))) { 7201 sctp_over_udp_stop(); 7202 return (ret); 7203 } 7204 #endif 7205 return (0); 7206 } 7207 7208 /* 7209 * sctp_min_mtu ()returns the minimum of all non-zero arguments. 7210 * If all arguments are zero, zero is returned. 7211 */ 7212 uint32_t 7213 sctp_min_mtu(uint32_t mtu1, uint32_t mtu2, uint32_t mtu3) 7214 { 7215 if (mtu1 > 0) { 7216 if (mtu2 > 0) { 7217 if (mtu3 > 0) { 7218 return (min(mtu1, min(mtu2, mtu3))); 7219 } else { 7220 return (min(mtu1, mtu2)); 7221 } 7222 } else { 7223 if (mtu3 > 0) { 7224 return (min(mtu1, mtu3)); 7225 } else { 7226 return (mtu1); 7227 } 7228 } 7229 } else { 7230 if (mtu2 > 0) { 7231 if (mtu3 > 0) { 7232 return (min(mtu2, mtu3)); 7233 } else { 7234 return (mtu2); 7235 } 7236 } else { 7237 return (mtu3); 7238 } 7239 } 7240 } 7241 7242 void 7243 sctp_hc_set_mtu(union sctp_sockstore *addr, uint16_t fibnum, uint32_t mtu) 7244 { 7245 struct in_conninfo inc; 7246 7247 memset(&inc, 0, sizeof(struct in_conninfo)); 7248 inc.inc_fibnum = fibnum; 7249 switch (addr->sa.sa_family) { 7250 #ifdef INET 7251 case AF_INET: 7252 inc.inc_faddr = addr->sin.sin_addr; 7253 break; 7254 #endif 7255 #ifdef INET6 7256 case AF_INET6: 7257 inc.inc_flags |= INC_ISIPV6; 7258 inc.inc6_faddr = addr->sin6.sin6_addr; 7259 break; 7260 #endif 7261 default: 7262 return; 7263 } 7264 tcp_hc_updatemtu(&inc, (u_long)mtu); 7265 } 7266 7267 uint32_t 7268 sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum) 7269 { 7270 struct in_conninfo inc; 7271 7272 memset(&inc, 0, sizeof(struct in_conninfo)); 7273 inc.inc_fibnum = fibnum; 7274 switch (addr->sa.sa_family) { 7275 #ifdef INET 7276 case AF_INET: 7277 inc.inc_faddr = addr->sin.sin_addr; 7278 break; 7279 #endif 7280 #ifdef INET6 7281 case AF_INET6: 7282 inc.inc_flags |= INC_ISIPV6; 7283 inc.inc6_faddr = addr->sin6.sin6_addr; 7284 break; 7285 #endif 7286 default: 7287 return (0); 7288 } 7289 return ((uint32_t)tcp_hc_getmtu(&inc)); 7290 } 7291