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