18c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*- 28c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. 3ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 58c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 68c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Redistribution and use in source and binary forms, with or without 78c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * modification, are permitted provided that the following conditions are met: 88c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 98c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a) Redistributions of source code must retain the above copyright notice, 100ac02f34d6041cd0018437596a5a9a94685e6919tuexen * this list of conditions and the following disclaimer. 118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * b) Redistributions in binary form must reproduce the above copyright 138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * notice, this list of conditions and the following disclaimer in 140ac02f34d6041cd0018437596a5a9a94685e6919tuexen * the documentation and/or other materials provided with the distribution. 158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * c) Neither the name of Cisco Systems, Inc. nor the names of its 178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * contributors may be used to endorse or promote products derived 188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * from this software without specific prior written permission. 198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * THE POSSIBILITY OF SUCH DAMAGE. 318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __FreeBSD__ 348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <sys/cdefs.h> 35bfb1bf7e665a02b48026482bf33d05c83dfad73bt__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 271221 2014-09-07 09:06:26Z tuexen $"); 368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_os.h> 398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_pcb.h> 408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctputil.h> 418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_var.h> 428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_sysctl.h> 438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 44b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if defined(__Userspace__) || defined(__FreeBSD__) 458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet6/sctp6_var.h> 468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_header.h> 498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_output.h> 508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_uio.h> 518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_timer.h> 528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_indata.h>/* for sctp_deliver_data() */ 538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_auth.h> 548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_asconf.h> 558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_bsd_addr.h> 567ec5951ec04f35070419877f6b015541f6b9728dtuexen#if defined(__Userspace__) 57a804fa53b20093a975fc501f62a08313110328cetuexen#include <netinet/sctp_constants.h> 587ec5951ec04f35070419877f6b015541f6b9728dtuexen#endif 59b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if defined(__FreeBSD__) 60b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#include <netinet/udp.h> 61b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#include <netinet/udp_var.h> 62b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#include <sys/proc.h> 63b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#define APPLE_FILE_NO 8 678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69000a5bac556b28e74e4e98c540f66b1743e9312dtuexen#if defined(__Windows__) 708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(SCTP_LOCAL_TRACE_BUF) 718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "eventrace_netinet.h" 728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include "sctputil.tmh" /* this is the file that will be auto generated */ 738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifndef KTR_SCTP 768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#define KTR_SCTP KTR_SUBSYS 778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenextern struct sctp_cc_functions sctp_cc_functions[]; 818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenextern struct sctp_ss_functions sctp_ss_functions[]; 828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 84c95692c15a6ca05efcd306c21fda119862cd66e0tsctp_sblog(struct sockbuf *sb, struct sctp_tcb *stcb, int from, int incr) 858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 86c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 880ac02f34d6041cd0018437596a5a9a94685e6919tuexen 898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sb.stcb = stcb; 908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sb.so_sbcc = sb->sb_cc; 918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sb.stcb_sbcc = stcb->asoc.sb_cc; 938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sb.stcb_sbcc = 0; 958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sb.incr = incr; 968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_SB, 988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 1008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 1018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 1028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 103c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 1048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 1058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 1078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc) 1088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 109c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 1108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 1110ac02f34d6041cd0018437596a5a9a94685e6919tuexen 1128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.close.inp = (void *)inp; 1138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.close.sctp_flags = inp->sctp_flags; 1148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 1158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.close.stcb = (void *)stcb; 1168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.close.state = (uint16_t)stcb->asoc.state; 1178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 1188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.close.stcb = 0; 1198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.close.state = 0; 1208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 1218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.close.loc = loc; 1228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 1238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_CLOSE, 1248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 0, 1258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 1268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 1278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 1288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 129c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 1308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 1318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 1338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenrto_logging(struct sctp_nets *net, int from) 1348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 135c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 1368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 1370ac02f34d6041cd0018437596a5a9a94685e6919tuexen 1388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(&sctp_clog, 0, sizeof(sctp_clog)); 1398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rto.net = (void *) net; 1408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rto.rtt = net->rtt / 1000; 1418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 1428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_RTT, 1438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 1448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 1458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 1468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 1478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 148c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 1498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 1508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 1528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t tsn, uint16_t sseq, uint16_t stream, int from) 1538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 154c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 1558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 1560ac02f34d6041cd0018437596a5a9a94685e6919tuexen 1578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.stcb = stcb; 1588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.n_tsn = tsn; 1598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.n_sseq = sseq; 1608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.e_tsn = 0; 1618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.e_sseq = 0; 1628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.strm = stream; 1638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 1648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_STRM, 1658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 1668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 1678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 1688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 1698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 170c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 1718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 1728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 1748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_nagle_event(struct sctp_tcb *stcb, int action) 1758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 176c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 1778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 1780ac02f34d6041cd0018437596a5a9a94685e6919tuexen 1798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.nagle.stcb = (void *)stcb; 1808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.nagle.total_flight = stcb->asoc.total_flight; 1818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.nagle.total_in_queue = stcb->asoc.total_output_queue_size; 1828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.nagle.count_in_queue = stcb->asoc.chunks_on_out_queue; 1838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.nagle.count_in_flight = stcb->asoc.total_flight_count; 1848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 1858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_NAGLE, 1868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen action, 1878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 1888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 1898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 1908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 191c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 1928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 1938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 1958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_sack(uint32_t old_cumack, uint32_t cumack, uint32_t tsn, uint16_t gaps, uint16_t dups, int from) 1968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 197c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 1988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 1990ac02f34d6041cd0018437596a5a9a94685e6919tuexen 2008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sack.cumack = cumack; 2018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sack.oldcumack = old_cumack; 2028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sack.tsn = tsn; 2038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sack.numGaps = gaps; 2048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.sack.numDups = dups; 2058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 2068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_SACK, 2078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 2088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 2098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 2108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 2118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 212c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 2138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 2148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 2168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from) 2178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 218c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 2198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 2200ac02f34d6041cd0018437596a5a9a94685e6919tuexen 2218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(&sctp_clog, 0, sizeof(sctp_clog)); 2228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.map.base = map; 2238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.map.cum = cum; 2248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.map.high = high; 2258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 2268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_MAP, 2278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 2288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 2298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 2308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 2318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 232c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 2338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 2348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 236c95692c15a6ca05efcd306c21fda119862cd66e0tsctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn, int from) 2378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 238c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 2398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 2400ac02f34d6041cd0018437596a5a9a94685e6919tuexen 2418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(&sctp_clog, 0, sizeof(sctp_clog)); 2428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.fr.largest_tsn = biggest_tsn; 2438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.fr.largest_new_tsn = biggest_new_tsn; 2448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.fr.tsn = tsn; 2458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 2468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_FR, 2478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 2488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 2498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 2508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 2518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 252c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 2538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 2548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 2568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_mb(struct mbuf *m, int from) 2578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 258c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 2598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 2600ac02f34d6041cd0018437596a5a9a94685e6919tuexen 2618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.mp = m; 2628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.mbuf_flags = (uint8_t)(SCTP_BUF_GET_FLAGS(m)); 2638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.size = (uint16_t)(SCTP_BUF_LEN(m)); 2648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.data = SCTP_BUF_AT(m, 0); 2658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BUF_IS_EXTENDED(m)) { 2668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.ext = SCTP_BUF_EXTEND_BASE(m); 2678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 2688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* APPLE does not use a ref_cnt, but a forward/backward ref queue */ 2698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 2708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.refcnt = (uint8_t)(SCTP_BUF_EXTEND_REFCNT(m)); 2718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 2720ac02f34d6041cd0018437596a5a9a94685e6919tuexen } else { 2738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.ext = 0; 2748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mb.refcnt = 0; 2758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 2778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_MBUF, 2788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 2798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 2808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 2818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 2828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 283c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 2848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 2858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 287c95692c15a6ca05efcd306c21fda119862cd66e0tsctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_read *poschk, int from) 2888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 289c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 2908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 2910ac02f34d6041cd0018437596a5a9a94685e6919tuexen 2928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 2938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("Gak log of NULL?\n"); 2948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 2958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.stcb = control->stcb; 2978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.n_tsn = control->sinfo_tsn; 2988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.n_sseq = control->sinfo_ssn; 2998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.strm = control->sinfo_stream; 3008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (poschk != NULL) { 3018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.e_tsn = poschk->sinfo_tsn; 3028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.e_sseq = poschk->sinfo_ssn; 3038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 3048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.e_tsn = 0; 3058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.strlog.e_sseq = 0; 3068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 3088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_STRM, 3098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 3108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 3118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 3128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 3138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 314c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 3158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 3168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 3188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from) 3198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 320c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 3218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 3220ac02f34d6041cd0018437596a5a9a94685e6919tuexen 3238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.net = net; 3248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.send_queue_cnt > 255) 3258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_send = 255; 3268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 3278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt; 3288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.stream_queue_cnt > 255) 3298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_str = 255; 3308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 3318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt; 3328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 3348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cwnd_new_value = net->cwnd; 3358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.inflight = net->flight_size; 3368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.pseudo_cumack = net->pseudo_cumack; 3378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.meets_pseudo_cumack = net->new_pseudo_cumack; 3388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.need_new_pseudo_cumack = net->find_pseudo_cumack; 3398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_CWNDLOG_PRESEND == from) { 3418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.meets_pseudo_cumack = stcb->asoc.peers_rwnd; 3428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cwnd_augment = augment; 3448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 3458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_CWND, 3468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 3478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 3488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 3498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 3508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 351c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 3528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 3538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifndef __APPLE__ 3558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 3568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from) 3578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 358c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 3598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 3600ac02f34d6041cd0018437596a5a9a94685e6919tuexen 3618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(&sctp_clog, 0, sizeof(sctp_clog)); 3628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 363c95692c15a6ca05efcd306c21fda119862cd66e0t sctp_clog.x.lock.sock = (void *) inp->sctp_socket; 3648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 366c95692c15a6ca05efcd306c21fda119862cd66e0t sctp_clog.x.lock.sock = (void *) NULL; 3678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.inp = (void *) inp; 3698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version >= 503000) || (defined(__APPLE__)) 3708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 3718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.tcb_lock = mtx_owned(&stcb->tcb_mtx); 3728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 3738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.tcb_lock = SCTP_LOCK_UNKNOWN; 3748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 3768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.inp_lock = mtx_owned(&inp->inp_mtx); 3778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.create_lock = mtx_owned(&inp->inp_create_mtx); 3788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 3798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.inp_lock = SCTP_LOCK_UNKNOWN; 3808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.create_lock = SCTP_LOCK_UNKNOWN; 3818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version <= 602000) 3838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.info_lock = mtx_owned(&SCTP_BASE_INFO(ipi_ep_mtx)); 3848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 3858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.info_lock = rw_wowned(&SCTP_BASE_INFO(ipi_ep_mtx)); 3868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 3878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp && (inp->sctp_socket)) { 3888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.sock_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx)); 3898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.sockrcvbuf_lock = mtx_owned(&(inp->sctp_socket->so_rcv.sb_mtx)); 3908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.socksndbuf_lock = mtx_owned(&(inp->sctp_socket->so_snd.sb_mtx)); 3918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 3928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.sock_lock = SCTP_LOCK_UNKNOWN; 3938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.sockrcvbuf_lock = SCTP_LOCK_UNKNOWN; 3948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.lock.socksndbuf_lock = SCTP_LOCK_UNKNOWN; 3958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 3978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 3988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_LOCK_EVENT, 3998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 4008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 4018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 4028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 4038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 404c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 4058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 4068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *net, int error, int burst, uint8_t from) 4108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 411c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 4128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 4130ac02f34d6041cd0018437596a5a9a94685e6919tuexen 4148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(&sctp_clog, 0, sizeof(sctp_clog)); 4158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.net = net; 4168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cwnd_new_value = error; 4178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.inflight = net->flight_size; 4188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cwnd_augment = burst; 4198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.send_queue_cnt > 255) 4208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_send = 255; 4218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 4228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_send = stcb->asoc.send_queue_cnt; 4238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.stream_queue_cnt > 255) 4248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_str = 255; 4258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 4268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt; 4278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 4288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_MAXBURST, 4298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 4308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 4318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 4328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 4338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 434c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 4358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 4368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_rwnd(uint8_t from, uint32_t peers_rwnd, uint32_t snd_size, uint32_t overhead) 4398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 440c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 4418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 4420ac02f34d6041cd0018437596a5a9a94685e6919tuexen 4438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.rwnd = peers_rwnd; 4448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.send_size = snd_size; 4458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.overhead = overhead; 4468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.new_rwnd = 0; 4478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 4488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_RWND, 4498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 4508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 4518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 4528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 4538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 454c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 4558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 4568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_rwnd_set(uint8_t from, uint32_t peers_rwnd, uint32_t flight_size, uint32_t overhead, uint32_t a_rwndval) 4598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 460c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 4618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 4620ac02f34d6041cd0018437596a5a9a94685e6919tuexen 4638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.rwnd = peers_rwnd; 4648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.send_size = flight_size; 4658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.overhead = overhead; 4668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.rwnd.new_rwnd = a_rwndval; 4678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 4688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_RWND, 4698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 4708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 4718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 4728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 4738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 474c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 4758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 4768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mbcnt_q, uint32_t mbcnt) 4798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 480c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 4818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 4820ac02f34d6041cd0018437596a5a9a94685e6919tuexen 4838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mbcnt.total_queue_size = total_oq; 4848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mbcnt.size_change = book; 4858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mbcnt.total_queue_mb_size = total_mbcnt_q; 4868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.mbcnt.mbcnt_change = mbcnt; 4878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 4888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_MBCNT, 4898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 4908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 4918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 4928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 4938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 494c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 4958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 4968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d) 4998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 500c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 5018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 5028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_MISC_EVENT, 5038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 5048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen a, b, c, d); 505c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 5068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 5078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 5090ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_wakeup_log(struct sctp_tcb *stcb, uint32_t wake_cnt, int from) 5108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 511c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 5128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 5130ac02f34d6041cd0018437596a5a9a94685e6919tuexen 5148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.stcb = (void *)stcb; 5158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.wake_cnt = wake_cnt; 5168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.flight = stcb->asoc.total_flight_count; 5178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.send_q = stcb->asoc.send_queue_cnt; 5188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.sent_q = stcb->asoc.sent_queue_cnt; 5198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.stream_queue_cnt < 0xff) 5218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.stream_qcnt = (uint8_t) stcb->asoc.stream_queue_cnt; 5228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 5238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.stream_qcnt = 0xff; 5248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.chunks_on_out_queue < 0xff) 5268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.chunks_on_oque = (uint8_t) stcb->asoc.chunks_on_out_queue; 5278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 5288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.chunks_on_oque = 0xff; 5298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.sctpflags = 0; 5318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* set in the defered mode stuff */ 5328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) 5338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.sctpflags |= 1; 5348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) 5358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.sctpflags |= 2; 5368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) 5378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.sctpflags |= 4; 538c95692c15a6ca05efcd306c21fda119862cd66e0t /* what about the sb */ 5398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_socket) { 5408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so = stcb->sctp_socket; 5418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.sbflags = (uint8_t)((so->so_snd.sb_flags & 0x00ff)); 5438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 5448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.wake.sbflags = 0xff; 5458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 5478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_WAKE, 5488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 5498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 5508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 5518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 5528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 553c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 5548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 5558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 5570ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_log_block(uint8_t from, struct sctp_association *asoc, int sendlen) 5588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 559c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) || defined(SCTP_LOCAL_TRACE_BUF) 5608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cwnd_log sctp_clog; 5610ac02f34d6041cd0018437596a5a9a94685e6919tuexen 5628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.blk.onsb = asoc->total_output_queue_size; 5638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.blk.send_sent_qcnt = (uint16_t) (asoc->send_queue_cnt + asoc->sent_queue_cnt); 5648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.blk.peer_rwnd = asoc->peers_rwnd; 5658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.blk.stream_qcnt = (uint16_t) asoc->stream_queue_cnt; 5668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.blk.chunks_on_oque = (uint16_t) asoc->chunks_on_out_queue; 5678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.blk.flight_size = (uint16_t) (asoc->total_flight/1024); 5688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.blk.sndlen = sendlen; 5698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x", 5708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_EVENT_BLOCK, 5718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from, 5728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log1, 5738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log2, 5748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log3, 5758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clog.x.misc.log4); 576c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 5778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 5788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 5800ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_fill_stat_log(void *optval SCTP_UNUSED, size_t *optsize SCTP_UNUSED) 5818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 5828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* May need to fix this if ktrdump does not work */ 5838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 5848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 5858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 5878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint8_t sctp_audit_data[SCTP_AUDIT_SIZE][2]; 5888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int sctp_audit_indx = 0; 5898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic 5918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 5928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_print_audit_report(void) 5938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 5948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 5958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int cnt; 5968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 5988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = sctp_audit_indx; i < SCTP_AUDIT_SIZE; i++) { 5998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_audit_data[i][0] == 0xe0) && 6008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_audit_data[i][1] == 0x01)) { 6018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 6028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (sctp_audit_data[i][0] == 0xf0) { 6048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 6058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if ((sctp_audit_data[i][0] == 0xc0) && 6078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_audit_data[i][1] == 0x01)) { 6088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 6108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0], 6128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (uint32_t) sctp_audit_data[i][1]); 6138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt++; 6148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((cnt % 14) == 0) 6158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < sctp_audit_indx; i++) { 6188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_audit_data[i][0] == 0xe0) && 6198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_audit_data[i][1] == 0x01)) { 6208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 6218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (sctp_audit_data[i][0] == 0xf0) { 6238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 6248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if ((sctp_audit_data[i][0] == 0xc0) && 6268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_audit_data[i][1] == 0x01)) { 6278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 6298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("%2.2x%2.2x ", (uint32_t) sctp_audit_data[i][0], 6318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (uint32_t) sctp_audit_data[i][1]); 6328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt++; 6338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((cnt % 14) == 0) 6348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("\n"); 6378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 6388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 6408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 6418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net) 6428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 6438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int resend_cnt, tot_out, rep, tot_book_cnt; 6448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *lnet; 6458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *chk; 6468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xAA; 6488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from; 6498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 6508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 6518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 6528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 6548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xAF; 6558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 0x01; 6568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 6578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 6588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 6598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 6618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 6638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xAF; 6648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 0x02; 6658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 6668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 6678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 6688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 6708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xA1; 6728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 6738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (0x000000ff & stcb->asoc.sent_queue_retran_cnt); 6748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 6758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 6768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 6778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rep = 0; 6798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_book_cnt = 0; 6808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen resend_cnt = tot_out = 0; 6818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 6828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->sent == SCTP_DATAGRAM_RESEND) { 6838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen resend_cnt++; 6848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (chk->sent < SCTP_DATAGRAM_RESEND) { 6858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_out += chk->book_size; 6868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_book_cnt++; 6878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) { 6908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xAF; 6918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 0xA1; 6928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 6938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 6948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 6958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("resend_cnt:%d asoc-tot:%d\n", 6978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen resend_cnt, stcb->asoc.sent_queue_retran_cnt); 6988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rep = 1; 6998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sent_queue_retran_cnt = resend_cnt; 7008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xA2; 7018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 7028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (0x000000ff & stcb->asoc.sent_queue_retran_cnt); 7038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 7048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 7058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 7068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tot_out != stcb->asoc.total_flight) { 7098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xAF; 7108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 0xA2; 7118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 7128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 7138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 7148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rep = 1; 7168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("tot_flt:%d asoc_tot:%d\n", tot_out, 7178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (int)stcb->asoc.total_flight); 7188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.total_flight = tot_out; 7198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tot_book_cnt != stcb->asoc.total_flight_count) { 7218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xAF; 7228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 0xA5; 7238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 7248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 7258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 7268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rep = 1; 7288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("tot_flt_book:%d\n", tot_book_cnt); 7298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.total_flight_count = tot_book_cnt; 7318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_out = 0; 7338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 7348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_out += lnet->flight_size; 7358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tot_out != stcb->asoc.total_flight) { 7378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = 0xAF; 7388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = 0xA3; 7398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 7408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 7418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 7428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rep = 1; 7448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("real flight:%d net total was %d\n", 7458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.total_flight, tot_out); 7468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now corrective action */ 7478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 7488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_out = 0; 7508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 7518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((chk->whoTo == lnet) && 7528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (chk->sent < SCTP_DATAGRAM_RESEND)) { 7538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_out += chk->book_size; 7548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (lnet->flight_size != tot_out) { 7578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("net:%p flight was %d corrected to %d\n", 758ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t (void *)lnet, lnet->flight_size, 7598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tot_out); 7608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen lnet->flight_size = tot_out; 7618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (rep) { 7658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_print_audit_report(); 7668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 7688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 7708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_audit_log(uint8_t ev, uint8_t fd) 7718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 7728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][0] = ev; 7748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_data[sctp_audit_indx][1] = fd; 7758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx++; 7768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 7778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_indx = 0; 7788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 7808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 7848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sctp_stop_timers_for_shutdown() should be called 7858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * when entering the SHUTDOWN_SENT or SHUTDOWN_ACK_SENT 7868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * state to make sure that all timers are stopped. 7878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 7888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 7898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_stop_timers_for_shutdown(struct sctp_tcb *stcb) 7908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 7918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_association *asoc; 7928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 7938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc = &stcb->asoc; 7958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer); 7978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer); 7988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer); 7998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer); 8008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer); 8018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &asoc->nets, sctp_next) { 8028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer); 8038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&net->hb_timer.timer); 8048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 8068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 8088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a list of sizes based on typical mtu's, used only if next hop size not 8098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * returned. 8108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 8118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic uint32_t sctp_mtu_sizes[] = { 8128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68, 8138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 296, 8148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 508, 8158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 512, 8168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 544, 8178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 576, 8188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1006, 8198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1492, 8208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1500, 8218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1536, 8228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2002, 8238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2048, 8248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4352, 8258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4464, 8268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8166, 8278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 17914, 8288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32000, 8298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 65535 8308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}; 8318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 8338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Return the largest MTU smaller than val. If there is no 8348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * entry, just return val. 8358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 8368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 8378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_get_prev_mtu(uint32_t val) 8388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 8398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t i; 8408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (val <= sctp_mtu_sizes[0]) { 8428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (val); 8438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 1; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) { 8458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (val <= sctp_mtu_sizes[i]) { 8468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 8478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sctp_mtu_sizes[i - 1]); 8508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 8518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 8538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Return the smallest MTU larger than val. If there is no 8548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * entry, just return val. 8558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 8568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 8570ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_get_next_mtu(uint32_t val) 8588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 8598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* select another MTU that is just bigger than this one */ 8608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t i; 8618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < (sizeof(sctp_mtu_sizes) / sizeof(uint32_t)); i++) { 8638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (val < sctp_mtu_sizes[i]) { 8648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sctp_mtu_sizes[i]); 8658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (val); 8688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 8698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 8718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_fill_random_store(struct sctp_pcb *m) 8728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 8738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 8748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here we use the MD5/SHA-1 to hash with our good randomNumbers and 8758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * our counter. The result becomes our good random numbers and we 8768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * then setup to give these out. Note that we do no locking to 8778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * protect this. This is ok, since if competing folks call this we 8788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * will get more gobbled gook in the random store which is what we 8798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * want. There is a danger that two guys will use the same random 8808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * numbers, but thats ok too since that is random as well :-> 8818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 8828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m->store_at = 0; 8838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_hmac(SCTP_HMAC, (uint8_t *)m->random_numbers, 8848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(m->random_numbers), (uint8_t *)&m->random_counter, 8858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(m->random_counter), (uint8_t *)m->random_store); 8868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m->random_counter++; 8878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 8888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 8908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_select_initial_TSN(struct sctp_pcb *inp) 8918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 8928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 8938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * A true implementation should use random selection process to get 8948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the initial stream sequence number, using RFC1750 as a good 8958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * guideline 8968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 8978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t x, *xp; 8988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *p; 8998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int store_at, new_store; 9008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->initial_sequence_debug != 0) { 9028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t ret; 9038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ret = inp->initial_sequence_debug; 9058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->initial_sequence_debug++; 9068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ret); 9078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen retry: 9098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store_at = inp->store_at; 9108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_store = store_at + sizeof(uint32_t); 9118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (new_store >= (SCTP_SIGNATURE_SIZE-3)) { 9128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_store = 0; 9138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!atomic_cmpset_int(&inp->store_at, store_at, new_store)) { 9158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto retry; 9168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (new_store == 0) { 9188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Refill the random store */ 9198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_fill_random_store(inp); 9208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen p = &inp->random_store[store_at]; 9228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen xp = (uint32_t *)p; 9238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen x = *xp; 9248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (x); 9258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 9268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 9280ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int check) 9298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 9300ac02f34d6041cd0018437596a5a9a94685e6919tuexen uint32_t x; 9318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct timeval now; 9328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9330ac02f34d6041cd0018437596a5a9a94685e6919tuexen if (check) { 9340ac02f34d6041cd0018437596a5a9a94685e6919tuexen (void)SCTP_GETTIME_TIMEVAL(&now); 9350ac02f34d6041cd0018437596a5a9a94685e6919tuexen } 9360ac02f34d6041cd0018437596a5a9a94685e6919tuexen for (;;) { 9378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen x = sctp_select_initial_TSN(&inp->sctp_ep); 9388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (x == 0) { 9398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we never use 0 */ 9408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 9418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9420ac02f34d6041cd0018437596a5a9a94685e6919tuexen if (!check || sctp_is_vtag_good(x, lport, rport, &now)) { 9430ac02f34d6041cd0018437596a5a9a94685e6919tuexen break; 9448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (x); 9478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 9488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 9507988ea8f0c067cf3757e798b473b1ae4d34b6dfdtsctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 9518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t override_tag, uint32_t vrf_id) 9528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 9538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_association *asoc; 9548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 9558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Anything set to zero is taken care of by the allocation routine's 9568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bzero 9578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 9588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 9608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Up front select what scoping to apply on addresses I tell my peer 9618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Not sure what to do with these right now, we will need to come up 9628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * with a way to set them. We may need to pass them through from the 9638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * caller in the sctp_aloc_assoc() function. 9648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 9658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 96620d5d287bff2075897105f85287230d55bdfa420t#if defined(SCTP_DETAILED_STR_STATS) 96720d5d287bff2075897105f85287230d55bdfa420t int j; 96820d5d287bff2075897105f85287230d55bdfa420t#endif 9698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc = &stcb->asoc; 9718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* init all variables to a known value. */ 9728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE); 9737988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->max_burst = inp->sctp_ep.max_burst; 9747988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->fr_max_burst = inp->sctp_ep.fr_max_burst; 9757988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 9767988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->cookie_life = inp->sctp_ep.def_cookie_life; 9777988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off; 978aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t asoc->ecn_supported = inp->ecn_supported; 979a8657c4fc04fb9cc82100f648810d51ec6ab155at asoc->prsctp_supported = inp->prsctp_supported; 980fb3816eaffe5878bb1286adb120fd160da178a05t asoc->auth_supported = inp->auth_supported; 981fb3816eaffe5878bb1286adb120fd160da178a05t asoc->asconf_supported = inp->asconf_supported; 9822344bfccffeb80545fca6a86e8cda3d56a6f50bft asoc->reconfig_supported = inp->reconfig_supported; 98344318e900a771ba1a5bafb510c38f33fd5cd8a39t asoc->nrsack_supported = inp->nrsack_supported; 984669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t asoc->pktdrop_supported = inp->pktdrop_supported; 9858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->sctp_cmt_pf = (uint8_t)0; 9867988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->sctp_frag_point = inp->sctp_frag_point; 9877988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->sctp_features = inp->sctp_features; 9887988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->default_dscp = inp->sctp_ep.default_dscp; 9898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 9907988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (inp->sctp_ep.default_flowlabel) { 9917988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->default_flowlabel = inp->sctp_ep.default_flowlabel; 9928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 9937988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (inp->ip_inp.inp.inp_flags & IN6P_AUTOFLOWLABEL) { 9947988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->default_flowlabel = sctp_select_initial_TSN(&inp->sctp_ep); 9958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->default_flowlabel &= 0x000fffff; 996b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen asoc->default_flowlabel |= 0x80000000; 9978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 9988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->default_flowlabel = 0; 9998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->sb_send_resv = 0; 10038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (override_tag) { 10048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->my_vtag = override_tag; 10058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 10067988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->my_vtag = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 1); 10078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Get the nonce tags */ 10097988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->my_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0); 10107988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->peer_vtag_nonce = sctp_select_a_tag(inp, stcb->sctp_ep->sctp_lport, stcb->rport, 0); 10118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->vrf_id = vrf_id; 10128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_ASOCLOG_OF_TSNS 10148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->tsn_in_at = 0; 1015e2828360ea9cf8951730d46f5c14626c9425cb30t asoc->tsn_out_at = 0; 10168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->tsn_in_wrapped = 0; 10178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->tsn_out_wrapped = 0; 10188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->cumack_log_at = 0; 10198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->cumack_log_atsnt = 0; 10208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_FS_SPEC_LOG 10228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->fs_index = 0; 10238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->refcnt = 0; 10258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->assoc_up_sent = 0; 10268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq = 10277988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sctp_select_initial_TSN(&inp->sctp_ep); 10288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1; 10298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we are optimisitic here */ 10308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->peer_supports_nat = 0; 10318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->sent_queue_retran_cnt = 0; 10328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* for CMT */ 10348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->last_net_cmt_send_started = NULL; 10358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* This will need to be adjusted */ 10378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->last_acked_seq = asoc->init_seq_number - 1; 10388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->advanced_peer_ack_point = asoc->last_acked_seq; 10398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->asconf_seq_in = asoc->last_acked_seq; 10408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* here we are different, we hold the next one we expect */ 10428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->str_reset_seq_in = asoc->last_acked_seq + 1; 10438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10447988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max; 10457988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->initial_rto = inp->sctp_ep.initial_rto; 10468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10477988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->max_init_times = inp->sctp_ep.max_init_times; 10487988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->max_send_times = inp->sctp_ep.max_send_times; 10497988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->def_net_failure = inp->sctp_ep.def_net_failure; 10507988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->def_net_pf_threshold = inp->sctp_ep.def_net_pf_threshold; 10518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->free_chunk_cnt = 0; 10528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->iam_blocking = 0; 10547988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->context = inp->sctp_context; 10557988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->local_strreset_support = inp->local_strreset_support; 10567988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->def_send = inp->def_send; 10577988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->delayed_ack = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 10587988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->sack_freq = inp->sctp_ep.sctp_sack_freq; 10598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->pr_sctp_cnt = 0; 10608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->total_output_queue_size = 0; 10618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10627988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 10637988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.ipv6_addr_legal = 1; 10647988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (SCTP_IPV6_V6ONLY(inp) == 0) { 10657988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.ipv4_addr_legal = 1; 10668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 10677988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.ipv4_addr_legal = 0; 10688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10697988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 10707988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.conn_addr_legal = 0; 10717988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 10728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 10737988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.ipv6_addr_legal = 0; 10747988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 10757988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) { 10767988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.conn_addr_legal = 1; 10777988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.ipv4_addr_legal = 0; 10787988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 10797988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.conn_addr_legal = 0; 10807988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.ipv4_addr_legal = 1; 10817988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 10827988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#else 10837988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->scope.ipv4_addr_legal = 1; 10847988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 10858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10877988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->my_rwnd = max(SCTP_SB_LIMIT_RCV(inp->sctp_socket), SCTP_MINIMAL_RWND); 10887988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->peers_rwnd = SCTP_SB_LIMIT_RCV(inp->sctp_socket); 10898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10907988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->smallest_mtu = inp->sctp_frag_point; 10917988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->minrto = inp->sctp_ep.sctp_minrto; 10927988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->maxrto = inp->sctp_ep.sctp_maxrto; 10938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->locked_on_sending = NULL; 10958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->stream_locked_on = 0; 10968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->ecn_echo_cnt_onq = 0; 10978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->stream_locked = 0; 10988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->send_sack = 1; 11008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_INIT(&asoc->sctp_restricted_addrs); 11028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->nets); 11048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->pending_reply_queue); 11058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->asconf_ack_sent); 11068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Setup to fill the hb random cache at first HB */ 11078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->hb_random_idx = 4; 11088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11097988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->sctp_autoclose_ticks = inp->sctp_ep.auto_close_time; 11108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11117988ea8f0c067cf3757e798b473b1ae4d34b6dfdt stcb->asoc.congestion_control_module = inp->sctp_ep.sctp_default_cc_module; 11127988ea8f0c067cf3757e798b473b1ae4d34b6dfdt stcb->asoc.cc_functions = sctp_cc_functions[inp->sctp_ep.sctp_default_cc_module]; 11138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11147988ea8f0c067cf3757e798b473b1ae4d34b6dfdt stcb->asoc.stream_scheduling_module = inp->sctp_ep.sctp_default_ss_module; 11157988ea8f0c067cf3757e798b473b1ae4d34b6dfdt stcb->asoc.ss_functions = sctp_ss_functions[inp->sctp_ep.sctp_default_ss_module]; 11168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 11188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Now the stream parameters, here we allocate space for all streams 11198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * that we request by default. 11208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 11218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams = 11227988ea8f0c067cf3757e798b473b1ae4d34b6dfdt inp->sctp_ep.pre_open_stream_count; 11238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *, 11248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->streamoutcnt * sizeof(struct sctp_stream_out), 11258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_M_STRMO); 11268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->strmout == NULL) { 11278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* big trouble no memory */ 11288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 11298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 11308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < asoc->streamoutcnt; i++) { 11328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 11338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * inbound side must be set to 0xffff, also NOTE when we get 11348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the INIT-ACK back (for INIT sender) we MUST reduce the 11358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * count (streamoutcnt) but first check if we sent to any of 11368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the upper streams that were dropped (if some were). Those 11378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * that were dropped must be notified to the upper layer as 11388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * failed to send. 11398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 1140e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t asoc->strmout[i].next_sequence_send = 0x0; 11418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->strmout[i].outqueue); 114260db5740d3bcc26fd4ebc19b6b0652506994fd14t asoc->strmout[i].chunks_on_queues = 0; 114320d5d287bff2075897105f85287230d55bdfa420t#if defined(SCTP_DETAILED_STR_STATS) 114420d5d287bff2075897105f85287230d55bdfa420t for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) { 114520d5d287bff2075897105f85287230d55bdfa420t asoc->strmout[i].abandoned_sent[j] = 0; 114620d5d287bff2075897105f85287230d55bdfa420t asoc->strmout[i].abandoned_unsent[j] = 0; 114720d5d287bff2075897105f85287230d55bdfa420t } 114820d5d287bff2075897105f85287230d55bdfa420t#else 114920d5d287bff2075897105f85287230d55bdfa420t asoc->strmout[i].abandoned_sent[0] = 0; 115020d5d287bff2075897105f85287230d55bdfa420t asoc->strmout[i].abandoned_unsent[0] = 0; 115120d5d287bff2075897105f85287230d55bdfa420t#endif 11528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->strmout[i].stream_no = i; 11538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->strmout[i].last_msg_incomplete = 0; 11548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->ss_functions.sctp_ss_init_stream(&asoc->strmout[i], NULL); 11558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->ss_functions.sctp_ss_init(stcb, asoc, 0); 11578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now the mapping array */ 11598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY; 11608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size, 11618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_M_MAP); 11628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->mapping_array == NULL) { 11638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(asoc->strmout, SCTP_M_STRMO); 11648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 11658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 11668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 1167000a5bac556b28e74e4e98c540f66b1743e9312dtuexen memset(asoc->mapping_array, 0, asoc->mapping_array_size); 11688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size, 11698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_M_MAP); 11708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->nr_mapping_array == NULL) { 11718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(asoc->strmout, SCTP_M_STRMO); 11728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(asoc->mapping_array, SCTP_M_MAP); 11738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 11748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 11758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size); 11778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now the init of the other outqueues */ 11798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->free_chunks); 11808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->control_send_queue); 11818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->asconf_send_queue); 11828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->send_queue); 11838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->sent_queue); 11848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->reasmqueue); 11858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->resetHead); 11867988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome; 11878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&asoc->asconf_queue); 11888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* authentication fields */ 11898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->authinfo.random = NULL; 11908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->authinfo.active_keyid = 0; 11918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->authinfo.assoc_key = NULL; 11928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->authinfo.assoc_keyid = 0; 11938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->authinfo.recv_key = NULL; 11948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->authinfo.recv_keyid = 0; 11958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_INIT(&asoc->shared_keys); 11968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->marked_retrans = 0; 11977988ea8f0c067cf3757e798b473b1ae4d34b6dfdt asoc->port = inp->sctp_ep.port; 11988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->timoinit = 0; 11998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->timodata = 0; 12008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->timosack = 0; 12018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->timoshutdown = 0; 12028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->timoheartbeat = 0; 12038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->timocookie = 0; 12048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->timoshutdownack = 0; 12058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&asoc->start_time); 12068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->discontinuity_time = asoc->start_time; 120720d5d287bff2075897105f85287230d55bdfa420t for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) { 120820d5d287bff2075897105f85287230d55bdfa420t asoc->abandoned_unsent[i] = 0; 120920d5d287bff2075897105f85287230d55bdfa420t asoc->abandoned_sent[i] = 0; 121020d5d287bff2075897105f85287230d55bdfa420t } 12118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when 12128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the association is freed. 12138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 12148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 12158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 12168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 12178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 12188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_print_mapping_array(struct sctp_association *asoc) 12198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 12208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen unsigned int i, limit; 12218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 122247a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("Mapping array size: %d, baseTSN: %8.8x, cumAck: %8.8x, highestTSN: (%8.8x, %8.8x).\n", 122347a306d634abf33223ef347472c4b1cd441d139ftuexen asoc->mapping_array_size, 122447a306d634abf33223ef347472c4b1cd441d139ftuexen asoc->mapping_array_base_tsn, 122547a306d634abf33223ef347472c4b1cd441d139ftuexen asoc->cumulative_tsn, 122647a306d634abf33223ef347472c4b1cd441d139ftuexen asoc->highest_tsn_inside_map, 122747a306d634abf33223ef347472c4b1cd441d139ftuexen asoc->highest_tsn_inside_nr_map); 12288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (limit = asoc->mapping_array_size; limit > 1; limit--) { 1229b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (asoc->mapping_array[limit - 1] != 0) { 12308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 12318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 123347a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("Renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit); 12348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < limit; i++) { 123547a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n'); 12368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (limit % 16) 123847a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("\n"); 12398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (limit = asoc->mapping_array_size; limit > 1; limit--) { 12408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->nr_mapping_array[limit - 1]) { 12418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 12428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 124447a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("Non renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit); 12458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < limit; i++) { 124647a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("%2.2x%c", asoc->nr_mapping_array[i], ((i + 1) % 16) ? ' ': '\n'); 12478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (limit % 16) 124947a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("\n"); 12508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 12518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 12528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 12538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed) 12548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 12558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* mapping array needs to grow */ 12568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *new_array1, *new_array2; 12578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t new_size; 12588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 12598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_size = asoc->mapping_array_size + ((needed+7)/8 + SCTP_MAPPING_ARRAY_INCR); 12608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP); 12618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP); 12628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((new_array1 == NULL) || (new_array2 == NULL)) { 12638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't get more, forget it */ 12648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n", new_size); 12658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (new_array1) { 12668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(new_array1, SCTP_M_MAP); 12678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (new_array2) { 12698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(new_array2, SCTP_M_MAP); 12708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (-1); 12728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(new_array1, 0, new_size); 12748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(new_array2, 0, new_size); 12758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size); 12768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size); 12778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(asoc->mapping_array, SCTP_M_MAP); 12788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP); 12798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->mapping_array = new_array1; 12808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->nr_mapping_array = new_array2; 12818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->mapping_array_size = new_size; 12828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 12838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 12848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 12858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 12868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 12878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_iterator_work(struct sctp_iterator *it) 12888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 12898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int iteration_count = 0; 12908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int inp_skip = 0; 1291b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int first_in = 1; 12928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *tinp; 1293000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 12948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INFO_RLOCK(); 12958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ITERATOR_LOCK(); 1296e2828360ea9cf8951730d46f5c14626c9425cb30t if (it->inp) { 12978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(it->inp); 12988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(it->inp); 12998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->inp == NULL) { 13018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* iterator is complete */ 13028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexendone_with_iterator: 13038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ITERATOR_UNLOCK(); 13048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INFO_RUNLOCK(); 13058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->function_atend != NULL) { 13068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*it->function_atend) (it->pointer, it->val); 13078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(it, SCTP_M_ITER); 13098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 13108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenselect_a_new_ep: 13128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (first_in) { 13138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen first_in = 0; 13148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 13158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(it->inp); 13168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (((it->pcb_flags) && 13188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((it->inp->sctp_flags & it->pcb_flags) != it->pcb_flags)) || 13198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((it->pcb_features) && 13208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((it->inp->sctp_features & it->pcb_features) != it->pcb_features))) { 13218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* endpoint flags or features don't match, so keep looking */ 13228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { 13238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(it->inp); 13248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_iterator; 13258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tinp = it->inp; 13278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->inp = LIST_NEXT(it->inp, sctp_list); 13288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(tinp); 13298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->inp == NULL) { 13308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_iterator; 13318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(it->inp); 13338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now go through each assoc which is in the desired state */ 13358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->done_current_ep == 0) { 13368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->function_inp != NULL) 13378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp_skip = (*it->function_inp)(it->inp, it->pointer, it->val); 13388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->done_current_ep = 1; 13398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->stcb == NULL) { 13418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* run the per instance function */ 13428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->stcb = LIST_FIRST(&it->inp->sctp_asoc_list); 13438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp_skip) || it->stcb == NULL) { 13458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->function_inp_end != NULL) { 13468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp_skip = (*it->function_inp_end)(it->inp, 13478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->pointer, 13488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->val); 13498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(it->inp); 13518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto no_stcb; 13528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (it->stcb) { 13548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(it->stcb); 13558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) { 13568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not in the right state... keep looking */ 13578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(it->stcb); 13588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto next_assoc; 13598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* see if we have limited out the iterator loop */ 13618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen iteration_count++; 13628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) { 13638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Pause to let others grab the lock */ 13648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&it->stcb->asoc.refcnt, 1); 13658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(it->stcb); 13668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(it->inp); 13678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(it->inp); 13688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ITERATOR_UNLOCK(); 13698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INFO_RUNLOCK(); 13708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INFO_RLOCK(); 13718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ITERATOR_LOCK(); 13728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_it_ctl.iterator_flags) { 13738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We won't be staying here */ 13748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(it->inp); 13758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&it->stcb->asoc.refcnt, -1); 13768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__FreeBSD__) 13778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_it_ctl.iterator_flags & 13788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ITERATOR_MUST_EXIT) { 13798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_iterator; 13808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 13828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_it_ctl.iterator_flags & 13838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ITERATOR_STOP_CUR_IT) { 13848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_IT; 13858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_iterator; 13868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_it_ctl.iterator_flags & 13888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ITERATOR_STOP_CUR_INP) { 13898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_it_ctl.iterator_flags &= ~SCTP_ITERATOR_STOP_CUR_INP; 13908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto no_stcb; 13918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* If we reach here huh? */ 139347a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("Unknown it ctl flag %x\n", 139447a306d634abf33223ef347472c4b1cd441d139ftuexen sctp_it_ctl.iterator_flags); 13958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_it_ctl.iterator_flags = 0; 13968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(it->inp); 13988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(it->inp); 13998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(it->stcb); 14008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&it->stcb->asoc.refcnt, -1); 14018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen iteration_count = 0; 14028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* run function on this one */ 14058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*it->function_assoc)(it->inp, it->stcb, it->pointer, it->val); 14068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 14088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we lie here, it really needs to have its own type but 14098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * first I must verify that this won't effect things :-0 14108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 14118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->no_chunk_output == 0) 14128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(it->inp, it->stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED); 14138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(it->stcb); 14158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen next_assoc: 14168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->stcb = LIST_NEXT(it->stcb, sctp_tcblist); 14178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->stcb == NULL) { 14188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Run last function */ 14198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->function_inp_end != NULL) { 14208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp_skip = (*it->function_inp_end)(it->inp, 14218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->pointer, 14228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->val); 14238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(it->inp); 14278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen no_stcb: 14288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* done with all assocs on this endpoint, move on to next endpoint */ 14298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->done_current_ep = 0; 14308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { 14318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->inp = NULL; 14328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 14338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen it->inp = LIST_NEXT(it->inp, sctp_list); 14348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (it->inp == NULL) { 14368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_iterator; 14378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto select_a_new_ep; 14398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 14408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 14428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_iterator_worker(void) 14438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 14448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_iterator *it, *nit; 14458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* This function is called with the WQ lock in place */ 14478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_it_ctl.iterator_running = 1; 14498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) { 14508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_it_ctl.cur_it = it; 14518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now lets work on this one */ 14528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); 14538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ITERATOR_WQ_UNLOCK(); 14548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 14558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_SET(it->vn); 14568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 14578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_iterator_work(it); 14588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_it_ctl.cur_it = NULL; 14598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 14608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 14618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 14628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ITERATOR_WQ_LOCK(); 14638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__FreeBSD__) 14648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) { 14658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 14668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 14688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*sa_ignore FREED_MEMORY*/ 14698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_it_ctl.iterator_running = 0; 14718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 14728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 14738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 14768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_handle_addr_wq(void) 14778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 14788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* deal with the ADDR wq from the rtsock calls */ 14798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *wi, *nwi; 14808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_asconf_iterator *asc; 14818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(asc, struct sctp_asconf_iterator *, 14838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct sctp_asconf_iterator), SCTP_M_ASC_IT); 14848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asc == NULL) { 14858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Try later, no memory */ 14868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, 14878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_inpcb *)NULL, 14888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_tcb *)NULL, 14898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_nets *)NULL); 14908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 14918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_INIT(&asc->list_of_work); 14938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asc->cnt = 0; 14948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_WQ_ADDR_LOCK(); 14968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) { 14978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_REMOVE(wi, sctp_nxt_addr); 14988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr); 14998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asc->cnt++; 15008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_WQ_ADDR_UNLOCK(); 15028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asc->cnt == 0) { 15048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(asc, SCTP_M_ASC_IT); 15058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 15068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_initiate_iterator(sctp_asconf_iterator_ep, 15078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_asconf_iterator_stcb, 15088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, /* No ep end for boundall */ 15098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PCB_FLAGS_BOUNDALL, 15108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PCB_ANY_FEATURES, 15118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_ANY_STATE, 15128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void *)asc, 0, 15138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_asconf_iterator_end, NULL, 0); 15148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 15168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 15188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_timeout_handler(void *t) 15198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 15208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 15218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 15228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 15238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_timer *tmr; 15240612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 15258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 15268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int did_output, type; 15288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = (struct sctp_timer *)t; 15308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)tmr->ep; 15318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = (struct sctp_tcb *)tmr->tcb; 15328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = (struct sctp_nets *)tmr->net; 15338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 15348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_SET((struct vnet *)tmr->vnet); 15358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen did_output = 1; 15378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 15398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_log(0xF0, (uint8_t) tmr->type); 15408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(3, inp, stcb, net); 15418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* sanity checks... */ 15448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tmr->self != (void *)tmr) { 15458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 15468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * SCTP_PRINTF("Stale SCTP timer fired (%p), ignoring...\n", 1547ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t * (void *)tmr); 15488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 15498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 15508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 15518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 15538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = 0xa001; 15558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!SCTP_IS_TIMER_TYPE_VALID(tmr->type)) { 15568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 15578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * SCTP_PRINTF("SCTP timer fired with invalid type: 0x%x\n", 15588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tmr->type); 15598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 15608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 15618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 15628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 15648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = 0xa002; 15668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((tmr->type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) { 15678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 15688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 15698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 15718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* if this is an iterator timeout, get the struct and clear inp */ 15738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = 0xa003; 15748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen type = tmr->type; 15758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 15768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 157723273859c39742f09cc5ec7c9bf32ff225661e82tuexen if ((inp->sctp_socket == NULL) && 15788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tmr->type != SCTP_TIMER_TYPE_INPKILL) && 15798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_INIT) && 15808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_SEND) && 15818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_RECV) && 15828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_HEARTBEAT) && 15838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_SHUTDOWN) && 15848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNACK) && 15858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_SHUTDOWNGUARD) && 15868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tmr->type != SCTP_TIMER_TYPE_ASOCKILL)) 15878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) { 15888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 15898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 15908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 15918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 15938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = 0xa004; 15968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 15978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 15988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state == 0) { 15998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, -1); 16008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 16018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 16028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 16048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 16058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 16068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 16078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = 0xa005; 16108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_TIMER1, "Timer type %d goes off\n", tmr->type); 16118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) { 16128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 16138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 16148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 16168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, -1); 16178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 16198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 16208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 16218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 16228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = 0xa006; 16248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 16258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 16268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 16278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, -1); 16288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((tmr->type != SCTP_TIMER_TYPE_ASOCKILL) && 16298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((stcb->asoc.state == 0) || 16308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED))) { 16318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 16328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 16338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 16348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 16368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 16378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 16388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 16398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* record in stopped what t-o occured */ 16428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = tmr->type; 16438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 16448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* mark as being serviced now */ 16458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_OS_TIMER_PENDING(&tmr->timer)) { 16468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 16478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Callout has been rescheduled. 16488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 16498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto get_out; 16508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) { 16528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 16538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Not active, so no action. 16548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 16558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto get_out; 16568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_OS_TIMER_DEACTIVATE(&tmr->timer); 16588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 16598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* call the handler for the appropriate timer type */ 16608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (tmr->type) { 16618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ZERO_COPY: 16628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 16638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 16648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { 16668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); 16678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 16698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ZCOPY_SENDQ: 16708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 16718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 16728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { 16748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ZERO_COPY_SENDQ_EVENT(inp, inp->sctp_socket); 16758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 16778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ADDR_WQ: 16788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_handle_addr_wq(); 16798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 16808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SEND: 16818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 16828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 16838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timodata); 16858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.timodata++; 16868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.num_send_timers_up--; 16878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.num_send_timers_up < 0) { 16888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.num_send_timers_up = 0; 16898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK_ASSERT(stcb); 1691b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (sctp_t3rxt_timer(inp, stcb, net)) { 16928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 16938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 16948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 16958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK_ASSERT(stcb); 16978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 16988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(4, inp, stcb, net); 16998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED); 17018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->asoc.num_send_timers_up == 0) && 17028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.sent_queue_cnt > 0)) { 17038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *chk; 17048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 17058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * safeguard. If there on some on the sent queue 17078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * somewhere but no timers running something is 17088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * wrong... so we start a timer on the first chunk 17098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * on the send queue on whatever net it is sent to. 17108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk = TAILQ_FIRST(&stcb->asoc.sent_queue); 17128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, 17138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->whoTo); 17148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_INIT: 17178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 17188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoinit); 17218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.timoinit++; 17228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_t1init_timer(inp, stcb, net)) { 17238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 17248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 17258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We do output but not here */ 17278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen did_output = 0; 17288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_RECV: 17308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 17318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timosack); 17348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.timosack++; 17358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); 17368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 17378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(4, inp, stcb, net); 17388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SACK_TMR, SCTP_SO_NOT_LOCKED); 17408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWN: 17428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 17438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_shutdown_timer(inp, stcb, net)) { 17468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 17478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 17488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoshutdown); 17508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.timoshutdown++; 17518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 17528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(4, inp, stcb, net); 17538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_TMR, SCTP_SO_NOT_LOCKED); 17558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_HEARTBEAT: 17578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL) || (net == NULL)) { 17588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoheartbeat); 17618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.timoheartbeat++; 17628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_heartbeat_timer(inp, stcb, net)) { 17638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 17648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 17658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 17678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(4, inp, stcb, net); 17688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_NOHB)) { 17708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 17718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_HB_TMR, SCTP_SO_NOT_LOCKED); 17728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_COOKIE: 17758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 17768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 17798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_cookie_timer(inp, stcb, net)) { 17808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 17818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 17828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timocookie); 17848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.timocookie++; 17858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 17868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(4, inp, stcb, net); 17878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We consider T3 and Cookie timer pretty much the same with 17908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * respect to where from in chunk_output. 17918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED); 17938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_NEWCOOKIE: 17958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 17968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct timeval tv; 17978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i, secret; 17988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 17998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timosecret); 18028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&tv); 18038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 18048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.time_of_secret_change = tv.tv_sec; 18058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.last_secret_number = 18068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.current_secret_number; 18078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.current_secret_number++; 18088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_ep.current_secret_number >= 18098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_HOW_MANY_SECRETS) { 18108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.current_secret_number = 0; 18118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen secret = (int)inp->sctp_ep.current_secret_number; 18138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) { 18148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.secret_key[secret][i] = 18158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_select_initial_TSN(&inp->sctp_ep); 18168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 18188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net); 18198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen did_output = 0; 18218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_PATHMTURAISE: 18238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timopathmtu); 18278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_pathmtu_timer(inp, stcb, net); 18288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen did_output = 0; 18298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWNACK: 18318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_shutdownack_timer(inp, stcb, net)) { 18358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 18368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 18378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoshutdownack); 1839e2828360ea9cf8951730d46f5c14626c9425cb30t stcb->asoc.timoshutdownack++; 18408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 18418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(4, inp, stcb, net); 18428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SHUT_ACK_TMR, SCTP_SO_NOT_LOCKED); 18448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 18468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoshutdownguard); 185047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_abort_an_association(inp, stcb, NULL, SCTP_SO_NOT_LOCKED); 18518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 18528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 18538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 18548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_STRRESET: 18558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_strreset_timer(inp, stcb, net)) { 18598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 18608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 18618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timostrmrst); 18638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_TMR, SCTP_SO_NOT_LOCKED); 18648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ASCONF: 18668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_asconf_timer(inp, stcb, net)) { 18708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock on tcb its gone */ 18718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_decr; 18728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoasconf); 18748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 18758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(4, inp, stcb, net); 18768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_ASCONF_TMR, SCTP_SO_NOT_LOCKED); 18788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_PRIM_DELETED: 18808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_delete_prim_timer(inp, stcb, net); 18848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timodelprim); 18858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 18878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_AUTOCLOSE: 18888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoautoclose); 18928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_autoclose_timer(inp, stcb, net); 18938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_AUTOCLOSE_TMR, SCTP_SO_NOT_LOCKED); 18948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen did_output = 0; 18958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ASOCKILL: 18978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 18988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoassockill); 19018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can we free it yet? */ 19028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 19038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL, SCTP_FROM_SCTPUTIL+SCTP_LOC_1); 19040612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 19058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(inp); 19068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 19078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 19088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 19098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 19108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 19118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL+SCTP_LOC_2); 19130612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 19148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 19158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 19178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * free asoc, always unlocks (or destroy's) so prevent 19188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * duplicate unlock or unlock of a free mtx :-0 19198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = NULL; 19218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_no_decr; 19228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_INPKILL: 19238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_timoinpkill); 19248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 19258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 19288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * special case, take away our increment since WE are the 19298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * killer 19308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 19328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL, SCTP_FROM_SCTPUTIL+SCTP_LOC_3); 19338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 19348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1); 19358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 19378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_FROM_INPKILL_TIMER); 19388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 19398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 1); 19408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = NULL; 19428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_no_decr; 19438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 19448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_TIMER1, "sctp_timeout_handler:unknown timer %d\n", 19458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->type); 19468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 1947b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen } 19488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_AUDITING_ENABLED 19498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_audit_log(0xF1, (uint8_t) tmr->type); 19508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) 19518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auditing(5, inp, stcb, net); 19528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((did_output) && stcb) { 19548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 19558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Now we need to clean up the control chunk chain if an 19568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ECNE is on it. It must be marked as UNSENT again so next 19578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * call will continue to send it until such time that we get 19588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a CWR, to remove it. It is, however, less likely that we 19598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * will find a ecn echo on the chain though. 19608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_fix_ecn_echo(&stcb->asoc); 19628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenget_out: 19648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 19658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 19668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenout_decr: 19698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 19708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 19718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenout_no_decr: 19748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type %d)\n", 19758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen type); 19768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 801000 19778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen CURVNET_RESTORE(); 19788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 19808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 19828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 19838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net) 19848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 19858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t to_ticks; 19868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_timer *tmr; 19878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL)) 19898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 19908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = NULL; 19928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 19938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK_ASSERT(stcb); 19948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (t_type) { 19968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ZERO_COPY: 19978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.zero_copy_timer; 19988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = SCTP_ZERO_COPY_TICK_DELAY; 19998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 20008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ZCOPY_SENDQ: 20018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.zero_copy_sendq_timer; 20028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = SCTP_ZERO_COPY_SENDQ_TICK_DELAY; 20038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 20048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ADDR_WQ: 20058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Only 1 tick away :-) */ 20068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &SCTP_BASE_INFO(addr_wq_timer); 20078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = SCTP_ADDRESS_TICK_DELAY; 20088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 20098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SEND: 20108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Here we use the RTO timer */ 20118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 20128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int rto_val; 20138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 20158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 20168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 20188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 20198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rto_val = stcb->asoc.initial_rto; 20208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 20218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rto_val = net->RTO; 20228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(rto_val); 20248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 20268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_INIT: 20278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 20288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here we use the INIT timer default usually about 1 20298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * minute. 20308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 20318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 20328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 20338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 20358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 20368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 20378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 20388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(net->RTO); 20398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 20418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_RECV: 20428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 20438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here we use the Delayed-Ack timer value from the inp 20448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ususually about 200ms. 20458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 20468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 20478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 20488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.dack_timer; 20508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.delayed_ack); 20518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 20528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWN: 20538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Here we use the RTO of the destination. */ 20548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 20558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 20568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 20588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 20598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 20608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(net->RTO); 20618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 20638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 20648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_HEARTBEAT: 20658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 20668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the net is used here so that we can add in the RTO. Even 20678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * though we use a different timer. We also add the HB timer 20688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * PLUS a random jitter. 20698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 20708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp == NULL) || (stcb == NULL) || (net == NULL)) { 20718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 20728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 20738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t rndval; 20748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t jitter; 20758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->dest_state & SCTP_ADDR_NOHB) && 20778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen !(net->dest_state & SCTP_ADDR_UNCONFIRMED)) { 20788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 20798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 20818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = stcb->asoc.initial_rto; 20828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 20838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = net->RTO; 20848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rndval = sctp_select_initial_TSN(&inp->sctp_ep); 20868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen jitter = rndval % to_ticks; 20878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (jitter >= (to_ticks >> 1)) { 20888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = to_ticks + (jitter - (to_ticks >> 1)); 20898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 20908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = to_ticks - jitter; 20918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) && 20938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen !(net->dest_state & SCTP_ADDR_PF)) { 20948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks += net->heart_beat_delay; 20958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 20978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Now we must convert the to_ticks that are now in 20988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ms to ticks. 20998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 21008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(to_ticks); 21018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->hb_timer; 21028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_COOKIE: 21058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 21068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here we can use the RTO timer from the network since one 21078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * RTT was compelete. If a retran happened then we will be 21088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * using the RTO initial value. 21098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 21108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 21118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 21148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 21158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 21168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(net->RTO); 21178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 21198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_NEWCOOKIE: 21218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 21228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * nothing needed but the endpoint here ususually about 60 21238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * minutes. 21248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 21258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 21268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.signature_change; 21298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE]; 21308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ASOCKILL: 21328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 21338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.strreset_timer; 21368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(SCTP_ASOC_KILL_TIMEOUT); 21378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_INPKILL: 21398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 21408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The inp is setup to die. We re-use the signature_chage 21418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * timer since that has stopped and we are in the GONE 21428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * state. 21438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 21448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 21458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.signature_change; 21488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT); 21498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_PATHMTURAISE: 21518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 21528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here we use the value found in the EP for PMTU ususually 21538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * about 10 minutes. 21548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 21558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (inp == NULL)) { 21568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net == NULL) { 21598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_NO_PMTUD) { 21628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU]; 21658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->pmtu_timer; 21668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWNACK: 21688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Here we use the RTO of the destination */ 21698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 21708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 21738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 21748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 21758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(net->RTO); 21768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 21788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 21808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 21818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here we use the endpoints shutdown guard timer usually 21828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * about 3 minutes. 21838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 21848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp == NULL) || (stcb == NULL)) { 21858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN]; 21888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.shut_guard_timer; 21898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_STRRESET: 21918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 21928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here the timer comes from the stcb but its value is from 21938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the net's RTO. 21948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 21958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 21968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 21978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 21998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 22008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 22018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(net->RTO); 22028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.strreset_timer; 22048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ASCONF: 22068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 22078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here the timer comes from the stcb but its value is from 22088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the net's RTO. 22098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 22108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 22118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO == 0) { 22148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 22158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 22168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(net->RTO); 22178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.asconf_timer; 22198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_PRIM_DELETED: 22218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net != NULL)) { 22228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 22258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.delete_prim_timer; 22268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_AUTOCLOSE: 22288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 22298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.sctp_autoclose_ticks == 0) { 22328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 22338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Really an error since stcb is NOT set to 22348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * autoclose 22358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 22368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to_ticks = stcb->asoc.sctp_autoclose_ticks; 22398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.autoclose_timer; 22408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 22428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_TIMER1, "%s: Unknown timer type %d\n", 22438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen __FUNCTION__, t_type); 22448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 2246b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen } 22478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((to_ticks <= 0) || (tmr == NULL)) { 22488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_TIMER1, "%s: %d:software error to_ticks:%d tmr:%p not set ??\n", 2249ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t __FUNCTION__, t_type, to_ticks, (void *)tmr); 22508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_OS_TIMER_PENDING(&tmr->timer)) { 22538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 22548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we do NOT allow you to have it already running. if it is 22558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we leave the current one up unchanged 22568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 22578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* At this point we can proceed */ 22608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (t_type == SCTP_TIMER_TYPE_SEND) { 22618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.num_send_timers_up++; 22628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = 0; 22648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->type = t_type; 22658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->ep = (void *)inp; 22668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->tcb = (void *)stcb; 22678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->net = (void *)net; 22688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->self = (void *)tmr; 22698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 22708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->vnet = (void *)curvnet; 22718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 22728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifndef __Panda__ 22738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->ticks = sctp_get_tick_count(); 22748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 22758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr); 22768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 22788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 22808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 22818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net, uint32_t from) 22828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 22838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_timer *tmr; 22848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) && 22868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp == NULL)) 22878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 22888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = NULL; 22908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 22918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK_ASSERT(stcb); 22928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (t_type) { 22948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ZERO_COPY: 22958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.zero_copy_timer; 22968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ZCOPY_SENDQ: 22988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.zero_copy_sendq_timer; 22998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ADDR_WQ: 23018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &SCTP_BASE_INFO(addr_wq_timer); 23028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SEND: 23048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 23058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 23088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_INIT: 23108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 23118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 23148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_RECV: 23168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 23178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.dack_timer; 23208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWN: 23228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 23238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 23268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_HEARTBEAT: 23288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 23298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->hb_timer; 23328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_COOKIE: 23348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 23358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 23388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_NEWCOOKIE: 23408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* nothing needed but the endpoint here */ 23418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.signature_change; 23428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 23438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We re-use the newcookie timer for the INP kill timer. We 23448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * must assure that we do not kill it by accident. 23458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 23468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ASOCKILL: 23488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 23498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Stop the asoc kill timer. 23508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 23518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 23528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.strreset_timer; 23558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_INPKILL: 23588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 23598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The inp is setup to die. We re-use the signature_chage 23608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * timer since that has stopped and we are in the GONE 23618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * state. 23628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 23638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &inp->sctp_ep.signature_change; 23648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_PATHMTURAISE: 23668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 23678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->pmtu_timer; 23708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWNACK: 23728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || (net == NULL)) { 23738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &net->rxt_timer; 23768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 23788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 23798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.shut_guard_timer; 23828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_STRRESET: 23848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 23858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.strreset_timer; 23888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_ASCONF: 23908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 23918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.asconf_timer; 23948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_PRIM_DELETED: 23968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 23978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 23988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.delete_prim_timer; 24008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMER_TYPE_AUTOCLOSE: 24028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 24038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 24048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr = &stcb->asoc.autoclose_timer; 24068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 24088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_TIMER1, "%s: Unknown timer type %d\n", 24098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen __FUNCTION__, t_type); 24108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 2411b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen } 24128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tmr == NULL) { 24138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 24148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((tmr->type != t_type) && tmr->type) { 24168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 24178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Ok we have a timer that is under joint use. Cookie timer 24188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * per chance with the SEND timer. We therefore are NOT 24198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * running the timer that the caller wants stopped. So just 24208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * return. 24218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 24228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 24238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((t_type == SCTP_TIMER_TYPE_SEND) && (stcb != NULL)) { 24258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.num_send_timers_up--; 24268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.num_send_timers_up < 0) { 24278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.num_send_timers_up = 0; 24288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->self = NULL; 24318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr->stopped_from = from; 24328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_OS_TIMER_STOP(&tmr->timer); 24338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 24348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 24358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 24378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_calculate_len(struct mbuf *m) 24388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 24398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t tlen = 0; 24408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *at; 24418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen at = m; 24438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (at) { 24448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tlen += SCTP_BUF_LEN(at); 24458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen at = SCTP_BUF_NEXT(at); 24468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (tlen); 24488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 24498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 24518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_mtu_size_reset(struct sctp_inpcb *inp, 24528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_association *asoc, uint32_t mtu) 24538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 24548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 24558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Reset the P-MTU size on this association, this involves changing 24568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the asoc MTU, going through ANY chunk+overhead larger than mtu to 24578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * allow the DF flag to be cleared. 24588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 24598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *chk; 24608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen unsigned int eff_mtu, ovh; 24618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->smallest_mtu = mtu; 24638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 24648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MIN_OVERHEAD; 24658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MIN_V4_OVERHEAD; 24678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen eff_mtu = mtu - ovh; 24698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) { 24708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->send_size > eff_mtu) { 24718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 24728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { 24758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->send_size > eff_mtu) { 24768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 24778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 24808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 24838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * given an association and starting time of the current RTT period return 24848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * RTO in number of msecs net should point to the current network 24858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 24868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 24888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_calculate_rto(struct sctp_tcb *stcb, 24898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_association *asoc, 24908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net, 24918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct timeval *told, 24928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int safe, int rtt_from_sack) 24938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 24948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*- 24958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * given an association and the starting time of the current RTT 24968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * period (in value1/value2) return RTO in number of msecs. 24978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 24988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int32_t rtt; /* RTT in ms */ 24998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t new_rto; 25008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int first_measure = 0; 25018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct timeval now, then, *old; 25028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Copy it out for sparc64 */ 25048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (safe == sctp_align_unsafe_makecopy) { 25058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen old = &then; 25068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&then, told, sizeof(struct timeval)); 25078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (safe == sctp_align_safe_nocopy) { 25088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen old = told; 25098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* error */ 25118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("Huh, bad rto calc call\n"); 25128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 25138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************/ 25158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 1. calculate new RTT */ 25168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************/ 25178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get the current time */ 25188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.use_precise_time) { 25198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETPTIME_TIMEVAL(&now); 25208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&now); 25228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen timevalsub(&now, old); 25248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* store the current RTT in us */ 25251349669d594d3cd36f3e28ce0f755c303f766723t net->rtt = (uint64_t)1000000 * (uint64_t)now.tv_sec + 25268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (uint64_t)now.tv_usec; 25278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* computer rtt in ms */ 25288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rtt = net->rtt / 1000; 2529b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((asoc->cc_functions.sctp_rtt_calculated) && (rtt_from_sack == SCTP_RTT_FROM_DATA)) { 25308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Tell the CC module that a new update has just occurred from a sack */ 25318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*asoc->cc_functions.sctp_rtt_calculated)(stcb, net, &now); 25328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Do we need to determine the lan? We do this only 25348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * on sacks i.e. RTT being determined from data not 25358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * non-data (HB/INIT->INITACK). 25368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 25378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((rtt_from_sack == SCTP_RTT_FROM_DATA) && 25388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->lan_type == SCTP_LAN_UNKNOWN)) { 25398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->rtt > SCTP_LOCAL_LAN_RTT) { 25408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->lan_type = SCTP_LAN_INTERNET; 25418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->lan_type = SCTP_LAN_LOCAL; 2543000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 25448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /***************************/ 25478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 2. update RTTVAR & SRTT */ 25488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /***************************/ 25498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*- 25508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Compute the scaled average lastsa and the 25518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * scaled variance lastsv as described in van Jacobson 25528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Paper "Congestion Avoidance and Control", Annex A. 25538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 25548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * (net->lastsa >> SCTP_RTT_SHIFT) is the srtt 25558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * (net->lastsa >> SCTP_RTT_VAR_SHIFT) is the rttvar 25568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 25578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->RTO_measured) { 25588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rtt -= (net->lastsa >> SCTP_RTT_SHIFT); 25598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->lastsa += rtt; 25608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (rtt < 0) { 25618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rtt = -rtt; 25628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rtt -= (net->lastsv >> SCTP_RTT_VAR_SHIFT); 25648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->lastsv += rtt; 25658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) { 25668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rto_logging(net, SCTP_LOG_RTTVAR); 25678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First RTO measurment */ 25708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->RTO_measured = 1; 25718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen first_measure = 1; 25728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->lastsa = rtt << SCTP_RTT_SHIFT; 25738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->lastsv = (rtt / 2) << SCTP_RTT_VAR_SHIFT; 25748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RTTVAR_LOGGING_ENABLE) { 25758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rto_logging(net, SCTP_LOG_INITIAL_RTT); 25768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->lastsv == 0) { 25798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->lastsv = SCTP_CLOCK_GRANULARITY; 25808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_rto = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv; 25828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((new_rto > SCTP_SAT_NETWORK_MIN) && 25838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.sat_network_lockout == 0)) { 25848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sat_network = 1; 25858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if ((!first_measure) && stcb->asoc.sat_network) { 25868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sat_network = 0; 25878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sat_network_lockout = 1; 25888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2589e2828360ea9cf8951730d46f5c14626c9425cb30t /* bound it, per C6/C7 in Section 5.3.1 */ 2590e2828360ea9cf8951730d46f5c14626c9425cb30t if (new_rto < stcb->asoc.minrto) { 25918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_rto = stcb->asoc.minrto; 25928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (new_rto > stcb->asoc.maxrto) { 25948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_rto = stcb->asoc.maxrto; 25958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we are now returning the RTO */ 2597e2828360ea9cf8951730d46f5c14626c9425cb30t return (new_rto); 25988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 25998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 26018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * return a pointer to a contiguous piece of data from the given mbuf chain 26028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * starting at 'off' for 'len' bytes. If the desired piece spans more than 26038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size 26048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain. 26058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 26068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexencaddr_t 26078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_m_getptr(struct mbuf *m, int off, int len, uint8_t * in_ptr) 26088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 26098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t count; 26108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *ptr; 26118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ptr = in_ptr; 26138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((off < 0) || (len <= 0)) 26148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 26158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* find the desired start location */ 26178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while ((m != NULL) && (off > 0)) { 26188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (off < SCTP_BUF_LEN(m)) 26198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen off -= SCTP_BUF_LEN(m); 26218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(m); 26228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m == NULL) 26248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 26258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is the current mbuf large enough (eg. contiguous)? */ 26278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_BUF_LEN(m) - off) >= len) { 26288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (mtod(m, caddr_t) + off); 26298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* else, it spans more than one mbuf, so save a temp copy... */ 26318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while ((m != NULL) && (len > 0)) { 26328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen count = min(SCTP_BUF_LEN(m) - off, len); 26338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bcopy(mtod(m, caddr_t) + off, ptr, count); 26348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len -= count; 26358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ptr += count; 26368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen off = 0; 26378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(m); 26388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((m == NULL) && (len > 0)) 26408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 26418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 26428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return ((caddr_t)in_ptr); 26438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 26458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct sctp_paramhdr * 26498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_get_next_param(struct mbuf *m, 26508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int offset, 26518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paramhdr *pull, 26528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int pull_limit) 26538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 26548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* This just provides a typed signature to Peter's Pull routine */ 26558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit, 26568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (uint8_t *) pull)); 26578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 26588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2660290e3870bdc4b436f18bfe30e6c243205fc29702tstruct mbuf * 26618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_add_pad_tombuf(struct mbuf *m, int padlen) 26628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 2663290e3870bdc4b436f18bfe30e6c243205fc29702t struct mbuf *m_last; 2664290e3870bdc4b436f18bfe30e6c243205fc29702t caddr_t dp; 26658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (padlen > 3) { 2667290e3870bdc4b436f18bfe30e6c243205fc29702t return (NULL); 26688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (padlen <= M_TRAILINGSPACE(m)) { 26708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 26718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The easy way. We hope the majority of the time we hit 26728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * here :) 26738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 2674290e3870bdc4b436f18bfe30e6c243205fc29702t m_last = m; 26758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 2676290e3870bdc4b436f18bfe30e6c243205fc29702t /* Hard way we must grow the mbuf chain */ 2677290e3870bdc4b436f18bfe30e6c243205fc29702t m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA); 2678290e3870bdc4b436f18bfe30e6c243205fc29702t if (m_last == NULL) { 2679290e3870bdc4b436f18bfe30e6c243205fc29702t return (NULL); 2680290e3870bdc4b436f18bfe30e6c243205fc29702t } 2681290e3870bdc4b436f18bfe30e6c243205fc29702t SCTP_BUF_LEN(m_last) = 0; 2682290e3870bdc4b436f18bfe30e6c243205fc29702t SCTP_BUF_NEXT(m_last) = NULL; 2683290e3870bdc4b436f18bfe30e6c243205fc29702t SCTP_BUF_NEXT(m) = m_last; 26848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2685290e3870bdc4b436f18bfe30e6c243205fc29702t dp = mtod(m_last, caddr_t) + SCTP_BUF_LEN(m_last); 2686290e3870bdc4b436f18bfe30e6c243205fc29702t SCTP_BUF_LEN(m_last) += padlen; 2687290e3870bdc4b436f18bfe30e6c243205fc29702t memset(dp, 0, padlen); 2688290e3870bdc4b436f18bfe30e6c243205fc29702t return (m_last); 26898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 26908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2691290e3870bdc4b436f18bfe30e6c243205fc29702tstruct mbuf * 26928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf) 26938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 26948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* find the last mbuf in chain and pad it */ 26958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_at; 26968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2697290e3870bdc4b436f18bfe30e6c243205fc29702t if (last_mbuf != NULL) { 26988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sctp_add_pad_tombuf(last_mbuf, padval)); 26998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27008f27eafd6937cbc8473a4b55a9c6fe8273d46523tuexen for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) { 27018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BUF_NEXT(m_at) == NULL) { 27028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sctp_add_pad_tombuf(m_at, padval)); 27038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2706290e3870bdc4b436f18bfe30e6c243205fc29702t return (NULL); 27078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 27088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 271047674b651417d493ff4e0318113fd7beeef119dbtuexensctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, 271147674b651417d493ff4e0318113fd7beeef119dbtuexen uint16_t error, struct sctp_abort_chunk *abort, uint8_t from_peer, int so_locked 27128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 27138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 27148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 27158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 27168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 27178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 27188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_change *sac; 27198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 272047674b651417d493ff4e0318113fd7beeef119dbtuexen size_t notif_len, abort_len; 272127c6a23c9dbbbe331f7a6b1ace5ffcb4055e2584tuexen unsigned int i; 27220612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 27238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 27248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 27258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 272647674b651417d493ff4e0318113fd7beeef119dbtuexen if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) { 272747674b651417d493ff4e0318113fd7beeef119dbtuexen notif_len = sizeof(struct sctp_assoc_change); 272847674b651417d493ff4e0318113fd7beeef119dbtuexen if (abort != NULL) { 27295310a647a74c51d125d106f350ff224bb017b0a5t abort_len = ntohs(abort->ch.chunk_length); 27308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 273147674b651417d493ff4e0318113fd7beeef119dbtuexen abort_len = 0; 273247674b651417d493ff4e0318113fd7beeef119dbtuexen } 273347674b651417d493ff4e0318113fd7beeef119dbtuexen if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) { 273447674b651417d493ff4e0318113fd7beeef119dbtuexen notif_len += SCTP_ASSOC_SUPPORTS_MAX; 273547674b651417d493ff4e0318113fd7beeef119dbtuexen } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) { 273647674b651417d493ff4e0318113fd7beeef119dbtuexen notif_len += abort_len; 273747674b651417d493ff4e0318113fd7beeef119dbtuexen } 273868beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 273947674b651417d493ff4e0318113fd7beeef119dbtuexen if (m_notify == NULL) { 274047674b651417d493ff4e0318113fd7beeef119dbtuexen /* Retry with smaller value. */ 274147674b651417d493ff4e0318113fd7beeef119dbtuexen notif_len = sizeof(struct sctp_assoc_change); 274268beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 274347674b651417d493ff4e0318113fd7beeef119dbtuexen if (m_notify == NULL) { 274447674b651417d493ff4e0318113fd7beeef119dbtuexen goto set_error; 274547674b651417d493ff4e0318113fd7beeef119dbtuexen } 27468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 274747674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_BUF_NEXT(m_notify) = NULL; 274847674b651417d493ff4e0318113fd7beeef119dbtuexen sac = mtod(m_notify, struct sctp_assoc_change *); 2749f496fe99adbad377f85add3a45e17f21a4702b41t memset(sac, 0, notif_len); 275047674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_type = SCTP_ASSOC_CHANGE; 275147674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_flags = 0; 275247674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_length = sizeof(struct sctp_assoc_change); 275347674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_state = state; 275447674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_error = error; 275547674b651417d493ff4e0318113fd7beeef119dbtuexen /* XXX verify these stream counts */ 275647674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_outbound_streams = stcb->asoc.streamoutcnt; 275747674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_inbound_streams = stcb->asoc.streamincnt; 275847674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_assoc_id = sctp_get_associd(stcb); 275947674b651417d493ff4e0318113fd7beeef119dbtuexen if (notif_len > sizeof(struct sctp_assoc_change)) { 276047674b651417d493ff4e0318113fd7beeef119dbtuexen if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) { 276147674b651417d493ff4e0318113fd7beeef119dbtuexen i = 0; 2762fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb->asoc.prsctp_supported == 1) { 276347674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR; 276447674b651417d493ff4e0318113fd7beeef119dbtuexen } 2765fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb->asoc.auth_supported == 1) { 276647674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH; 276747674b651417d493ff4e0318113fd7beeef119dbtuexen } 2768fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb->asoc.asconf_supported == 1) { 276947674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF; 277047674b651417d493ff4e0318113fd7beeef119dbtuexen } 277147674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF; 2772fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb->asoc.reconfig_supported == 1) { 277347674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG; 277447674b651417d493ff4e0318113fd7beeef119dbtuexen } 277547674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_length += i; 277647674b651417d493ff4e0318113fd7beeef119dbtuexen } else if ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC)) { 277747674b651417d493ff4e0318113fd7beeef119dbtuexen memcpy(sac->sac_info, abort, abort_len); 277847674b651417d493ff4e0318113fd7beeef119dbtuexen sac->sac_length += abort_len; 27798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 278147674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_BUF_LEN(m_notify) = sac->sac_length; 278247674b651417d493ff4e0318113fd7beeef119dbtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 2783f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t 0, 0, stcb->asoc.context, 0, 0, 0, 2784f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t m_notify); 278547674b651417d493ff4e0318113fd7beeef119dbtuexen if (control != NULL) { 278647674b651417d493ff4e0318113fd7beeef119dbtuexen control->length = SCTP_BUF_LEN(m_notify); 278747674b651417d493ff4e0318113fd7beeef119dbtuexen /* not that we need this */ 278847674b651417d493ff4e0318113fd7beeef119dbtuexen control->tail_mbuf = m_notify; 278947674b651417d493ff4e0318113fd7beeef119dbtuexen control->spec_flags = M_NOTIFICATION; 279047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 2791f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t control, 2792f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, 2793f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t so_locked); 279447674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 279547674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_m_freem(m_notify); 27968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 279847674b651417d493ff4e0318113fd7beeef119dbtuexen /* 279947674b651417d493ff4e0318113fd7beeef119dbtuexen * For 1-to-1 style sockets, we send up and error when an ABORT 280047674b651417d493ff4e0318113fd7beeef119dbtuexen * comes in. 280147674b651417d493ff4e0318113fd7beeef119dbtuexen */ 280247674b651417d493ff4e0318113fd7beeef119dbtuexenset_error: 280347674b651417d493ff4e0318113fd7beeef119dbtuexen if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 280447674b651417d493ff4e0318113fd7beeef119dbtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && 280547674b651417d493ff4e0318113fd7beeef119dbtuexen ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) { 2806ac641287e0df6fd0b0ede6a7bd9d2932c13b5c58t SOCK_LOCK(stcb->sctp_socket); 280747674b651417d493ff4e0318113fd7beeef119dbtuexen if (from_peer) { 280847674b651417d493ff4e0318113fd7beeef119dbtuexen if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) { 280947674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED); 281047674b651417d493ff4e0318113fd7beeef119dbtuexen stcb->sctp_socket->so_error = ECONNREFUSED; 281147674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 281247674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET); 281347674b651417d493ff4e0318113fd7beeef119dbtuexen stcb->sctp_socket->so_error = ECONNRESET; 28148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 281547674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 2816682e11ee64158de5e65420faf52a7f6eaed92625t if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) || 2817682e11ee64158de5e65420faf52a7f6eaed92625t (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) { 2818682e11ee64158de5e65420faf52a7f6eaed92625t SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT); 2819682e11ee64158de5e65420faf52a7f6eaed92625t stcb->sctp_socket->so_error = ETIMEDOUT; 2820682e11ee64158de5e65420faf52a7f6eaed92625t } else { 2821682e11ee64158de5e65420faf52a7f6eaed92625t SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED); 2822682e11ee64158de5e65420faf52a7f6eaed92625t stcb->sctp_socket->so_error = ECONNABORTED; 2823682e11ee64158de5e65420faf52a7f6eaed92625t } 28248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 282547674b651417d493ff4e0318113fd7beeef119dbtuexen } 282647674b651417d493ff4e0318113fd7beeef119dbtuexen /* Wake ANY sleepers */ 28270612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 282847674b651417d493ff4e0318113fd7beeef119dbtuexen so = SCTP_INP_SO(stcb->sctp_ep); 282947674b651417d493ff4e0318113fd7beeef119dbtuexen if (!so_locked) { 283047674b651417d493ff4e0318113fd7beeef119dbtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 283147674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_TCB_UNLOCK(stcb); 283247674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_SOCKET_LOCK(so, 1); 283347674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_TCB_LOCK(stcb); 283447674b651417d493ff4e0318113fd7beeef119dbtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 283547674b651417d493ff4e0318113fd7beeef119dbtuexen if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { 28368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 283747674b651417d493ff4e0318113fd7beeef119dbtuexen return; 28388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 283947674b651417d493ff4e0318113fd7beeef119dbtuexen } 28408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 284147674b651417d493ff4e0318113fd7beeef119dbtuexen if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 284247674b651417d493ff4e0318113fd7beeef119dbtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && 284347674b651417d493ff4e0318113fd7beeef119dbtuexen ((state == SCTP_COMM_LOST) || (state == SCTP_CANT_STR_ASSOC))) { 2844ac641287e0df6fd0b0ede6a7bd9d2932c13b5c58t#if defined(__APPLE__) 284547674b651417d493ff4e0318113fd7beeef119dbtuexen socantrcvmore(stcb->sctp_socket); 2846ac641287e0df6fd0b0ede6a7bd9d2932c13b5c58t#else 2847ac641287e0df6fd0b0ede6a7bd9d2932c13b5c58t socantrcvmore_locked(stcb->sctp_socket); 2848ac641287e0df6fd0b0ede6a7bd9d2932c13b5c58t#endif 28498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 285047674b651417d493ff4e0318113fd7beeef119dbtuexen sorwakeup(stcb->sctp_socket); 285147674b651417d493ff4e0318113fd7beeef119dbtuexen sowwakeup(stcb->sctp_socket); 28520612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 285347674b651417d493ff4e0318113fd7beeef119dbtuexen if (!so_locked) { 285447674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_SOCKET_UNLOCK(so, 1); 285547674b651417d493ff4e0318113fd7beeef119dbtuexen } 285647674b651417d493ff4e0318113fd7beeef119dbtuexen#endif 28578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 28588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 28608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state, 28618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa, uint32_t error) 28628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 28638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 28648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddr_change *spc; 28658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 28668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2867b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb == NULL) || 2868b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) { 28698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 28708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 28718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 287268beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_NOWAIT, 1, MT_DATA); 28738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) 28748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 28758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 28768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen spc = mtod(m_notify, struct sctp_paddr_change *); 28771fb710c36aa9c19e470ebc5c5974879871f7e221t memset(spc, 0, sizeof(struct sctp_paddr_change)); 28788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen spc->spc_type = SCTP_PEER_ADDR_CHANGE; 28798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen spc->spc_flags = 0; 28808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen spc->spc_length = sizeof(struct sctp_paddr_change); 28818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sa->sa_family) { 28828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 28838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 28848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in)); 28858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 28878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 28888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 28898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_EMBEDDED_V6_SCOPE 28918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 28928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 28938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6)); 28948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_EMBEDDED_V6_SCOPE 28968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr; 28978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) { 28988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin6->sin6_scope_id == 0) { 28998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* recover scope_id for user */ 29008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 2901e2828360ea9cf8951730d46f5c14626c9425cb30t (void)sa6_recoverscope(sin6); 29028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 29038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)in6_recoverscope(sin6, &sin6->sin6_addr, 29048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL); 29058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* clear embedded scope_id for user */ 29088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_clearscope(&sin6->sin6_addr); 29098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 29128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 291566e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 291666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 291766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_conn)); 291866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 291966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 29208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 29218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TSNH */ 29228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen spc->spc_state = state; 29258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen spc->spc_error = error; 29268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen spc->spc_assoc_id = sctp_get_associd(stcb); 29278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_paddr_change); 29298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = NULL; 29308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 29328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 29330ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 29340ac02f34d6041cd0018437596a5a9a94685e6919tuexen m_notify); 29358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 29368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 29378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 29388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 29398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = SCTP_BUF_LEN(m_notify); 29418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 29428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not that we need this */ 29438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_notify; 29448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 2945f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t control, 2946f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t &stcb->sctp_socket->so_rcv, 1, 2947f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t SCTP_READ_LOCK_NOT_HELD, 2948f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t SCTP_SO_NOT_LOCKED); 29498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 29508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 295347674b651417d493ff4e0318113fd7beeef119dbtuexensctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, 29548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *chk, int so_locked 29558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 29568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 29578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 29598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 29608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 29618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_send_failed *ssf; 29625741e159bdf238ef4b61085d6fbfea2947386238tuexen struct sctp_send_failed_event *ssfe; 29638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 29648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int length; 29658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2966b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb == NULL) || 29675741e159bdf238ef4b61085d6fbfea2947386238tuexen (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && 29685741e159bdf238ef4b61085d6fbfea2947386238tuexen sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) { 29698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 29708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 29718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29735741e159bdf238ef4b61085d6fbfea2947386238tuexen if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 29745741e159bdf238ef4b61085d6fbfea2947386238tuexen length = sizeof(struct sctp_send_failed_event); 29755741e159bdf238ef4b61085d6fbfea2947386238tuexen } else { 29765741e159bdf238ef4b61085d6fbfea2947386238tuexen length = sizeof(struct sctp_send_failed); 29775741e159bdf238ef4b61085d6fbfea2947386238tuexen } 297868beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(length, 0, M_NOWAIT, 1, MT_DATA); 29798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) 29808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 29818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 29828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 29835741e159bdf238ef4b61085d6fbfea2947386238tuexen if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 29845741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe = mtod(m_notify, struct sctp_send_failed_event *); 2985f496fe99adbad377f85add3a45e17f21a4702b41t memset(ssfe, 0, length); 29865741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT; 298747674b651417d493ff4e0318113fd7beeef119dbtuexen if (sent) { 29885741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_flags = SCTP_DATA_SENT; 298947674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 299047674b651417d493ff4e0318113fd7beeef119dbtuexen ssfe->ssfe_flags = SCTP_DATA_UNSENT; 299147674b651417d493ff4e0318113fd7beeef119dbtuexen } 2992f496fe99adbad377f85add3a45e17f21a4702b41t length += chk->send_size; 2993f496fe99adbad377f85add3a45e17f21a4702b41t length -= sizeof(struct sctp_data_chunk); 29945741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_length = length; 29955741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_error = error; 29965741e159bdf238ef4b61085d6fbfea2947386238tuexen /* not exactly what the user sent in, but should be close :) */ 29975741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number; 29985741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags; 29995741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype; 30005741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_context = chk->rec.data.context; 30015741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb); 30025741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_assoc_id = sctp_get_associd(stcb); 30035741e159bdf238ef4b61085d6fbfea2947386238tuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event); 30045741e159bdf238ef4b61085d6fbfea2947386238tuexen } else { 30055741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf = mtod(m_notify, struct sctp_send_failed *); 3006f496fe99adbad377f85add3a45e17f21a4702b41t memset(ssf, 0, length); 30075741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_type = SCTP_SEND_FAILED; 300847674b651417d493ff4e0318113fd7beeef119dbtuexen if (sent) { 30095741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_flags = SCTP_DATA_SENT; 301047674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 301147674b651417d493ff4e0318113fd7beeef119dbtuexen ssf->ssf_flags = SCTP_DATA_UNSENT; 301247674b651417d493ff4e0318113fd7beeef119dbtuexen } 3013f496fe99adbad377f85add3a45e17f21a4702b41t length += chk->send_size; 3014f496fe99adbad377f85add3a45e17f21a4702b41t length -= sizeof(struct sctp_data_chunk); 30155741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_length = length; 30165741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_error = error; 30175741e159bdf238ef4b61085d6fbfea2947386238tuexen /* not exactly what the user sent in, but should be close :) */ 30185741e159bdf238ef4b61085d6fbfea2947386238tuexen bzero(&ssf->ssf_info, sizeof(ssf->ssf_info)); 30195741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number; 30205741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq; 30215741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags; 30225741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype; 30235741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_context = chk->rec.data.context; 30245741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb); 30255741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_assoc_id = sctp_get_associd(stcb); 30265741e159bdf238ef4b61085d6fbfea2947386238tuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed); 30275741e159bdf238ef4b61085d6fbfea2947386238tuexen } 30288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->data) { 30298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 30308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * trim off the sctp chunk header(it should 30318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * be there) 30328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 30338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->send_size >= sizeof(struct sctp_data_chunk)) { 30348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_adj(chk->data, sizeof(struct sctp_data_chunk)); 30358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_mbuf_crush(chk->data); 30368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->send_size -= sizeof(struct sctp_data_chunk); 30378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = chk->data; 30408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Steal off the mbuf */ 30418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->data = NULL; 30428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 30438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For this case, we check the actual socket buffer, since the assoc 30448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is going away we don't want to overfill the socket buffer for a 30458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * non-reader 30468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 30478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 30488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 30498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 30508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 30528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 30530ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 30548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_notify); 30558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 30568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 30578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 30588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 30598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 30618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 30628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control, 30638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->sctp_socket->so_rcv, 1, 30648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_READ_LOCK_NOT_HELD, 30658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so_locked); 30668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 30678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 30708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error, 30718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_queue_pending *sp, int so_locked 30728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 30738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 30748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 30758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 30768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 30778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 30788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_send_failed *ssf; 30795741e159bdf238ef4b61085d6fbfea2947386238tuexen struct sctp_send_failed_event *ssfe; 30808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 30818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int length; 30828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3083b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb == NULL) || 30845741e159bdf238ef4b61085d6fbfea2947386238tuexen (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && 30855741e159bdf238ef4b61085d6fbfea2947386238tuexen sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) { 30868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 30878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 30888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30895741e159bdf238ef4b61085d6fbfea2947386238tuexen if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 30905741e159bdf238ef4b61085d6fbfea2947386238tuexen length = sizeof(struct sctp_send_failed_event); 30915741e159bdf238ef4b61085d6fbfea2947386238tuexen } else { 30925741e159bdf238ef4b61085d6fbfea2947386238tuexen length = sizeof(struct sctp_send_failed); 30935741e159bdf238ef4b61085d6fbfea2947386238tuexen } 309468beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(length, 0, M_NOWAIT, 1, MT_DATA); 30955741e159bdf238ef4b61085d6fbfea2947386238tuexen if (m_notify == NULL) { 30968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 30978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 30985741e159bdf238ef4b61085d6fbfea2947386238tuexen } 30998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 31005741e159bdf238ef4b61085d6fbfea2947386238tuexen if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { 31015741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe = mtod(m_notify, struct sctp_send_failed_event *); 3102f496fe99adbad377f85add3a45e17f21a4702b41t memset(ssfe, 0, length); 3103f869e438447cc860e3c4bb11795ed58f30f30c36tuexen ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT; 310447674b651417d493ff4e0318113fd7beeef119dbtuexen ssfe->ssfe_flags = SCTP_DATA_UNSENT; 3105f496fe99adbad377f85add3a45e17f21a4702b41t length += sp->length; 31065741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_length = length; 31075741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_error = error; 31085741e159bdf238ef4b61085d6fbfea2947386238tuexen /* not exactly what the user sent in, but should be close :) */ 31095741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_sid = sp->stream; 31105741e159bdf238ef4b61085d6fbfea2947386238tuexen if (sp->some_taken) { 31115741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG; 31125741e159bdf238ef4b61085d6fbfea2947386238tuexen } else { 31135741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_flags = SCTP_DATA_NOT_FRAG; 31145741e159bdf238ef4b61085d6fbfea2947386238tuexen } 31155741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_ppid = sp->ppid; 31165741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_context = sp->context; 31175741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb); 31185741e159bdf238ef4b61085d6fbfea2947386238tuexen ssfe->ssfe_assoc_id = sctp_get_associd(stcb); 31195741e159bdf238ef4b61085d6fbfea2947386238tuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event); 31208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31215741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf = mtod(m_notify, struct sctp_send_failed *); 3122f496fe99adbad377f85add3a45e17f21a4702b41t memset(ssf, 0, length); 31235741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_type = SCTP_SEND_FAILED; 312447674b651417d493ff4e0318113fd7beeef119dbtuexen ssf->ssf_flags = SCTP_DATA_UNSENT; 3125f496fe99adbad377f85add3a45e17f21a4702b41t length += sp->length; 31265741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_length = length; 31275741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_error = error; 31285741e159bdf238ef4b61085d6fbfea2947386238tuexen /* not exactly what the user sent in, but should be close :) */ 31295741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_stream = sp->stream; 3130e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t ssf->ssf_info.sinfo_ssn = 0; 31315741e159bdf238ef4b61085d6fbfea2947386238tuexen if (sp->some_taken) { 31325741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG; 31335741e159bdf238ef4b61085d6fbfea2947386238tuexen } else { 31345741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_flags = SCTP_DATA_NOT_FRAG; 31355741e159bdf238ef4b61085d6fbfea2947386238tuexen } 31365741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_ppid = sp->ppid; 31375741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_context = sp->context; 31385741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb); 31395741e159bdf238ef4b61085d6fbfea2947386238tuexen ssf->ssf_assoc_id = sctp_get_associd(stcb); 31405741e159bdf238ef4b61085d6fbfea2947386238tuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed); 31418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = sp->data; 31438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Steal off the mbuf */ 31458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp->data = NULL; 31468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 31478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For this case, we check the actual socket buffer, since the assoc 31488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is going away we don't want to overfill the socket buffer for a 31498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * non-reader 31508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 31518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 31528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 31538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 31548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 31568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 31570ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 31580ac02f34d6041cd0018437596a5a9a94685e6919tuexen m_notify); 31598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 31608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 31618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 31628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 31638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 31658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 31668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control, 31678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked); 31688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 31698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 31730ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_notify_adaptation_layer(struct sctp_tcb *stcb) 31748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 31758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 31768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_adaptation_event *sai; 31778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 31788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3179b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb == NULL) || 3180b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) { 31818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 31828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 31838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3184000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 318568beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_NOWAIT, 1, MT_DATA); 31868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) 31878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 31888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 31898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 31908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sai = mtod(m_notify, struct sctp_adaptation_event *); 3191f496fe99adbad377f85add3a45e17f21a4702b41t memset(sai, 0, sizeof(struct sctp_adaptation_event)); 31928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sai->sai_type = SCTP_ADAPTATION_INDICATION; 31938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sai->sai_flags = 0; 31948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sai->sai_length = sizeof(struct sctp_adaptation_event); 31958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sai->sai_adaptation_ind = stcb->asoc.peers_adaptation; 31968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sai->sai_assoc_id = sctp_get_associd(stcb); 31978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_adaptation_event); 31998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = NULL; 32008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 32028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 32030ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 32040ac02f34d6041cd0018437596a5a9a94685e6919tuexen m_notify); 32058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 32068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 32078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 32088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 32098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = SCTP_BUF_LEN(m_notify); 32118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 32128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not that we need this */ 32138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_notify; 32148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 32158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control, 32168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 32178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 32188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* This always must be called with the read-queue LOCKED in the INP */ 32208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 32218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error, 32228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t val, int so_locked 32238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 32248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 32258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 32268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 32278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 32288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 32298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_pdapi_event *pdapi; 32308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 32318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockbuf *sb; 32328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3233b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb == NULL) || 3234b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) { 32358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 32368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 32378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { 32398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 32408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3241000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 324268beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_NOWAIT, 1, MT_DATA); 32438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) 32448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 32458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 32468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 32478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi = mtod(m_notify, struct sctp_pdapi_event *); 3248f496fe99adbad377f85add3a45e17f21a4702b41t memset(pdapi, 0, sizeof(struct sctp_pdapi_event)); 32498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT; 32508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi->pdapi_flags = 0; 32518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi->pdapi_length = sizeof(struct sctp_pdapi_event); 32528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi->pdapi_indication = error; 32538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi->pdapi_stream = (val >> 16); 32548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi->pdapi_seq = (val & 0x0000ffff); 32558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pdapi->pdapi_assoc_id = sctp_get_associd(stcb); 32568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event); 32588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = NULL; 32598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 32600ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 32618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_notify); 32628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 32638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 32648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 32658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 32668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 32688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = SCTP_BUF_LEN(m_notify); 32698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not that we need this */ 32708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_notify; 32718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = 0; 32728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = 0; 32738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sb = &stcb->sctp_socket->so_rcv; 32748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 32758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify)); 32768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sballoc(stcb, sb, m_notify); 32788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 32798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0); 32808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&control->length, SCTP_BUF_LEN(m_notify)); 32828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->end_added = 1; 32838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.control_pdapi) 32848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi, control, next); 32858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else { 32868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we really should not see this case */ 32878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INSERT_TAIL(&stcb->sctp_ep->read_queue, control, next); 32888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep && stcb->sctp_socket) { 32908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* This should always be the case */ 32910612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 32928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 32938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(stcb->sctp_ep); 32958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 32968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 32978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 32988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 32998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 33008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 33018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 33028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 33038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 33048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 33078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 33080612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 33098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 33108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 33118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 33138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 33158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 33178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify_shutdown_event(struct sctp_tcb *stcb) 33188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 33198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 33208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_shutdown_event *sse; 33218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 33228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 33248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For TCP model AND UDP connected sockets we will send an error up 33258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * when an SHUTDOWN completes 33268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 33278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 33288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 33298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* mark socket closed for read/write and wakeup! */ 33300612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 33318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 3332000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 33338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(stcb->sctp_ep); 33348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 33358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 33378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 33388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 33398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { 33408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 33418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 3342000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 33438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 33448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen socantsendmore(stcb->sctp_socket); 33450612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 33468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 33478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 33488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) { 33508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 33518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 33528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3353000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 335468beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 0, M_NOWAIT, 1, MT_DATA); 33558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) 33568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 33578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 33588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sse = mtod(m_notify, struct sctp_shutdown_event *); 3359f496fe99adbad377f85add3a45e17f21a4702b41t memset(sse, 0, sizeof(struct sctp_shutdown_event)); 33608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sse->sse_type = SCTP_SHUTDOWN_EVENT; 33618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sse->sse_flags = 0; 33628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sse->sse_length = sizeof(struct sctp_shutdown_event); 33638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sse->sse_assoc_id = sctp_get_associd(stcb); 33648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_shutdown_event); 33668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = NULL; 33678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 33698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 33700ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 33710ac02f34d6041cd0018437596a5a9a94685e6919tuexen m_notify); 33728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 33738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 33748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 33758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 33768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 33788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = SCTP_BUF_LEN(m_notify); 33798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not that we need this */ 33808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_notify; 33818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 33828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control, 33838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 33848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 33858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 33878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify_sender_dry_event(struct sctp_tcb *stcb, 33888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int so_locked 33898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 33908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 33918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 33928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 33938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 33948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 33958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sender_dry_event *event; 33968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 33978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3398b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb == NULL) || 3399b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) { 34008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 34018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 34028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3403000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 340468beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_sender_dry_event), 0, M_NOWAIT, 1, MT_DATA); 34058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) { 34068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 34078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 34088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 34108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event = mtod(m_notify, struct sctp_sender_dry_event *); 3411f496fe99adbad377f85add3a45e17f21a4702b41t memset(event, 0, sizeof(struct sctp_sender_dry_event)); 34128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->sender_dry_type = SCTP_SENDER_DRY_EVENT; 34138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->sender_dry_flags = 0; 34148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->sender_dry_length = sizeof(struct sctp_sender_dry_event); 34158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->sender_dry_assoc_id = sctp_get_associd(stcb); 34168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_sender_dry_event); 34188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = NULL; 34198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 34218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 34220ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 34230ac02f34d6041cd0018437596a5a9a94685e6919tuexen m_notify); 34248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 34258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 34268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 34278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 34288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = SCTP_BUF_LEN(m_notify); 34308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 34318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not that we need this */ 34328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_notify; 34338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, control, 34348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked); 34358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 34368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3438c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexenvoid 3439c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexensctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t numberout, int flag) 34408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 34418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 34428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 3443c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct sctp_stream_change_event *stradd; 34448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34458a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen if ((stcb == NULL) || 34468a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) { 34478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 34488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 34498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3450c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((stcb->asoc.peer_req_out) && flag) { 3451c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* Peer made the request, don't tell the local user */ 3452c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stcb->asoc.peer_req_out = 0; 3453c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen return; 3454c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 3455c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stcb->asoc.peer_req_out = 0; 3456f496fe99adbad377f85add3a45e17f21a4702b41t m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA); 34578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) 34588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 34598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 34608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 3461c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stradd = mtod(m_notify, struct sctp_stream_change_event *); 3462f496fe99adbad377f85add3a45e17f21a4702b41t memset(stradd, 0, sizeof(struct sctp_stream_change_event)); 3463c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT; 3464c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stradd->strchange_flags = flag; 3465f496fe99adbad377f85add3a45e17f21a4702b41t stradd->strchange_length = sizeof(struct sctp_stream_change_event); 3466c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stradd->strchange_assoc_id = sctp_get_associd(stcb); 3467c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stradd->strchange_instrms = numberin; 3468c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen stradd->strchange_outstrms = numberout; 3469f496fe99adbad377f85add3a45e17f21a4702b41t SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event); 3470c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_BUF_NEXT(m_notify) = NULL; 3471c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 3472c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* no space */ 3473c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen sctp_m_freem(m_notify); 3474c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen return; 3475c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 3476c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* append to socket */ 3477c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 3478c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 0, 0, stcb->asoc.context, 0, 0, 0, 3479c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen m_notify); 3480c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (control == NULL) { 3481c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* no memory */ 3482c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen sctp_m_freem(m_notify); 3483c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen return; 3484c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 3485c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen control->spec_flags = M_NOTIFICATION; 3486c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen control->length = SCTP_BUF_LEN(m_notify); 3487c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* not that we need this */ 3488c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen control->tail_mbuf = m_notify; 3489c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 3490c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen control, 3491c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 3492c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen} 3493c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 3494c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexenvoid 3495c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexensctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32_t recv_tsn, int flag) 3496c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen{ 3497c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct mbuf *m_notify; 3498c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct sctp_queued_to_read *control; 3499c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct sctp_assoc_reset_event *strasoc; 35008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35018a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen if ((stcb == NULL) || 35028a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) { 3503c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* event not enabled */ 3504c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen return; 3505c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 3506f496fe99adbad377f85add3a45e17f21a4702b41t m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA); 3507c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (m_notify == NULL) 3508c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* no space left */ 3509c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen return; 3510c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_BUF_LEN(m_notify) = 0; 3511c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strasoc = mtod(m_notify, struct sctp_assoc_reset_event *); 3512f496fe99adbad377f85add3a45e17f21a4702b41t memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event)); 3513c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT; 3514c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strasoc->assocreset_flags = flag; 3515f496fe99adbad377f85add3a45e17f21a4702b41t strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event); 3516c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strasoc->assocreset_assoc_id= sctp_get_associd(stcb); 3517c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strasoc->assocreset_local_tsn = sending_tsn; 3518c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strasoc->assocreset_remote_tsn = recv_tsn; 3519f496fe99adbad377f85add3a45e17f21a4702b41t SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event); 35208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = NULL; 35218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 35228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space */ 35238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 35248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 35258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 35278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 35280ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 35290ac02f34d6041cd0018437596a5a9a94685e6919tuexen m_notify); 35308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 35318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 35328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 35338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 35348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 35368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = SCTP_BUF_LEN(m_notify); 35378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not that we need this */ 35388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_notify; 35398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 35408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control, 35418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 35428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 35438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3545c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 35468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 35478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify_stream_reset(struct sctp_tcb *stcb, 35488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int number_entries, uint16_t * list, int flag) 35498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 35508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_notify; 35518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control; 35528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_reset_event *strreset; 35538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int len; 3554a067b45afc762b4afd08065d3f61ee251f53f018tuexen 35558a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen if ((stcb == NULL) || 35568a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT))) { 35578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* event not enabled */ 35588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 35598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3560000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 356168beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA); 35628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m_notify == NULL) 35638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space left */ 35648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 35658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = 0; 35668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t)); 35678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (len > M_TRAILINGSPACE(m_notify)) { 35688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* never enough room */ 35698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 35708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 35718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen strreset = mtod(m_notify, struct sctp_stream_reset_event *); 3573f496fe99adbad377f85add3a45e17f21a4702b41t memset(strreset, 0, len); 35748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen strreset->strreset_type = SCTP_STREAM_RESET_EVENT; 3575c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strreset->strreset_flags = flag; 35768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen strreset->strreset_length = len; 35778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen strreset->strreset_assoc_id = sctp_get_associd(stcb); 35788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (number_entries) { 35798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 35808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < number_entries; i++) { 3582c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strreset->strreset_stream_list[i] = ntohs(list[i]); 35838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m_notify) = len; 35868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(m_notify) = NULL; 35878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) { 35888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no space */ 35898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 35908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 35918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append to socket */ 35938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 35940ac02f34d6041cd0018437596a5a9a94685e6919tuexen 0, 0, stcb->asoc.context, 0, 0, 0, 35950ac02f34d6041cd0018437596a5a9a94685e6919tuexen m_notify); 35968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 35978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory */ 35988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m_notify); 35998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 36008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->spec_flags = M_NOTIFICATION; 36028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = SCTP_BUF_LEN(m_notify); 36038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not that we need this */ 36048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_notify; 36058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 36068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control, 36078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 36088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 36098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 361147674b651417d493ff4e0318113fd7beeef119dbtuexenstatic void 361247674b651417d493ff4e0318113fd7beeef119dbtuexensctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_error_chunk *chunk) 361347674b651417d493ff4e0318113fd7beeef119dbtuexen{ 361447674b651417d493ff4e0318113fd7beeef119dbtuexen struct mbuf *m_notify; 361547674b651417d493ff4e0318113fd7beeef119dbtuexen struct sctp_remote_error *sre; 361647674b651417d493ff4e0318113fd7beeef119dbtuexen struct sctp_queued_to_read *control; 361747674b651417d493ff4e0318113fd7beeef119dbtuexen size_t notif_len, chunk_len; 361847674b651417d493ff4e0318113fd7beeef119dbtuexen 361947674b651417d493ff4e0318113fd7beeef119dbtuexen if ((stcb == NULL) || 362047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) { 362147674b651417d493ff4e0318113fd7beeef119dbtuexen return; 362247674b651417d493ff4e0318113fd7beeef119dbtuexen } 362347674b651417d493ff4e0318113fd7beeef119dbtuexen if (chunk != NULL) { 36245310a647a74c51d125d106f350ff224bb017b0a5t chunk_len = ntohs(chunk->ch.chunk_length); 362547674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 362647674b651417d493ff4e0318113fd7beeef119dbtuexen chunk_len = 0; 362747674b651417d493ff4e0318113fd7beeef119dbtuexen } 362847674b651417d493ff4e0318113fd7beeef119dbtuexen notif_len = sizeof(struct sctp_remote_error) + chunk_len; 362968beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 363047674b651417d493ff4e0318113fd7beeef119dbtuexen if (m_notify == NULL) { 363147674b651417d493ff4e0318113fd7beeef119dbtuexen /* Retry with smaller value. */ 363247674b651417d493ff4e0318113fd7beeef119dbtuexen notif_len = sizeof(struct sctp_remote_error); 363368beeca578347438d9c434680197647ed551935ft m_notify = sctp_get_mbuf_for_msg(notif_len, 0, M_NOWAIT, 1, MT_DATA); 363447674b651417d493ff4e0318113fd7beeef119dbtuexen if (m_notify == NULL) { 363547674b651417d493ff4e0318113fd7beeef119dbtuexen return; 363647674b651417d493ff4e0318113fd7beeef119dbtuexen } 363747674b651417d493ff4e0318113fd7beeef119dbtuexen } 363847674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_BUF_NEXT(m_notify) = NULL; 363947674b651417d493ff4e0318113fd7beeef119dbtuexen sre = mtod(m_notify, struct sctp_remote_error *); 36401fb710c36aa9c19e470ebc5c5974879871f7e221t memset(sre, 0, notif_len); 364147674b651417d493ff4e0318113fd7beeef119dbtuexen sre->sre_type = SCTP_REMOTE_ERROR; 364247674b651417d493ff4e0318113fd7beeef119dbtuexen sre->sre_flags = 0; 364347674b651417d493ff4e0318113fd7beeef119dbtuexen sre->sre_length = sizeof(struct sctp_remote_error); 364447674b651417d493ff4e0318113fd7beeef119dbtuexen sre->sre_error = error; 364547674b651417d493ff4e0318113fd7beeef119dbtuexen sre->sre_assoc_id = sctp_get_associd(stcb); 364647674b651417d493ff4e0318113fd7beeef119dbtuexen if (notif_len > sizeof(struct sctp_remote_error)) { 364747674b651417d493ff4e0318113fd7beeef119dbtuexen memcpy(sre->sre_data, chunk, chunk_len); 364847674b651417d493ff4e0318113fd7beeef119dbtuexen sre->sre_length += chunk_len; 364947674b651417d493ff4e0318113fd7beeef119dbtuexen } 365047674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_BUF_LEN(m_notify) = sre->sre_length; 365147674b651417d493ff4e0318113fd7beeef119dbtuexen control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination, 365247674b651417d493ff4e0318113fd7beeef119dbtuexen 0, 0, stcb->asoc.context, 0, 0, 0, 365347674b651417d493ff4e0318113fd7beeef119dbtuexen m_notify); 365447674b651417d493ff4e0318113fd7beeef119dbtuexen if (control != NULL) { 365547674b651417d493ff4e0318113fd7beeef119dbtuexen control->length = SCTP_BUF_LEN(m_notify); 365647674b651417d493ff4e0318113fd7beeef119dbtuexen /* not that we need this */ 365747674b651417d493ff4e0318113fd7beeef119dbtuexen control->tail_mbuf = m_notify; 365847674b651417d493ff4e0318113fd7beeef119dbtuexen control->spec_flags = M_NOTIFICATION; 365947674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_add_to_readq(stcb->sctp_ep, stcb, 366047674b651417d493ff4e0318113fd7beeef119dbtuexen control, 366147674b651417d493ff4e0318113fd7beeef119dbtuexen &stcb->sctp_socket->so_rcv, 1, 366247674b651417d493ff4e0318113fd7beeef119dbtuexen SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); 366347674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 366447674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_m_freem(m_notify); 366547674b651417d493ff4e0318113fd7beeef119dbtuexen } 366647674b651417d493ff4e0318113fd7beeef119dbtuexen} 366747674b651417d493ff4e0318113fd7beeef119dbtuexen 366847674b651417d493ff4e0318113fd7beeef119dbtuexen 36698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 36708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, 36718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t error, void *data, int so_locked 36728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 36738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 36748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 36758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 36768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 36778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) || 36788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 36798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 36808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { 36818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* If the socket is gone we are out of here */ 36828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 36838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__) 36858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_socket->so_rcv.sb_state & SBS_CANTRCVMORE) { 36868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 36878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_socket->so_state & SS_CANTRCVMORE) { 36888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 36898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 36908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 36928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so_locked) { 36938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep)); 36948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 36958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep)); 36968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 3698f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t if ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) || 3699f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED)) { 37008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) || 37018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (notification == SCTP_NOTIFY_INTERFACE_UP) || 37028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) { 37038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Don't report these in front states */ 37048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 37058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (notification) { 37088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_ASSOC_UP: 37098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.assoc_up_sent == 0) { 371047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error, NULL, 0, so_locked); 37118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.assoc_up_sent = 1; 37128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) { 37140ac02f34d6041cd0018437596a5a9a94685e6919tuexen sctp_notify_adaptation_layer(stcb); 37158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3716fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb->asoc.auth_supported == 0) { 37178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0, 3718f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t NULL, so_locked); 37198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_ASSOC_DOWN: 372247674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error, NULL, 0, so_locked); 37230612043f643c9b26245564c05defca64d472060etuexen#if defined(__Userspace__) 37240ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen if (stcb->sctp_ep->recv_callback) { 3725000a5bac556b28e74e4e98c540f66b1743e9312dtuexen if (stcb->sctp_socket) { 372673e265d74b8dddf404a3200cc2a4b593025158e7tuexen union sctp_sockstore addr; 372773e265d74b8dddf404a3200cc2a4b593025158e7tuexen struct sctp_rcvinfo rcv; 372873e265d74b8dddf404a3200cc2a4b593025158e7tuexen 372973e265d74b8dddf404a3200cc2a4b593025158e7tuexen memset(&addr, 0, sizeof(union sctp_sockstore)); 373073e265d74b8dddf404a3200cc2a4b593025158e7tuexen memset(&rcv, 0, sizeof(struct sctp_rcvinfo)); 37310ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen atomic_add_int(&stcb->asoc.refcnt, 1); 37320ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen SCTP_TCB_UNLOCK(stcb); 3733d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen stcb->sctp_ep->recv_callback(stcb->sctp_socket, addr, NULL, 0, rcv, 0, stcb->sctp_ep->ulp_info); 37340ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen SCTP_TCB_LOCK(stcb); 37350ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 37360ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen } 373773c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen } 373873c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen#endif 37398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_INTERFACE_DOWN: 37418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 37438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = (struct sctp_nets *)data; 37458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE, 37468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&net->ro._l_addr, error); 37478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_INTERFACE_UP: 37508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 37528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = (struct sctp_nets *)data; 37548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE, 37558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&net->ro._l_addr, error); 37568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_INTERFACE_CONFIRMED: 37598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 37618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = (struct sctp_nets *)data; 37638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED, 37648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&net->ro._l_addr, error); 37658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_SPECIAL_SP_FAIL: 37688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_send_failed2(stcb, error, 3769f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (struct sctp_stream_queue_pending *)data, so_locked); 37708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 377147674b651417d493ff4e0318113fd7beeef119dbtuexen case SCTP_NOTIFY_SENT_DG_FAIL: 377247674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_send_failed(stcb, 1, error, 37738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_tmit_chunk *)data, so_locked); 37748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 377547674b651417d493ff4e0318113fd7beeef119dbtuexen case SCTP_NOTIFY_UNSENT_DG_FAIL: 377647674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_send_failed(stcb, 0, error, 3777f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (struct sctp_tmit_chunk *)data, so_locked); 377847674b651417d493ff4e0318113fd7beeef119dbtuexen break; 37798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION: 37808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t val; 37828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = *((uint32_t *)data); 37838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_partial_delivery_indication(stcb, error, val, so_locked); 37858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 378747674b651417d493ff4e0318113fd7beeef119dbtuexen case SCTP_NOTIFY_ASSOC_LOC_ABORTED: 3788f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) || 3789f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t ((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) { 379047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked); 37918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 379247674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked); 37938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 379547674b651417d493ff4e0318113fd7beeef119dbtuexen case SCTP_NOTIFY_ASSOC_REM_ABORTED: 3796f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) || 3797f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t ((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) { 379847674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked); 379947674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 380047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked); 380147674b651417d493ff4e0318113fd7beeef119dbtuexen } 38028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_ASSOC_RESTART: 380447674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked); 3805fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb->asoc.auth_supported == 0) { 38068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0, 3807f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t NULL, so_locked); 38088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_STR_RESET_SEND: 38113deb01b1bdee799175510a3e63155882311686f7tuexen sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_OUTGOING_SSN); 38128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_STR_RESET_RECV: 38143deb01b1bdee799175510a3e63155882311686f7tuexen sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), SCTP_STREAM_RESET_INCOMING); 38158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_STR_RESET_FAILED_OUT: 3817000a5bac556b28e74e4e98c540f66b1743e9312dtuexen sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), 3818f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED)); 38198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 3820cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen case SCTP_NOTIFY_STR_RESET_DENIED_OUT: 3821cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), 3822cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen (SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_DENIED)); 3823cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen break; 38248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_STR_RESET_FAILED_IN: 3825000a5bac556b28e74e4e98c540f66b1743e9312dtuexen sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), 3826f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED)); 38278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 3828cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen case SCTP_NOTIFY_STR_RESET_DENIED_IN: 3829cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen sctp_notify_stream_reset(stcb, error, ((uint16_t *) data), 3830cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen (SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_DENIED)); 3831cdadd9c6abe95c90cef647c7391c5152a3858eb4tuexen break; 38328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_ASCONF_ADD_IP: 38338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data, 38348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error); 38358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_ASCONF_DELETE_IP: 38378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data, 3838f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t error); 38398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_ASCONF_SET_PRIMARY: 38418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data, 3842f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t error); 38438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_PEER_SHUTDOWN: 38458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_shutdown_event(stcb); 38468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_AUTH_NEW_KEY: 384808f3696ad42fc22082922592e23297cfaf790dcctuexen sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error, 3849f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (uint16_t)(uintptr_t)data, 3850f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t so_locked); 38518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_AUTH_FREE_KEY: 38538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY, error, 3854f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (uint16_t)(uintptr_t)data, 3855f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t so_locked); 38568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_NO_PEER_AUTH: 38588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, error, 3859f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t (uint16_t)(uintptr_t)data, 3860f16a3dca2395cee32963ab65a1fecbeaeccaa1b5t so_locked); 38618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFY_SENDER_DRY: 38638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_sender_dry_event(stcb, so_locked); 38648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 386547674b651417d493ff4e0318113fd7beeef119dbtuexen case SCTP_NOTIFY_REMOTE_ERROR: 386647674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_notify_remote_error(stcb, error, data); 386747674b651417d493ff4e0318113fd7beeef119dbtuexen break; 38688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 38698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_UTIL1, "%s: unknown notification %xh (%u)\n", 38708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen __FUNCTION__, notification, notification); 38718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end switch */ 38738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 38748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 387647674b651417d493ff4e0318113fd7beeef119dbtuexensctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked 38778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 38788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 38798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 38808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 38818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 38828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_association *asoc; 38838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_out *outs; 38848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *chk, *nchk; 38858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_queue_pending *sp, *nsp; 38868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 38878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 38898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 38908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc = &stcb->asoc; 38928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) { 38938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* already being freed */ 38948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 38958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 38978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so_locked) { 38988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep)); 38998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 39008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep)); 39018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 39038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 39048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 39058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (asoc->state & SCTP_STATE_CLOSED_SOCKET)) { 39068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 39078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now through all the gunk freeing chunks */ 39098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) { 39108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_SEND_LOCK(stcb); 39118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* sent queue SHOULD be empty */ 39138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH_SAFE(chk, &asoc->sent_queue, sctp_next, nchk) { 39148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); 39158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->sent_queue_cnt--; 391660db5740d3bcc26fd4ebc19b6b0652506994fd14t if (chk->sent != SCTP_DATAGRAM_NR_ACKED) { 3917446be8e8a472f6e688885674d2430118fc4be5d7t if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) { 3918446be8e8a472f6e688885674d2430118fc4be5d7t asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--; 3919446be8e8a472f6e688885674d2430118fc4be5d7t#ifdef INVARIANTS 3920446be8e8a472f6e688885674d2430118fc4be5d7t } else { 3921446be8e8a472f6e688885674d2430118fc4be5d7t panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number); 3922446be8e8a472f6e688885674d2430118fc4be5d7t#endif 3923446be8e8a472f6e688885674d2430118fc4be5d7t } 3924446be8e8a472f6e688885674d2430118fc4be5d7t } 39258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->data != NULL) { 39268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_bufspace(stcb, asoc, chk, 1); 392747674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 392847674b651417d493ff4e0318113fd7beeef119dbtuexen error, chk, so_locked); 39298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->data) { 39308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(chk->data); 39318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->data = NULL; 39328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_a_chunk(stcb, chk, so_locked); 39358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*sa_ignore FREED_MEMORY*/ 39368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* pending send queue SHOULD be empty */ 39388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { 39398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); 39408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->send_queue_cnt--; 3941446be8e8a472f6e688885674d2430118fc4be5d7t if (asoc->strmout[chk->rec.data.stream_number].chunks_on_queues > 0) { 3942446be8e8a472f6e688885674d2430118fc4be5d7t asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--; 3943446be8e8a472f6e688885674d2430118fc4be5d7t#ifdef INVARIANTS 3944446be8e8a472f6e688885674d2430118fc4be5d7t } else { 3945446be8e8a472f6e688885674d2430118fc4be5d7t panic("No chunks on the queues for sid %u.", chk->rec.data.stream_number); 3946446be8e8a472f6e688885674d2430118fc4be5d7t#endif 3947446be8e8a472f6e688885674d2430118fc4be5d7t } 39488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->data != NULL) { 39498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_bufspace(stcb, asoc, chk, 1); 395047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 395147674b651417d493ff4e0318113fd7beeef119dbtuexen error, chk, so_locked); 39528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->data) { 39538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(chk->data); 39548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->data = NULL; 39558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_a_chunk(stcb, chk, so_locked); 39588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*sa_ignore FREED_MEMORY*/ 39598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < asoc->streamoutcnt; i++) { 39618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* For each stream */ 39628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen outs = &asoc->strmout[i]; 39638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* clean up any sends there */ 39648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->locked_on_sending = NULL; 39658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { 39668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->stream_queue_cnt--; 39678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&outs->outqueue, sp, next); 39688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_spbufspace(stcb, asoc, sp); 39698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sp->data) { 39708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb, 397147674b651417d493ff4e0318113fd7beeef119dbtuexen error, (void *)sp, so_locked); 39728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sp->data) { 39738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(sp->data); 39748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp->data = NULL; 3975647dfd814628db0cc7cbfecaf4acb44f997eadb2tuexen sp->tail_mbuf = NULL; 3976647dfd814628db0cc7cbfecaf4acb44f997eadb2tuexen sp->length = 0; 39778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sp->net) { 39808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(sp->net); 39818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp->net = NULL; 39828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Free the chunk */ 39848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_a_strmoq(stcb, sp, so_locked); 39858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*sa_ignore FREED_MEMORY*/ 39868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 39898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) { 39908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_SEND_UNLOCK(stcb); 39918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 39938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 39948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 399547674b651417d493ff4e0318113fd7beeef119dbtuexensctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error, 399647674b651417d493ff4e0318113fd7beeef119dbtuexen struct sctp_abort_chunk *abort, int so_locked 39978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 39988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 39998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 40008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 40018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 40028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 40038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 40048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 40068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so_locked) { 40078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep)); 40088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 40098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep)); 40108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 40128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 40138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 40148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) { 40158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_WAS_ABORTED; 40168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 40188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 40198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { 40208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 40218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Tell them we lost the asoc */ 402347674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_report_all_outbound(stcb, error, 1, so_locked); 402447674b651417d493ff4e0318113fd7beeef119dbtuexen if (from_peer) { 402547674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked); 402647674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 402747674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_ASSOC_LOC_ABORTED, stcb, error, abort, so_locked); 402847674b651417d493ff4e0318113fd7beeef119dbtuexen } 40298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 40308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 40318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 40328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 4033e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen struct mbuf *m, int iphlen, 4034e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen struct sockaddr *src, struct sockaddr *dst, 4035e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen struct sctphdr *sh, struct mbuf *op_err, 40366a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 40376a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen uint8_t use_mflowid, uint32_t mflowid, 40386a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 40396a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen uint32_t vrf_id, uint16_t port) 40408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 40418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vtag; 40420612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 40438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 40448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 40458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 40468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vtag = 0; 40478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 40488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We have a TCB to abort, send notification too */ 40498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vtag = stcb->asoc.peer_vtag; 405047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_abort_notification(stcb, 0, 0, NULL, SCTP_SO_NOT_LOCKED); 40518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get the assoc vrf id and table id */ 40528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = stcb->asoc.vrf_id; 40538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; 40548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4055e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err, 40566a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 40576a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen use_mflowid, mflowid, 40586a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 40596a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen vrf_id, port); 40608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 40618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Ok, now lets free it */ 40620612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 40638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(inp); 40648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 40658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 40668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 40678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 40688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 40698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 40708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR_COUNTER32(sctps_aborted); 40718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 40728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 40738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_DECR_GAUGE32(sctps_currestab); 40748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL+SCTP_LOC_4); 40760612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 40778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 40788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 40798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 40818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_ASOCLOG_OF_TSNS 40828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 40838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_print_out_track_log(struct sctp_tcb *stcb) 40848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 40858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef NOSIY_PRINTS 40868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 40878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("Last ep reason:%x\n", stcb->sctp_ep->last_abort_code); 40888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("IN bound TSN log-aaa\n"); 40898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->asoc.tsn_in_at == 0) && (stcb->asoc.tsn_in_wrapped == 0)) { 40908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("None rcvd\n"); 40918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto none_in; 40928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.tsn_in_wrapped) { 4094b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen for (i = stcb->asoc.tsn_in_at; i < SCTP_TSN_LOG_SIZE; i++) { 40958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 40968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].tsn, 40978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].strm, 40988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].seq, 40998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].flgs, 41008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].sz); 41018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.tsn_in_at) { 4104b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen for (i = 0; i < stcb->asoc.tsn_in_at; i++) { 41058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 41068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].tsn, 41078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].strm, 41088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].seq, 41098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].flgs, 41108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.in_tsnlog[i].sz); 41118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen none_in: 41148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("OUT bound TSN log-aaa\n"); 41158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->asoc.tsn_out_at == 0) && 41168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.tsn_out_wrapped == 0)) { 41178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("None sent\n"); 41188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.tsn_out_wrapped) { 4120b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen for (i = stcb->asoc.tsn_out_at; i < SCTP_TSN_LOG_SIZE; i++) { 41218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 41228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].tsn, 41238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].strm, 41248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].seq, 41258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].flgs, 41268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].sz); 41278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.tsn_out_at) { 4130b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen for (i = 0; i < stcb->asoc.tsn_out_at; i++) { 41318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("TSN:%x strm:%d seq:%d flags:%x sz:%d\n", 41328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].tsn, 41338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].strm, 41348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].seq, 41358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].flgs, 41368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.out_tsnlog[i].sz); 41378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 41418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 41448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 414547674b651417d493ff4e0318113fd7beeef119dbtuexen struct mbuf *op_err, 414647674b651417d493ff4e0318113fd7beeef119dbtuexen int so_locked 41478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 41488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 41498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen) 41518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 41520612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 41538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 41548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41560612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 41578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(inp); 41588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 41608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so_locked) { 41618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_lock_assert(SCTP_INP_SO(inp)); 41628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 41638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_unlock_assert(SCTP_INP_SO(inp)); 41648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 41678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Got to have a TCB */ 41688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 41696c1813d4ac9e00b805e1a400f004f2994b2297e5t if (LIST_EMPTY(&inp->sctp_asoc_list)) { 41708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 41718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 41728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 41738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 41768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_DIRECTLY_NOCMPSET); 41778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 41788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 41798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 41808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 41828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 41858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 41868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.state |= SCTP_STATE_WAS_ABORTED; 41878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* notify the ulp */ 418947674b651417d493ff4e0318113fd7beeef119dbtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 419047674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_abort_notification(stcb, 0, 0, NULL, so_locked); 419147674b651417d493ff4e0318113fd7beeef119dbtuexen } 41928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* notify the peer */ 41938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_abort_tcb(stcb, op_err, so_locked); 41948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR_COUNTER32(sctps_aborted); 41958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 41968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 41978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_DECR_GAUGE32(sctps_currestab); 41988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now free the asoc */ 42008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_ASOCLOG_OF_TSNS 42018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_print_out_track_log(stcb); 42028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 42030612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 42048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 42058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 42068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 42078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 42088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 42098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 42108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 42128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL+SCTP_LOC_5); 42130612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 42148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 42158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 42168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 42188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 42198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 42208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4221e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexensctp_handle_ootb(struct mbuf *m, int iphlen, int offset, 4222e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen struct sockaddr *src, struct sockaddr *dst, 4223e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen struct sctphdr *sh, struct sctp_inpcb *inp, 42248f9e45fea288542b24a6bda01269c6fc184d991at struct mbuf *cause, 42256a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 42266a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen uint8_t use_mflowid, uint32_t mflowid, 42276a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 42286a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen uint32_t vrf_id, uint16_t port) 42298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 42308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_chunkhdr *ch, chunk_buf; 42318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen unsigned int chk_length; 423223273859c39742f09cc5ec7c9bf32ff225661e82tuexen int contains_init_chunk; 42338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 42348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue); 42358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Generate a TO address for future reference */ 42368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 42376c1813d4ac9e00b805e1a400f004f2994b2297e5t if (LIST_EMPTY(&inp->sctp_asoc_list)) { 42388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 42398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1); 42408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 42418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 42428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_DIRECTLY_NOCMPSET); 42438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 42448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(SCTP_INP_SO(inp), 1); 42458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 42468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 424823273859c39742f09cc5ec7c9bf32ff225661e82tuexen contains_init_chunk = 0; 42498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 42508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(*ch), (uint8_t *) & chunk_buf); 42518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (ch != NULL) { 42528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk_length = ntohs(ch->chunk_length); 42538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk_length < sizeof(*ch)) { 42548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* break to abort land */ 42558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 42568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (ch->chunk_type) { 425823273859c39742f09cc5ec7c9bf32ff225661e82tuexen case SCTP_INIT: 425923273859c39742f09cc5ec7c9bf32ff225661e82tuexen contains_init_chunk = 1; 426023273859c39742f09cc5ec7c9bf32ff225661e82tuexen break; 42618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PACKET_DROPPED: 42628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we don't respond to pkt-dropped */ 42638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 42648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ABORT_ASSOCIATION: 42658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we don't respond with an ABORT to an ABORT */ 42668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 42678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SHUTDOWN_COMPLETE: 42688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 42698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we ignore it since we are not waiting for it and 42708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * peer is gone 42718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 42728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 42738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SHUTDOWN_ACK: 4274e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen sctp_send_shutdown_complete2(src, dst, sh, 42756a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 42766a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen use_mflowid, mflowid, 42776a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 42786a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen vrf_id, port); 42798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 42808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 42818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 42828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen offset += SCTP_SIZE32(chk_length); 42848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 42858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(*ch), (uint8_t *) & chunk_buf); 42868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 428723273859c39742f09cc5ec7c9bf32ff225661e82tuexen if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 428823273859c39742f09cc5ec7c9bf32ff225661e82tuexen ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 428923273859c39742f09cc5ec7c9bf32ff225661e82tuexen (contains_init_chunk == 0))) { 42908f9e45fea288542b24a6bda01269c6fc184d991at sctp_send_abort(m, iphlen, src, dst, sh, 0, cause, 42916a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 42926a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen use_mflowid, mflowid, 42936a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 42946a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen vrf_id, port); 429523273859c39742f09cc5ec7c9bf32ff225661e82tuexen } 42968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 42978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 42988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 42998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * check the inbound datagram to make sure there is not an abort inside it, 43008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * if there is return 1, else return 0. 43018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 43028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 43038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_is_there_an_abort_here(struct mbuf *m, int iphlen, uint32_t * vtagfill) 43048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 43058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_chunkhdr *ch; 43068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_init_chunk *init_chk, chunk_buf; 43078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int offset; 43088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen unsigned int chk_length; 43098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen offset = iphlen + sizeof(struct sctphdr); 43118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch), 43128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (uint8_t *) & chunk_buf); 43138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (ch != NULL) { 43148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk_length = ntohs(ch->chunk_length); 43158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk_length < sizeof(*ch)) { 43168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* packet is probably corrupt */ 43178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we seem to be ok, is it an abort? */ 43208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) { 43218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* yep, tell them */ 43228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (1); 43238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ch->chunk_type == SCTP_INITIATION) { 43258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* need to update the Vtag */ 43268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m, 43278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen offset, sizeof(*init_chk), (uint8_t *) & chunk_buf); 43288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (init_chk != NULL) { 43298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *vtagfill = ntohl(init_chk->init.initiate_tag); 43308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Nope, move to the next chunk */ 43338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen offset += SCTP_SIZE32(chk_length); 43348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 43358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(*ch), (uint8_t *) & chunk_buf); 43368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 43388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 43398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 43418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * currently (2/02), ifa_addr embeds scope_id's and don't have sin6_scope_id 43428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * set (i.e. it's 0) so, create this function to compare link local scopes 43438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 43448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 43458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 43468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_is_same_scope(struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2) 43478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 43488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 43498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*__Userspace__ Returning 1 here always */ 43508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 43518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 43528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 a, b; 43538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* save copies */ 43558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen a = *addr1; 43568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen b = *addr2; 43578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (a.sin6_scope_id == 0) 43598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 43608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa6_recoverscope(&a)) { 43618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 43628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in6_recoverscope(&a, &a.sin6_addr, NULL)) { 43638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 43648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't get scope, so can't match */ 43658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 43668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (b.sin6_scope_id == 0) 43688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 43698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa6_recoverscope(&b)) { 43708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 43718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in6_recoverscope(&b, &b.sin6_addr, NULL)) { 43728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 43738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't get scope, so can't match */ 43748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 43758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (a.sin6_scope_id != b.sin6_scope_id) 43778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 43788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 43798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr1->sin6_scope_id != addr2->sin6_scope_id) 43808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 43818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 43828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (1); 43848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 43858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 43878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 43888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * returns a sockaddr_in6 with embedded scope recovered and removed 43898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 43908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct sockaddr_in6 * 43918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_recover_scope(struct sockaddr_in6 *addr, struct sockaddr_in6 *store) 43928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 43938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* check and strip embedded scope junk */ 43948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sin6_family == AF_INET6) { 43958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) { 43968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sin6_scope_id == 0) { 43978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *store = *addr; 43988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 43998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!sa6_recoverscope(store)) { 44008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 44018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!in6_recoverscope(store, &store->sin6_addr, 44028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL)) { 44038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 44048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* use the recovered scope */ 44058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr = store; 44068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 44088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* else, return the original "to" addr */ 44098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_clearscope(&addr->sin6_addr); 44108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (addr); 44148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 44158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 44168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 44178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 44198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * are the two addresses the same? currently a "scopeless" check returns: 1 44208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * if same, 0 if not 44218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 44228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 44238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2) 44248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 44258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* must be valid */ 44278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa1 == NULL || sa2 == NULL) 44288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 44298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* must be the same family */ 44318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa1->sa_family != sa2->sa_family) 44328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 4433000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 44348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sa1->sa_family) { 44358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 44368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 44378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* IPv6 addresses */ 44398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6_1, *sin6_2; 44408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6_1 = (struct sockaddr_in6 *)sa1; 44428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6_2 = (struct sockaddr_in6 *)sa2; 44438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (SCTP6_ARE_ADDR_EQUAL(sin6_1, 44448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6_2)); 44458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 44478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 44488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 44498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* IPv4 addresses */ 44518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin_1, *sin_2; 44528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_1 = (struct sockaddr_in *)sa1; 44548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_2 = (struct sockaddr_in *)sa2; 44558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr); 44568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 445866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 445966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 446066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen { 446166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen struct sockaddr_conn *sconn_1, *sconn_2; 446266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen 446366e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen sconn_1 = (struct sockaddr_conn *)sa1; 446466e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen sconn_2 = (struct sockaddr_conn *)sa2; 446566e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen return (sconn_1->sconn_addr == sconn_2->sconn_addr); 446666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 446766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 44688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 44698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we don't do these... */ 44708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 44718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 44738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 44758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_print_address(struct sockaddr *sa) 44768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 44778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 4478c95692c15a6ca05efcd306c21fda119862cd66e0t#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 44798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen char ip6buf[INET6_ADDRSTRLEN]; 4480c95692c15a6ca05efcd306c21fda119862cd66e0t#endif 4481000a5bac556b28e74e4e98c540f66b1743e9312dtuexen#endif 4482000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 44838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sa->sa_family) { 44848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 44858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 44868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 44888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 449023273859c39742f09cc5ec7c9bf32ff225661e82tuexen#if defined(__Userspace__) 449123273859c39742f09cc5ec7c9bf32ff225661e82tuexen SCTP_PRINTF("IPv6 address: %x:%x:%x:%x:%x:%x:%x:%x:port:%d scope:%u\n", 44921a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[0]), 44931a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[1]), 44941a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[2]), 44951a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[3]), 44961a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[4]), 44971a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[5]), 44981a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[6]), 44991a0a058c2e170a7749bd410bdeff477bbd75a615tuexen ntohs(sin6->sin6_addr.s6_addr16[7]), 45008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ntohs(sin6->sin6_port), 45018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_scope_id); 45028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 45038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 45049166fbec1be731c68a575747cbd94bd54fe4692dt SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n", 45058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ip6_sprintf(ip6buf, &sin6->sin6_addr), 45069166fbec1be731c68a575747cbd94bd54fe4692dt ntohs(sin6->sin6_port), 45079166fbec1be731c68a575747cbd94bd54fe4692dt sin6->sin6_scope_id); 45088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 45099166fbec1be731c68a575747cbd94bd54fe4692dt SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n", 45108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ip6_sprintf(&sin6->sin6_addr), 45118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ntohs(sin6->sin6_port), 45128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_scope_id); 45138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 45149166fbec1be731c68a575747cbd94bd54fe4692dt#endif 45158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 45188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 45198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 45208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 45218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 45228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen unsigned char *p; 45238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 45248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 45258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen p = (unsigned char *)&sin->sin_addr; 45268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("IPv4 address: %u.%u.%u.%u:%d\n", 45278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen p[0], p[1], p[2], p[3], ntohs(sin->sin_port)); 45288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 453166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 453266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 453366e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen { 453466e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen struct sockaddr_conn *sconn; 453566e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen 453666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen sconn = (struct sockaddr_conn *)sa; 453766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen SCTP_PRINTF("AF_CONN address: %p\n", sconn->sconn_addr); 453866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 453966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 454066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 45418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 45428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("?\n"); 45438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 45468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 45478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 45488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, 45498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *new_inp, 45508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 45518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int waitflags) 45528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 45538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 45548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * go through our old INP and pull off any control structures that 45558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * belong to stcb and move then to the new inp. 45568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 45578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *old_so, *new_so; 45588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control, *nctl; 45598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_readhead tmp_queue; 45608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m; 45618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 45628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 45638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen old_so = old_inp->sctp_socket; 45648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_so = new_inp->sctp_socket; 45658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INIT(&tmp_queue); 45668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 700000 45678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&(old_so->so_rcv)); 45688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 45698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) 45708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sblock(&old_so->so_rcv, waitflags); 45718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 45728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 700000 45738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&(old_so->so_rcv)); 45748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 45758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 45768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak, can't get sblock, we have a problem. 45778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * data will be left stranded.. and we 45788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * don't dare look at it since the 45798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * other thread may be reading something. 45808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Oh well, its a screwed up app that does 45818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a peeloff OR a accept while reading 45828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * from the main socket... actually its 45838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * only the peeloff() case, since I think 45848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * read will fail on a listening socket.. 45858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 45868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 45878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* lock the socket buffers */ 45898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(old_inp); 45908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH_SAFE(control, &old_inp->read_queue, next, nctl) { 45918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Pull off all for out target stcb */ 45928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->stcb == stcb) { 45938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* remove it we want it */ 45948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&old_inp->read_queue, control, next); 45958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INSERT_TAIL(&tmp_queue, control, next); 45968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = control->data; 45978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (m) { 45988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 45998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE,SCTP_BUF_LEN(m)); 46008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sbfree(control, stcb, &old_so->so_rcv, m); 46028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 46038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0); 46048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(m); 46068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(old_inp); 46108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Remove the sb-lock on the old socket */ 46118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 700000 46128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&(old_so->so_rcv)); 46138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 46158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sbunlock(&old_so->so_rcv, 1); 46168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) 46198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sbunlock(&old_so->so_rcv); 46208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 700000 46228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&(old_so->so_rcv)); 46238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now we move them over to the new socket buffer */ 46258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(new_inp); 46268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH_SAFE(control, &tmp_queue, next, nctl) { 46278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INSERT_TAIL(&new_inp->read_queue, control, next); 46288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = control->data; 46298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (m) { 46308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 46318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m)); 46328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sballoc(stcb, &new_so->so_rcv, m); 46348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 46358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0); 46368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(m); 46388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(new_inp); 46418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 46428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 46448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_add_to_readq(struct sctp_inpcb *inp, 46458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 46468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control, 46478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockbuf *sb, 46488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int end, 46498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int inp_read_lock_held, 46508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int so_locked 46518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 46528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 46538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 46558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 46568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 46578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here we must place the control on the end of the socket read 46588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * queue AND increment sb_cc so that select will work properly on 46598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * read. 46608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 4661b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct mbuf *m, *prev = NULL; 46628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 46648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak, TSNH!! */ 46658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 46668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("Gak, inp NULL on add_to_readq"); 46678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 46698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 46718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so_locked) { 46728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_lock_assert(SCTP_INP_SO(inp)); 46738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 46748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_unlock_assert(SCTP_INP_SO(inp)); 46758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp_read_lock_held == 0) 46788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 46798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { 46808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(control->whoFrom); 46818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->data) { 46828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(control->data); 46838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = NULL; 46848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), control); 46868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp_read_lock_held == 0) 46878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 46888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 46898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(control->spec_flags & M_NOTIFICATION)) { 46918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&inp->total_recvs, 1); 46928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!control->do_not_ref_stcb) { 46938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->total_recvs, 1); 46948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = control->data; 46978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = 0; 46988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = 0; 46998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (m) { 47008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BUF_LEN(m) == 0) { 47018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Skip mbufs with NO length */ 47028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (prev == NULL) { 47038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First one */ 47048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = sctp_m_free(m); 47058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = control->data; 47068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 47078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(prev) = sctp_m_free(m); 47088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(prev); 47098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m == NULL) { 47118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = prev; 47128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 47148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen prev = m; 47168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 47178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m)); 47188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sballoc(stcb, sb, m); 47208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 47218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0); 47228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&control->length, SCTP_BUF_LEN(m)); 47248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(m); 47258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (prev != NULL) { 47278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = prev; 47288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 47298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Everything got collapsed out?? */ 47308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(control->whoFrom); 47318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), control); 47328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp_read_lock_held == 0) 47338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 47348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 47358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (end) { 47378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->end_added = 1; 47388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47390ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen#if defined(__Userspace__) 47400ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen if (inp->recv_callback) { 47410ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen if (inp_read_lock_held == 0) 47420ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen SCTP_INP_READ_UNLOCK(inp); 47430ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen if (control->end_added == 1) { 47440ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen struct socket *so; 47450ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen struct mbuf *m; 474673e265d74b8dddf404a3200cc2a4b593025158e7tuexen char *buffer; 474773e265d74b8dddf404a3200cc2a4b593025158e7tuexen struct sctp_rcvinfo rcv; 474873e265d74b8dddf404a3200cc2a4b593025158e7tuexen union sctp_sockstore addr; 4749f134d2564b9f6f3dc2ec8bd5390ef7687553c5cbt int flags; 475073c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen 475173e265d74b8dddf404a3200cc2a4b593025158e7tuexen if ((buffer = malloc(control->length)) == NULL) { 475273e265d74b8dddf404a3200cc2a4b593025158e7tuexen return; 475373e265d74b8dddf404a3200cc2a4b593025158e7tuexen } 4754498b53d78c906df68d1ae863d55f59359ad458b2t so = stcb->sctp_socket; 47550ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen for (m = control->data; m; m = SCTP_BUF_NEXT(m)) { 47560ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen sctp_sbfree(control, control->stcb, &so->so_rcv, m); 47570ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen } 47580ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen atomic_add_int(&stcb->asoc.refcnt, 1); 47590ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen SCTP_TCB_UNLOCK(stcb); 476073e265d74b8dddf404a3200cc2a4b593025158e7tuexen m_copydata(control->data, 0, control->length, buffer); 476173e265d74b8dddf404a3200cc2a4b593025158e7tuexen memset(&rcv, 0, sizeof(struct sctp_rcvinfo)); 476273e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_sid = control->sinfo_stream; 476373e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_ssn = control->sinfo_ssn; 476473e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_flags = control->sinfo_flags; 476573e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_ppid = control->sinfo_ppid; 476673e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_tsn = control->sinfo_tsn; 476773e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_cumtsn = control->sinfo_cumtsn; 476873e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_context = control->sinfo_context; 476973e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_assoc_id = control->sinfo_assoc_id; 477073e265d74b8dddf404a3200cc2a4b593025158e7tuexen memset(&addr, 0, sizeof(union sctp_sockstore)); 477173e265d74b8dddf404a3200cc2a4b593025158e7tuexen switch (control->whoFrom->ro._l_addr.sa.sa_family) { 477273e265d74b8dddf404a3200cc2a4b593025158e7tuexen#ifdef INET 477373e265d74b8dddf404a3200cc2a4b593025158e7tuexen case AF_INET: 477473e265d74b8dddf404a3200cc2a4b593025158e7tuexen addr.sin = control->whoFrom->ro._l_addr.sin; 477573e265d74b8dddf404a3200cc2a4b593025158e7tuexen break; 477673e265d74b8dddf404a3200cc2a4b593025158e7tuexen#endif 477773e265d74b8dddf404a3200cc2a4b593025158e7tuexen#ifdef INET6 477873e265d74b8dddf404a3200cc2a4b593025158e7tuexen case AF_INET6: 477973e265d74b8dddf404a3200cc2a4b593025158e7tuexen addr.sin6 = control->whoFrom->ro._l_addr.sin6; 478073e265d74b8dddf404a3200cc2a4b593025158e7tuexen break; 478173e265d74b8dddf404a3200cc2a4b593025158e7tuexen#endif 478266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 478366e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen addr.sconn = control->whoFrom->ro._l_addr.sconn; 478466e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 478573e265d74b8dddf404a3200cc2a4b593025158e7tuexen default: 478673e265d74b8dddf404a3200cc2a4b593025158e7tuexen addr.sa = control->whoFrom->ro._l_addr.sa; 478773e265d74b8dddf404a3200cc2a4b593025158e7tuexen break; 478873e265d74b8dddf404a3200cc2a4b593025158e7tuexen } 4789f134d2564b9f6f3dc2ec8bd5390ef7687553c5cbt flags = MSG_EOR; 479073e265d74b8dddf404a3200cc2a4b593025158e7tuexen if (control->spec_flags & M_NOTIFICATION) { 479173e265d74b8dddf404a3200cc2a4b593025158e7tuexen flags |= MSG_NOTIFICATION; 479273e265d74b8dddf404a3200cc2a4b593025158e7tuexen } 4793d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen inp->recv_callback(so, addr, buffer, control->length, rcv, flags, inp->ulp_info); 47940ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen SCTP_TCB_LOCK(stcb); 47950ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 4796e863c174caf47be9814fa7b3fdfae2db0c3a8383t sctp_free_remote_addr(control->whoFrom); 4797e863c174caf47be9814fa7b3fdfae2db0c3a8383t control->whoFrom = NULL; 479873e265d74b8dddf404a3200cc2a4b593025158e7tuexen sctp_m_freem(control->data); 47990ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen control->data = NULL; 48000ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen control->length = 0; 48010ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen sctp_free_a_readq(stcb, control); 480273c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen } 48030ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen return; 480473c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen } 48050ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen#endif 48068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INSERT_TAIL(&inp->read_queue, control, next); 48078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp_read_lock_held == 0) 48088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 48098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp && inp->sctp_socket) { 48108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { 48118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); 48128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 48130612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 48148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 481573c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen 48168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(inp); 48178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 4818b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb) { 4819b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen atomic_add_int(&stcb->asoc.refcnt, 1); 4820b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen SCTP_TCB_UNLOCK(stcb); 4821b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen } 48228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 4823b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb) { 4824b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen SCTP_TCB_LOCK(stcb); 4825b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 4826b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen } 48278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 48288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 48298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 48308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 48338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sorwakeup(inp, inp->sctp_socket); 48340612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 48358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 48368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 48378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 48398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 48428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 48458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_append_to_readq(struct sctp_inpcb *inp, 48468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 48478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_queued_to_read *control, 48488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m, 48498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int end, 48508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ctls_cumack, 48518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockbuf *sb) 48528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 48538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 48548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * A partial delivery API event is underway. OR we are appending on 48558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the reassembly queue. 48568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 48578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * If PDAPI this means we need to add m to the end of the data. 48588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Increase the length in the control AND increment the sb_cc. 48598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Otherwise sb is NULL and all we need to do is put it at the end 48608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * of the mbuf chain. 48618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 4862b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int len = 0; 48638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *mm, *tail = NULL, *prev = NULL; 48648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 48668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 48678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 48698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen get_out: 48708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 48718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 48728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (-1); 48748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ)) { 48768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 4877b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (0); 48788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->end_added) { 48808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* huh this one is complete? */ 48818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto get_out; 48828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen mm = m; 48848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (mm == NULL) { 48858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto get_out; 48868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (mm) { 48898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BUF_LEN(mm) == 0) { 48908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Skip mbufs with NO lenght */ 48918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (prev == NULL) { 48928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First one */ 48938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = sctp_m_free(mm); 48948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen mm = m; 48958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 48968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(prev) = sctp_m_free(mm); 48978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen mm = SCTP_BUF_NEXT(prev); 48988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 49008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen prev = mm; 49028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len += SCTP_BUF_LEN(mm); 49038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sb) { 49048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 49058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(mm)); 49068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sballoc(stcb, sb, mm); 49088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 49098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(sb, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0); 49108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen mm = SCTP_BUF_NEXT(mm); 49138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (prev) { 49158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tail = prev; 49168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 49178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Really there should always be a prev */ 49188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (m == NULL) { 49198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Huh nothing left? */ 49208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 49218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("Nothing left to add?"); 49228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 49238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto get_out; 49248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 49258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tail = m; 49278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->tail_mbuf) { 49298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* append */ 49308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(control->tail_mbuf) = m; 49318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = tail; 49328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 49338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* nothing there */ 49348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 49358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->data != NULL) { 49368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("This should NOT happen"); 49378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 49398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = m; 49408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = tail; 49418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&control->length, len); 49438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (end) { 49448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* message is complete */ 49458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb && (control == stcb->asoc.control_pdapi)) { 49468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.control_pdapi = NULL; 49478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = 0; 49498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->end_added = 1; 49508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 49528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->do_not_ref_stcb = 1; 49538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 49558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * When we are appending in partial delivery, the cum-ack is used 49568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * for the actual pd-api highest tsn on this mbuf. The true cum-ack 49578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is populated in the outbound sinfo structure from the true cumack 49588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * if the association exists... 49598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 49604be9124eddeed30d7df8dfc5168c77e95979ee0dt control->sinfo_tsn = control->sinfo_cumtsn = ctls_cumack; 49610ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen#if defined(__Userspace__) 49620ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen if (inp->recv_callback) { 49634be9124eddeed30d7df8dfc5168c77e95979ee0dt uint32_t pd_point, length; 49644be9124eddeed30d7df8dfc5168c77e95979ee0dt 49654be9124eddeed30d7df8dfc5168c77e95979ee0dt length = control->length; 49664be9124eddeed30d7df8dfc5168c77e95979ee0dt if (stcb != NULL && stcb->sctp_socket != NULL) { 49674be9124eddeed30d7df8dfc5168c77e95979ee0dt pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, 49684be9124eddeed30d7df8dfc5168c77e95979ee0dt stcb->sctp_ep->partial_delivery_point); 49694be9124eddeed30d7df8dfc5168c77e95979ee0dt } else { 49704be9124eddeed30d7df8dfc5168c77e95979ee0dt pd_point = inp->partial_delivery_point; 49714be9124eddeed30d7df8dfc5168c77e95979ee0dt } 49724be9124eddeed30d7df8dfc5168c77e95979ee0dt if ((control->end_added == 1) || (length >= pd_point)) { 49730ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen struct socket *so; 497473e265d74b8dddf404a3200cc2a4b593025158e7tuexen char *buffer; 497573e265d74b8dddf404a3200cc2a4b593025158e7tuexen struct sctp_rcvinfo rcv; 497673e265d74b8dddf404a3200cc2a4b593025158e7tuexen union sctp_sockstore addr; 4977f134d2564b9f6f3dc2ec8bd5390ef7687553c5cbt int flags; 497873c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen 497973e265d74b8dddf404a3200cc2a4b593025158e7tuexen if ((buffer = malloc(control->length)) == NULL) { 498073e265d74b8dddf404a3200cc2a4b593025158e7tuexen return (-1); 498173e265d74b8dddf404a3200cc2a4b593025158e7tuexen } 49826c1813d4ac9e00b805e1a400f004f2994b2297e5t so = stcb->sctp_socket; 49830ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen for (m = control->data; m; m = SCTP_BUF_NEXT(m)) { 49840ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen sctp_sbfree(control, control->stcb, &so->so_rcv, m); 49850ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen } 498673e265d74b8dddf404a3200cc2a4b593025158e7tuexen m_copydata(control->data, 0, control->length, buffer); 498773e265d74b8dddf404a3200cc2a4b593025158e7tuexen memset(&rcv, 0, sizeof(struct sctp_rcvinfo)); 498873e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_sid = control->sinfo_stream; 498973e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_ssn = control->sinfo_ssn; 499073e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_flags = control->sinfo_flags; 499173e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_ppid = control->sinfo_ppid; 499273e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_tsn = control->sinfo_tsn; 499373e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_cumtsn = control->sinfo_cumtsn; 499473e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_context = control->sinfo_context; 499573e265d74b8dddf404a3200cc2a4b593025158e7tuexen rcv.rcv_assoc_id = control->sinfo_assoc_id; 499673e265d74b8dddf404a3200cc2a4b593025158e7tuexen memset(&addr, 0, sizeof(union sctp_sockstore)); 499773e265d74b8dddf404a3200cc2a4b593025158e7tuexen switch (control->whoFrom->ro._l_addr.sa.sa_family) { 499873e265d74b8dddf404a3200cc2a4b593025158e7tuexen#ifdef INET 499973e265d74b8dddf404a3200cc2a4b593025158e7tuexen case AF_INET: 500073e265d74b8dddf404a3200cc2a4b593025158e7tuexen addr.sin = control->whoFrom->ro._l_addr.sin; 500173e265d74b8dddf404a3200cc2a4b593025158e7tuexen break; 500273e265d74b8dddf404a3200cc2a4b593025158e7tuexen#endif 500373e265d74b8dddf404a3200cc2a4b593025158e7tuexen#ifdef INET6 500473e265d74b8dddf404a3200cc2a4b593025158e7tuexen case AF_INET6: 500573e265d74b8dddf404a3200cc2a4b593025158e7tuexen addr.sin6 = control->whoFrom->ro._l_addr.sin6; 500673e265d74b8dddf404a3200cc2a4b593025158e7tuexen break; 500773e265d74b8dddf404a3200cc2a4b593025158e7tuexen#endif 500866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 500966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen addr.sconn = control->whoFrom->ro._l_addr.sconn; 501066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 501173e265d74b8dddf404a3200cc2a4b593025158e7tuexen default: 501273e265d74b8dddf404a3200cc2a4b593025158e7tuexen addr.sa = control->whoFrom->ro._l_addr.sa; 501373e265d74b8dddf404a3200cc2a4b593025158e7tuexen break; 501473e265d74b8dddf404a3200cc2a4b593025158e7tuexen } 5015f134d2564b9f6f3dc2ec8bd5390ef7687553c5cbt flags = 0; 50164be9124eddeed30d7df8dfc5168c77e95979ee0dt if (control->end_added == 1) { 50174be9124eddeed30d7df8dfc5168c77e95979ee0dt flags |= MSG_EOR; 50184be9124eddeed30d7df8dfc5168c77e95979ee0dt } 501973e265d74b8dddf404a3200cc2a4b593025158e7tuexen if (control->spec_flags & M_NOTIFICATION) { 502073e265d74b8dddf404a3200cc2a4b593025158e7tuexen flags |= MSG_NOTIFICATION; 502173e265d74b8dddf404a3200cc2a4b593025158e7tuexen } 502273e265d74b8dddf404a3200cc2a4b593025158e7tuexen sctp_m_freem(control->data); 50230ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen control->data = NULL; 50244be9124eddeed30d7df8dfc5168c77e95979ee0dt control->tail_mbuf = NULL; 50250ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen control->length = 0; 50264be9124eddeed30d7df8dfc5168c77e95979ee0dt if (control->end_added) { 5027e863c174caf47be9814fa7b3fdfae2db0c3a8383t sctp_free_remote_addr(control->whoFrom); 5028e863c174caf47be9814fa7b3fdfae2db0c3a8383t control->whoFrom = NULL; 50294be9124eddeed30d7df8dfc5168c77e95979ee0dt sctp_free_a_readq(stcb, control); 50304be9124eddeed30d7df8dfc5168c77e95979ee0dt } else { 50314be9124eddeed30d7df8dfc5168c77e95979ee0dt control->some_taken = 1; 50324be9124eddeed30d7df8dfc5168c77e95979ee0dt } 50334be9124eddeed30d7df8dfc5168c77e95979ee0dt atomic_add_int(&stcb->asoc.refcnt, 1); 50344be9124eddeed30d7df8dfc5168c77e95979ee0dt SCTP_TCB_UNLOCK(stcb); 50354be9124eddeed30d7df8dfc5168c77e95979ee0dt inp->recv_callback(so, addr, buffer, length, rcv, flags, inp->ulp_info); 50364be9124eddeed30d7df8dfc5168c77e95979ee0dt SCTP_TCB_LOCK(stcb); 50374be9124eddeed30d7df8dfc5168c77e95979ee0dt atomic_subtract_int(&stcb->asoc.refcnt, 1); 503873c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen } 50390ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen if (inp) 50400ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen SCTP_INP_READ_UNLOCK(inp); 50410ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen return (0); 504273c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen } 50430ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen#endif 50448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp) { 50458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 50468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp && inp->sctp_socket) { 50488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { 50498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); 50508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 50510612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 50528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 505373c31e0d1075341a12dc84bd5a4c5ab479124f34tuexen 50548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(inp); 5055b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb) { 5056b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen atomic_add_int(&stcb->asoc.refcnt, 1); 5057b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen SCTP_TCB_UNLOCK(stcb); 5058b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen } 50598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 5060b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb) { 5061b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen SCTP_TCB_LOCK(stcb); 5062b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 5063b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen } 50648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 50658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 50668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 50678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 50698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sorwakeup(inp, inp->sctp_socket); 50700612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 50718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 50728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 50738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 50768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 50778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*************HOLD THIS COMMENT FOR PATCH FILE OF 50818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *************ALTERNATE ROUTING CODE 50828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 50838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/*************HOLD THIS COMMENT FOR END OF PATCH FILE OF 50858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *************ALTERNATE ROUTING CODE 50868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 50878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct mbuf * 50898f9e45fea288542b24a6bda01269c6fc184d991atsctp_generate_cause(uint16_t code, char *info) 50908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 50918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m; 50928f9e45fea288542b24a6bda01269c6fc184d991at struct sctp_gen_error_cause *cause; 50938f9e45fea288542b24a6bda01269c6fc184d991at size_t info_len, len; 50948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50958f9e45fea288542b24a6bda01269c6fc184d991at if ((code == 0) || (info == NULL)) { 50968f9e45fea288542b24a6bda01269c6fc184d991at return (NULL); 50978f9e45fea288542b24a6bda01269c6fc184d991at } 50988f9e45fea288542b24a6bda01269c6fc184d991at info_len = strlen(info); 50998f9e45fea288542b24a6bda01269c6fc184d991at len = sizeof(struct sctp_paramhdr) + info_len; 51008f9e45fea288542b24a6bda01269c6fc184d991at m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); 51018f9e45fea288542b24a6bda01269c6fc184d991at if (m != NULL) { 51028f9e45fea288542b24a6bda01269c6fc184d991at SCTP_BUF_LEN(m) = len; 51038f9e45fea288542b24a6bda01269c6fc184d991at cause = mtod(m, struct sctp_gen_error_cause *); 51048f9e45fea288542b24a6bda01269c6fc184d991at cause->code = htons(code); 51058f9e45fea288542b24a6bda01269c6fc184d991at cause->length = htons((uint16_t)len); 51068f9e45fea288542b24a6bda01269c6fc184d991at memcpy(cause->info, info, info_len); 51078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (m); 51098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 51108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5111a06ca64c1ea60031147a135d015c66e4803beb1ctstruct mbuf * 5112a06ca64c1ea60031147a135d015c66e4803beb1ctsctp_generate_no_user_data_cause(uint32_t tsn) 5113a06ca64c1ea60031147a135d015c66e4803beb1ct{ 5114a06ca64c1ea60031147a135d015c66e4803beb1ct struct mbuf *m; 5115a06ca64c1ea60031147a135d015c66e4803beb1ct struct sctp_error_no_user_data *no_user_data_cause; 5116a06ca64c1ea60031147a135d015c66e4803beb1ct size_t len; 5117a06ca64c1ea60031147a135d015c66e4803beb1ct 5118a06ca64c1ea60031147a135d015c66e4803beb1ct len = sizeof(struct sctp_error_no_user_data); 5119a06ca64c1ea60031147a135d015c66e4803beb1ct m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); 5120a06ca64c1ea60031147a135d015c66e4803beb1ct if (m != NULL) { 5121a06ca64c1ea60031147a135d015c66e4803beb1ct SCTP_BUF_LEN(m) = len; 5122a06ca64c1ea60031147a135d015c66e4803beb1ct no_user_data_cause = mtod(m, struct sctp_error_no_user_data *); 5123a06ca64c1ea60031147a135d015c66e4803beb1ct no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA); 5124a06ca64c1ea60031147a135d015c66e4803beb1ct no_user_data_cause->cause.length = htons((uint16_t)len); 5125a06ca64c1ea60031147a135d015c66e4803beb1ct no_user_data_cause->tsn = tsn; /* tsn is passed in as NBO */ 5126a06ca64c1ea60031147a135d015c66e4803beb1ct } 5127a06ca64c1ea60031147a135d015c66e4803beb1ct return (m); 5128a06ca64c1ea60031147a135d015c66e4803beb1ct} 5129a06ca64c1ea60031147a135d015c66e4803beb1ct 51308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MBCNT_LOGGING 51318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 51328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc, 51338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *tp1, int chk_cnt) 51348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 51358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tp1->data == NULL) { 51368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 51378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->chunks_on_out_queue -= chk_cnt; 51398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBCNT_LOGGING_ENABLE) { 51408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE, 51418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->total_output_queue_size, 51428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1->book_size, 51438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 0, 51448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1->mbcnt); 51458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->total_output_queue_size >= tp1->book_size) { 51478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&asoc->total_output_queue_size, -tp1->book_size); 51488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 51498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->total_output_queue_size = 0; 51508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) || 51538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) { 51548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { 51558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size; 51568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 51578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_socket->so_snd.sb_cc = 0; 51588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 51628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 51648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 51668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, 516747674b651417d493ff4e0318113fd7beeef119dbtuexen uint8_t sent, int so_locked 51688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING) 51698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_UNUSED 51708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 51718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) 51728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 51738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_out *strq; 51748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *chk = NULL, *tp2; 51758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_queue_pending *sp; 5176b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen uint16_t stream = 0, seq = 0; 51778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t foundeom = 0; 51788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ret_sz = 0; 51798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int notdone; 5180b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int do_wakeup_routine = 0; 518120d5d287bff2075897105f85287230d55bdfa420t 51828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 51838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so_locked) { 51848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep)); 51858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 51868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep)); 51878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 51898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stream = tp1->rec.data.stream_number; 51908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen seq = tp1->rec.data.stream_seq; 519120d5d287bff2075897105f85287230d55bdfa420t if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) { 519220d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.abandoned_sent[0]++; 519320d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++; 519420d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.strmout[stream].abandoned_sent[0]++; 519520d5d287bff2075897105f85287230d55bdfa420t#if defined(SCTP_DETAILED_STR_STATS) 519620d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.strmout[stream].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++; 519720d5d287bff2075897105f85287230d55bdfa420t#endif 519820d5d287bff2075897105f85287230d55bdfa420t } else { 519920d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.abandoned_unsent[0]++; 520020d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++; 520120d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.strmout[stream].abandoned_unsent[0]++; 520220d5d287bff2075897105f85287230d55bdfa420t#if defined(SCTP_DETAILED_STR_STATS) 520320d5d287bff2075897105f85287230d55bdfa420t stcb->asoc.strmout[stream].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++; 520420d5d287bff2075897105f85287230d55bdfa420t#endif 520520d5d287bff2075897105f85287230d55bdfa420t } 52068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen do { 52078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ret_sz += tp1->book_size; 52088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tp1->data != NULL) { 52098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tp1->sent < SCTP_DATAGRAM_RESEND) { 52108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_flight_size_decrease(tp1); 52118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_total_flight_decrease(stcb, tp1); 52128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1); 52148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.peers_rwnd += tp1->send_size; 52158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh); 521647674b651417d493ff4e0318113fd7beeef119dbtuexen if (sent) { 521747674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked); 521847674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 521947674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked); 522047674b651417d493ff4e0318113fd7beeef119dbtuexen } 52218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tp1->data) { 52228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(tp1->data); 52238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1->data = NULL; 52248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen do_wakeup_routine = 1; 52268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (PR_SCTP_BUF_ENABLED(tp1->flags)) { 52278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sent_queue_cnt_removeable--; 52288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1->sent = SCTP_FORWARD_TSN_SKIP; 52318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) == 52328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_DATA_NOT_FRAG) { 52338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not frag'ed we ae done */ 52348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen notdone = 0; 52358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen foundeom = 1; 52368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { 52378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* end of frag, we are done */ 52388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen notdone = 0; 52398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen foundeom = 1; 52408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 52428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Its a begin or middle piece, we must mark all of 52438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * it 52448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 52458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen notdone = 1; 52468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1 = TAILQ_NEXT(tp1, sctp_next); 52478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } while (tp1 && notdone); 52498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (foundeom == 0) { 52508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 52518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The multi-part message was scattered across the send and 52528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sent queue. 52538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 52548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) { 52558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((tp1->rec.data.stream_number != stream) || 5256e2828360ea9cf8951730d46f5c14626c9425cb30t (tp1->rec.data.stream_seq != seq)) { 52578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 52588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* save to chk in case we have some on stream out 52608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * queue. If so and we have an un-transmitted one 52618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we don't have to fudge the TSN. 52628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 52638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk = tp1; 52648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ret_sz += tp1->book_size; 52658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1); 526647674b651417d493ff4e0318113fd7beeef119dbtuexen if (sent) { 526747674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked); 526847674b651417d493ff4e0318113fd7beeef119dbtuexen } else { 526947674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked); 527047674b651417d493ff4e0318113fd7beeef119dbtuexen } 52718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tp1->data) { 52728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(tp1->data); 52738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1->data = NULL; 52748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* No flight involved here book the size to 0 */ 52768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1->book_size = 0; 52778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { 52788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen foundeom = 1; 52798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen do_wakeup_routine = 1; 52818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tp1->sent = SCTP_FORWARD_TSN_SKIP; 52828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next); 52838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* on to the sent queue so we can wait for it to be passed by. */ 52848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1, 52858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_next); 52868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.send_queue_cnt--; 52878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sent_queue_cnt++; 52888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (foundeom == 0) { 52918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 52928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Still no eom found. That means there 52938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is stuff left on the stream out queue.. yuck. 52948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 52958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_SEND_LOCK(stcb); 5296e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t strq = &stcb->asoc.strmout[stream]; 5297e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sp = TAILQ_FIRST(&strq->outqueue); 5298e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t if (sp != NULL) { 5299e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sp->discard_rest = 1; 5300e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t /* 5301e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * We may need to put a chunk on the 5302e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * queue that holds the TSN that 5303e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * would have been sent with the LAST 5304e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * bit. 5305e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t */ 5306e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t if (chk == NULL) { 5307e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t /* Yep, we have to */ 5308e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sctp_alloc_a_chunk(stcb, chk); 53098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk == NULL) { 5310e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t /* we are hosed. All we can 5311e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * do is nothing.. which will 5312e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * cause an abort if the peer is 5313e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * paying attention. 53148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 5315e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t goto oh_well; 53168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5317e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t memset(chk, 0, sizeof(*chk)); 5318e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.rcv_flags = SCTP_DATA_LAST_FRAG; 5319e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->sent = SCTP_FORWARD_TSN_SKIP; 5320e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->asoc = &stcb->asoc; 5321e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.stream_seq = strq->next_sequence_send; 5322e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.stream_number = sp->stream; 5323e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.payloadtype = sp->ppid; 5324e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.context = sp->context; 5325e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->flags = sp->act_flags; 5326e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t if (sp->net) 5327e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->whoTo = sp->net; 5328e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t else 5329e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->whoTo = stcb->asoc.primary_destination; 5330e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t atomic_add_int(&chk->whoTo->ref_count, 1); 5331e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t#if defined(__FreeBSD__) || defined(__Panda__) 5332e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1); 5333e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t#else 5334e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.TSN_seq = stcb->asoc.sending_seq++; 5335e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t#endif 5336e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t stcb->asoc.pr_sctp_cnt++; 5337e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next); 5338e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t stcb->asoc.sent_queue_cnt++; 5339e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t stcb->asoc.pr_sctp_cnt++; 5340e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t } else { 5341e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG; 5342e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t } 5343e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t strq->next_sequence_send++; 5344e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t oh_well: 5345e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t if (sp->data) { 5346e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t /* Pull any data to free up the SB and 5347e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * allow sender to "add more" while we 5348e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t * will throw away :-) 5349e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t */ 5350e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sctp_free_spbufspace(stcb, &stcb->asoc, sp); 5351e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t ret_sz += sp->length; 5352e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t do_wakeup_routine = 1; 5353e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sp->some_taken = 1; 5354e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sctp_m_freem(sp->data); 5355e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sp->data = NULL; 5356e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sp->tail_mbuf = NULL; 5357e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t sp->length = 0; 53588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5359e5a3ccc4bb0971ef33da073d15fd0fc1ccaa3c01t } 53608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_SEND_UNLOCK(stcb); 53618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (do_wakeup_routine) { 53630612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 53648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 53658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(stcb->sctp_ep); 53678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 53688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 53698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 53708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 53718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 53728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 53738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { 53748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* assoc was freed while we were unlocked */ 53758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 53768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ret_sz); 53778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 53808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket); 53810612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 53828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!so_locked) { 53838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 53848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 53868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ret_sz); 53888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 53898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 53918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * checks to see if the given address, sa, is one that is currently known by 53928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the kernel note: can't distinguish the same address on multiple interfaces 53938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * and doesn't handle multiple addresses with different zone/scope id's note: 53948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ifa_ifwithaddr() compares the entire sockaddr struct 53958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 53968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct sctp_ifa * 53978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr, 53988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int holds_lock) 53998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 54008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 54018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) { 54038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 54048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 54078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (laddr->ifa == NULL) 54088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 54098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_family != laddr->ifa->address.sa.sa_family) 54108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 54118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 54128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_family == AF_INET) { 54138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((struct sockaddr_in *)addr)->sin_addr.s_addr == 54148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen laddr->ifa->address.sin.sin_addr.s_addr) { 54158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* found him. */ 54168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) { 54178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 54188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (laddr->ifa); 54208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 54248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 54258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_family == AF_INET6) { 54268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr, 54278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &laddr->ifa->address.sin6)) { 54288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* found him. */ 54298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) { 54308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 54318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (laddr->ifa); 54338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 543766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 543866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen if (addr->sa_family == AF_CONN) { 543966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen if (((struct sockaddr_conn *)addr)->sconn_addr == laddr->ifa->address.sconn.sconn_addr) { 544066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen /* found him. */ 544166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen if (holds_lock == 0) { 544266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen SCTP_INP_RUNLOCK(inp); 544366e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 544466e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen return (laddr->ifa); 544566e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 544666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 544766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 544866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 54498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) { 54518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 54528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 54548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 54558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenuint32_t 54578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_get_ifa_hash_val(struct sockaddr *addr) 54588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 54598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (addr->sa_family) { 54608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 54618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 54628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 54648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)addr; 54668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sin->sin_addr.s_addr ^ (sin->sin_addr.s_addr >> 16)); 54678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 54698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 54709ac77419b79fa1b61bed4326c4ef825a19335704t case AF_INET6: 54718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 54738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t hash_of_addr; 54748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)addr; 547623273859c39742f09cc5ec7c9bf32ff225661e82tuexen#if !defined(__Windows__) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_Windows) 54778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hash_of_addr = (sin6->sin6_addr.s6_addr32[0] + 54788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_addr.s6_addr32[1] + 54798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_addr.s6_addr32[2] + 54808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_addr.s6_addr32[3]); 54818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 54828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hash_of_addr = (((uint32_t *)&sin6->sin6_addr)[0] + 54838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((uint32_t *)&sin6->sin6_addr)[1] + 54848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((uint32_t *)&sin6->sin6_addr)[2] + 54858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((uint32_t *)&sin6->sin6_addr)[3]); 54868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 54878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hash_of_addr = (hash_of_addr ^ (hash_of_addr >> 16)); 54888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (hash_of_addr); 54898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 54919ac77419b79fa1b61bed4326c4ef825a19335704t#if defined(__Userspace__) 54929ac77419b79fa1b61bed4326c4ef825a19335704t case AF_CONN: 54939ac77419b79fa1b61bed4326c4ef825a19335704t { 54949ac77419b79fa1b61bed4326c4ef825a19335704t struct sockaddr_conn *sconn; 54955e35dea4d54c8ee4a750282fee252af98032dd37t uintptr_t temp; 54969ac77419b79fa1b61bed4326c4ef825a19335704t 54979ac77419b79fa1b61bed4326c4ef825a19335704t sconn = (struct sockaddr_conn *)addr; 54985e35dea4d54c8ee4a750282fee252af98032dd37t temp = (uintptr_t)sconn->sconn_addr; 54999ac77419b79fa1b61bed4326c4ef825a19335704t return ((uint32_t)(temp ^ (temp >> 16))); 55009ac77419b79fa1b61bed4326c4ef825a19335704t } 55019ac77419b79fa1b61bed4326c4ef825a19335704t#endif 55028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 55038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 55068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 55078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct sctp_ifa * 55098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock) 55108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 55118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *sctp_ifap; 55128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_vrf *vrf; 55138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifalist *hash_head; 55148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t hash_of_addr; 55158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) 55178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RLOCK(); 55188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf = sctp_find_vrf(vrf_id); 55208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf == NULL) { 55218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stage_right: 55228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) 55238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 55248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 55258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hash_of_addr = sctp_get_ifa_hash_val(addr); 55288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hash_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)]; 55308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hash_head == NULL) { 55318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("hash_of_addr:%x mask:%x table:%x - ", 55328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hash_of_addr, (uint32_t)vrf->vrf_addr_hashmark, 55338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (uint32_t)(hash_of_addr & vrf->vrf_addr_hashmark)); 55348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_print_address(addr); 55358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("No such bucket for address\n"); 55368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) 55378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 55388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 55408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifap, hash_head, next_bucket) { 55428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_ifap == NULL) { 55438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 55448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("Huh LIST_FOREACH corrupt"); 55458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto stage_right; 55468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 55478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("LIST corrupt of sctp_ifap's?\n"); 55488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto stage_right; 55498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 55508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_family != sctp_ifap->address.sa.sa_family) 55528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 55538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 55548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_family == AF_INET) { 55558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((struct sockaddr_in *)addr)->sin_addr.s_addr == 55568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ifap->address.sin.sin_addr.s_addr) { 55578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* found him. */ 55588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) 55598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 55608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sctp_ifap); 55618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 55658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 55668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_family == AF_INET6) { 55678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr, 55688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &sctp_ifap->address.sin6)) { 55698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* found him. */ 55708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) 55718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 55728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (sctp_ifap); 55738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 557766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 557866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen if (addr->sa_family == AF_CONN) { 557966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen if (((struct sockaddr_conn *)addr)->sconn_addr == sctp_ifap->address.sconn.sconn_addr) { 558066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen /* found him. */ 558166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen if (holds_lock == 0) 558266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen SCTP_IPI_ADDR_RUNLOCK(); 558366e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen return (sctp_ifap); 558466e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 558566e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 558666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 558766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 55888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (holds_lock == 0) 55908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 55918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 55928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 55938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 55958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_user_rcvd(struct sctp_tcb *stcb, uint32_t *freed_so_far, int hold_rlock, 55968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t rwnd_req) 55978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 55988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* User pulled some data, do we need a rwnd update? */ 55998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int r_unlocked = 0; 56008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t dif, rwnd; 56018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so = NULL; 56028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) 56048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 56058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 56078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & (SCTP_STATE_ABOUT_TO_BE_FREED | 56098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STATE_SHUTDOWN_RECEIVED | 56108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STATE_SHUTDOWN_ACK_SENT)) { 56118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Pre-check If we are freeing no update */ 56128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto no_lock; 56138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(stcb->sctp_ep); 56158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 56168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { 56178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 56188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = stcb->sctp_socket; 56208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so == NULL) { 56218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 56228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->freed_by_sorcv_sincelast, *freed_so_far); 56248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Have you have freed enough to look */ 56258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *freed_so_far = 0; 56268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Yep, its worth a look and the lock overhead */ 56278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Figure out what the rwnd would be */ 56298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rwnd = sctp_calc_rwnd(stcb, &stcb->asoc); 56308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (rwnd >= stcb->asoc.my_last_reported_rwnd) { 56318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen dif = rwnd - stcb->asoc.my_last_reported_rwnd; 56328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen dif = 0; 56348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (dif >= rwnd_req) { 56368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock) { 56378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(stcb->sctp_ep); 56388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen r_unlocked = 1; 56398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 56418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 56428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * One last check before we allow the guy possibly 56438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * to get in. There is a race, where the guy has not 56448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * reached the gate. In that case 56458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 56468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 56478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 56498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 56508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* No reports here */ 56518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 56528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 56538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_wu_sacks_sent); 56558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_sack(stcb, SCTP_SO_LOCKED); 5656000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 56578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(stcb->sctp_ep, stcb, 56588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED); 56598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* make sure no timer is running */ 5660b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTPUTIL+SCTP_LOC_6); 56618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 56628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Update how much we have pending */ 56648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->freed_by_sorcv_sincelast = dif; 56658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out: 56678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so && r_unlocked && hold_rlock) { 56688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(stcb->sctp_ep); 56698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(stcb->sctp_ep); 56728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen no_lock: 56738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, -1); 56748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 56758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 56768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 56788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_sorecvmsg(struct socket *so, 56798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct uio *uio, 56808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf **mp, 56818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *from, 56828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int fromlen, 56838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int *msg_flags, 56848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndrcvinfo *sinfo, 56858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int filling_sinfo) 56868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 56878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 56888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * MSG flags we will look at MSG_DONTWAIT - non-blocking IO. 56898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * MSG_PEEK - Look don't touch :-D (only valid with OUT mbuf copy 56908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * mp=NULL thus uio is the copy method to userland) MSG_WAITALL - ?? 56918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * On the way out we may send out any combination of: 56928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * MSG_NOTIFICATION MSG_EOR 56938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 56948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 5695b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct sctp_inpcb *inp = NULL; 5696b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int my_len = 0; 5697b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int cp_len = 0, error = 0; 5698b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct sctp_queued_to_read *control = NULL, *ctl = NULL, *nxt = NULL; 5699b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct mbuf *m = NULL; 57008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 57018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int wakeup_read_socket = 0; 57028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int freecnt_applied = 0; 5703b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int out_flags = 0, in_flags = 0; 57048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int block_allowed = 1; 57058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t freed_so_far = 0; 57068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t copied_so_far = 0; 5707b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int in_eeor_mode = 0; 57088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int no_rcv_needed = 0; 5709b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen uint32_t rwnd_req = 0; 57108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int hold_sblock = 0; 57118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int hold_rlock = 0; 57128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int slen = 0; 57138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t held_length = 0; 57148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 57158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int sockbuf_lock = 0; 57168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (uio == NULL) { 57198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 57208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 57218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (msg_flags) { 57248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in_flags = *msg_flags; 57258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in_flags & MSG_PEEK) 57268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR(sctps_read_peeks); 57278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 57288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in_flags = 0; 57298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 57311ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 57328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen slen = uio->uio_resid; 57331ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#else 57341ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen slen = uio_resid(uio); 57358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 57378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen slen = uio->uio_resid; 57388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Pull in and set up our int flags */ 57418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in_flags & MSG_OOB) { 57428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Out of band's NOT supported */ 57438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EOPNOTSUPP); 57448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((in_flags & MSG_PEEK) && (mp != NULL)) { 57468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 57478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 57488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((in_flags & (MSG_DONTWAIT 57508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version > 500000 57518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen | MSG_NBIO 57528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen )) || 57548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SO_IS_NBIO(so)) { 57558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen block_allowed = 0; 57568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* setup the endpoint */ 57588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 57598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 57608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT); 57618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EFAULT); 57628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT); 57648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Must be at least a MTU's worth */ 57658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (rwnd_req < SCTP_MIN_RWND) 57668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rwnd_req = SCTP_MIN_RWND; 57678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); 576815aed6e434dc1aac416f14635bb78920317d60e7t if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) { 57698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 57701ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 57718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_ENTER, 57721ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio->uio_resid); 57738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 57748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_ENTER, 57751ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio_resid(uio)); 57768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 57788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_ENTER, 57798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rwnd_req, in_eeor_mode, so->so_rcv.sb_cc, uio->uio_resid); 57808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__) 57838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&so->so_rcv); 57848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 1; 57858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) { 57878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 57881ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 57898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_ENTERPL, 57901ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid); 57918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 57928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_ENTERPL, 57931ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen rwnd_req, block_allowed, so->so_rcv.sb_cc, uio_resid(uio)); 57948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 57968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_ENTERPL, 57978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen rwnd_req, block_allowed, so->so_rcv.sb_cc, uio->uio_resid); 57988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 58028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags)); 58038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 58048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) 58068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sblock(&so->so_rcv, (block_allowed ? SBL_WAIT : 0)); 58078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 58088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 58098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release_unlocked; 58108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5811288bc15d7ec52924125686f12d3305b1730d9e6bt#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 5812288bc15d7ec52924125686f12d3305b1730d9e6bt sockbuf_lock = 1; 5813288bc15d7ec52924125686f12d3305b1730d9e6bt#endif 58148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen restart: 58158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__) 58168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock == 0) { 58178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&so->so_rcv); 58188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 1; 58198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 58218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 58228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sbunlock(&so->so_rcv, 1); 58238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 58248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 700000 58268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sbunlock(&so->so_rcv); 58278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 58288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen restart_nosblocks: 58308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock == 0) { 58318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&so->so_rcv); 58328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 1; 58338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 58358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { 58368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 58378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__) 583947674b651417d493ff4e0318113fd7beeef119dbtuexen if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) { 58408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 584147674b651417d493ff4e0318113fd7beeef119dbtuexen if ((so->so_state & SS_CANTRCVMORE) && (so->so_rcv.sb_cc == 0)) { 58428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 58438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_error) { 58448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = so->so_error; 58458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((in_flags & MSG_PEEK) == 0) 58468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_error = 0; 58478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 58488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 58498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_rcv.sb_cc == 0) { 58508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* indicate EOF */ 58518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 58528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 58538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((so->so_rcv.sb_cc <= held_length) && block_allowed) { 58578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we need to wait for data */ 58588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((so->so_rcv.sb_cc == 0) && 58598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 58608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { 58618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) { 58628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* For active open side clear flags for re-use 58638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * passive open is blocked by connect. 58648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 58658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) { 58668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* You were aborted, passive side always hits here */ 58678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET); 58688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ECONNRESET; 58698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_state &= ~(SS_ISCONNECTING | 58718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SS_ISDISCONNECTING | 58728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SS_ISCONFIRMING | 58738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SS_ISCONNECTED); 58748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 58758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) { 58768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN); 58778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 58788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 58818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sbwait(&so->so_rcv); 58848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 58858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 58868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen held_length = 0; 58888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto restart_nosblocks; 58898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (so->so_rcv.sb_cc == 0) { 58908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_error) { 58918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = so->so_error; 58928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((in_flags & MSG_PEEK) == 0) 58938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_error = 0; 58948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 58958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 58968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 58978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) { 58988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* For active open side clear flags for re-use 58998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * passive open is blocked by connect. 59008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 59018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) { 59028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* You were aborted, passive side always hits here */ 59038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET); 59048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ECONNRESET; 59058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_state &= ~(SS_ISCONNECTING | 59078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SS_ISDISCONNECTING | 59088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SS_ISCONFIRMING | 59098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SS_ISCONNECTED); 59108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 59118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) { 59128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN); 59138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 59148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 59178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EWOULDBLOCK); 59208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EWOULDBLOCK; 59218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 59238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock == 1) { 59258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&so->so_rcv); 59268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 0; 59278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 59298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags)); 59308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 59318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 700000 59328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0)); 59338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 59348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we possibly have data we can read */ 59358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*sa_ignore FREED_MEMORY*/ 59368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = TAILQ_FIRST(&inp->read_queue); 59378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control == NULL) { 59388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* This could be happening since 59398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the appender did the increment but as not 59408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * yet did the tailq insert onto the read_queue 59418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 59428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 0) { 59438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 59448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = TAILQ_FIRST(&inp->read_queue); 59468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control == NULL) && (so->so_rcv.sb_cc != 0)) { 59478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 59488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("Huh, its non zero and nothing on control?"); 59498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 59508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_rcv.sb_cc = 0; 59518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 59538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 0; 59548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto restart; 59558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->length == 0) && 59588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->do_not_ref_stcb)) { 59598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Clean up code for freeing assoc that left behind a pdapi.. 59608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * maybe a peer in EEOR that just closed after sending and 59618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * never indicated a EOR. 59628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 59638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 0) { 59648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 1; 59658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 59668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = 0; 59688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->data) { 59698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Hmm there is data here .. fix */ 59708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m_tmp; 5971b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int cnt = 0; 59728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_tmp = control->data; 59738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (m_tmp) { 59748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += SCTP_BUF_LEN(m_tmp); 59758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BUF_NEXT(m_tmp) == NULL) { 59768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = m_tmp; 59778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->end_added = 1; 59788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_tmp = SCTP_BUF_NEXT(m_tmp); 59808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = cnt; 59828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* remove it */ 59848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&inp->read_queue, control, next); 59858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Add back any hiddend data */ 59868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(control->whoFrom); 59878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_a_readq(stcb, control); 59888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock) { 59908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 0; 59918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 59928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto restart; 59948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->length == 0) && 59968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->end_added == 1)) { 59978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Do we also need to check for (control->pdapi_aborted == 1)? */ 59988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 0) { 59998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 1; 60008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 60018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&inp->read_queue, control, next); 60038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->data) { 60048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 60058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("control->data not null but control->length == 0"); 60068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 60078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("Strange, data left in the control buffer. Cleaning up.\n"); 60088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(control->data); 60098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = NULL; 60108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->aux_data) { 60138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_free (control->aux_data); 60148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->aux_data = NULL; 60158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(control->whoFrom); 60178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_a_readq(stcb, control); 60188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock) { 60198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 0; 60208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 60218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto restart; 60238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->length == 0) { 60258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) && 60268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (filling_sinfo)) { 60278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* find a more suitable one then this */ 60288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ctl = TAILQ_NEXT(control, next); 60298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (ctl) { 60308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((ctl->stcb != control->stcb) && (ctl->length) && 60318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (ctl->some_taken || 60328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (ctl->spec_flags & M_NOTIFICATION) || 60338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((ctl->do_not_ref_stcb == 0) && 60348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0))) 60358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) { 60368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*- 60378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * If we have a different TCB next, and there is data 60388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * present. If we have already taken some (pdapi), OR we can 60398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ref the tcb and no delivery as started on this stream, we 60408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * take it. Note we allow a notification on a different 60418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * assoc to be delivered.. 60428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 60438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = ctl; 60448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto found_one; 60458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) && 60468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (ctl->length) && 60478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((ctl->some_taken) || 60488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((ctl->do_not_ref_stcb == 0) && 60498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((ctl->spec_flags & M_NOTIFICATION) == 0) && 60508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))) { 60518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*- 60528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * If we have the same tcb, and there is data present, and we 60538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * have the strm interleave feature present. Then if we have 60548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * taken some (pdapi) or we can refer to tht tcb AND we have 60558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * not started a delivery for this stream, we can take it. 60568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Note we do NOT allow a notificaiton on the same assoc to 60578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * be delivered. 60588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 60598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = ctl; 60608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto found_one; 60618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ctl = TAILQ_NEXT(ctl, next); 60638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 60668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * if we reach here, not suitable replacement is available 60678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * <or> fragment interleave is NOT on. So stuff the sb_cc 60688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * into the our held count, and its time to sleep again. 60698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 60708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen held_length = so->so_rcv.sb_cc; 60718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = so->so_rcv.sb_cc; 60728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto restart; 60738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Clear the held length since there is something to read */ 60758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = 0; 60768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock) { 60778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 60788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 0; 60798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen found_one: 60818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 60828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * If we reach here, control has a some data for us to read off. 60838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Note that stcb COULD be NULL. 60848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 60858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->some_taken++; 60868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock) { 60878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&so->so_rcv); 60888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 0; 60898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = control->stcb; 60918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 60928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->do_not_ref_stcb == 0) && 60938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) { 60948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (freecnt_applied == 0) 60958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = NULL; 60968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (control->do_not_ref_stcb == 0) { 60978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* you can't free it on me please */ 60988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 60998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The lock on the socket buffer protects us so the 61008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * free code will stop. But since we used the socketbuf 61018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * lock and the sender uses the tcb_lock to increment, 61028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we need to use the atomic add to the refcnt 61038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 61048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (freecnt_applied) { 61058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 61068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("refcnt already incremented"); 61078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 610847a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("refcnt already incremented?\n"); 61098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 61128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freecnt_applied = 1; 61138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 61158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Setup to remember how much we have not yet told 61168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the peer our rwnd has opened up. Note we grab 61178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the value from the tcb from last time. 61188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Note too that sack sending clears this when a sack 61198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is sent, which is fine. Once we hit the rwnd_req, 61208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we then will go to the sctp_user_rcvd() that will 61218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * not lock until it KNOWs it MUST send a WUP-SACK. 61228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 61238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far = stcb->freed_by_sorcv_sincelast; 61248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->freed_by_sorcv_sincelast = 0; 61258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb && 61288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((control->spec_flags & M_NOTIFICATION) == 0) && 61298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->do_not_ref_stcb == 0) { 61308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1; 61318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 61338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First lets get off the sinfo and sockaddr info */ 61348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sinfo) && filling_sinfo) { 61358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(sinfo, control, sizeof(struct sctp_nonpad_sndrcvinfo)); 61368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen nxt = TAILQ_NEXT(control, next); 61378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) || 61388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) { 61398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_extrcvinfo *s_extra; 61408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra = (struct sctp_extrcvinfo *)sinfo; 61418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((nxt) && 61428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (nxt->length)) { 61438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_flags = SCTP_NEXT_MSG_AVAIL; 61448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nxt->sinfo_flags & SCTP_UNORDERED) { 61458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_IS_UNORDERED; 61468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nxt->spec_flags & M_NOTIFICATION) { 61488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_IS_NOTIFICATION; 61498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_aid = nxt->sinfo_assoc_id; 61518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_length = nxt->length; 61528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_ppid = nxt->sinfo_ppid; 61538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_stream = nxt->sinfo_stream; 61548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nxt->tail_mbuf != NULL) { 61558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nxt->end_added) { 61568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_flags |= SCTP_NEXT_MSG_ISCOMPLETE; 61578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we explicitly 0 this, since the memcpy got 61618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * some other things beyond the older sinfo_ 61628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * that is on the control's structure :-D 61638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 61648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen nxt = NULL; 61658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_flags = SCTP_NO_NEXT_MSG; 61668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_aid = 0; 61678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_length = 0; 61688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_ppid = 0; 61698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_stream = 0; 61708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 61738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * update off the real current cum-ack, if we have an stcb. 61748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 61758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->do_not_ref_stcb == 0) && stcb) 61768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinfo->sinfo_cumtsn = stcb->asoc.cumulative_tsn; 61778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 61788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * mask off the high bits, we keep the actual chunk bits in 61798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * there. 61808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 61818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinfo->sinfo_flags &= 0x00ff; 61828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) { 61838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinfo->sinfo_flags |= SCTP_UNORDERED; 61848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_ASOCLOG_OF_TSNS 61878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 61888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int index, newindex; 61898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_pcbtsn_rlog *entry; 61908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen do { 61918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen index = inp->readlog_index; 61928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen newindex = index + 1; 61938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (newindex >= SCTP_READ_LOG_SIZE) { 61948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen newindex = 0; 61958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } while (atomic_cmpset_int(&inp->readlog_index, index, newindex) == 0); 61978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen entry = &inp->readlog[index]; 61988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen entry->vtag = control->sinfo_assoc_id; 61998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen entry->strm = control->sinfo_stream; 62008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen entry->seq = control->sinfo_ssn; 62018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen entry->sz = control->length; 62028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen entry->flgs = control->sinfo_flags; 62038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (fromlen && from) { 6206f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 6207314c1b3e200a8767983b36e7956f254e6c3ce322tuexen cp_len = min((size_t)fromlen, (size_t)control->whoFrom->ro._l_addr.sa.sa_len); 62088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6209314c1b3e200a8767983b36e7956f254e6c3ce322tuexen switch (control->whoFrom->ro._l_addr.sa.sa_family) { 6210314c1b3e200a8767983b36e7956f254e6c3ce322tuexen#ifdef INET6 6211314c1b3e200a8767983b36e7956f254e6c3ce322tuexen case AF_INET6: 6212f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifndef HAVE_SA_LEN 6213314c1b3e200a8767983b36e7956f254e6c3ce322tuexen cp_len = min((size_t)fromlen, sizeof(struct sockaddr_in6)); 62148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6215314c1b3e200a8767983b36e7956f254e6c3ce322tuexen ((struct sockaddr_in6 *)from)->sin6_port = control->port_from; 6216314c1b3e200a8767983b36e7956f254e6c3ce322tuexen break; 62178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6218314c1b3e200a8767983b36e7956f254e6c3ce322tuexen#ifdef INET 6219314c1b3e200a8767983b36e7956f254e6c3ce322tuexen case AF_INET: 6220f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifndef HAVE_SA_LEN 6221314c1b3e200a8767983b36e7956f254e6c3ce322tuexen cp_len = min((size_t)fromlen, sizeof(struct sockaddr_in)); 6222314c1b3e200a8767983b36e7956f254e6c3ce322tuexen#endif 6223314c1b3e200a8767983b36e7956f254e6c3ce322tuexen ((struct sockaddr_in *)from)->sin_port = control->port_from; 6224314c1b3e200a8767983b36e7956f254e6c3ce322tuexen break; 6225314c1b3e200a8767983b36e7956f254e6c3ce322tuexen#endif 622666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 622766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 6228f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifndef HAVE_SA_LEN 622966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen cp_len = min((size_t)fromlen, sizeof(struct sockaddr_conn)); 623066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 623166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen ((struct sockaddr_conn *)from)->sconn_port = control->port_from; 623266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 623366e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 6234314c1b3e200a8767983b36e7956f254e6c3ce322tuexen default: 6235f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifndef HAVE_SA_LEN 6236314c1b3e200a8767983b36e7956f254e6c3ce322tuexen cp_len = min((size_t)fromlen, sizeof(struct sockaddr)); 6237314c1b3e200a8767983b36e7956f254e6c3ce322tuexen#endif 6238314c1b3e200a8767983b36e7956f254e6c3ce322tuexen break; 6239314c1b3e200a8767983b36e7956f254e6c3ce322tuexen } 6240314c1b3e200a8767983b36e7956f254e6c3ce322tuexen memcpy(from, &control->whoFrom->ro._l_addr, cp_len); 62418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(INET) && defined(INET6) 62438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) && 6244314c1b3e200a8767983b36e7956f254e6c3ce322tuexen (from->sa_family == AF_INET) && 62458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((size_t)fromlen >= sizeof(struct sockaddr_in6))) { 62468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 62478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 sin6; 62488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6249314c1b3e200a8767983b36e7956f254e6c3ce322tuexen sin = (struct sockaddr_in *)from; 62508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero(&sin6, sizeof(sin6)); 62518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6.sin6_family = AF_INET6; 62527b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 62538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6.sin6_len = sizeof(struct sockaddr_in6); 62548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 625523273859c39742f09cc5ec7c9bf32ff225661e82tuexen#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin) || defined(__Userspace_os_Windows) 6256314c1b3e200a8767983b36e7956f254e6c3ce322tuexen ((uint32_t *)&sin6.sin6_addr)[2] = htonl(0xffff); 62578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bcopy(&sin->sin_addr, 6258314c1b3e200a8767983b36e7956f254e6c3ce322tuexen &(((uint32_t *)&sin6.sin6_addr)[3]), 6259314c1b3e200a8767983b36e7956f254e6c3ce322tuexen sizeof(uint32_t)); 62608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 62618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((uint32_t *)&sin6.sin6_addr)[2] = htonl(0xffff); 62628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bcopy(&sin->sin_addr, 62638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &((uint32_t *)&sin6.sin6_addr)[3], 62648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(uint32_t)); 62658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 62668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); 62678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bcopy(&sin->sin_addr, 62688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &sin6.sin6_addr.s6_addr32[3], 62698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(sin6.sin6_addr.s6_addr32[3])); 62708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6.sin6_port = sin->sin_port; 6272314c1b3e200a8767983b36e7956f254e6c3ce322tuexen memcpy(from, &sin6, sizeof(struct sockaddr_in6)); 62738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 6276e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET6 62778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 6278314c1b3e200a8767983b36e7956f254e6c3ce322tuexen struct sockaddr_in6 lsa6, *from6; 6279314c1b3e200a8767983b36e7956f254e6c3ce322tuexen 6280314c1b3e200a8767983b36e7956f254e6c3ce322tuexen from6 = (struct sockaddr_in6 *)from; 6281314c1b3e200a8767983b36e7956f254e6c3ce322tuexen sctp_recover_scope_mac(from6, (&lsa6)); 62828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now copy out what data we can */ 62878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (mp == NULL) { 62888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy out each mbuf in the chain up to length */ 62898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen get_more_data: 62908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = control->data; 62918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (m) { 62928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Move out all we can */ 62938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 62941ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 62958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cp_len = (int)uio->uio_resid; 62961ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#else 62971ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen cp_len = (int)uio_resid(uio); 62988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 63008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cp_len = (int)uio->uio_resid; 63018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen my_len = (int)SCTP_BUF_LEN(m); 63038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cp_len > my_len) { 63048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not enough in this buf */ 63058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cp_len = my_len; 63068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock) { 63088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 63098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 0; 63108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 63128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 0); 63138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cp_len > 0) 63158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = uiomove(mtod(m, char *), cp_len, uio); 63168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 63178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 0); 63188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* re-read */ 63208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 63218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 63228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 63248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->do_not_ref_stcb == 0) && stcb && 63258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 63268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen no_rcv_needed = 1; 63278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 63298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* error we are out of here */ 63308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 63318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_BUF_NEXT(m) == NULL) && 63338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (cp_len >= SCTP_BUF_LEN(m)) && 63348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((control->end_added == 0) || 63358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->end_added && 63368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (TAILQ_NEXT(control, next) == NULL))) 63378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) { 63388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 63398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 1; 63408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cp_len == SCTP_BUF_LEN(m)) { 63428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_BUF_NEXT(m)== NULL) && 63438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->end_added)) { 63448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_EOR; 63458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->do_not_ref_stcb == 0) && 63468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->stcb != NULL) && 63478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((control->spec_flags & M_NOTIFICATION) == 0)) 63488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 63498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->spec_flags & M_NOTIFICATION) { 63518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_NOTIFICATION; 63528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we ate up the mbuf */ 63548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in_flags & MSG_PEEK) { 63558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* just looking */ 63568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(m); 63578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen copied_so_far += cp_len; 63588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* dispose of the mbuf */ 63608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 63618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&so->so_rcv, 63628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m)); 63638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sbfree(control, stcb, &so->so_rcv, m); 63658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 63668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&so->so_rcv, 63678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0); 63688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen copied_so_far += cp_len; 63708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far += cp_len; 63718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far += MSIZE; 63728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&control->length, cp_len); 63738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = sctp_m_free(m); 63748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = control->data; 63758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* been through it all, must hold sb lock ok to null tail */ 63768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->data == NULL) { 63778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 63788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) 63798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->end_added == 0) || 63808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (TAILQ_NEXT(control, next) == NULL)) { 63818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* If the end is not added, OR the 63828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * next is NOT null we MUST have the lock. 63838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 63848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (mtx_owned(&inp->inp_rdata_mtx) == 0) { 63858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("Hmm we don't own the lock?"); 63868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->tail_mbuf = NULL; 63918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 63928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->end_added) && ((out_flags & MSG_EOR) == 0)) { 63938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("end_added, nothing left and no MSG_EOR"); 63948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Do we need to trim the mbuf? */ 64008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->spec_flags & M_NOTIFICATION) { 64018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_NOTIFICATION; 64028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((in_flags & MSG_PEEK) == 0) { 64048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_RESV_UF(m, cp_len); 64058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(m) -= cp_len; 64068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 64078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&so->so_rcv, control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, cp_len); 64088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&so->so_rcv.sb_cc, cp_len); 6410b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((control->do_not_ref_stcb == 0) && 64118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb) { 64128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.sb_cc, cp_len); 64138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen copied_so_far += cp_len; 64158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far += cp_len; 64168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far += MSIZE; 64178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 64188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&so->so_rcv, control->do_not_ref_stcb?NULL:stcb, 64198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LOG_SBRESULT, 0); 64208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&control->length, cp_len); 64228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 64238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen copied_so_far += cp_len; 64248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 64271ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 64288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) { 64291ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#else 64301ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen if ((out_flags & MSG_EOR) || (uio_resid(uio) == 0)) { 64318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 64338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) { 64348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((stcb) && (in_flags & MSG_PEEK) == 0) && 64388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->do_not_ref_stcb == 0) && 64398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (freed_so_far >= rwnd_req)) { 64408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 64418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end while(m) */ 64438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 64448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * At this point we have looked at it all and we either have 64458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a MSG_EOR/or read all the user wants... <OR> 64468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * control->length == 0. 64478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 64488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) { 64498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we are done with this control */ 64508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->length == 0) { 64518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->data) { 64528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 64538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("control->data not null at read eor?"); 64548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 64558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("Strange, data left in the control buffer .. invarients would panic?\n"); 64568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(control->data); 64578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = NULL; 64588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen done_with_control: 64618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_NEXT(control, next) == NULL) { 64628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* If we don't have a next we need a 64638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * lock, if there is a next interrupt 64648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is filling ahead of us and we don't 64658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * need a lock to remove this guy 64668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * (which is the head of the queue). 64678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 64688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 0) { 64698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 64708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 1; 64718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_REMOVE(&inp->read_queue, control, next); 64748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Add back any hiddend data */ 64758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->held_length) { 64768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen held_length = 0; 64778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = 0; 64788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen wakeup_read_socket = 1; 64798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->aux_data) { 64818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_free (control->aux_data); 64828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->aux_data = NULL; 64838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen no_rcv_needed = control->do_not_ref_stcb; 64858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(control->whoFrom); 64868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = NULL; 64878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_a_readq(stcb, control); 64888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = NULL; 64898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((freed_so_far >= rwnd_req) && 64908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (no_rcv_needed == 0)) 64918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 64928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 64938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 64948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 64958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The user did not read all of this 64968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * message, turn off the returned MSG_EOR 64978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * since we are leaving more behind on the 64988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * control to read. 64998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 65008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 65018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->end_added && 65028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->data == NULL) && 65038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->tail_mbuf == NULL)) { 65048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("Gak, control->length is corrupt?"); 65058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen no_rcv_needed = control->do_not_ref_stcb; 65088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags &= ~MSG_EOR; 65098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (out_flags & MSG_EOR) { 65128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 65151ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 65168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((uio->uio_resid == 0) || 65171ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#else 65181ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen if ((uio_resid(uio) == 0) || 65198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 65218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((uio->uio_resid == 0) || 65228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 652318818c8dd0d4cafdb259fa73f01f7825948faadct ((in_eeor_mode) && 652418818c8dd0d4cafdb259fa73f01f7825948faadct (copied_so_far >= (uint32_t)max(so->so_rcv.sb_lowat, 1)))) { 65258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 65288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * If I hit here the receiver wants more and this message is 65298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NOT done (pd-api). So two questions. Can we block? if not 65308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we are done. Did the user NOT set MSG_WAITALL? 65318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 65328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (block_allowed == 0) { 65338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 65368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We need to wait for more data a few things: - We don't 65378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sbunlock() so we don't get someone else reading. - We 65388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * must be sure to account for the case where what is added 65398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is NOT to our control when we wakeup. 65408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 65418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 65428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Do we need to tell the transport a rwnd update might be 65438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * needed before we go to sleep? 65448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 65458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((stcb) && (in_flags & MSG_PEEK) == 0) && 65468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((freed_so_far >= rwnd_req) && 65478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control->do_not_ref_stcb == 0) && 65488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (no_rcv_needed == 0))) { 65498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 65508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen wait_some_more: 65528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__) 65538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { 65548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 65578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_state & SS_CANTRCVMORE) { 65588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 65628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) 65638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 65658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 1) { 65668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 65678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 0; 65688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock == 0) { 65708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&so->so_rcv); 65718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 1; 65728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((copied_so_far) && (control->length == 0) && 65748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) { 65758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65774b225662b4d798e7046f8c27ae1867b4fe4f4c17t#if defined(__APPLE__) 65784b225662b4d798e7046f8c27ae1867b4fe4f4c17t sbunlock(&so->so_rcv, 1); 65794b225662b4d798e7046f8c27ae1867b4fe4f4c17t#endif 65808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_rcv.sb_cc <= control->held_length) { 65818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sbwait(&so->so_rcv); 65828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 65838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) 65848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release; 65858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 65868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto release_unlocked; 65878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = 0; 65908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 65928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sblock(&so->so_rcv, SBLOCKWAIT(in_flags)); 65938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock) { 65958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&so->so_rcv); 65968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 0; 65978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->length == 0) { 65998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* still nothing here */ 66008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->end_added == 1) { 66018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* he aborted, or is done i.e.did a shutdown */ 66028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_EOR; 66038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->pdapi_aborted) { 66048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0)) 66058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 66068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 66078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_TRUNC; 66088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->do_not_ref_stcb == 0) && ((control->spec_flags & M_NOTIFICATION) == 0)) 66108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 66118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_control; 66138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_rcv.sb_cc > held_length) { 66158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->held_length = so->so_rcv.sb_cc; 66168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen held_length = 0; 66178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto wait_some_more; 66198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (control->data == NULL) { 66208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we must re-sync since data 66218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is probably being added 66228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 66238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 66248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->length > 0) && (control->data == NULL)) { 66258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* big trouble.. we have the lock and its corrupt? */ 66268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 66278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic ("Impossible data==NULL length !=0"); 66288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 66298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_EOR; 66308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_TRUNC; 66318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = 0; 66328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 66338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_control; 66348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 66368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We will fall around to get more data */ 66378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto get_more_data; 66398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*- 66418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Give caller back the mbuf chain, 66428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * store in uio_resid the length 66438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 66448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen wakeup_read_socket = 0; 66458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((control->end_added == 0) || 66468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (TAILQ_NEXT(control, next) == NULL)) { 66478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Need to get rlock */ 66488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 0) { 66498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 66508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 1; 66518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->end_added) { 66548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_EOR; 6655b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((control->do_not_ref_stcb == 0) && 6656b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen (control->stcb != NULL) && 6657b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen ((control->spec_flags & M_NOTIFICATION) == 0)) 66588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 0; 66598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control->spec_flags & M_NOTIFICATION) { 66618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_flags |= MSG_NOTIFICATION; 66628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 66641ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 66658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uio->uio_resid = control->length; 66661ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#else 66671ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen uio_setresid(uio, control->length); 66688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 66698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 66708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uio->uio_resid = control->length; 66718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 66728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *mp = control->data; 66738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = control->data; 66748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (m) { 66758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 66768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&so->so_rcv, 66778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m)); 66788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sbfree(control, stcb, &so->so_rcv, m); 66808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far += SCTP_BUF_LEN(m); 66818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far += MSIZE; 66828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) { 66838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sblog(&so->so_rcv, 66848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->do_not_ref_stcb?NULL:stcb, SCTP_LOG_SBRESULT, 0); 66858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m = SCTP_BUF_NEXT(m); 66878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->data = control->tail_mbuf = NULL; 66898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control->length = 0; 66908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (out_flags & MSG_EOR) { 66918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Done with this control */ 66928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto done_with_control; 66938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen release: 66968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 1) { 66978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 66988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_rlock = 0; 66998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version < 700000) || defined(__Userspace__) 67018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock == 0) { 67028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&so->so_rcv); 67038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 1; 67048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 67068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock == 1) { 67078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&so->so_rcv); 67088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 0; 67098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 67128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sbunlock(&so->so_rcv, 1); 67138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) 67168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sbunlock(&so->so_rcv); 67178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 67188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sockbuf_lock = 0; 67198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen release_unlocked: 67238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock) { 67248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&so->so_rcv); 67258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hold_sblock = 0; 67268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb) && (in_flags & MSG_PEEK) == 0) { 67288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((freed_so_far >= rwnd_req) && 67298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (control && (control->do_not_ref_stcb == 0)) && 67308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (no_rcv_needed == 0)) 67318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 67328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out: 67348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (msg_flags) { 67358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *msg_flags = out_flags; 67368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((out_flags & MSG_EOR) == 0) && 67388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((in_flags & MSG_PEEK) == 0) && 67398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sinfo) && 67408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO) || 67418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO))) { 67428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_extrcvinfo *s_extra; 67438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra = (struct sctp_extrcvinfo *)sinfo; 67448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen s_extra->sreinfo_next_flags = SCTP_NO_NEXT_MSG; 67458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_rlock == 1) { 67478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 67488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hold_sblock) { 67508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&so->so_rcv); 67518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 700000 67538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sockbuf_lock) { 67548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sbunlock(&so->so_rcv); 67558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (freecnt_applied) { 67598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 67608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The lock on the socket buffer protects us so the free 67618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * code will stop. But since we used the socketbuf lock and 67628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the sender uses the tcb_lock to increment, we need to use 67638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the atomic add to the refcnt. 67648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 67658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 67668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 67678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("stcb for refcnt has gone NULL?"); 67688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto stage_left; 67698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 67708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto stage_left; 67718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, -1); 67748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Save the value back for next time */ 67758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->freed_by_sorcv_sincelast = freed_so_far; 67768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) { 67788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 67798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_DONE, 67808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far, 67818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 67821ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 67831ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen ((uio) ? (slen - uio->uio_resid) : slen), 67848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 67851ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen ((uio) ? (slen - uio_resid(uio)) : slen), 67868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 67881ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen ((uio) ? (slen - uio->uio_resid) : slen), 67898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.my_rwnd, 67918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_rcv.sb_cc); 67928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 67938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_SORECV_DONE, 67948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen freed_so_far, 67958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 67961ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen#if defined(APPLE_LEOPARD) 67971ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen ((uio) ? (slen - uio->uio_resid) : slen), 67988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 67991ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen ((uio) ? (slen - uio_resid(uio)) : slen), 68008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 68021ebe9fa737dc60b9cb716812477d62f9b4107f53tuexen ((uio) ? (slen - uio->uio_resid) : slen), 68038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 0, 68058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_rcv.sb_cc); 68068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stage_left: 68098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (wakeup_read_socket) { 68108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sorwakeup(inp, so); 68118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 68138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 68148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MBUF_LOGGING 68178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct mbuf * 68188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_m_free(struct mbuf *m) 68198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 68208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { 68218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BUF_IS_EXTENDED(m)) { 68228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_mb(m, SCTP_MBUF_IFREE); 68238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (m_free(m)); 68268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 68278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid sctp_m_freem(struct mbuf *mb) 68298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 68308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen while (mb != NULL) 68318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen mb = sctp_m_free(mb); 68328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 68338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 68378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id) 68388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 68398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Given a local address. For all associations 68408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * that holds the address, request a peer-set-primary. 68418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 68428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *ifa; 68438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *wi; 68448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0); 68468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ifa == NULL) { 68478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EADDRNOTAVAIL); 68488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRNOTAVAIL); 68498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now that we have the ifa we must awaken the 68518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * iterator with this message. 68528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 68538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr); 68548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (wi == NULL) { 68558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOMEM); 68568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 68578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now incr the count and int wi structure */ 68598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INCR_LADDR_COUNT(); 68608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero(wi, sizeof(*wi)); 68618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); 68628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen wi->ifa = ifa; 68638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen wi->action = SCTP_SET_PRIM_ADDR; 68648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&ifa->refcount, 1); 68658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now add it to the work queue */ 68678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_WQ_ADDR_LOCK(); 68688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 68698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Should this really be a tailq? As it is we will process the 68708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * newest first :-0 68718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 68728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr); 68738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_WQ_ADDR_UNLOCK(); 68748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, 68758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_inpcb *)NULL, 68768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_tcb *)NULL, 68778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_nets *)NULL); 68788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 68798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 68808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 68828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* no sctp_soreceive for __Userspace__ now */ 68838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Userspace__) 68868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 68878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_soreceive( struct socket *so, 68888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr **psa, 68898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct uio *uio, 68908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf **mp0, 68918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf **controlp, 68928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int *flagsp) 68938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 68948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error, fromlen; 68958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t sockbuf[256]; 68968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *from; 68978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_extrcvinfo sinfo; 68988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int filling_sinfo = 1; 68998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 69008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 69028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* pickup the assoc we are reading from */ 69038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 69048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 69058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 69068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT) && 69088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO) && 69098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) || 69108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (controlp == NULL)) { 69118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* user does not want the sndrcv ctl */ 69128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen filling_sinfo = 0; 69138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (psa) { 69158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from = (struct sockaddr *)sockbuf; 69168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fromlen = sizeof(sockbuf); 6917f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 69188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from->sa_len = 0; 69198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 69218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from = NULL; 69228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fromlen = 0; 69238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 69268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 69278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6928f496fe99adbad377f85add3a45e17f21a4702b41t if (filling_sinfo) { 6929f496fe99adbad377f85add3a45e17f21a4702b41t memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo)); 6930f496fe99adbad377f85add3a45e17f21a4702b41t } 69318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp, 69328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo); 6933f496fe99adbad377f85add3a45e17f21a4702b41t if (controlp != NULL) { 69348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy back the sinfo in a CMSG format */ 69358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (filling_sinfo) 69368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *controlp = sctp_build_ctl_nchunk(inp, 69378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sctp_sndrcvinfo *)&sinfo); 69388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 69398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *controlp = NULL; 69408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (psa) { 69428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy back the address info */ 6943f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 69448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (from && from->sa_len) { 69458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 69468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (from) { 69478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__) 69498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *psa = sodupsockaddr(from, M_NOWAIT); 69508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 69518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *psa = dup_sockaddr(from, mp0 == 0); 69528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 69548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *psa = NULL; 69558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 69588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 69598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 69618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 69628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version < 603000) || defined(__Windows__) 69658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 69668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * General routine to allocate a hash table with control of memory flags. 69678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is in 7.0 and beyond for sure :-) 69688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 69698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid * 69708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_hashinit_flags(int elements, struct malloc_type *type, 69718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen u_long *hashmask, int flags) 69728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 69738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen long hashsize; 69748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_HEAD(generic, generic) *hashtbl; 69758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 69768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (elements <= 0) { 69798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 69808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("hashinit: bad elements"); 69818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 698247a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("hashinit: bad elements?"); 69838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen elements = 1; 69848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (hashsize = 1; hashsize <= elements; hashsize <<= 1) 69878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 69888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashsize >>= 1; 69898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (flags & HASH_WAITOK) 69908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK); 69918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else if (flags & HASH_NOWAIT) 69928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_NOWAIT); 69938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else { 69948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 69958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen panic("flag incorrect in hashinit_flags"); 69968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 69978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 69988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 70008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory? */ 70028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hashtbl == NULL) 70038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 70048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < hashsize; i++) 70068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_INIT(&hashtbl[i]); 70078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *hashmask = hashsize - 1; 70088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (hashtbl); 70098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 70108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 70118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else /* __Userspace__ ifdef above sctp_soreceive */ 70138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 70148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * __Userspace__ Defining sctp_hashinit_flags() and sctp_hashdestroy() for userland. 70158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NOTE: We don't want multiple definitions here. So sctp_hashinit_flags() above for 70168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *__FreeBSD__ must be excluded. 70178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 70188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 70198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid * 70218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_hashinit_flags(int elements, struct malloc_type *type, 70228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen u_long *hashmask, int flags) 70238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 70248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen long hashsize; 70258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_HEAD(generic, generic) *hashtbl; 70268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 70278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (elements <= 0) { 702947a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("hashinit: bad elements?"); 70308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 703147a306d634abf33223ef347472c4b1cd441d139ftuexen return (NULL); 70328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 70338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen elements = 1; 70348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 70358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 70368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (hashsize = 1; hashsize <= elements; hashsize <<= 1) 70378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 70388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashsize >>= 1; 70398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*cannot use MALLOC here because it has to be declared or defined 70408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen using MALLOC_DECLARE or MALLOC_DEFINE first. */ 70418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (flags & HASH_WAITOK) 70428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl)); 70438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else if (flags & HASH_NOWAIT) 70448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl)); 70458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else { 70468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INVARIANTS 7047ac15c9a0691d5760c1c3b9b70f6daaaa067b7274t SCTP_PRINTF("flag incorrect in hashinit_flags.\n"); 70488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 704947a306d634abf33223ef347472c4b1cd441d139ftuexen return (NULL); 70508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 70518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no memory? */ 70538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hashtbl == NULL) 70548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 70558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < hashsize; i++) 70578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_INIT(&hashtbl[i]); 70588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *hashmask = hashsize - 1; 70598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (hashtbl); 70608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 70618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 70648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask) 70658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 70668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_HEAD(generic, generic) *hashtbl, *hp; 70678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashtbl = vhashtbl; 70698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++) 70708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!LIST_EMPTY(hp)) { 7071ac15c9a0691d5760c1c3b9b70f6daaaa067b7274t SCTP_PRINTF("hashdestroy: hash not empty.\n"); 70728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 70738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 70748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen FREE(hashtbl, type); 70758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 70768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 70798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_hashfreedestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask) 70808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 70818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_HEAD(generic, generic) *hashtbl/*, *hp*/; 70828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 70838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_ENTRY(type) *start, *temp; 70848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 70858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hashtbl = vhashtbl; 70868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Apparently temp is not dynamically allocated, so attempts to 70878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen free it results in error. 70888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++) 70898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!LIST_EMPTY(hp)) { 70908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen start = LIST_FIRST(hp); 7091b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen while (start != NULL) { 70928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen temp = start; 70938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen start = start->le_next; 7094ef2346ee09e2a6d7e580c0d41191f82e3b1f4937t SCTP_PRINTF("%s: %p \n", __func__, (void *)temp); 70958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen FREE(temp, type); 70968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 70978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 70988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 70998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen FREE(hashtbl, type); 71008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 71018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 71028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 71038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 71048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 71058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 71068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 71078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, 71088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int totaddr, int *error) 71098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 71108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int added = 0; 71118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 71128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 71138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 71148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t incr = 0; 71158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 71168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 71178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 71188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 71198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 71208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 71218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 71228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = addr; 71238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = stcb->sctp_ep; 71248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = 0; 71258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < totaddr; i++) { 71268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sa->sa_family) { 71278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 71288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 71298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen incr = sizeof(struct sockaddr_in); 71308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 71318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sin->sin_addr.s_addr == INADDR_ANY) || 71328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sin->sin_addr.s_addr == INADDR_BROADCAST) || 71338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 71348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 71358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_7); 71368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 71378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 71388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 71398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) { 71408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* assoc gone no un-lock */ 71418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS); 71428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_7); 71438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = ENOBUFS; 71448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 71458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 71468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen added++; 71478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 71488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 71498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 71508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 71518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen incr = sizeof(struct sockaddr_in6); 71528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 71538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 71548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 71558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 71568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_8); 71578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 71588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 71598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 71608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) { 71618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* assoc gone no un-lock */ 71628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS); 71638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_8); 71648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = ENOBUFS; 71658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 71668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 71678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen added++; 71688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 71698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 717066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 717166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 717266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen incr = sizeof(struct sockaddr_in6); 717366e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) { 717466e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen /* assoc gone no un-lock */ 717566e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS); 717666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_8); 717766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen *error = ENOBUFS; 717866e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen goto out_now; 717966e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen } 718066e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen added++; 718166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 718266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 71838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 71848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 71858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 71868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)((caddr_t)sa + incr); 71878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 71888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_now: 71898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (added); 71908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 71918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 71928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct sctp_tcb * 71938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, 71948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int *totaddr, int *num_v4, int *num_v6, int *error, 71958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int limit, int *bad_addr) 71968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 71978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 7198b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct sctp_tcb *stcb = NULL; 71998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t incr, at, i; 72008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen at = incr = 0; 72018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = addr; 72028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = *num_v6 = *num_v4 = 0; 72048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* account and validate addresses */ 72058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < (size_t)*totaddr; i++) { 72068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sa->sa_family) { 72078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 72088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 72098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*num_v4) += 1; 72108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen incr = sizeof(struct sockaddr_in); 7211f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 72128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_len != incr) { 72138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 72148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 72158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *bad_addr = 1; 72168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 72178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 72228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 72238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 72248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 72258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 72278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 72288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Must be non-mapped for connectx */ 72298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 72308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 72318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *bad_addr = 1; 72328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 72338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*num_v6) += 1; 72358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen incr = sizeof(struct sockaddr_in6); 7236f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 72378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_len != incr) { 72388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 72398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 72408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *bad_addr = 1; 72418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 72428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 7245000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 72468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 72488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *totaddr = i; 72498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we are done */ 72508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (i == (size_t)*totaddr) { 72538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 72568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL); 72578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 72588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Already have or am bring up an association */ 72598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (stcb); 72608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 72618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 72628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((at + incr) > (size_t)limit) { 72648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *totaddr = i; 72658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)((caddr_t)sa + incr); 72688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return ((struct sctp_tcb *)NULL); 72708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 72718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 72738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sctp_bindx(ADD) for one address. 72748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * assumes all arguments are valid/checked by caller. 72758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 72768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 72778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp, 72788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa, sctp_assoc_t assoc_id, 72798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id, int *error, void *p) 72808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 72818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr_touse; 72828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 72838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in sin; 72848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 72868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i, fnd = 0; 72878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* see if we're bound all already! */ 72908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 72918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 72928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 72938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 72948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 72968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Is the VRF one we have */ 72978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 72988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf_id == inp->m_vrf_ids[i]) { 72998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 73008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 73018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 73048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr_touse = sa; 73108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 73118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 73128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 7313f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 73148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_len != sizeof(struct sockaddr_in6)) { 73158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 73218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can only bind v6 on PF_INET6 sockets */ 73228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)addr_touse; 73278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 73288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 73298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPV6_V6ONLY(inp)) { 73308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't bind v4-mapped on PF_INET sockets */ 73318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_sin6_2_sin(&sin, sin6); 73368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr_touse = (struct sockaddr *)&sin; 73378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 73418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 7342f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 73438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_len != sizeof(struct sockaddr_in)) { 73448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 73508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPV6_V6ONLY(inp)) { 73518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't bind v4 on PF_INET sockets */ 73528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 73598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !(defined(__Panda__) || defined(__Windows__)) 73608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (p == NULL) { 73618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't get proc for Net/Open BSD */ 73628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = sctp_inpcb_bind(so, addr_touse, NULL, p); 73688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 73718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * No locks required here since bind and mgmt_ep_sa 73728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * all do their own locking. If we do something for 73738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the FIX: below we may need to lock in that case. 73748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 73758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (assoc_id == 0) { 73768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* add the address */ 73778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *lep; 73788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *lsin = (struct sockaddr_in *)addr_touse; 73798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* validate the incoming port */ 73818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((lsin->sin_port != 0) && 73828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (lsin->sin_port != inp->sctp_lport)) { 73838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 73848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 73858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 73868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 73878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* user specified 0 port, set it to existing port */ 73888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen lsin->sin_port = inp->sctp_lport; 73898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen lep = sctp_pcb_findep(addr_touse, 1, 0, vrf_id); 73928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (lep != NULL) { 73938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 73948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We must decrement the refcount 73958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * since we have the ep already and 73968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * are binding. No remove going on 73978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * here. 73988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 73998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(lep); 74008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (lep == inp) { 74028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* already bound to it.. ok */ 74038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (lep == NULL) { 74058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)addr_touse)->sin_port = 0; 74068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = sctp_addr_mgmt_ep_sa(inp, addr_touse, 74078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ADD_IP_ADDRESS, 74088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id, NULL); 74098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 74108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EADDRINUSE; 74118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*error) 74138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 74158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 74168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * FIX: decide whether we allow assoc based 74178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bindx 74188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 74198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 74218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 74228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 74238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sctp_bindx(DELETE) for one address. 74248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * assumes all arguments are valid/checked by caller. 74258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 74268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 74270ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_bindx_delete_address(struct sctp_inpcb *inp, 74288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa, sctp_assoc_t assoc_id, 74298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id, int *error) 74308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 74318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr_touse; 74328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 74338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in sin; 74348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 74368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i, fnd = 0; 74378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 74398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* see if we're bound all already! */ 74408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 74418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 74428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 74438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 74468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Is the VRF one we have */ 74478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 74488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf_id == inp->m_vrf_ids[i]) { 74498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 74508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 74518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 74548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 74558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 74568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr_touse = sa; 7460e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET6 74618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 74628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 7463f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 74648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_len != sizeof(struct sockaddr_in6)) { 74658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 74668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 74678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 74718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can only bind v6 on PF_INET6 sockets */ 74728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 74738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 74748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)addr_touse; 74778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 74788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 74798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPV6_V6ONLY(inp)) { 74808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't bind mapped-v4 on PF_INET sockets */ 74818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 74828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 74838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_sin6_2_sin(&sin, sin6); 74868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr_touse = (struct sockaddr *)&sin; 74878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 74918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 7492f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 74938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_len != sizeof(struct sockaddr_in)) { 74948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 74958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 74968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 74978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 75008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPV6_V6ONLY(inp)) { 75018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't bind v4 on PF_INET sockets */ 75028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); 75038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = EINVAL; 75048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 75058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 75098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * No lock required mgmt_ep_sa does its own locking. 75108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * If the FIX: below is ever changed we may need to 75118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * lock before calling association level binding. 75128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 75138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (assoc_id == 0) { 75148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* delete the address */ 75158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *error = sctp_addr_mgmt_ep_sa(inp, addr_touse, 75168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_DEL_IP_ADDRESS, 75178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id, NULL); 75188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 75198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 75208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * FIX: decide whether we allow assoc based 75218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bindx 75228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 75238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 75258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 75278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * returns the valid local address count for an assoc, taking into account 75288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * all scoping rules 75298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 75308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 75318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_local_addr_count(struct sctp_tcb *stcb) 75328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 7533bb7718cf40846152b19b119af6d4b3bdb85db6b1t int loopback_scope; 7534bb7718cf40846152b19b119af6d4b3bdb85db6b1t#if defined(INET) 7535bb7718cf40846152b19b119af6d4b3bdb85db6b1t int ipv4_local_scope, ipv4_addr_legal; 7536bb7718cf40846152b19b119af6d4b3bdb85db6b1t#endif 7537bb7718cf40846152b19b119af6d4b3bdb85db6b1t#if defined (INET6) 7538bb7718cf40846152b19b119af6d4b3bdb85db6b1t int local_scope, site_scope, ipv6_addr_legal; 7539bb7718cf40846152b19b119af6d4b3bdb85db6b1t#endif 75407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 75417988ea8f0c067cf3757e798b473b1ae4d34b6dfdt int conn_addr_legal; 75427988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 75438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_vrf *vrf; 75448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifn *sctp_ifn; 75458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *sctp_ifa; 75468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int count = 0; 75478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Turn on all the appropriate scopes */ 75497988ea8f0c067cf3757e798b473b1ae4d34b6dfdt loopback_scope = stcb->asoc.scope.loopback_scope; 7550bb7718cf40846152b19b119af6d4b3bdb85db6b1t#if defined(INET) 75517988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; 7552bb7718cf40846152b19b119af6d4b3bdb85db6b1t ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; 7553bb7718cf40846152b19b119af6d4b3bdb85db6b1t#endif 7554bb7718cf40846152b19b119af6d4b3bdb85db6b1t#if defined(INET6) 75557988ea8f0c067cf3757e798b473b1ae4d34b6dfdt local_scope = stcb->asoc.scope.local_scope; 75567988ea8f0c067cf3757e798b473b1ae4d34b6dfdt site_scope = stcb->asoc.scope.site_scope; 75577988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; 7558bb7718cf40846152b19b119af6d4b3bdb85db6b1t#endif 75597988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 75607988ea8f0c067cf3757e798b473b1ae4d34b6dfdt conn_addr_legal = stcb->asoc.scope.conn_addr_legal; 75617988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 75628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RLOCK(); 75638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf = sctp_find_vrf(stcb->asoc.vrf_id); 75648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf == NULL) { 75658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no vrf, no addresses */ 75668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 75678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 75688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 75718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 75728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bound all case: go through all ifns on the vrf 75738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 75748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 75758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((loopback_scope == 0) && 75768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { 75778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 75788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 75808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_addr_restricted(stcb, sctp_ifa)) 75818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 75828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sctp_ifa->address.sa.sa_family) { 75838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 75848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 75858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ipv4_addr_legal) { 75868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 75878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7588bfb1bf7e665a02b48026482bf33d05c83dfad73bt sin = &sctp_ifa->address.sin; 75898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr == 0) { 75908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* skip unspecified addrs */ 75918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 75928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7593998635733088fde643e6d807fa76679c4ceeaa00t#if defined(__FreeBSD__) 7594998635733088fde643e6d807fa76679c4ceeaa00t if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred, 7595998635733088fde643e6d807fa76679c4ceeaa00t &sin->sin_addr) != 0) { 7596998635733088fde643e6d807fa76679c4ceeaa00t continue; 7597998635733088fde643e6d807fa76679c4ceeaa00t } 7598998635733088fde643e6d807fa76679c4ceeaa00t#endif 75998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((ipv4_local_scope == 0) && 76008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 76018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* count this one */ 76048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen count++; 76058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 76068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 76098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 76108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 76118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 76128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ipv6_addr_legal) { 76138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 76148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME) 76168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 lsa6; 76178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7618bfb1bf7e665a02b48026482bf33d05c83dfad73bt sin6 = &sctp_ifa->address.sin6; 76198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 76208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7622998635733088fde643e6d807fa76679c4ceeaa00t#if defined(__FreeBSD__) 7623998635733088fde643e6d807fa76679c4ceeaa00t if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred, 7624998635733088fde643e6d807fa76679c4ceeaa00t &sin6->sin6_addr) != 0) { 7625998635733088fde643e6d807fa76679c4ceeaa00t continue; 7626998635733088fde643e6d807fa76679c4ceeaa00t } 7627998635733088fde643e6d807fa76679c4ceeaa00t#endif 76288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 76298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (local_scope == 0) 76308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 76328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin6->sin6_scope_id == 0) { 76338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 76348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa6_recoverscope(sin6) != 0) 76358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 76368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bad link 76378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * local 76388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * address 76398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 76408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 76428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen lsa6 = *sin6; 76438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in6_recoverscope(&lsa6, 76448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &lsa6.sin6_addr, 76458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL)) 76468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 76478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bad link 76488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * local 76498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * address 76508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 76518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = &lsa6; 76538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 76548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 76568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((site_scope == 0) && 76588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 76598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* count this one */ 76628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen count++; 76638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 76658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 766666e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#if defined(__Userspace__) 766766e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen case AF_CONN: 76687988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (conn_addr_legal) { 76697988ea8f0c067cf3757e798b473b1ae4d34b6dfdt count++; 76707988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 767166e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen break; 767266e2e9e4f917602ca2550fd7aa1de334a3128e0ftuexen#endif 76738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 76748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TSNH */ 76758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 76768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 76808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 76818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * subset bound case 76828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 76838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 76848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, 76858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_nxt_addr) { 76868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_addr_restricted(stcb, laddr->ifa)) { 76878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* count this one */ 76908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen count++; 76918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 76948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (count); 76958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 76968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_LOCAL_TRACE_BUF) 76988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 77008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_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) 7701000a5bac556b28e74e4e98c540f66b1743e9312dtuexen{ 77028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t saveindex, newindex; 77038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Windows__) 77058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_log) == NULL) { 77068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 77078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen do { 77098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen saveindex = SCTP_BASE_SYSCTL(sctp_log)->index; 77108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (saveindex >= SCTP_MAX_LOGGING_SIZE) { 77118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen newindex = 1; 77128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 77138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen newindex = saveindex + 1; 77148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } while (atomic_cmpset_int(&SCTP_BASE_SYSCTL(sctp_log)->index, saveindex, newindex) == 0); 77168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (saveindex >= SCTP_MAX_LOGGING_SIZE) { 77178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen saveindex = 0; 77188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT; 77208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].subsys = subsys; 77218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[0] = a; 77228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[1] = b; 77238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[2] = c; 77248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[3] = d; 77258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[4] = e; 77268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log)->entry[saveindex].params[5] = f; 77278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 77288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen do { 77298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen saveindex = SCTP_BASE_SYSCTL(sctp_log).index; 77308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (saveindex >= SCTP_MAX_LOGGING_SIZE) { 77318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen newindex = 1; 77328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 77338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen newindex = saveindex + 1; 77348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } while (atomic_cmpset_int(&SCTP_BASE_SYSCTL(sctp_log).index, saveindex, newindex) == 0); 77368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (saveindex >= SCTP_MAX_LOGGING_SIZE) { 77378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen saveindex = 0; 77388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].timestamp = SCTP_GET_CYCLECOUNT; 77408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].subsys = subsys; 77418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[0] = a; 77428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[1] = b; 77438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[2] = c; 77448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[3] = d; 77458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[4] = e; 77468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_log).entry[saveindex].params[5] = f; 77478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 77498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) 77528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 800044 77538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 77548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored) 77558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 77568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct ip *iph; 7757b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET6 7758b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t struct ip6_hdr *ip6; 7759b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 77608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *sp, *last; 77618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct udphdr *uhdr; 7762b0959c60931b4d5bff2fd48cea483d72c437969etuexen uint16_t port; 77638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((m->m_flags & M_PKTHDR) == 0) { 77658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't handle one that is not a pkt hdr */ 77668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 77678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7768b0959c60931b4d5bff2fd48cea483d72c437969etuexen /* Pull the src port */ 77698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen iph = mtod(m, struct ip *); 77708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uhdr = (struct udphdr *)((caddr_t)iph + off); 77718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen port = uhdr->uh_sport; 7772b0959c60931b4d5bff2fd48cea483d72c437969etuexen /* Split out the mbuf chain. Leave the 7773b0959c60931b4d5bff2fd48cea483d72c437969etuexen * IP header in m, place the 7774b0959c60931b4d5bff2fd48cea483d72c437969etuexen * rest in the sp. 7775b0959c60931b4d5bff2fd48cea483d72c437969etuexen */ 777668beeca578347438d9c434680197647ed551935ft sp = m_split(m, off, M_NOWAIT); 77778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sp == NULL) { 77788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak, drop packet, we can't do a split */ 77798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 77808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7781b0959c60931b4d5bff2fd48cea483d72c437969etuexen if (sp->m_pkthdr.len < sizeof(struct udphdr) + sizeof(struct sctphdr)) { 7782b0959c60931b4d5bff2fd48cea483d72c437969etuexen /* Gak, packet can't have an SCTP header in it - too small */ 77838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_freem(sp); 77848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 77858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7786b0959c60931b4d5bff2fd48cea483d72c437969etuexen /* Now pull up the UDP header and SCTP header together */ 7787b0959c60931b4d5bff2fd48cea483d72c437969etuexen sp = m_pullup(sp, sizeof(struct udphdr) + sizeof(struct sctphdr)); 77888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sp == NULL) { 77898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak pullup failed */ 77908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 77918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7792b0959c60931b4d5bff2fd48cea483d72c437969etuexen /* Trim out the UDP header */ 77938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_adj(sp, sizeof(struct udphdr)); 77948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now reconstruct the mbuf chain */ 7796b0959c60931b4d5bff2fd48cea483d72c437969etuexen for (last = m; last->m_next; last = last->m_next); 77978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen last->m_next = sp; 77988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m->m_pkthdr.len += sp->m_pkthdr.len; 77998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen iph = mtod(m, struct ip *); 78008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (iph->ip_v) { 78018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 7802b0959c60931b4d5bff2fd48cea483d72c437969etuexen case IPVERSION: 78034bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#if __FreeBSD_version >= 1000000 78044bda18bd6192b29406d04eeb576f5d5d7bd32fc7t iph->ip_len = htons(ntohs(iph->ip_len) - sizeof(struct udphdr)); 78054bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#else 7806b0959c60931b4d5bff2fd48cea483d72c437969etuexen iph->ip_len -= sizeof(struct udphdr); 78074bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#endif 7808b0959c60931b4d5bff2fd48cea483d72c437969etuexen sctp_input_with_port(m, off, port); 7809b0959c60931b4d5bff2fd48cea483d72c437969etuexen break; 78108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 7812b0959c60931b4d5bff2fd48cea483d72c437969etuexen case IPV6_VERSION >> 4: 7813b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t ip6 = mtod(m, struct ip6_hdr *); 7814b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - sizeof(struct udphdr)); 7815b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp6_input_with_port(&m, &off, port); 7816b0959c60931b4d5bff2fd48cea483d72c437969etuexen break; 78178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7818b0959c60931b4d5bff2fd48cea483d72c437969etuexen default: 7819b0959c60931b4d5bff2fd48cea483d72c437969etuexen goto out; 7820b0959c60931b4d5bff2fd48cea483d72c437969etuexen break; 78218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 78238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out: 78248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen m_freem(m); 78258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 78268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7828000a5bac556b28e74e4e98c540f66b1743e9312dtuexenvoid 78298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_over_udp_stop(void) 78308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 78318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 78328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * This function assumes sysctl caller holds sctp_sysctl_info_lock() for writting! 78338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 7834b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET 7835b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) { 7836b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t soclose(SCTP_BASE_INFO(udp4_tun_socket)); 7837b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t SCTP_BASE_INFO(udp4_tun_socket) = NULL; 78388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7839b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 7840b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET6 7841b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) { 7842b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t soclose(SCTP_BASE_INFO(udp6_tun_socket)); 7843b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t SCTP_BASE_INFO(udp6_tun_socket) = NULL; 7844b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t } 7845b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 78468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 78478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 78488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 78498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_over_udp_start(void) 78508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 78518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 800044 78528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint16_t port; 78538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ret; 7854b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET 78558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in sin; 7856b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 7857b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET6 7858b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t struct sockaddr_in6 sin6; 7859b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 78608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 78618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * This function assumes sysctl caller holds sctp_sysctl_info_lock() for writting! 78628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 78638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port); 7864b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if (ntohs(port) == 0) { 78658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Must have a port set */ 7866b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 78678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7868b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET 7869b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if (SCTP_BASE_INFO(udp4_tun_socket) != NULL) { 7870b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t /* Already running -- must stop first */ 7871b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t return (EALREADY); 7872b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t } 7873b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 7874b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET6 7875b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if (SCTP_BASE_INFO(udp6_tun_socket) != NULL) { 78768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Already running -- must stop first */ 7877b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EALREADY); 78788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7879b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 7880b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET 7881b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if ((ret = socreate(PF_INET, &SCTP_BASE_INFO(udp4_tun_socket), 7882b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t SOCK_DGRAM, IPPROTO_UDP, 7883b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t curthread->td_ucred, curthread))) { 7884b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp_over_udp_stop(); 78858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ret); 78868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7887b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t /* Call the special UDP hook. */ 7888b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp4_tun_socket), 7889b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp_recv_udp_tunneled_packet))) { 7890b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp_over_udp_stop(); 7891b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t return (ret); 78928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7893b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t /* Ok, we have a socket, bind it to the port. */ 7894b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t memset(&sin, 0, sizeof(struct sockaddr_in)); 7895b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sin.sin_len = sizeof(struct sockaddr_in); 78968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin.sin_family = AF_INET; 78978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin.sin_port = htons(port); 7898b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if ((ret = sobind(SCTP_BASE_INFO(udp4_tun_socket), 7899b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t (struct sockaddr *)&sin, curthread))) { 79008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_over_udp_stop(); 79018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ret); 79028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7903b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 7904b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#ifdef INET6 7905b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if ((ret = socreate(PF_INET6, &SCTP_BASE_INFO(udp6_tun_socket), 7906b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t SOCK_DGRAM, IPPROTO_UDP, 7907b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t curthread->td_ucred, curthread))) { 7908b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp_over_udp_stop(); 7909b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t return (ret); 7910b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t } 7911b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t /* Call the special UDP hook. */ 7912b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if ((ret = udp_set_kernel_tunneling(SCTP_BASE_INFO(udp6_tun_socket), 7913b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp_recv_udp_tunneled_packet))) { 7914b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp_over_udp_stop(); 7915b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t return (ret); 7916b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t } 7917b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t /* Ok, we have a socket, bind it to the port. */ 7918b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t memset(&sin6, 0, sizeof(struct sockaddr_in6)); 7919b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sin6.sin6_len = sizeof(struct sockaddr_in6); 7920b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sin6.sin6_family = AF_INET6; 7921b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sin6.sin6_port = htons(port); 7922b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t if ((ret = sobind(SCTP_BASE_INFO(udp6_tun_socket), 7923b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t (struct sockaddr *)&sin6, curthread))) { 7924b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t sctp_over_udp_stop(); 7925b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t return (ret); 7926b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t } 7927b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 79288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 79298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 7930b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t return (ENOTSUP); 79318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 79338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7934