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