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/sctp_usrreq.c 271221 2014-09-07 09:06:26Z tuexen $"); 368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 37ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen 388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_os.h> 398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __FreeBSD__ 408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <sys/proc.h> 418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_pcb.h> 438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_header.h> 448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_var.h> 45e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET6 468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace_os_FreeBSD) 478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet6/sctp6_var.h> 488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_sysctl.h> 518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_output.h> 528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_uio.h> 538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_asconf.h> 548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctputil.h> 558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_indata.h> 568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_timer.h> 578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_auth.h> 588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_bsd_addr.h> 596c632b3f6e570981666f8a3ff4be34eaf1735835t#if !defined(__Userspace__) 608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/udp.h> 6181616c6a3e184f46276632dd15aa489cd06d94dftuexen#endif 628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(HAVE_SCTP_PEELOFF_SOCKOPT) 648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#include <netinet/sctp_peeloff.h> 658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* HAVE_SCTP_PEELOFF_SOCKOPT */ 668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#define APPLE_FILE_NO 7 698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenextern struct sctp_cc_functions sctp_cc_functions[]; 728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenextern struct sctp_ss_functions sctp_ss_functions[]; 738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 75153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#if defined(__Userspace__) 76b049c47efe2be4692752fdeb90cbc26f5bd3a1c7tuexensctp_init(uint16_t port, 77e6b8257902dfec8b1e5d9b80d5364a78c06777cat int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df), 78e6b8257902dfec8b1e5d9b80d5364a78c06777cat void (*debug_printf)(const char *format, ...)) 797fbcb406549bdf370031d2ad5befb44e39b95ffft#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)) 807fbcb406549bdf370031d2ad5befb44e39b95ffftsctp_init(struct protosw *pp SCTP_UNUSED, struct domain *dp SCTP_UNUSED) 81153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#else 828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_init(void) 83153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Panda__) && !defined(__Userspace__) 868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen u_long sb_max_adj; 878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 88a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 896afa8eeaacc73cac676094ffb23334c1e728c48at#if defined(__Userspace__) 9081616c6a3e184f46276632dd15aa489cd06d94dftuexen#if defined(__Userspace_os_Windows) 919fde21ced28f3314e75a2d90e5dcc7867e2a6b75t#if defined(INET) || defined(INET6) 9281616c6a3e184f46276632dd15aa489cd06d94dftuexen WSADATA wsaData; 9381616c6a3e184f46276632dd15aa489cd06d94dftuexen 949fde21ced28f3314e75a2d90e5dcc7867e2a6b75t if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { 9547a306d634abf33223ef347472c4b1cd441d139ftuexen SCTP_PRINTF("WSAStartup failed\n"); 9681616c6a3e184f46276632dd15aa489cd06d94dftuexen exit (-1); 9781616c6a3e184f46276632dd15aa489cd06d94dftuexen } 989fde21ced28f3314e75a2d90e5dcc7867e2a6b75t#endif 9981616c6a3e184f46276632dd15aa489cd06d94dftuexen InitializeConditionVariable(&accept_cond); 10081616c6a3e184f46276632dd15aa489cd06d94dftuexen InitializeCriticalSection(&accept_mtx); 1016afa8eeaacc73cac676094ffb23334c1e728c48at#else 1026afa8eeaacc73cac676094ffb23334c1e728c48at pthread_cond_init(&accept_cond, NULL); 1036afa8eeaacc73cac676094ffb23334c1e728c48at pthread_mutex_init(&accept_mtx, NULL); 1046afa8eeaacc73cac676094ffb23334c1e728c48at#endif 10581616c6a3e184f46276632dd15aa489cd06d94dftuexen#endif 1068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Initialize and modify the sysctled variables */ 1078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_init_sysctls(); 1088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 1090612043f643c9b26245564c05defca64d472060etuexen#if defined(__Userspace_os_Windows) 11081616c6a3e184f46276632dd15aa489cd06d94dftuexen srand((unsigned int)time(NULL)); 11181616c6a3e184f46276632dd15aa489cd06d94dftuexen#else 11281616c6a3e184f46276632dd15aa489cd06d94dftuexen srandom(getpid()); /* so inp->sctp_ep.random_numbers are truly random... */ 11381616c6a3e184f46276632dd15aa489cd06d94dftuexen#endif 1148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Panda__) 1168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sendspace = SB_MAX; 1178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_recvspace = SB_MAX; 1188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Userspace__) 1208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_sendspace) = SB_MAX; 1218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_recvspace) = SB_RAW; 122153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) = port; 1238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 1248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) 1258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE) 1268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = (nmbclusters / 8); 1278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 1298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Allow a user to take no more than 1/2 the number of clusters or 1308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the SB_MAX whichever is smaller for the send window. 1318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 1328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 1338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sb_max_adj = (u_long)((u_quad_t) (sb_max) * MCLBYTES / (MSIZE + MCLBYTES)); 1348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 1358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sb_max_adj = (u_long)((u_quad_t) (SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES)); 1368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 1388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_sendspace) = sb_max_adj; 1398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 1408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_sendspace) = min(sb_max_adj, 1418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (((uint32_t)nmbclusters / 2) * SCTP_DEFAULT_MAXSEGMENT)); 1428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 1448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Now for the recv window, should we take the same amount? or 1458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For 1468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * now I will just copy. 1478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 1488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_SYSCTL(sctp_recvspace) = SCTP_BASE_SYSCTL(sctp_sendspace); 1498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_VAR(first_time) = 0; 1518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_VAR(sctp_pcb_initialized) = 0; 152a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(__Userspace__) 153a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if !defined(__Userspace_os_Windows) 154a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(INET) || defined(INET6) 155a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen SCTP_BASE_VAR(userspace_route) = -1; 156a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 157a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 158a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#ifdef INET 159a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen SCTP_BASE_VAR(userspace_rawsctp) = -1; 160a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen SCTP_BASE_VAR(userspace_udpsctp) = -1; 161a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 162a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#ifdef INET6 163a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen SCTP_BASE_VAR(userspace_rawsctp6) = -1; 164a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen SCTP_BASE_VAR(userspace_udpsctp6) = -1; 165a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 166a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen SCTP_BASE_VAR(timer_thread_should_exit) = 0; 167b049c47efe2be4692752fdeb90cbc26f5bd3a1c7tuexen SCTP_BASE_VAR(conn_output) = conn_output; 168e6b8257902dfec8b1e5d9b80d5364a78c06777cat SCTP_BASE_VAR(debug_printf) = debug_printf; 169a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 1708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_pcb_init(); 17173e265d74b8dddf404a3200cc2a4b593025158e7tuexen#if defined(__Userspace__) 17273e265d74b8dddf404a3200cc2a4b593025158e7tuexen sctp_start_timer(); 17373e265d74b8dddf404a3200cc2a4b593025158e7tuexen#endif 1748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_PACKET_LOGGING) 1758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_VAR(packet_log_writers) = 0; 1768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_VAR(packet_log_end) = 0; 1778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero(&SCTP_BASE_VAR(packet_log_buffer), SCTP_PACKET_LOG_SIZE); 1788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 1808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BASE_VAR(sctp_main_timer_ticks) = 0; 1818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_start_main_timer(); 1827fbcb406549bdf370031d2ad5befb44e39b95ffft timeout(sctp_delayed_startup, NULL, 1); 1838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 1858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 1878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_finish(void) 1888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 1898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 1907fbcb406549bdf370031d2ad5befb44e39b95ffft untimeout(sctp_delayed_startup, NULL); 1918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_over_udp_stop(); 1928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_address_monitor_stop(); 1938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stop_main_timer(); 1948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19514d7b0ffb5f8052c2291203059092157c65d3e10tuexen#if defined(__Userspace__) 196c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen#if defined(INET) || defined(INET6) 19714d7b0ffb5f8052c2291203059092157c65d3e10tuexen recv_thread_destroy(); 198c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen#endif 199a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if !defined(__Userspace_os_Windows) 200a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(INET) || defined(INET6) 2010d50fd1e0425ccd187b9530411e5675413362f82tuexen if (SCTP_BASE_VAR(userspace_route) != -1) { 2020d50fd1e0425ccd187b9530411e5675413362f82tuexen pthread_join(SCTP_BASE_VAR(recvthreadroute), NULL); 2030d50fd1e0425ccd187b9530411e5675413362f82tuexen } 204a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 205a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 206e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET 2070d50fd1e0425ccd187b9530411e5675413362f82tuexen if (SCTP_BASE_VAR(userspace_rawsctp) != -1) { 208a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(__Userspace_os_Windows) 209a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw), INFINITE); 2100e516dd1fe21e9101c233c725a7ebc2dca6a7d8et CloseHandle(SCTP_BASE_VAR(recvthreadraw)); 211a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#else 212a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen pthread_join(SCTP_BASE_VAR(recvthreadraw), NULL); 213a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 214a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen } 2150d50fd1e0425ccd187b9530411e5675413362f82tuexen if (SCTP_BASE_VAR(userspace_udpsctp) != -1) { 216a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(__Userspace_os_Windows) 217a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp), INFINITE); 2180e516dd1fe21e9101c233c725a7ebc2dca6a7d8et CloseHandle(SCTP_BASE_VAR(recvthreadudp)); 219a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#else 220a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen pthread_join(SCTP_BASE_VAR(recvthreadudp), NULL); 221a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 222a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen } 223a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 224e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET6 2250d50fd1e0425ccd187b9530411e5675413362f82tuexen if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { 226a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(__Userspace_os_Windows) 227a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw6), INFINITE); 2280e516dd1fe21e9101c233c725a7ebc2dca6a7d8et CloseHandle(SCTP_BASE_VAR(recvthreadraw6)); 229a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#else 230a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen pthread_join(SCTP_BASE_VAR(recvthreadraw6), NULL); 231a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 232a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen } 2330d50fd1e0425ccd187b9530411e5675413362f82tuexen if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) { 234a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(__Userspace_os_Windows) 235a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp6), INFINITE); 2360e516dd1fe21e9101c233c725a7ebc2dca6a7d8et CloseHandle(SCTP_BASE_VAR(recvthreadudp6)); 237a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#else 238a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen pthread_join(SCTP_BASE_VAR(recvthreadudp6), NULL); 239a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 240a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen } 241a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 242a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen SCTP_BASE_VAR(timer_thread_should_exit) = 1; 243a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#if defined(__Userspace_os_Windows) 244a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen WaitForSingleObject(SCTP_BASE_VAR(timer_thread), INFINITE); 2450e516dd1fe21e9101c233c725a7ebc2dca6a7d8et CloseHandle(SCTP_BASE_VAR(timer_thread)); 246a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#else 247a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen pthread_join(SCTP_BASE_VAR(timer_thread), NULL); 248a1f4f8b6475213e9fcf527fd5404b74733885f7btuexen#endif 24914d7b0ffb5f8052c2291203059092157c65d3e10tuexen#endif 2508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_pcb_finish(); 251334aac245024f2dd2de46c4b8f3b28e833d88592t#if defined(__Userspace__) 252334aac245024f2dd2de46c4b8f3b28e833d88592t#if defined(__Userspace_os_Windows) 253334aac245024f2dd2de46c4b8f3b28e833d88592t DeleteConditionVariable(&accept_cond); 254334aac245024f2dd2de46c4b8f3b28e833d88592t DeleteCriticalSection(&accept_mtx); 255334aac245024f2dd2de46c4b8f3b28e833d88592t#else 256334aac245024f2dd2de46c4b8f3b28e833d88592t pthread_cond_destroy(&accept_cond); 257334aac245024f2dd2de46c4b8f3b28e833d88592t pthread_mutex_destroy(&accept_mtx); 258334aac245024f2dd2de46c4b8f3b28e833d88592t#endif 259334aac245024f2dd2de46c4b8f3b28e833d88592t#endif 2608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Windows__) 2618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_finish_sysctls(); 2626f4c08134ae7f03bbbe3299d3ebcd331e7bf9ad5t#if defined(INET) || defined(INET6) 2636f4c08134ae7f03bbbe3299d3ebcd331e7bf9ad5t WSACleanup(); 2646f4c08134ae7f03bbbe3299d3ebcd331e7bf9ad5t#endif 2658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 2668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 2678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 2710ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint16_t nxtsz) 2728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 2738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tmit_chunk *chk; 2748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint16_t overhead; 2758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 2768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Adjust that too */ 2778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.smallest_mtu = nxtsz; 2788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now off to subtract IP_DF flag if needed */ 2798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen overhead = IP_HDR_SIZE; 2808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.peer_auth_chunks)) { 2818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen overhead += sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id); 2828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) { 2848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((chk->send_size + overhead) > nxtsz) { 2858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 2868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 2898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((chk->send_size + overhead) > nxtsz) { 2908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 2918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For this guy we also mark for immediate resend 2928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * since we sent to big of chunk 2938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 2948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 2958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->sent < SCTP_DATAGRAM_RESEND) { 2968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_flight_size_decrease(chk); 2978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_total_flight_decrease(stcb, chk); 2988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 2998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (chk->sent != SCTP_DATAGRAM_RESEND) { 3008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); 3018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->sent = SCTP_DATAGRAM_RESEND; 3038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->rec.data.doing_fast_retransmit = 0; 3048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) { 3058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU, 3068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->whoTo->flight_size, 3078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->book_size, 3088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (uintptr_t)chk->whoTo, 3098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->rec.data.TSN_seq); 3108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Clear any time so NO RTT is being done */ 3128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chk->do_rtt = 0; 3138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 3168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 31814ba474e7d8520db1b04d650c6a788bdc5dab9e0tuexen#if !defined(__Userspace__) 3198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Panda__) || defined(__Windows__) 3208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 3218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 3228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 3238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 3248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify_mbuf(struct sctp_inpcb *inp, 3258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 3268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net, 3278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct ip *ip, 3288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctphdr *sh) 3298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 3308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct icmp *icmph; 3318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int totsz, tmr_stopped = 0; 3328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint16_t nxtsz; 3338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* protection */ 3358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 3368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (ip == NULL) || (sh == NULL)) { 3378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 3388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 3398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 3418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First job is to verify the vtag matches what I would send */ 3438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 3448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 3458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 3468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) - 3488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct ip))); 3498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (icmph->icmp_type != ICMP_UNREACH) { 3508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We only care about unreachable */ 3518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 3528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 3538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (icmph->icmp_code != ICMP_UNREACH_NEEDFRAG) { 3558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not a unreachable message due to frag. */ 3568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 3578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 3588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3594bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#if defined(__FreeBSD__) && __FreeBSD_version >= 1000000 3604bda18bd6192b29406d04eeb576f5d5d7bd32fc7t totsz = ntohs(ip->ip_len); 3614bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#else 3628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen totsz = ip->ip_len; 3634bda18bd6192b29406d04eeb576f5d5d7bd32fc7t#endif 3648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen nxtsz = ntohs(icmph->icmp_nextmtu); 3668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nxtsz == 0) { 3678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 3688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * old type router that does not tell us what the next size 3698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * mtu is. Rats we will have to guess (in a educated fashion 3708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * of course) 3718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 3728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen nxtsz = sctp_get_prev_mtu(totsz); 3738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Stop any PMTU timer */ 3758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 3768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tmr_stopped = 1; 3778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 3788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_1); 3798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Adjust destination size limit */ 3818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->mtu > nxtsz) { 3828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->mtu = nxtsz; 3838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->port) { 3848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->mtu -= sizeof(struct udphdr); 3858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now what about the ep? */ 3888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.smallest_mtu > nxtsz) { 3890ac02f34d6041cd0018437596a5a9a94685e6919tuexen sctp_pathmtu_adjustment(stcb, nxtsz); 3908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tmr_stopped) 3928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 3938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 3958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 3968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 3988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify(struct sctp_inpcb *inp, 3998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct ip *ip, 4008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctphdr *sh, 4018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *to, 4028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 4038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net) 4048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 4050612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 4078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct icmp *icmph; 4108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41147674b651417d493ff4e0318113fd7beeef119dbtuexen /* protection */ 4128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 4138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sh == NULL) || (to == NULL)) { 4148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 4158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 4178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First job is to verify the vtag matches what I would send */ 4198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 4208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 4228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) - 4258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct ip))); 4268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (icmph->icmp_type != ICMP_UNREACH) { 4278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We only care about unreachable */ 4288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 4308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((icmph->icmp_code == ICMP_UNREACH_NET) || 4328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_HOST) || 4338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_NET_UNKNOWN) || 4348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_HOST_UNKNOWN) || 4358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_ISOLATED) || 4368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_NET_PROHIB) || 4378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_HOST_PROHIB) || 43822a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Panda__) 4398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_ADMIN)) { 44022a33a1debfe70529be4aa018a2912bfe5dcd8dat#elif defined(__Userspace_os_NetBSD) 44122a33a1debfe70529be4aa018a2912bfe5dcd8dat (icmph->icmp_code == ICMP_UNREACH_ADMIN_PROHIBIT)) { 4428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 4438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_FILTER_PROHIB)) { 4448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 4478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Hmm reachablity problems we must examine closely. If its 4488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * not reachable, we may have lost a network. Or if there is 4498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NO protocol at the other end named SCTP. well we consider 4508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * it a OOTB abort. 4518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 4528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 4538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Ok that destination is NOT reachable */ 4548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 4558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 4568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 45747674b651417d493ff4e0318113fd7beeef119dbtuexen stcb, 0, 4588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void *)net, SCTP_SO_NOT_LOCKED); 4598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if ((icmph->icmp_code == ICMP_UNREACH_PROTOCOL) || 4628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_PORT)) { 4638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 4648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here the peer is either playing tricks on us, 4658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * including an address that belongs to someone who 4668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * does not support SCTP OR was a userland 4678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * implementation that shutdown and now is dead. In 4688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * either case treat it like a OOTB abort with no 4698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * TCB 4708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 47147674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED); 4720612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(inp); 4748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 4758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 4778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 4788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 4798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_2); 4810612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 4838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed.*/ 4848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock here, since the TCB is gone */ 4868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 4878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 4906c632b3f6e570981666f8a3ff4be34eaf1735835t#endif 4916c632b3f6e570981666f8a3ff4be34eaf1735835t#endif 4928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 4948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Panda__) && !defined(__Userspace__) 4958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 4968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 4988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid * 4998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ctlinput(cmd, sa, vip) 5018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int cmd; 5028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 5038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *vip; 5048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 5058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct ip *ip = vip; 5068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctphdr *sh; 5078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 5088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIX, for non-bsd is this right? */ 5098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = SCTP_DEFAULT_VRFID; 5108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family != AF_INET || 5118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) { 5128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 5138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 5148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 5158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 5168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (PRC_IS_REDIRECT(cmd)) { 5198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ip = 0; 5208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) { 5218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 5228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 5238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 5248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 5258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ip) { 5288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp = NULL; 5298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 5308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net = NULL; 5318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in to, from; 5328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sh = (struct sctphdr *)((caddr_t)ip + (ip->ip_hl << 2)); 5348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero(&to, sizeof(to)); 5358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero(&from, sizeof(from)); 5368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from.sin_family = to.sin_family = AF_INET; 5377b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 5388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from.sin_len = to.sin_len = sizeof(to); 5398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from.sin_port = sh->src_port; 5418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen from.sin_addr = ip->ip_src; 5428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to.sin_port = sh->dest_port; 5438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen to.sin_addr = ip->ip_dst; 5448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 5468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 'to' holds the dest of the packet that failed to be sent. 5478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 'from' holds our local endpoint address. Thus we reverse 5488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the to and the from in the lookup. 5498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 550e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen stcb = sctp_findassociation_addr_sa((struct sockaddr *)&to, 551e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen (struct sockaddr *)&from, 5528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &inp, &net, 1, vrf_id); 5538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL && inp && (inp->sctp_socket != NULL)) { 5548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cmd != PRC_MSGSIZE) { 5558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify(inp, ip, sh, 5568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&to, stcb, 5578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net); 5588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 5598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* handle possible ICMP size messages */ 5608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_notify_mbuf(inp, stcb, net, ip, sh); 5618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 5638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 500000 5648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 5658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * XXX must be fixed for 5.x and higher, leave for 5668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * 4.x 5678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 5688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (PRC_IS_REDIRECT(cmd) && inp) { 5698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in_rtchange((struct inpcb *)inp, 5708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inetctlerrmap[cmd]); 5718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb == NULL) && (inp != NULL)) { 5748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* reduce ref-count */ 5758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 5768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 5778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 5788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 5808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 5818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 5858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 5868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 5878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (NULL); 5888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 5908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 5928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) 5948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 5958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_getcred(SYSCTL_HANDLER_ARGS) 5968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 5978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct xucred xuc; 5988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in addrs[2]; 5998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 6008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 6018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 6028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error; 6038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 6048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIX, for non-bsd is this right? */ 6068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = SCTP_DEFAULT_VRFID; 6078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version > 602000 6098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = priv_check(req->td, PRIV_NETINET_GETCRED); 6108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif __FreeBSD_version >= 500000 6128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(req->td); 6138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 6148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(req->p); 6158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) 6178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 6188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = SYSCTL_IN(req, addrs, sizeof(addrs)); 6208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) 6218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 6228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 623e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen stcb = sctp_findassociation_addr_sa(sintosa(&addrs[1]), 624e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen sintosa(&addrs[0]), 6258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &inp, &net, 1, vrf_id); 6268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) { 6278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp != NULL) && (stcb == NULL)) { 6288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* reduce ref-count */ 6298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 6308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 6318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto cred_can_cont; 6328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 6358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 6368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 6378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 6398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We use the write lock here, only 6408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * since in the error leg we need it. 6418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * If we used RLOCK, then we would have 6428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * to wlock/decr/unlock/rlock. Which 6438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * in theory could create a hole. Better 6448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * to use higher wlock. 6458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 6468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 6478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cred_can_cont: 6488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket); 6498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 6508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 6518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 6528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cru2x(inp->sctp_socket->so_cred, &xuc); 6548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 6558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 6568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenout: 6578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 6588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 6598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenSYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW, 6618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 0, 0, sctp_getcred, "S,ucred", "Get the ucred of a SCTP connection"); 6628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* #if defined(__FreeBSD__) */ 6638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 6668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Panda__) || defined(__Windows__) || defined(__Userspace__) 6678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 6688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__FreeBSD__) && __FreeBSD_version > 690000 6698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic void 6708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 6718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 6728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_abort(struct socket *so) 6748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 6758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 6768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t flags; 6778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 6792fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 6808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version > 690000 6818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 6828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 6838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 684b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 6858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 6888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_must_try_again: 6898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 6908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 6918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 17); 6928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 6948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 6958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 6968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 16); 6978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 6988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 6998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 7008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_LOCK(so); 7018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SB_CLEAR(so->so_snd); 7028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* same for the rcv ones, they are only 7038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * here for the accounting/select. 7048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 7058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SB_CLEAR(so->so_rcv); 7068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 7088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_usecount--; 7098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 7108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now null out the reference, we are completely detached. */ 7118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_pcb = NULL; 7128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 7148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 7158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 7168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 7178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto sctp_must_try_again; 7188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version > 690000 7218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 7228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 723b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (0); 7248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 7268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7270612043f643c9b26245564c05defca64d472060etuexen#if defined(__Panda__) || defined(__Userspace__) 7288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 7298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 7308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 7318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 7330ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED) 7348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) || defined(__Userspace__) 7350ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id) 7368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 7370ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_attach(struct socket *so, int proto SCTP_UNUSED, PKTHREAD p SCTP_UNUSED) 7388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 7390ac02f34d6041cd0018437596a5a9a94685e6919tuexensctp_attach(struct socket *so, int proto SCTP_UNUSED, struct proc *p SCTP_UNUSED) 7408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 7428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 7438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct inpcb *ip_inp; 7448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error; 7458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Panda__) && !defined(__Userspace__) 7468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id = SCTP_DEFAULT_VRFID; 7478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef IPSEC 7498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t flags; 7508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 7528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 7538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp != 0) { 7548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 755b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 7568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 7588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); 7598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 760b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (error); 7618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_inpcb_alloc(so, vrf_id); 7648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 765b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (error); 7668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 7688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 7698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */ 7708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ip_inp = &inp->ip_inp.inp; 7718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ip_inp->inp_vflag |= INP_IPV4; 7728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); 7738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef IPSEC 7748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !(defined(__APPLE__)) 7758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ipsec_init_policy(so, &ip_inp->inp_sp); 7768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 7778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 17); 7788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error != 0) { 7808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen try_again: 7818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 7828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 7838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 7848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 7858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 15); 7868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 7888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 7898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 7908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 7918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 7928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 7938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto try_again; 7948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 7958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 7968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 798b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (error); 7998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 8018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* IPSEC */ 8028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 803b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (0); 8048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 8057a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 8067a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 8077a9f1edd34bf82c194a2f9d0c64394f431175138tuexenstatic int 8087a9f1edd34bf82c194a2f9d0c64394f431175138tuexensctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p) 8097a9f1edd34bf82c194a2f9d0c64394f431175138tuexen{ 8107a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#elif defined(__FreeBSD__) || defined(__APPLE__) 8117a9f1edd34bf82c194a2f9d0c64394f431175138tuexenstatic int 8127a9f1edd34bf82c194a2f9d0c64394f431175138tuexensctp_bind(struct socket *so, struct sockaddr *addr, struct proc *p) { 8137a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#elif defined(__Panda__) || defined(__Userspace__) 8147a9f1edd34bf82c194a2f9d0c64394f431175138tuexenint 8157a9f1edd34bf82c194a2f9d0c64394f431175138tuexensctp_bind(struct socket *so, struct sockaddr *addr) { 8167a9f1edd34bf82c194a2f9d0c64394f431175138tuexen void *p = NULL; 8177a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#elif defined(__Windows__) 8187a9f1edd34bf82c194a2f9d0c64394f431175138tuexenstatic int 8197a9f1edd34bf82c194a2f9d0c64394f431175138tuexensctp_bind(struct socket *so, struct sockaddr *addr, PKTHREAD p) { 8207a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#else 8217a9f1edd34bf82c194a2f9d0c64394f431175138tuexenstatic int 8227a9f1edd34bf82c194a2f9d0c64394f431175138tuexensctp_bind(struct socket *so, struct mbuf *nam, struct proc *p) 8237a9f1edd34bf82c194a2f9d0c64394f431175138tuexen{ 8247a9f1edd34bf82c194a2f9d0c64394f431175138tuexen struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *): NULL; 8257a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 8267a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 8279ac77419b79fa1b61bed4326c4ef825a19335704t struct sctp_inpcb *inp; 8287a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 8299ac77419b79fa1b61bed4326c4ef825a19335704t inp = (struct sctp_inpcb *)so->so_pcb; 8309ac77419b79fa1b61bed4326c4ef825a19335704t if (inp == NULL) { 8317a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 8327a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EINVAL); 8337a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 8349ac77419b79fa1b61bed4326c4ef825a19335704t if (addr != NULL) { 835f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 8369ac77419b79fa1b61bed4326c4ef825a19335704t if ((addr->sa_family != AF_INET) || 8379ac77419b79fa1b61bed4326c4ef825a19335704t (addr->sa_len != sizeof(struct sockaddr_in))) { 8389ac77419b79fa1b61bed4326c4ef825a19335704t#else 8399ac77419b79fa1b61bed4326c4ef825a19335704t if (addr->sa_family != AF_INET) { 8407a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 8419ac77419b79fa1b61bed4326c4ef825a19335704t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 8429ac77419b79fa1b61bed4326c4ef825a19335704t return (EINVAL); 8439ac77419b79fa1b61bed4326c4ef825a19335704t } 8447a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 8459ac77419b79fa1b61bed4326c4ef825a19335704t return (sctp_inpcb_bind(so, addr, NULL, p)); 8467a9f1edd34bf82c194a2f9d0c64394f431175138tuexen} 8477a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 8487a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 849dad58c401bed435161454933c0b0a6d27ac03e48tuexen#if defined(__Userspace__) 850dad58c401bed435161454933c0b0a6d27ac03e48tuexen 851dad58c401bed435161454933c0b0a6d27ac03e48tuexenint 852dad58c401bed435161454933c0b0a6d27ac03e48tuexensctpconn_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id) 853dad58c401bed435161454933c0b0a6d27ac03e48tuexen{ 854dad58c401bed435161454933c0b0a6d27ac03e48tuexen struct sctp_inpcb *inp; 855dad58c401bed435161454933c0b0a6d27ac03e48tuexen struct inpcb *ip_inp; 856dad58c401bed435161454933c0b0a6d27ac03e48tuexen int error; 857dad58c401bed435161454933c0b0a6d27ac03e48tuexen 858dad58c401bed435161454933c0b0a6d27ac03e48tuexen inp = (struct sctp_inpcb *)so->so_pcb; 859dad58c401bed435161454933c0b0a6d27ac03e48tuexen if (inp != NULL) { 860dad58c401bed435161454933c0b0a6d27ac03e48tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 861dad58c401bed435161454933c0b0a6d27ac03e48tuexen return (EINVAL); 862dad58c401bed435161454933c0b0a6d27ac03e48tuexen } 863dad58c401bed435161454933c0b0a6d27ac03e48tuexen if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 864dad58c401bed435161454933c0b0a6d27ac03e48tuexen error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); 865dad58c401bed435161454933c0b0a6d27ac03e48tuexen if (error) { 866dad58c401bed435161454933c0b0a6d27ac03e48tuexen return (error); 867dad58c401bed435161454933c0b0a6d27ac03e48tuexen } 868dad58c401bed435161454933c0b0a6d27ac03e48tuexen } 869dad58c401bed435161454933c0b0a6d27ac03e48tuexen error = sctp_inpcb_alloc(so, vrf_id); 870dad58c401bed435161454933c0b0a6d27ac03e48tuexen if (error) { 871dad58c401bed435161454933c0b0a6d27ac03e48tuexen return (error); 872dad58c401bed435161454933c0b0a6d27ac03e48tuexen } 873dad58c401bed435161454933c0b0a6d27ac03e48tuexen inp = (struct sctp_inpcb *)so->so_pcb; 874dad58c401bed435161454933c0b0a6d27ac03e48tuexen SCTP_INP_WLOCK(inp); 8757a9f1edd34bf82c194a2f9d0c64394f431175138tuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; 8767988ea8f0c067cf3757e798b473b1ae4d34b6dfdt inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_CONN; 877dad58c401bed435161454933c0b0a6d27ac03e48tuexen ip_inp = &inp->ip_inp.inp; 87875cd23222c96d5ebe5a9082c57a263f917f1462btuexen ip_inp->inp_vflag |= INP_CONN; 879dad58c401bed435161454933c0b0a6d27ac03e48tuexen ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); 880dad58c401bed435161454933c0b0a6d27ac03e48tuexen SCTP_INP_WUNLOCK(inp); 881dad58c401bed435161454933c0b0a6d27ac03e48tuexen return (0); 882dad58c401bed435161454933c0b0a6d27ac03e48tuexen} 8838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 885dcb94e06c8e8dde2dde9f254e245728c75cdefd7tuexensctpconn_bind(struct socket *so, struct sockaddr *addr) 886dcb94e06c8e8dde2dde9f254e245728c75cdefd7tuexen{ 8879ac77419b79fa1b61bed4326c4ef825a19335704t struct sctp_inpcb *inp; 8888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8899ac77419b79fa1b61bed4326c4ef825a19335704t inp = (struct sctp_inpcb *)so->so_pcb; 8909ac77419b79fa1b61bed4326c4ef825a19335704t if (inp == NULL) { 8919ac77419b79fa1b61bed4326c4ef825a19335704t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 892b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 8938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 8949ac77419b79fa1b61bed4326c4ef825a19335704t if (addr != NULL) { 895f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 8969ac77419b79fa1b61bed4326c4ef825a19335704t if ((addr->sa_family != AF_CONN) || 8979ac77419b79fa1b61bed4326c4ef825a19335704t (addr->sa_len != sizeof(struct sockaddr_conn))) { 8989ac77419b79fa1b61bed4326c4ef825a19335704t#else 8999ac77419b79fa1b61bed4326c4ef825a19335704t if (addr->sa_family != AF_CONN) { 9008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9019ac77419b79fa1b61bed4326c4ef825a19335704t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 9029ac77419b79fa1b61bed4326c4ef825a19335704t return (EINVAL); 9039ac77419b79fa1b61bed4326c4ef825a19335704t } 904dcb94e06c8e8dde2dde9f254e245728c75cdefd7tuexen } 9059ac77419b79fa1b61bed4326c4ef825a19335704t return (sctp_inpcb_bind(so, addr, NULL, NULL)); 9068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 9078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 690000) || defined(__Windows__) || defined(__Userspace__) 9108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 9118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_close(struct socket *so) 9128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 9138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 9148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t flags; 9158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 9172fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) 9188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 9198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Inform all the lower layer assoc that we 9218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * are done. 9228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 9238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_must_try_again: 9248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 9258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 9268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 17); 9278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 9298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 930907b9e7d7c75f02c3d1f6c70016127990e8fe648t#if defined(__Userspace__) 931907b9e7d7c75f02c3d1f6c70016127990e8fe648t if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) || 932907b9e7d7c75f02c3d1f6c70016127990e8fe648t (so->so_rcv.sb_cc > 0)) { 933907b9e7d7c75f02c3d1f6c70016127990e8fe648t#else 9348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) || 9358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (so->so_rcv.sb_cc > 0)) { 936907b9e7d7c75f02c3d1f6c70016127990e8fe648t#endif 9378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 9388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 13); 9398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 9418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 9428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 9438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 9448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 14); 9458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE, 9478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 9488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* The socket is now detached, no matter what 9508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the state of the SCTP association. 9518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 9528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_LOCK(so); 9538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SB_CLEAR(so->so_snd); 9548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* same for the rcv ones, they are only 9558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * here for the accounting/select. 9568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 9578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SB_CLEAR(so->so_rcv); 9588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) 9608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now null out the reference, we are completely detached. */ 9618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_pcb = NULL; 9628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 9648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 9658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 9668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 9678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto sctp_must_try_again; 9688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 9718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 9728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 9748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 9778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_detach(struct socket *so) 9788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 9798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 9808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t flags; 9818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 9828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 9832fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 9848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version > 690000 9858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 9868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 9878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 988b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 9898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 9918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_must_try_again: 9928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 9938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 9948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 17); 9958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 9968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 9978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 998907b9e7d7c75f02c3d1f6c70016127990e8fe648t#if defined(__Userspace__) 999907b9e7d7c75f02c3d1f6c70016127990e8fe648t if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) || 1000907b9e7d7c75f02c3d1f6c70016127990e8fe648t (so->so_rcv.sb_cc > 0)) { 1001907b9e7d7c75f02c3d1f6c70016127990e8fe648t#else 10028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) || 10038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (so->so_rcv.sb_cc > 0)) { 1004907b9e7d7c75f02c3d1f6c70016127990e8fe648t#endif 10058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 10068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 13); 10078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 10098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 10108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 10118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOG_CLOSING 10128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_closing(inp, NULL, 13); 10138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE, 10158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 10168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* The socket is now detached, no matter what 10188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the state of the SCTP association. 10198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 10208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SB_CLEAR(so->so_snd); 10218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* same for the rcv ones, they are only 10228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * here for the accounting/select. 10238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 10248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SB_CLEAR(so->so_rcv); 10258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__APPLE__) 10268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now disconnect */ 10278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_pcb = NULL; 10288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 10308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags = inp->sctp_flags; 10318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 10328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto sctp_must_try_again; 10338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version > 690000 10368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 10378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 1038b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (0); 10398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 10418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 10448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* __Userspace__ is not calling sctp_sendm */ 10458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !(defined(__Panda__) || defined(__Windows__)) 10478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 10488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 10498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 10508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *control, struct thread *p); 10518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 10538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 10548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *control, struct proc *p); 10558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 10598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 10608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 10618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *control, struct thread *p) 10628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 10638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 10648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 10658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *control, struct proc *p) 10668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 10678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 10688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 10698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error; 10708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 10718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 10722fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 10738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control) { 10748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(control); 10758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = NULL; 10768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 10788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m); 1079b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 10808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Got to have an to address if we are NOT a connected socket */ 10828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((addr == NULL) && 10838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) || 1084b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))) { 10858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto connected_type; 10868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (addr == NULL) { 10878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ); 10888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EDESTADDRREQ; 10898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m); 10908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control) { 10918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(control); 10928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = NULL; 10938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 10958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 10968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 10978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_family != AF_INET) { 10988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* must be a v4 address! */ 10998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ); 11008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(m); 11018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control) { 11028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(control); 11038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen control = NULL; 11048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EDESTADDRREQ; 11068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 11078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* INET6 */ 11098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenconnected_type: 11108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* now what about control */ 11118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (control) { 11128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->control) { 11138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("huh? control set?\n"); 11148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_m_freem(inp->control); 11158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->control = NULL; 11168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->control = control; 11188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Place the data */ 11208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->pkt) { 11218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_NEXT(inp->pkt_last) = m; 11228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->pkt_last = m; 11238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 11248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->pkt_last = inp->pkt = m; 11258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ( 11270612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) 11288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FreeBSD uses a flag passed */ 11298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((flags & PRUS_MORETOCOME) == 0) 11308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 11318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1 /* Open BSD does not have any "more to come" 11328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * indication */ 11338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 11348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ) { 11358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 11368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * note with the current version this code will only be used 11378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for 11388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * re-defining sosend to use the sctp_sosend. One can 11398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * optionally switch back to this code (by changing back the 11408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * definitions) but this is not advisable. This code is used 11418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * by FreeBSD when sending a file with sendfile() though. 11428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 11438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ret; 11448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags); 11468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->pkt = NULL; 11478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->control = NULL; 11488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ret); 11498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 11508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 11518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 11538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 11548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 11568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_disconnect(struct socket *so) 11578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 11588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 11598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 11618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 11628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 11638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOTCONN); 11648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 11668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 11678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 11688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (LIST_EMPTY(&inp->sctp_asoc_list)) { 11698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* No connection */ 11708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 11718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 11728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 11738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_association *asoc; 11748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 11758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 11768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 11778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 11788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 11798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 11808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 11818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 11828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 11838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc = &stcb->asoc; 11848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 11858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are about to be freed, out of here */ 11868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 11878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 11888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 11898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 1190907b9e7d7c75f02c3d1f6c70016127990e8fe648t#if defined(__Userspace__) 1191907b9e7d7c75f02c3d1f6c70016127990e8fe648t if (((so->so_options & SCTP_SO_LINGER) && 119215aed6e434dc1aac416f14635bb78920317d60e7t (so->so_linger == 0)) || 1193907b9e7d7c75f02c3d1f6c70016127990e8fe648t (so->so_rcv.sb_cc > 0)) { 1194907b9e7d7c75f02c3d1f6c70016127990e8fe648t#else 11958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((so->so_options & SO_LINGER) && 119615aed6e434dc1aac416f14635bb78920317d60e7t (so->so_linger == 0)) || 11978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (so->so_rcv.sb_cc > 0)) { 1198907b9e7d7c75f02c3d1f6c70016127990e8fe648t#endif 11998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_GET_STATE(asoc) != 12008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STATE_COOKIE_WAIT) { 12018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Left with Data unread */ 12028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *err; 12038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 120468beeca578347438d9c434680197647ed551935ft err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_NOWAIT, 1, MT_DATA); 12058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (err) { 12068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 12078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Fill in the user 12088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * initiated abort 12098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 12108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paramhdr *ph; 12118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 12128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ph = mtod(err, struct sctp_paramhdr *); 12138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr); 12148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT); 12158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ph->param_length = htons(SCTP_BUF_LEN(err)); 12168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_abort_tcb(stcb, err, SCTP_SO_LOCKED); 12188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR_COUNTER32(sctps_aborted); 12198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 12218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 12228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 12238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_DECR_GAUGE32(sctps_currestab); 12248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_3); 12268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* No unlock tcb assoc is gone */ 12278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 12288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&asoc->send_queue) && 12308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&asoc->sent_queue) && 12318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (asoc->stream_queue_cnt == 0)) { 12328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* there is nothing queued to send, so done */ 12338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->locked_on_sending) { 12348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto abort_anyway; 12358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) && 12378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) { 12388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only send SHUTDOWN 1st time thru */ 12398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *netp; 12407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt 12418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) || 12428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 12438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_DECR_GAUGE32(sctps_currestab); 12448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT); 12468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING); 12477988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sctp_stop_timers_for_shutdown(stcb); 12487988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (stcb->asoc.alternate) { 12497988ea8f0c067cf3757e798b473b1ae4d34b6dfdt netp = stcb->asoc.alternate; 12507988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 12517988ea8f0c067cf3757e798b473b1ae4d34b6dfdt netp = stcb->asoc.primary_destination; 12527988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 12537988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sctp_send_shutdown(stcb,netp); 12548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 12558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep, stcb, netp); 12568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 12578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep, stcb, netp); 12587988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED); 12598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 12618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 12628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we still got (or just got) data to send, 12638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * so set SHUTDOWN_PENDING 12648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 12658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 12668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * XXX sockets draft says that SCTP_EOF 12678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * should be sent with no data. currently, 12688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we will allow user data to be sent first 12698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * and move to SHUTDOWN-PENDING 12708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 12718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *netp; 12728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.alternate) { 12738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen netp = stcb->asoc.alternate; 12748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 12758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen netp = stcb->asoc.primary_destination; 12768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 12788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->state |= SCTP_STATE_SHUTDOWN_PENDING; 12798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, 12808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen netp); 12818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->locked_on_sending) { 12828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Locked to send out the data */ 12838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_queue_pending *sp; 12848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead); 12858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sp == NULL) { 12868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("Error, sp is NULL, locked on sending is non-null strm:%d\n", 12878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->locked_on_sending->stream_no); 12888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 12898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sp->length == 0) && (sp->msg_is_complete == 0)) 12908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT; 12918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 12938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&asoc->send_queue) && 12948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&asoc->sent_queue) && 12958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 12968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *op_err; 12978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen abort_anyway: 12988f9e45fea288542b24a6bda01269c6fc184d991at op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); 12998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ+SCTP_LOC_4; 13008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED); 13018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_INCR_COUNTER32(sctps_aborted); 13028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) || 13038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 13048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_DECR_GAUGE32(sctps_currestab); 13058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 13078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_5); 13088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 13098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 13108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED); 13118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen soisdisconnecting(so); 13148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 13158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 13168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 13178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not reached */ 13198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 13208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* UDP model does not support this */ 13218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 13228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 1323b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EOPNOTSUPP); 13248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 13268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1327e5acde438f3c0c70f50751fa4c6a8209650f67cbtuexen#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) 13288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 13298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_flush(struct socket *so, int how) 13308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 13318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 13328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We will just clear out the values and let 13338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * subsequent close clear out the data, if any. 13348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Note if the user did a shutdown(SHUT_RD) they 13358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * will not be able to read the data, the socket 13368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * will block that from happening. 13378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 13388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 13398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 13408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 13418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp == NULL) { 13428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1343b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 13448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 13468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* For the 1 to many model this does nothing */ 13478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 13488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 13498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 13508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 13528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) { 13538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First make sure the sb will be happy, we don't 13548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * use these except maybe the count 13558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 13568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 13578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_LOCK(inp); 1358e5acde438f3c0c70f50751fa4c6a8209650f67cbtuexen inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ; 13598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_READ_UNLOCK(inp); 13608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 13618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_rcv.sb_cc = 0; 13628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_rcv.sb_mbcnt = 0; 13638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_rcv.sb_mb = NULL; 13648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((how == PRU_FLUSH_WR) || (how == PRU_FLUSH_RDWR)) { 13668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First make sure the sb will be happy, we don't 13678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * use these except maybe the count 13688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 13698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_snd.sb_cc = 0; 13708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_snd.sb_mbcnt = 0; 13718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_snd.sb_mb = NULL; 13728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 13738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 13758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 13768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 13778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 13788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 13798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_shutdown(struct socket *so) 13808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 13818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 13828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 13838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 13842fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 13858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 1386b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 13878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 13888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 13898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* For UDP model this is a invalid call */ 1390e2fb489e7481204003db964c24f54c4ba99d327et if (!((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1391e2fb489e7481204003db964c24f54c4ba99d327et (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { 13928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Restore the flags that the soshutdown took away. */ 13938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version >= 502115) || defined(__Windows__) 13948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&so->so_rcv); 13958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_rcv.sb_state &= ~SBS_CANTRCVMORE; 13968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&so->so_rcv); 13978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 13988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_state &= ~SS_CANTRCVMORE; 13998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 14008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* This proc will wakeup for read and do nothing (I hope) */ 14018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 14028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 14038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EOPNOTSUPP); 14048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 14068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Ok if we reach here its the TCP model and it is either a SHUT_WR 14078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * or SHUT_RDWR. This means we put the shutdown flag against it. 14088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 14098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 14108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 14118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_association *asoc; 14128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((so->so_state & 14148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SS_ISCONNECTED|SS_ISCONNECTING|SS_ISDISCONNECTING)) == 0) { 14158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 14168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOTCONN); 14178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen socantsendmore(so); 14198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 14218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 14228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 14238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Ok we hit the case that the shutdown call was 14248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * made after an abort or something. Nothing to do 14258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * now. 14268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 14278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 14288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 14298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 14318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc = &stcb->asoc; 14328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&asoc->send_queue) && 14338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&asoc->sent_queue) && 14348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (asoc->stream_queue_cnt == 0)) { 14358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->locked_on_sending) { 14368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto abort_anyway; 14378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* there is nothing queued to send, so I'm done... */ 14398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) { 14408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only send SHUTDOWN the first time through */ 14418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *netp; 14427988ea8f0c067cf3757e798b473b1ae4d34b6dfdt 14438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) || 14448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) { 14458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_STAT_DECR_GAUGE32(sctps_currestab); 14468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT); 14488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING); 14497988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sctp_stop_timers_for_shutdown(stcb); 14507988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (stcb->asoc.alternate) { 14517988ea8f0c067cf3757e798b473b1ae4d34b6dfdt netp = stcb->asoc.alternate; 14527988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 14537988ea8f0c067cf3757e798b473b1ae4d34b6dfdt netp = stcb->asoc.primary_destination; 14547988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 14557988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sctp_send_shutdown(stcb, netp); 14568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 14578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep, stcb, netp); 14588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 14598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep, stcb, netp); 14607988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED); 14618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 14638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 14648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we still got (or just got) data to send, so set 14658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * SHUTDOWN_PENDING 14668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 14678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *netp; 14688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.alternate) { 14698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen netp = stcb->asoc.alternate; 14708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 14718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen netp = stcb->asoc.primary_destination; 14728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->state |= SCTP_STATE_SHUTDOWN_PENDING; 14758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, 14768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen netp); 14778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 14788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (asoc->locked_on_sending) { 14798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Locked to send out the data */ 14808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_queue_pending *sp; 14818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp = TAILQ_LAST(&asoc->locked_on_sending->outqueue, sctp_streamhead); 14828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sp == NULL) { 14838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("Error, sp is NULL, locked on sending is non-null strm:%d\n", 14848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->locked_on_sending->stream_no); 14858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 14868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sp->length == 0) && (sp-> msg_is_complete == 0)) { 14878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen asoc->state |= SCTP_STATE_PARTIAL_MSG_LEFT; 14888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 14918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&asoc->send_queue) && 14928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&asoc->sent_queue) && 14938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { 14948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *op_err; 14958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen abort_anyway: 14968f9e45fea288542b24a6bda01269c6fc184d991at op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, ""); 14978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ+SCTP_LOC_6; 14988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_abort_an_association(stcb->sctp_ep, stcb, 14998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen op_err, SCTP_SO_LOCKED); 15008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto skip_unlock; 15018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 15028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED); 15038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 15068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen skip_unlock: 15088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 1509b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (0); 15108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 15118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 15138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * copies a "user" presentable address and removes embedded scope, etc. 15148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * returns 0 on success, 1 on error 15158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 15168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic uint32_t 15178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa) 15188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 15198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 15208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 15218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 lsa6; 15228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa, 15248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &lsa6); 15258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1527f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 15288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(ss, sa, sa->sa_len); 15298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 15307988ea8f0c067cf3757e798b473b1ae4d34b6dfdt switch (sa->sa_family) { 15317988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET 15327988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET: 15338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(ss, sa, sizeof(struct sockaddr_in)); 15347988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 15357988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 15367988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET6 15377988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET6: 15388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(ss, sa, sizeof(struct sockaddr_in6)); 15397988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 15407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 15417988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 15427988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 15437988ea8f0c067cf3757e798b473b1ae4d34b6dfdt memcpy(ss, sa, sizeof(struct sockaddr_conn)); 15447988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 15457988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 15467988ea8f0c067cf3757e798b473b1ae4d34b6dfdt default: 15477988ea8f0c067cf3757e798b473b1ae4d34b6dfdt /* TSNH */ 15487988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 15498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 15508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 15518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 15528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 15538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 15578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NOTE: assumes addr lock is held 15588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 15598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic size_t 15608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, 15618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 15628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t limit, 15638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_storage *sas, 15648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id) 15658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 15668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifn *sctp_ifn; 15678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *sctp_ifa; 15688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t actual; 156927d5428d96bc21c1097c731755876b8ffaef1b23t int loopback_scope; 157027d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET) 157127d5428d96bc21c1097c731755876b8ffaef1b23t int ipv4_local_scope, ipv4_addr_legal; 157227d5428d96bc21c1097c731755876b8ffaef1b23t#endif 157327d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET6) 157427d5428d96bc21c1097c731755876b8ffaef1b23t int local_scope, site_scope, ipv6_addr_legal; 157527d5428d96bc21c1097c731755876b8ffaef1b23t#endif 15767988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 15777988ea8f0c067cf3757e798b473b1ae4d34b6dfdt int conn_addr_legal; 15787988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 15798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_vrf *vrf; 15808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual = 0; 15828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (limit <= 0) 15838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 15848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 15858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 15868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Turn on all the appropriate scope */ 15877988ea8f0c067cf3757e798b473b1ae4d34b6dfdt loopback_scope = stcb->asoc.scope.loopback_scope; 158827d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET) 15897988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; 159027d5428d96bc21c1097c731755876b8ffaef1b23t ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; 159127d5428d96bc21c1097c731755876b8ffaef1b23t#endif 159227d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET6) 15937988ea8f0c067cf3757e798b473b1ae4d34b6dfdt local_scope = stcb->asoc.scope.local_scope; 15947988ea8f0c067cf3757e798b473b1ae4d34b6dfdt site_scope = stcb->asoc.scope.site_scope; 15957988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; 159627d5428d96bc21c1097c731755876b8ffaef1b23t#endif 15977988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 15987988ea8f0c067cf3757e798b473b1ae4d34b6dfdt conn_addr_legal = stcb->asoc.scope.conn_addr_legal; 15997988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 16008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 16017988ea8f0c067cf3757e798b473b1ae4d34b6dfdt /* Use generic values for endpoints. */ 16027988ea8f0c067cf3757e798b473b1ae4d34b6dfdt loopback_scope = 1; 160327d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET) 16047988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv4_local_scope = 1; 160527d5428d96bc21c1097c731755876b8ffaef1b23t#endif 160627d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET6) 16077988ea8f0c067cf3757e798b473b1ae4d34b6dfdt local_scope = 1; 16087988ea8f0c067cf3757e798b473b1ae4d34b6dfdt site_scope = 1; 160927d5428d96bc21c1097c731755876b8ffaef1b23t#endif 16107988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 161127d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET6) 16127988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv6_addr_legal = 1; 161327d5428d96bc21c1097c731755876b8ffaef1b23t#endif 161427d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET) 16157988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (SCTP_IPV6_V6ONLY(inp)) { 16167988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv4_addr_legal = 0; 16177988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 16187988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv4_addr_legal = 1; 16197988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 162027d5428d96bc21c1097c731755876b8ffaef1b23t#endif 16217988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 16227988ea8f0c067cf3757e798b473b1ae4d34b6dfdt conn_addr_legal = 0; 16237988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 16247988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 162527d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET6) 16267988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv6_addr_legal = 0; 162727d5428d96bc21c1097c731755876b8ffaef1b23t#endif 16287988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 16297988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) { 16307988ea8f0c067cf3757e798b473b1ae4d34b6dfdt conn_addr_legal = 1; 163127d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET) 16327988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv4_addr_legal = 0; 163327d5428d96bc21c1097c731755876b8ffaef1b23t#endif 16347988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 16357988ea8f0c067cf3757e798b473b1ae4d34b6dfdt conn_addr_legal = 0; 163627d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET) 16377988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ipv4_addr_legal = 1; 163827d5428d96bc21c1097c731755876b8ffaef1b23t#endif 16397988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 16407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#else 164127d5428d96bc21c1097c731755876b8ffaef1b23t#if defined(INET) 16428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ipv4_addr_legal = 1; 16437988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 164427d5428d96bc21c1097c731755876b8ffaef1b23t#endif 16458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf = sctp_find_vrf(vrf_id); 16488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf == NULL) { 16498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 16508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 16528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 16538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((loopback_scope == 0) && 16548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { 16558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Skip loopback if loopback_scope not set */ 16568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 16578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 16598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 16608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 16618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For the BOUND-ALL case, the list 16628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * associated with a TCB is Always 16638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * considered a reverse list.. i.e. 16648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * it lists addresses that are NOT 16658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * part of the association. If this 16668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * is one of those we must skip it. 16678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 16688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_addr_restricted(stcb, 16698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ifa)) { 16708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 16718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sctp_ifa->address.sa.sa_family) { 16748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 16758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 16768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ipv4_addr_legal) { 16778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 16788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 1679bfb1bf7e665a02b48026482bf33d05c83dfad73bt sin = &sctp_ifa->address.sin; 16808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr == 0) { 16818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 16828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we skip unspecifed 16838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * addresses 16848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 16858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 16868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 1687998635733088fde643e6d807fa76679c4ceeaa00t#if defined(__FreeBSD__) 1688998635733088fde643e6d807fa76679c4ceeaa00t if (prison_check_ip4(inp->ip_inp.inp.inp_cred, 1689998635733088fde643e6d807fa76679c4ceeaa00t &sin->sin_addr) != 0) { 1690998635733088fde643e6d807fa76679c4ceeaa00t continue; 1691998635733088fde643e6d807fa76679c4ceeaa00t } 1692998635733088fde643e6d807fa76679c4ceeaa00t#endif 16938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((ipv4_local_scope == 0) && 16948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 16958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 16968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 16988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 16998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas); 17008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 17018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6)); 17028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sizeof(struct sockaddr_in6); 17038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 17048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(sas, sin, sizeof(*sin)); 17068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 17078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin)); 17088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sizeof(*sin); 17098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 17108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (actual >= limit) { 17138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 17148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 17168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 17218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 17228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ipv6_addr_legal) { 17238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 17248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 17258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME) 17268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 lsa6; 17278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 1728bfb1bf7e665a02b48026482bf33d05c83dfad73bt sin6 = &sctp_ifa->address.sin6; 17298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 17308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we skip unspecifed 17328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * addresses 17338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 1736998635733088fde643e6d807fa76679c4ceeaa00t#if defined(__FreeBSD__) 1737998635733088fde643e6d807fa76679c4ceeaa00t if (prison_check_ip6(inp->ip_inp.inp.inp_cred, 1738998635733088fde643e6d807fa76679c4ceeaa00t &sin6->sin6_addr) != 0) { 1739998635733088fde643e6d807fa76679c4ceeaa00t continue; 1740998635733088fde643e6d807fa76679c4ceeaa00t } 1741998635733088fde643e6d807fa76679c4ceeaa00t#endif 17428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 17438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (local_scope == 0) 17448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 17468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin6->sin6_scope_id == 0) { 17478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 17488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa6_recoverscope(sin6) != 0) 17498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bad link 17518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * local 17528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * address 17538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 17568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen lsa6 = *sin6; 17578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in6_recoverscope(&lsa6, 17588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &lsa6.sin6_addr, 17598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL)) 17608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bad link 17628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * local 17638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * address 17648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = &lsa6; 17678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 17688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 17708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((site_scope == 0) && 17728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 17738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(sas, sin6, sizeof(*sin6)); 17767988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 17778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6)); 17788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sizeof(*sin6); 17798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (actual >= limit) { 17808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 17818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 17838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17877988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 17887988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 17897988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (conn_addr_legal) { 17907988ea8f0c067cf3757e798b473b1ae4d34b6dfdt memcpy(sas, &sctp_ifa->address.sconn, sizeof(struct sockaddr_conn)); 17917988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_conn *)sas)->sconn_port = inp->sctp_lport; 17927988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_conn)); 17937988ea8f0c067cf3757e798b473b1ae4d34b6dfdt actual += sizeof(struct sockaddr_conn); 17947988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (actual >= limit) { 17957988ea8f0c067cf3757e798b473b1ae4d34b6dfdt return (actual); 17967988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 17977988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 17987988ea8f0c067cf3757e798b473b1ae4d34b6dfdt continue; 17997988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 18007988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 18028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TSNH */ 18038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 18048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 18088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 1809f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifndef HAVE_SA_LEN 18108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t sa_len = 0; 18118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18127988ea8f0c067cf3757e798b473b1ae4d34b6dfdt 18138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 18148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 18158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_addr_restricted(stcb, laddr->ifa)) { 18168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 18178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_fill_user_address(sas, &laddr->ifa->address.sa)) 18208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 18217988ea8f0c067cf3757e798b473b1ae4d34b6dfdt switch (laddr->ifa->address.sa.sa_family) { 18227988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET 18237988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET: 18247988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 18257988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18277988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET6 18287988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET6: 18297988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 18307988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18317988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18327988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 18337988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 18347988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_conn *)sas)->sconn_port = inp->sctp_lport; 18357988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18367988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18377988ea8f0c067cf3757e798b473b1ae4d34b6dfdt default: 18387988ea8f0c067cf3757e798b473b1ae4d34b6dfdt /* TSNH */ 18397988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 1841f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 18428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + 18438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen laddr->ifa->address.sa.sa_len); 18448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += laddr->ifa->address.sa.sa_len; 18458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 18467988ea8f0c067cf3757e798b473b1ae4d34b6dfdt switch (laddr->ifa->address.sa.sa_family) { 18477988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET 18487988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET: 18497988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sa_len = sizeof(struct sockaddr_in); 18507988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18517988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18527988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET6 18537988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET6: 18547988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sa_len = sizeof(struct sockaddr_in6); 18557988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18567988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18577988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 18587988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 18597988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sa_len = sizeof(struct sockaddr_conn); 18607988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18617988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18627988ea8f0c067cf3757e798b473b1ae4d34b6dfdt default: 18637988ea8f0c067cf3757e798b473b1ae4d34b6dfdt /* TSNH */ 18647988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18657988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 18668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sa_len); 18678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sa_len; 18688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (actual >= limit) { 18708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 18718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 18758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 18768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 18778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic size_t 18788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_fill_up_addresses(struct sctp_inpcb *inp, 18798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 18808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t limit, 18818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_storage *sas) 18828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 18838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size = 0; 18848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 18858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t id; 18868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 18888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RLOCK(); 18898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 18908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 18918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * FIX ME: ?? this WILL report duplicate addresses if they appear 18928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * in more than one VRF. 18938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 18948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* fill up addresses for all VRFs on the endpoint */ 18958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (id = 0; (id < inp->num_vrfs) && (size < limit); id++) { 18968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sctp_fill_up_addresses_vrf(inp, stcb, limit, sas, 18978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids[id]); 18988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + size); 18998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 19018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* fill up addresses for the endpoint's default vrf */ 19028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_fill_up_addresses_vrf(inp, stcb, limit, sas, 19038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_vrf_id); 19048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 19068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (size); 19078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 19088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 19108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NOTE: assumes addr lock is held 19118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 19138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id) 19148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 19158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int cnt = 0; 19168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_vrf *vrf = NULL; 19178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 19198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * In both sub-set bound an bound_all cases we return the MAXIMUM 19208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * number of addresses that you COULD get. In reality the sub-set 19218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bound may have an exclusion list for a given TCB OR in the 19228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bound-all case a TCB may NOT include the loopback or other 19238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * addresses as well. 19248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf = sctp_find_vrf(vrf_id); 19268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf == NULL) { 19278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 19288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 19308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifn *sctp_ifn; 19318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *sctp_ifa; 19328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 19348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 19358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Count them if they are the right type */ 19368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sctp_ifa->address.sa.sa_family) { 19378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 19388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 19398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 19408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 19428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in); 19438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 19468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 19478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19507988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 19517988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 19527988ea8f0c067cf3757e798b473b1ae4d34b6dfdt cnt += sizeof(struct sockaddr_conn); 19537988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 19547988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 19558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 19568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 19618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 19628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 19648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (laddr->ifa->address.sa.sa_family) { 19658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 19668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 19678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 19688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 19708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in); 19718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 19748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 19758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 197875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 197975cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 198075cd23222c96d5ebe5a9082c57a263f917f1462btuexen cnt += sizeof(struct sockaddr_conn); 198175cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 198275cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 19838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 19848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (cnt); 19898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 19908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 19928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_count_max_addresses(struct sctp_inpcb *inp) 19938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 19948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int cnt = 0; 19958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 19968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int id; 19978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RLOCK(); 20008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 20018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 20028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * FIX ME: ?? this WILL count duplicate addresses if they appear 20038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * in more than one VRF. 20048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 20058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* count addresses for all VRFs on the endpoint */ 20068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (id = 0; id < inp->num_vrfs; id++) { 20078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sctp_count_max_addresses_vrf(inp, inp->m_vrf_ids[id]); 20088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 20108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* count addresses for the endpoint's default VRF */ 20118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = sctp_count_max_addresses_vrf(inp, inp->def_vrf_id); 20128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 20138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 20148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (cnt); 20158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 20168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 20188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval, 20198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t optsize, void *p, int delay) 20208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 20218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 20228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int creat_lock_on = 0; 20238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 20248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 20258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr; 20268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 2027b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int bad_addresses = 0; 20288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_assoc_t *a_id; 20298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_PCB1, "Connectx called\n"); 20318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 20338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 20348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are already connected AND the TCP model */ 20358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 20368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 20378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 20408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 20418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2042b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 20438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 20468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 20478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 20488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 20498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 20518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 20528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EALREADY); 20538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 20558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_LOCK(inp); 20568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen creat_lock_on = 1; 20578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 20588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 20598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 20608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EFAULT; 20618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen totaddrp = (int *)optval; 20648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen totaddr = *totaddrp; 20658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)(totaddrp + 1); 2066b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen stcb = sctp_connectx_helper_find(inp, sa, &totaddr, &num_v4, &num_v6, &error, (optsize - sizeof(int)), &bad_addresses); 2067b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb != NULL) || bad_addresses) { 20688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Already have or am bring up an association */ 20698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_UNLOCK(inp); 20708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen creat_lock_on = 0; 20718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 20728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 20738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (bad_addresses == 0) { 20748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 20758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 20768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 20808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 20818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (num_v6 > 0)) { 20828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 20838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 20868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (num_v4 > 0)) { 20878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct in6pcb *inp6; 20888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp6 = (struct in6pcb *)inp; 20908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_IPV6_V6ONLY(inp6)) { 20918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 20928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * if IPV6_V6ONLY flag, ignore connections destined 20938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * to a v4 addr or v4-mapped addr 20948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 20958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 20968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 20978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* INET6 */ 21018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 21028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PCB_FLAGS_UNBOUND) { 21038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Bind a ephemeral port */ 21048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_inpcb_bind(so, NULL, NULL, p); 21058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 21068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 21078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIX ME: do we want to pass in a vrf on the connect call? */ 21118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 2112000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 21138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are GOOD to go */ 21158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id, 21168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 21178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct thread *)p 21188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 21198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (PKTHREAD)p 21208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 21218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct proc *)p 21228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 21238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ); 21248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 21258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak! no memory */ 21268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 21278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 21298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 21308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Set the connected flag so we can queue data */ 21318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen soisconnecting(so); 21328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 21348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* move to second address */ 21358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sa->sa_family) { 21368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 21378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 21388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in)); 21398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 21418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 21428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 21438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6)); 21448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 21468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 21478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 21518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_connectx_helper_add(stcb, sa, (totaddr-1), &error); 21528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Fill in the return id */ 21538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 21548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_6); 21558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 21568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen a_id = (sctp_assoc_t *)optval; 21588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *a_id = sctp_get_associd(stcb); 21598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* initialize authentication parameters for the assoc */ 21618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_initialize_auth_params(inp, stcb); 21628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (delay) { 21648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* doing delayed connection */ 21658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_connection = 1; 21668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination); 21678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 21688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 21698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 21708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 21728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 21738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 21748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Set the connected flag so we can queue data */ 21758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen soisconnecting(so); 21768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_now: 21788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (creat_lock_on) { 21798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_UNLOCK(inp); 21808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 2182b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (error); 21838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 21848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#define SCTP_FIND_STCB(inp, stcb, assoc_id) { \ 21868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||\ 21878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { \ 21888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); \ 21898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); \ 21908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { \ 21918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); \ 21928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 21938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); \ 21948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (assoc_id > SCTP_ALL_ASSOC) { \ 21958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \ 21968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { \ 21978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \ 21988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; \ 21998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; \ 22008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 22018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { \ 22028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = NULL; \ 22038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 22048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22070ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen#define SCTP_CHECK_AND_CAST(destp, srcp, type, size) {\ 22088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size < sizeof(type)) { \ 22098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); \ 22108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; \ 22118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; \ 22128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { \ 22138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen destp = (type *)srcp; \ 22148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 22158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Panda__) || defined(__Userspace__) 22188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 22198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 22208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 22218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 22228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, 22238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p) { 22248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp = NULL; 22258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error, val = 0; 22268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 22278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval == NULL) { 22298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 22318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 22342fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 22358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return EINVAL; 22378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 22398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 22418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 22428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 22438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 22448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 22458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 22468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 22478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 22488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 22498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 22508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 22518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT); 22528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 22548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4); 22558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 22578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 22588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only valid for bound all sockets */ 22598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 22608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 22618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 22638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto flags_out; 22648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 22678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); 22688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 22708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY); 22718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 22738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO); 22748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 22768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) 22778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = TICKS_TO_SEC(inp->sctp_ep.auto_close_time); 22788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 22798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = 0; 22808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 22838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 22848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 22858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end switch (sopt->sopt_name) */ 22868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < sizeof(val)) { 22878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 22898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags_out: 22918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 22928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 22938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* return the option value */ 22948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *(int *)optval = val; 22958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(val); 22968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_PACKET_LOG: 22998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_PACKET_LOGGING 23018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *target; 23028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ret; 23038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize); 23058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ret = sctp_copy_out_packet_log(target , (int)*optsize); 23068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = ret; 23078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 23088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 23098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 23108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 23118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REUSE_PORT: 23148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 23168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 23188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't do this for a 1-m socket */ 23198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 23208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 23238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 23248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 23258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_POINT: 23288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 23308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 23328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->partial_delivery_point; 23338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 23348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_FRAGMENT_INTERLEAVE: 23378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 23398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 23418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) { 23428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) { 23438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = SCTP_FRAG_LEVEL_2; 23448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = SCTP_FRAG_LEVEL_1; 23468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = SCTP_FRAG_LEVEL_0; 23498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 23518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CMT_ON_OFF: 23548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 23568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 23588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 23598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 23608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.sctp_cmt_on_off; 23618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 23628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 23648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 23658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 23668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 23678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_cmt_on_off; 23688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 23698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 23718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 23728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 23758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 23768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_CC: 23808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 23828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 23848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 23858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 23868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.congestion_control_module; 23878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 23888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 23908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 23918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 23928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 23938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_ep.sctp_default_cc_module; 23948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 23958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 23978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 23988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 24018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 24028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CC_OPTION: 24068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cc_option *cc_opt; 24088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, *optsize); 24108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id); 24118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 24128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) { 24158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 24168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 0, cc_opt); 24188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_cc_option); 24198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 24218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_SS: 24258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 24278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 24298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 24308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 24318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.stream_scheduling_module; 24328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 24338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 24358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 24368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 24378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 24388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_ep.sctp_default_ss_module; 24398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 24408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 24428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 24468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 24478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SS_VALUE: 24518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_value *av; 24538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize); 24558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 24568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 24578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], 24588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &av->stream_value) < 0) { 24598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 24608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_stream_value); 24638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 24658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't get stream value without association */ 24678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 24688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ADDR_LEN: 24738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 24758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 24778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 24798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value == AF_INET) { 24808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = sizeof(struct sockaddr_in); 24818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 24828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 24848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 24858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value == AF_INET6) { 24868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = sizeof(struct sockaddr_in6); 24878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 24888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 249075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 249175cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (av->assoc_value == AF_CONN) { 249275cd23222c96d5ebe5a9082c57a263f917f1462btuexen av->assoc_value = sizeof(struct sockaddr_conn); 249375cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = 0; 249475cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 249575cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 24968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 24978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 24988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 25008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ASSOC_NUMBER: 25048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value, cnt; 25068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 25088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 25098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 25108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 25118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt++; 25128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 25148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = cnt; 25158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 25168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ASSOC_ID_LIST: 25198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_ids *ids; 25218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen unsigned int at, limit; 2522000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 25238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ids, optval, struct sctp_assoc_ids, *optsize); 25248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen at = 0; 25258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen limit = (*optsize-sizeof(uint32_t))/ sizeof(sctp_assoc_t); 25268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 25278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 25288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (at < limit) { 25298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ids->gaids_assoc_id[at++] = sctp_get_associd(stcb); 25308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 25328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 25338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 25378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 25388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ids->gaids_number_of_ids = at; 25398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = ((at * sizeof(sctp_assoc_t)) + sizeof(uint32_t)); 25408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONTEXT: 25448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 25468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 25488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 25498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 25518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.context; 25528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 25538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 25558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 25568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 25578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 25588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_context; 25598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 25608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 25628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 25638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 25668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 25678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_VRF_ID: 25718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *default_vrfid; 25738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, *optsize); 25758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *default_vrfid = inp->def_vrf_id; 25768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 25778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ASOC_VRF: 25808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *id; 25828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(id, optval, struct sctp_assoc_value, *optsize); 25848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, id->assoc_id); 25858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 25868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 25878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 25888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen id->assoc_value = stcb->asoc.vrf_id; 25908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 25918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_VRF_IDS: 25958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 25978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int siz_needed; 25988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *vrf_ids; 25998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(vrf_ids, optval, uint32_t, *optsize); 26018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen siz_needed = inp->num_vrfs * sizeof(uint32_t); 26028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < siz_needed) { 26038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 26048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 26058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(vrf_ids, inp->m_vrf_ids, siz_needed); 26078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = siz_needed; 26088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 26108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 26118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 26128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 26138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_NONCE_VALUES: 26168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_get_nonce_values *gnv; 26188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(gnv, optval, struct sctp_get_nonce_values, *optsize); 26208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, gnv->gn_assoc_id); 26218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 26238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen gnv->gn_peers_tag = stcb->asoc.peer_vtag; 26248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen gnv->gn_local_tag = stcb->asoc.my_vtag; 26258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 26268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_get_nonce_values); 26278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 26298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 26308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DELAYED_SACK: 26348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sack_info *sack; 26368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, *optsize); 26388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 26398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 26408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = stcb->asoc.delayed_ack; 26418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_freq = stcb->asoc.sack_freq; 26428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 26438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 26458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 26468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_FUTURE_ASSOC)) { 26478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 26488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 26498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_freq = inp->sctp_ep.sctp_sack_freq; 26508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 26518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 26538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 26548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 26578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sack_info); 26588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_SNDBUF_USE: 26628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sockstat *ss; 26648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ss, optval, struct sctp_sockstat, *optsize); 26668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, ss->ss_assoc_id); 26678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 26698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ss->ss_total_sndbuf = stcb->asoc.total_output_queue_size; 26708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ss->ss_total_recv_buf = (stcb->asoc.size_on_reasm_queue + 26718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.size_on_all_streams); 26728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 26738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sockstat); 26748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 26768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 26778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAX_BURST: 26818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 900000 26838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *value; 26848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint8_t, *optsize); 26868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 26888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_ep.max_burst < 256) { 26898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->sctp_ep.max_burst; 26908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = 255; 26928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 26948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint8_t); 26958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 26968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 26978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 26998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 27008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 27028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.max_burst; 27038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 27048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 27068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 27078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 27088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 27098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_ep.max_burst; 27108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 27118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 27138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 27148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 27178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 27188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 27208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 27218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAXSEG: 27238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 27248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 27258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ovh; 27268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 27288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 27298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 27318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = sctp_get_frag_point(stcb, &stcb->asoc); 27328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 27338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 27358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 27368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 27378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 27388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 27398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 27408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 27428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_frag_point >= SCTP_DEFAULT_MAXSEGMENT) 27448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = 0; 27458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 27468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_frag_point - ovh; 27478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 27488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 27508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 27518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 27548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 27558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 27578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_STAT_LOG: 27598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_fill_stat_log(optval, optsize); 27608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 27618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENTS: 27628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 27638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event_subscribe *events; 27648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, *optsize); 27668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(events, 0, sizeof(struct sctp_event_subscribe)); 27678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 27688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT)) 27698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_data_io_event = 1; 27708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT)) 27728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_association_event = 1; 27738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT)) 27758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_address_event = 1; 27768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) 27788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_send_failure_event = 1; 27798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR)) 27818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_peer_error_event = 1; 27828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) 27848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_shutdown_event = 1; 27858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT)) 27878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_partial_delivery_event = 1; 27888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) 27908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_adaptation_layer_event = 1; 27918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT)) 27938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_authentication_event = 1; 27948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT)) 27968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_sender_dry_event = 1; 27978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT)) 27998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_stream_reset_event = 1; 28008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 28018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_event_subscribe); 28028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_LAYER: 28058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 28078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 28098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 28118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->sctp_ep.adaptation_layer_indicator; 28128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 28138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_INITIAL_DBG_SEQ: 28178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 28198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 28218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 28228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->sctp_ep.initial_sequence_debug; 28238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 28248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_LOCAL_ADDR_SIZE: 28288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 28308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 28328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 28338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = sctp_count_max_addresses(inp); 28348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 28358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_REMOTE_ADDR_SIZE: 28398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 28418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size; 28428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 28438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 28458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIXME MT: change to sctp_assoc_value? */ 28468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) *value); 28478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 28498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = 0; 28508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Count the sizes */ 28518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 28528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 28538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sizeof(struct sockaddr_in6); 28548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 28558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) { 28568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 28578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 28588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sizeof(struct sockaddr_in); 28598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 28618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 28628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 28638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sizeof(struct sockaddr_in6); 28648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 286675cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 286775cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 286875cd23222c96d5ebe5a9082c57a263f917f1462btuexen size += sizeof(struct sockaddr_conn); 286975cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 287075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 28718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 28728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 28778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = (uint32_t) size; 28788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 28808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 28818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 28828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_PEER_ADDRESSES: 28868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 28878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Get the address information, an array is passed in to 28888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * fill up we pack it. 28898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 28908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t cpsz, left; 28928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_storage *sas; 28938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 28948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *saddr; 28958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 28978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 28988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 29008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen left = (*optsize) - sizeof(struct sctp_getaddresses); 29018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_getaddresses); 29028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)&saddr->addr[0]; 29038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 29058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 29068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = sizeof(struct sockaddr_in6); 29078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) { 29098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 29108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 29118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = sizeof(struct sockaddr_in); 29128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 29158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 29168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = sizeof(struct sockaddr_in6); 29178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 291975cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 292075cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 292175cd23222c96d5ebe5a9082c57a263f917f1462btuexen cpsz = sizeof(struct sockaddr_conn); 292275cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 292375cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 29248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 29258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = 0; 29268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cpsz == 0) { 29308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (left < cpsz) { 29338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not enough room. */ 29348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(INET) && defined(INET6) 29378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) && 29388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) { 29398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Must map the address */ 29408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr, 29418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr_in6 *)sas); 29428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(sas, &net->ro._l_addr, cpsz); 29458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(INET) && defined(INET6) 29468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)sas)->sin_port = stcb->rport; 29498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz); 29518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen left -= cpsz; 29528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize += cpsz; 29538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 29558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 29578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 29588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_LOCAL_ADDRESSES: 29628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 29638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t limit, actual; 29648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_storage *sas; 29658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *saddr; 29668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 29688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 29698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)&saddr->addr[0]; 29718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen limit = *optsize - sizeof(sctp_assoc_t); 29728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual = sctp_fill_up_addresses(inp, stcb, limit, sas); 29738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 29748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 29758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sockaddr_storage) + actual; 29778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_PARAMS: 29808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 29818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrparams *paddrp; 29828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 29838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize); 29858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 29868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 29888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 29898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 29908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 29928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 29938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 29948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 29958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 29968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddrp->spp_address, &net, NULL, NULL); 29978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 29988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 29998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb && (net == NULL)) { 30028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 30038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)&paddrp->spp_address; 30058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 30068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 30078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 30088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 30108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 30118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 30128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 30138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 30148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 30158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 30178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 30188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 30198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 30208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 30218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 30238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 30248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 30258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 30268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 30278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 30288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 30308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 303175cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 303275cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 303375cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 303475cd23222c96d5ebe5a9082c57a263f917f1462btuexen 303575cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 303675cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 303775cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 303875cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 303975cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 304075cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 304175cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 304275cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 304375cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 30448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 30458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 30468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 30478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 30488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 30498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 30538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Applies to the specific association */ 30548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags = 0; 30558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 30568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ovh; 30578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 30588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 30598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 30618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval = net->heart_beat_delay; 30648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmaxrxt = net->failure_threshold; 30658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmtu = net->mtu - ovh; 30668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get flags for HB */ 30678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_NOHB) { 30688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_DISABLE; 30698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_ENABLE; 30718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get flags for PMTU */ 30738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_NO_PMTUD) { 30748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_ENABLE; 30758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_DISABLE; 30778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dscp & 0x01) { 30798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_dscp = net->dscp & 0xfc; 30808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_DSCP; 30818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 30838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->ro._l_addr.sa.sa_family == AF_INET6) && 30848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->flowlabel & 0x80000000)) { 30858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_ipv6_flowlabel = net->flowlabel & 0x000fffff; 30868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 30878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 30898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 30918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * No destination so return default 30928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * value 30938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 30948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure; 30958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc); 30968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.default_dscp & 0x01) { 30978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc; 30988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_DSCP; 30998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 31018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.default_flowlabel & 0x80000000) { 31028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel & 0x000fffff; 31038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 31048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 31068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* default settings should be these */ 31078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { 31088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_DISABLE; 31098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_ENABLE; 31118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) { 31138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_DISABLE; 31148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_ENABLE; 31168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay; 31188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_assoc_id = sctp_get_associd(stcb); 31208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 31218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 31238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 31248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC)) { 31258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Use endpoint defaults */ 31268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 31278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure; 31288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 31298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC; 31308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get inp's default */ 31318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_ep.default_dscp & 0x01) { 31328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_dscp = inp->sctp_ep.default_dscp & 0xfc; 31338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_DSCP; 31348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 31368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 31378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_ep.default_flowlabel & 0x80000000)) { 31388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_ipv6_flowlabel = inp->sctp_ep.default_flowlabel & 0x000fffff; 31398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 31408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 31428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't return this */ 31438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmtu = 0; 31448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { 31468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_ENABLE; 31478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_DISABLE; 31498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) { 31518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_ENABLE; 31528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_DISABLE; 31548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 31568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 31588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 31598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 31628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_paddrparams); 31638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 31658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_PEER_ADDR_INFO: 31678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 31688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrinfo *paddri; 31698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 31708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize); 31728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id); 31738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 31758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 31768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&paddri->spinfo_address); 31778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 31798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 31808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 31818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 31828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 31838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddri->spinfo_address, &net, NULL, NULL); 31848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 31858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 31868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb) && (net)) { 31908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { 31918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's unconfirmed */ 31928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_state = SCTP_UNCONFIRMED; 31938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (net->dest_state & SCTP_ADDR_REACHABLE) { 31948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's active */ 31958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_state = SCTP_ACTIVE; 31968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's inactive */ 31988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_state = SCTP_INACTIVE; 31998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_cwnd = net->cwnd; 32018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT; 32028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_rto = net->RTO; 32038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_assoc_id = sctp_get_associd(stcb); 32048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_mtu = net->mtu; 32058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 32068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_paddrinfo); 32078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 32088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 32098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 32108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 32128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 32138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PCB_STATUS: 32178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 32188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_pcbinfo *spcb; 32198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(spcb, optval, struct sctp_pcbinfo, *optsize); 32218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_fill_pcbinfo(spcb); 32228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_pcbinfo); 32238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_STATUS: 32268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 32278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 32288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_status *sstat; 32298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sstat, optval, struct sctp_status, *optsize); 32318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sstat->sstat_assoc_id); 32328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 32348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 32358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 32368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 32398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * I think passing the state is fine since 32408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sctp_constants.h will be available to the user 32418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * land. 32428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 32438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_state = stcb->asoc.state; 32448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_assoc_id = sctp_get_associd(stcb); 32458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_rwnd = stcb->asoc.peers_rwnd; 32468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt; 32478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 32488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We can't include chunks that have been passed to 32498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the socket layer. Only things in queue. 32508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 32518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue + 32528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cnt_on_all_streams); 32538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_instrms = stcb->asoc.streamincnt; 32568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_outstrms = stcb->asoc.streamoutcnt; 32578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc); 3258f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 32598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&sstat->sstat_primary.spinfo_address, 32608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 32618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len); 32628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 32638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET) { 32648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&sstat->sstat_primary.spinfo_address, 32658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 32668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct sockaddr_in)); 32678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 32688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&sstat->sstat_primary.spinfo_address, 32698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 32708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct sockaddr_in6)); 32718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 32738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = stcb->asoc.primary_destination; 32748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport; 32758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 32768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Again the user can get info from sctp_constants.h 32778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * for what the state of the network is. 32788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 32798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { 32808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's unconfirmed */ 32818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_state = SCTP_UNCONFIRMED; 32828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (net->dest_state & SCTP_ADDR_REACHABLE) { 32838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's active */ 32848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_state = SCTP_ACTIVE; 32858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 32868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's inactive */ 32878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_state = SCTP_INACTIVE; 32888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_cwnd = net->cwnd; 32908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT; 32918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_rto = net->RTO; 32928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_mtu = net->mtu; 32938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb); 32948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 32958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_status); 32968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RTOINFO: 32998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 33008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_rtoinfo *srto; 33018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, *optsize); 33038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 33048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 33068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_initial = stcb->asoc.initial_rto; 33078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_max = stcb->asoc.maxrto; 33088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_min = stcb->asoc.minrto; 33098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 33128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 33138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (srto->srto_assoc_id == SCTP_FUTURE_ASSOC)) { 33148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 33158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_initial = inp->sctp_ep.initial_rto; 33168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_max = inp->sctp_ep.sctp_maxrto; 33178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_min = inp->sctp_ep.sctp_minrto; 33188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 33198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 33218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 33228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 33258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_rtoinfo); 33268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 33288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMEOUTS: 33308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 33318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_timeouts *stimo; 33328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(stimo, optval, struct sctp_timeouts, *optsize); 33348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, stimo->stimo_assoc_id); 33358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 33378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_init= stcb->asoc.timoinit; 33388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_data= stcb->asoc.timodata; 33398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_sack= stcb->asoc.timosack; 33408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_shutdown= stcb->asoc.timoshutdown; 33418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_heartbeat= stcb->asoc.timoheartbeat; 33428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_cookie= stcb->asoc.timocookie; 33438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_shutdownack= stcb->asoc.timoshutdownack; 33448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_timeouts); 33468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 33488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 33498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 33518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOCINFO: 33538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 33548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assocparams *sasoc; 33558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, *optsize); 33578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 33588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 33608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = TICKS_TO_MSEC(stcb->asoc.cookie_life); 33618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times; 33628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets; 33638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd; 33648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd; 33658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 33688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 33698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC)) { 33708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 33718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = TICKS_TO_MSEC(inp->sctp_ep.def_cookie_life); 33728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times; 33738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_number_peer_destinations = 0; 33748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_peer_rwnd = 0; 33758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv); 33768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 33778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 33798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 33808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 33838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assocparams); 33848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 33868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SEND_PARAM: 33888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 33898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndrcvinfo *s_info; 33908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, *optsize); 33928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 33938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 33958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(s_info, &stcb->asoc.def_send, sizeof(stcb->asoc.def_send)); 33968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 33998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 34008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC)) { 34018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 34028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(s_info, &inp->def_send, sizeof(inp->def_send)); 34038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 34058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 34068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 3407000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 34088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 34108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sndrcvinfo); 34118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_INITMSG: 34158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 34168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_initmsg *sinit; 34178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, *optsize); 34198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 34208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count; 34218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome; 34228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_max_attempts = inp->sctp_ep.max_init_times; 34238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max; 34248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_initmsg); 34268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PRIMARY_ADDR: 34298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we allow a "get" operation on this */ 34308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 34318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setprim *ssp; 34328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ssp, optval, struct sctp_setprim, *optsize); 34348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id); 34358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 34378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* simply copy out the sockaddr_storage... */ 343818818c8dd0d4cafdb259fa73f01f7825948faadct size_t len; 34398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = *optsize; 3441f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 34428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len) 34438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = stcb->asoc.primary_destination->ro._l_addr.sa.sa_len; 34448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 34458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET && 34468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len > sizeof(struct sockaddr_in)) 34478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = sizeof(struct sockaddr_in); 34488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else if ( 34498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET6 && 34508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len > sizeof(struct sockaddr_in6)) 34518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = sizeof(struct sockaddr_in6); 34528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 34538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&ssp->ssp_addr, 34558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 34568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len); 34578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 34588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_setprim); 34598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 34608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 34618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 34628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_HMAC_IDENT: 34668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 34678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_hmacalgo *shmac; 34688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_hmaclist_t *hmaclist; 34698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t size; 34708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 34718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize); 34738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 34758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hmaclist = inp->sctp_ep.local_hmacs; 34768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hmaclist == NULL) { 34778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no HMACs to return */ 34788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(*shmac); 34798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there room for all of the hmac ids? */ 34838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sizeof(*shmac) + (hmaclist->num_algo * 34848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(shmac->shmac_idents[0])); 34858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((size_t)(*optsize) < size) { 34868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 34878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 34888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the list */ 34928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shmac->shmac_number_of_idents = hmaclist->num_algo; 34938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < hmaclist->num_algo; i++) { 34948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shmac->shmac_idents[i] = hmaclist->hmac[i]; 34958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = size; 34988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_ACTIVE_KEY: 35018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 35028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *scact; 35038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, *optsize); 35058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 35068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 35088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get the active key on the assoc */ 35098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen scact->scact_keynumber = stcb->asoc.authinfo.active_keyid; 35108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 35118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 35138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 35148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_FUTURE_ASSOC)) { 35158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get the endpoint active key */ 35168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 35178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen scact->scact_keynumber = inp->sctp_ep.default_keyid; 35188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 35198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 35218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 35258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authkeyid); 35268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 35288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_LOCAL_AUTH_CHUNKS: 35308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 35318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authchunks *sac; 35328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auth_chklist_t *chklist = NULL; 35338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size = 0; 35348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 35368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 35378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 35398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get off the assoc */ 35408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chklist = stcb->asoc.local_auth_chunks; 35418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there enough space? */ 35428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_auth_get_chklist_size(chklist); 35438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 35448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 35468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the chunks */ 35488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 35491a2e446bdbc52cc6178a3f80092943a84706ece9tuexen sac->gauth_number_of_chunks = (uint32_t)size; 35508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authchunks) + size; 35518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 35538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 35558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 35568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sac->gauth_assoc_id == SCTP_FUTURE_ASSOC)) { 35578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get off the endpoint */ 35588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 35598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chklist = inp->sctp_ep.local_auth_chunks; 35608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there enough space? */ 35618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_auth_get_chklist_size(chklist); 35628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 35638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 35658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the chunks */ 35678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 35681a2e446bdbc52cc6178a3f80092943a84706ece9tuexen sac->gauth_number_of_chunks = (uint32_t)size; 35698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authchunks) + size; 35708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 35728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 35748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 35788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_AUTH_CHUNKS: 35808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 35818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authchunks *sac; 35828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auth_chklist_t *chklist = NULL; 35838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size = 0; 35848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 35868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 35878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 35898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get off the assoc */ 35908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chklist = stcb->asoc.peer_auth_chunks; 35918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there enough space? */ 35928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_auth_get_chklist_size(chklist); 35938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 35948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 35968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the chunks */ 35988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 35991a2e446bdbc52cc6178a3f80092943a84706ece9tuexen sac->gauth_number_of_chunks = (uint32_t)size; 36008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authchunks) + size; 36018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 36038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 36048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 36058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 36068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 36088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(HAVE_SCTP_PEELOFF_SOCKOPT) 36108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEELOFF: 36118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 36128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_peeloff_opt *peeloff; 36138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(peeloff, optval, struct sctp_peeloff_opt, *optsize); 36158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* do the peeloff */ 36168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_peeloff_option(p, peeloff); 36178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 36188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_peeloff_opt); 36198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 36228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* HAVE_SCTP_PEELOFF_SOCKOPT */ 36238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENT: 36248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 36258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event *event; 36268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t event_type; 36278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, *optsize); 36298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, event->se_assoc_id); 36308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (event->se_type) { 36328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOC_CHANGE: 36338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT; 3634000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_CHANGE: 36368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPADDREVNT; 3637000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REMOTE_ERROR: 36398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPEERERR; 3640000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SEND_FAILED: 36428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT; 3643000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SHUTDOWN_EVENT: 36458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT; 3646000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_INDICATION: 36488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT; 3649000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_EVENT: 36518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_PDAPIEVNT; 3652000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTHENTICATION_EVENT: 36548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_AUTHEVNT; 3655000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_STREAM_RESET_EVENT: 36578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT; 3658000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SENDER_DRY_EVENT: 36608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_DRYEVNT; 3661000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFICATIONS_STOPPED_EVENT: 36638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 36648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 36658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 36668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 3667298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_ASSOC_RESET_EVENT: 3668298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT; 3669298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 3670298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_STREAM_CHANGE_EVENT: 3671298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT; 3672298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 36735741e159bdf238ef4b61085d6fbfea2947386238tuexen case SCTP_SEND_FAILED_EVENT: 36745741e159bdf238ef4b61085d6fbfea2947386238tuexen event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT; 36755741e159bdf238ef4b61085d6fbfea2947386238tuexen break; 36768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 36778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 36788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 36798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 36808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 36818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event_type > 0) { 36838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 36848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->se_on = sctp_stcb_is_feature_on(inp, stcb, event_type); 36858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 36868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 36878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 36888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 36898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_FUTURE_ASSOC)) { 36908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 36918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->se_on = sctp_is_feature_on(inp, event_type); 36928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 36938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 36948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 36958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 36968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_event); 37018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVRCVINFO: 37058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int onoff; 37078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < sizeof(int)) { 37098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 37108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 37118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37126f63c1f0e9307e260e6d8724b12d0153cedb4a9atuexen SCTP_INP_RLOCK(inp); 37138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 37148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* return the option value */ 37188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *(int *)optval = onoff; 37198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(int); 37208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVNXTINFO: 37248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int onoff; 37268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < sizeof(int)) { 37288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 37298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 37308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37316f63c1f0e9307e260e6d8724b12d0153cedb4a9atuexen SCTP_INP_RLOCK(inp); 37328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 37338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* return the option value */ 37378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *(int *)optval = onoff; 37388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(int); 37398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SNDINFO: 37438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndinfo *info; 37458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, *optsize); 37478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id); 37488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 37508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_sid = stcb->asoc.def_send.sinfo_stream; 37518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags = stcb->asoc.def_send.sinfo_flags; 37528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags &= 0xfff0; 37538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_ppid = stcb->asoc.def_send.sinfo_ppid; 37548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_context = stcb->asoc.def_send.sinfo_context; 37558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 37568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 37588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 37598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_FUTURE_ASSOC)) { 37608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 37618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_sid = inp->def_send.sinfo_stream; 37628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags = inp->def_send.sinfo_flags; 37638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags &= 0xfff0; 37648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_ppid = inp->def_send.sinfo_ppid; 37658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_context = inp->def_send.sinfo_context; 37668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 37698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 37708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sndinfo); 37748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_PRINFO: 37788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_default_prinfo *info; 37808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, *optsize); 37828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id); 37838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 37858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 37868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_value = stcb->asoc.def_send.sinfo_timetolive; 37878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 37888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 37908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 37918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_FUTURE_ASSOC)) { 37928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 37938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags); 37948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_value = inp->def_send.sinfo_timetolive; 37958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 37988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 37998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 38028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_default_prinfo); 38038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_THLDS: 38078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 38088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrthlds *thlds; 38098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 38108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize); 38128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); 38138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 38158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 38168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address); 38178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 38198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 38208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 38218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 38228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 38238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&thlds->spt_address, &net, NULL, NULL); 38248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 38258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 38268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3828b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 38298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 38308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)&thlds->spt_address; 38328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 38338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 38348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 38358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 38378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 38388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 38398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 38418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 38448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 38458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 38468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 38478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 38488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 38508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 38518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 38528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 38548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 38578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 385875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 385975cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 386075cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 386175cd23222c96d5ebe5a9082c57a263f917f1462btuexen 386275cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 386375cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 386475cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 386575cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 386675cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 386775cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 386875cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 386975cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 387075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 38718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 38728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 38738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 38758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 38808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 38818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathmaxrxt = net->failure_threshold; 38828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathpfthld = net->pf_threshold; 38838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathmaxrxt = stcb->asoc.def_net_failure; 38858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathpfthld = stcb->asoc.def_net_pf_threshold; 38868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_assoc_id = sctp_get_associd(stcb); 38888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 38918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 38928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC)) { 38938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Use endpoint defaults */ 38948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 38958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathmaxrxt = inp->sctp_ep.def_net_failure; 3896000a5bac556b28e74e4e98c540f66b1743e9312dtuexen thlds->spt_pathpfthld = inp->sctp_ep.def_net_pf_threshold; 38978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 38988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 39008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 39018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 39048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_paddrthlds); 39058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 39068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 39078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3908153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen case SCTP_REMOTE_UDP_ENCAPS_PORT: 3909153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 3910153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_udpencaps *encaps; 3911153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_nets *net; 3912000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 3913153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize); 3914153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); 3915153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3916153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 3917153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address); 3918153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3919153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen /* We increment here since sctp_findassociation_ep_addr() wil 3920153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * do a decrement if it finds the stcb as long as the locked 3921153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * tcb (last argument) is NOT a TCB.. aka NULL. 3922153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen */ 3923153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = NULL; 3924153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_INCR_REF(inp); 3925153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL); 3926153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb == NULL) { 3927153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_DECR_REF(inp); 3928153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3929153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3930153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb && (net == NULL)) { 3931153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr *sa; 3932000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 3933153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sa = (struct sockaddr *)&encaps->sue_address; 3934153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET 3935153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET) { 3936153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in *sin; 3937153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3938153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin = (struct sockaddr_in *)sa; 3939153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sin->sin_addr.s_addr) { 3940153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 3941153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3942153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3943153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 3944153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3945153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 3946153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 3947153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET6 3948153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET6) { 3949153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in6 *sin6; 3950153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3951153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin6 = (struct sockaddr_in6 *)sa; 3952153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 3953153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 3954153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3955153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3956153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 3957153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3958153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 3959153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 396075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 396175cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 396275cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 396375cd23222c96d5ebe5a9082c57a263f917f1462btuexen 396475cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 396575cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 396675cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 396775cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 396875cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 396975cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 397075cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 397175cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 397275cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 3973153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 3974153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EAFNOSUPPORT; 3975153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3976153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3977153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 3978153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3979153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3980153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3981153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 3982153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (net) { 3983153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen encaps->sue_port = net->port; 3984153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3985153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen encaps->sue_port = stcb->asoc.port; 3986153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3987153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3988153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3989153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3990153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3991153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC)) { 3992153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_RLOCK(inp); 3993153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen encaps->sue_port = inp->sctp_ep.port; 3994153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_RUNLOCK(inp); 3995153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3996153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3997153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 3998153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3999153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 4000153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (error == 0) { 4001443f94da739e8e8968e5eb93c2f82f73287cfd5dt *optsize = sizeof(struct sctp_udpencaps); 4002153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 4003153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 4004153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 4005aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t case SCTP_ECN_SUPPORTED: 4006aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t { 4007aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t struct sctp_assoc_value *av; 4008aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t 4009aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 4010aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4011aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t 4012aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t if (stcb) { 4013aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t av->assoc_value = stcb->asoc.ecn_supported; 4014aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_TCB_UNLOCK(stcb); 4015aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } else { 4016aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4017aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4018aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 4019aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_INP_RLOCK(inp); 4020aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t av->assoc_value = inp->ecn_supported; 4021aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_INP_RUNLOCK(inp); 4022aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } else { 4023aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4024aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t error = EINVAL; 4025aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 4026aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 4027aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t if (error == 0) { 4028aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t *optsize = sizeof(struct sctp_assoc_value); 4029aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 4030aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t break; 4031aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 4032a8657c4fc04fb9cc82100f648810d51ec6ab155at case SCTP_PR_SUPPORTED: 4033a8657c4fc04fb9cc82100f648810d51ec6ab155at { 4034a8657c4fc04fb9cc82100f648810d51ec6ab155at struct sctp_assoc_value *av; 4035a8657c4fc04fb9cc82100f648810d51ec6ab155at 4036a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 4037a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4038a8657c4fc04fb9cc82100f648810d51ec6ab155at 4039a8657c4fc04fb9cc82100f648810d51ec6ab155at if (stcb) { 4040a8657c4fc04fb9cc82100f648810d51ec6ab155at av->assoc_value = stcb->asoc.prsctp_supported; 4041a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_TCB_UNLOCK(stcb); 4042a8657c4fc04fb9cc82100f648810d51ec6ab155at } else { 4043a8657c4fc04fb9cc82100f648810d51ec6ab155at if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4044a8657c4fc04fb9cc82100f648810d51ec6ab155at (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4045a8657c4fc04fb9cc82100f648810d51ec6ab155at (av->assoc_id == SCTP_FUTURE_ASSOC)) { 4046a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_INP_RLOCK(inp); 4047a8657c4fc04fb9cc82100f648810d51ec6ab155at av->assoc_value = inp->prsctp_supported; 4048a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_INP_RUNLOCK(inp); 4049a8657c4fc04fb9cc82100f648810d51ec6ab155at } else { 4050a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4051a8657c4fc04fb9cc82100f648810d51ec6ab155at error = EINVAL; 4052a8657c4fc04fb9cc82100f648810d51ec6ab155at } 4053a8657c4fc04fb9cc82100f648810d51ec6ab155at } 4054a8657c4fc04fb9cc82100f648810d51ec6ab155at if (error == 0) { 4055a8657c4fc04fb9cc82100f648810d51ec6ab155at *optsize = sizeof(struct sctp_assoc_value); 4056a8657c4fc04fb9cc82100f648810d51ec6ab155at } 4057a8657c4fc04fb9cc82100f648810d51ec6ab155at break; 4058a8657c4fc04fb9cc82100f648810d51ec6ab155at } 4059fb3816eaffe5878bb1286adb120fd160da178a05t case SCTP_AUTH_SUPPORTED: 4060fb3816eaffe5878bb1286adb120fd160da178a05t { 4061fb3816eaffe5878bb1286adb120fd160da178a05t struct sctp_assoc_value *av; 4062fb3816eaffe5878bb1286adb120fd160da178a05t 4063fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 4064fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4065fb3816eaffe5878bb1286adb120fd160da178a05t 4066fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb) { 4067fb3816eaffe5878bb1286adb120fd160da178a05t av->assoc_value = stcb->asoc.auth_supported; 4068fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_TCB_UNLOCK(stcb); 4069fb3816eaffe5878bb1286adb120fd160da178a05t } else { 4070fb3816eaffe5878bb1286adb120fd160da178a05t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4071fb3816eaffe5878bb1286adb120fd160da178a05t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4072fb3816eaffe5878bb1286adb120fd160da178a05t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 4073fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_RLOCK(inp); 4074fb3816eaffe5878bb1286adb120fd160da178a05t av->assoc_value = inp->auth_supported; 4075fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_RUNLOCK(inp); 4076fb3816eaffe5878bb1286adb120fd160da178a05t } else { 4077fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4078fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 4079fb3816eaffe5878bb1286adb120fd160da178a05t } 4080fb3816eaffe5878bb1286adb120fd160da178a05t } 4081fb3816eaffe5878bb1286adb120fd160da178a05t if (error == 0) { 4082fb3816eaffe5878bb1286adb120fd160da178a05t *optsize = sizeof(struct sctp_assoc_value); 4083fb3816eaffe5878bb1286adb120fd160da178a05t } 4084fb3816eaffe5878bb1286adb120fd160da178a05t break; 4085fb3816eaffe5878bb1286adb120fd160da178a05t } 4086fb3816eaffe5878bb1286adb120fd160da178a05t case SCTP_ASCONF_SUPPORTED: 4087fb3816eaffe5878bb1286adb120fd160da178a05t { 4088fb3816eaffe5878bb1286adb120fd160da178a05t struct sctp_assoc_value *av; 4089fb3816eaffe5878bb1286adb120fd160da178a05t 4090fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 4091fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4092fb3816eaffe5878bb1286adb120fd160da178a05t 4093fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb) { 4094fb3816eaffe5878bb1286adb120fd160da178a05t av->assoc_value = stcb->asoc.asconf_supported; 4095fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_TCB_UNLOCK(stcb); 4096fb3816eaffe5878bb1286adb120fd160da178a05t } else { 4097fb3816eaffe5878bb1286adb120fd160da178a05t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4098fb3816eaffe5878bb1286adb120fd160da178a05t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4099fb3816eaffe5878bb1286adb120fd160da178a05t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 4100fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_RLOCK(inp); 4101fb3816eaffe5878bb1286adb120fd160da178a05t av->assoc_value = inp->asconf_supported; 4102fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_RUNLOCK(inp); 4103fb3816eaffe5878bb1286adb120fd160da178a05t } else { 4104fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4105fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 4106fb3816eaffe5878bb1286adb120fd160da178a05t } 4107fb3816eaffe5878bb1286adb120fd160da178a05t } 4108fb3816eaffe5878bb1286adb120fd160da178a05t if (error == 0) { 4109fb3816eaffe5878bb1286adb120fd160da178a05t *optsize = sizeof(struct sctp_assoc_value); 4110fb3816eaffe5878bb1286adb120fd160da178a05t } 4111fb3816eaffe5878bb1286adb120fd160da178a05t break; 4112fb3816eaffe5878bb1286adb120fd160da178a05t } 41132344bfccffeb80545fca6a86e8cda3d56a6f50bft case SCTP_RECONFIG_SUPPORTED: 41142344bfccffeb80545fca6a86e8cda3d56a6f50bft { 41152344bfccffeb80545fca6a86e8cda3d56a6f50bft struct sctp_assoc_value *av; 41162344bfccffeb80545fca6a86e8cda3d56a6f50bft 41172344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 41182344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_FIND_STCB(inp, stcb, av->assoc_id); 41192344bfccffeb80545fca6a86e8cda3d56a6f50bft 41202344bfccffeb80545fca6a86e8cda3d56a6f50bft if (stcb) { 41212344bfccffeb80545fca6a86e8cda3d56a6f50bft av->assoc_value = stcb->asoc.reconfig_supported; 41222344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_TCB_UNLOCK(stcb); 41232344bfccffeb80545fca6a86e8cda3d56a6f50bft } else { 41242344bfccffeb80545fca6a86e8cda3d56a6f50bft if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 41252344bfccffeb80545fca6a86e8cda3d56a6f50bft (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 41262344bfccffeb80545fca6a86e8cda3d56a6f50bft (av->assoc_id == SCTP_FUTURE_ASSOC)) { 41272344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_INP_RLOCK(inp); 41282344bfccffeb80545fca6a86e8cda3d56a6f50bft av->assoc_value = inp->reconfig_supported; 41292344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_INP_RUNLOCK(inp); 41302344bfccffeb80545fca6a86e8cda3d56a6f50bft } else { 41312344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 41322344bfccffeb80545fca6a86e8cda3d56a6f50bft error = EINVAL; 41332344bfccffeb80545fca6a86e8cda3d56a6f50bft } 41342344bfccffeb80545fca6a86e8cda3d56a6f50bft } 41352344bfccffeb80545fca6a86e8cda3d56a6f50bft if (error == 0) { 41362344bfccffeb80545fca6a86e8cda3d56a6f50bft *optsize = sizeof(struct sctp_assoc_value); 41372344bfccffeb80545fca6a86e8cda3d56a6f50bft } 41382344bfccffeb80545fca6a86e8cda3d56a6f50bft break; 41392344bfccffeb80545fca6a86e8cda3d56a6f50bft } 414044318e900a771ba1a5bafb510c38f33fd5cd8a39t case SCTP_NRSACK_SUPPORTED: 414144318e900a771ba1a5bafb510c38f33fd5cd8a39t { 414244318e900a771ba1a5bafb510c38f33fd5cd8a39t struct sctp_assoc_value *av; 414344318e900a771ba1a5bafb510c38f33fd5cd8a39t 414444318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 414544318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 414644318e900a771ba1a5bafb510c38f33fd5cd8a39t 414744318e900a771ba1a5bafb510c38f33fd5cd8a39t if (stcb) { 414844318e900a771ba1a5bafb510c38f33fd5cd8a39t av->assoc_value = stcb->asoc.nrsack_supported; 414944318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_TCB_UNLOCK(stcb); 415044318e900a771ba1a5bafb510c38f33fd5cd8a39t } else { 415144318e900a771ba1a5bafb510c38f33fd5cd8a39t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 415244318e900a771ba1a5bafb510c38f33fd5cd8a39t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 415344318e900a771ba1a5bafb510c38f33fd5cd8a39t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 415444318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_INP_RLOCK(inp); 415544318e900a771ba1a5bafb510c38f33fd5cd8a39t av->assoc_value = inp->nrsack_supported; 415644318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_INP_RUNLOCK(inp); 415744318e900a771ba1a5bafb510c38f33fd5cd8a39t } else { 415844318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 415944318e900a771ba1a5bafb510c38f33fd5cd8a39t error = EINVAL; 416044318e900a771ba1a5bafb510c38f33fd5cd8a39t } 416144318e900a771ba1a5bafb510c38f33fd5cd8a39t } 416244318e900a771ba1a5bafb510c38f33fd5cd8a39t if (error == 0) { 416344318e900a771ba1a5bafb510c38f33fd5cd8a39t *optsize = sizeof(struct sctp_assoc_value); 416444318e900a771ba1a5bafb510c38f33fd5cd8a39t } 416544318e900a771ba1a5bafb510c38f33fd5cd8a39t break; 416644318e900a771ba1a5bafb510c38f33fd5cd8a39t } 4167669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t case SCTP_PKTDROP_SUPPORTED: 4168669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t { 4169669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t struct sctp_assoc_value *av; 4170669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t 4171669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 4172669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4173669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t 4174669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t if (stcb) { 4175669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t av->assoc_value = stcb->asoc.pktdrop_supported; 4176669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_TCB_UNLOCK(stcb); 4177669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } else { 4178669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4179669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4180669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 4181669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_INP_RLOCK(inp); 4182669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t av->assoc_value = inp->pktdrop_supported; 4183669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_INP_RUNLOCK(inp); 4184669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } else { 4185669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4186669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t error = EINVAL; 4187669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 4188669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 4189669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t if (error == 0) { 4190669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t *optsize = sizeof(struct sctp_assoc_value); 4191669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 4192669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t break; 4193669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 41942d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen case SCTP_ENABLE_STREAM_RESET: 41952d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen { 41962d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen struct sctp_assoc_value *av; 41972d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen 41982d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 41992d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 42002d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen 42012d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen if (stcb) { 42022d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen av->assoc_value = (uint32_t)stcb->asoc.local_strreset_support; 42032d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_TCB_UNLOCK(stcb); 42042d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } else { 42052d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 42062d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 42072d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 42082d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_INP_RLOCK(inp); 42092d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen av->assoc_value = (uint32_t)inp->local_strreset_support; 42102d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_INP_RUNLOCK(inp); 42112d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } else { 42122d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 42132d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen error = EINVAL; 42142d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 42152d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 42162d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen if (error == 0) { 42172d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen *optsize = sizeof(struct sctp_assoc_value); 42182d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 42192d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen break; 42202d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 422120d5d287bff2075897105f85287230d55bdfa420t case SCTP_PR_STREAM_STATUS: 422220d5d287bff2075897105f85287230d55bdfa420t { 422320d5d287bff2075897105f85287230d55bdfa420t struct sctp_prstatus *sprstat; 422420d5d287bff2075897105f85287230d55bdfa420t uint16_t sid; 422520d5d287bff2075897105f85287230d55bdfa420t uint16_t policy; 422620d5d287bff2075897105f85287230d55bdfa420t 422720d5d287bff2075897105f85287230d55bdfa420t SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize); 422820d5d287bff2075897105f85287230d55bdfa420t SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id); 422920d5d287bff2075897105f85287230d55bdfa420t 423020d5d287bff2075897105f85287230d55bdfa420t sid = sprstat->sprstat_sid; 423120d5d287bff2075897105f85287230d55bdfa420t policy = sprstat->sprstat_policy; 423220d5d287bff2075897105f85287230d55bdfa420t#if defined(SCTP_DETAILED_STR_STATS) 423320d5d287bff2075897105f85287230d55bdfa420t if ((stcb != NULL) && 423420d5d287bff2075897105f85287230d55bdfa420t (policy != SCTP_PR_SCTP_NONE) && 423520d5d287bff2075897105f85287230d55bdfa420t (sid < stcb->asoc.streamoutcnt) && 423620d5d287bff2075897105f85287230d55bdfa420t ((policy == SCTP_PR_SCTP_ALL) || 423720d5d287bff2075897105f85287230d55bdfa420t (PR_SCTP_VALID_POLICY(policy)))) { 423820d5d287bff2075897105f85287230d55bdfa420t#else 423920d5d287bff2075897105f85287230d55bdfa420t if ((stcb != NULL) && 424020d5d287bff2075897105f85287230d55bdfa420t (policy != SCTP_PR_SCTP_NONE) && 424120d5d287bff2075897105f85287230d55bdfa420t (sid < stcb->asoc.streamoutcnt) && 424220d5d287bff2075897105f85287230d55bdfa420t (policy == SCTP_PR_SCTP_ALL)) { 424320d5d287bff2075897105f85287230d55bdfa420t#endif 424420d5d287bff2075897105f85287230d55bdfa420t if (policy == SCTP_PR_SCTP_ALL) { 424520d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; 424620d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; 424720d5d287bff2075897105f85287230d55bdfa420t } else { 424820d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy]; 424920d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy]; 425020d5d287bff2075897105f85287230d55bdfa420t } 425120d5d287bff2075897105f85287230d55bdfa420t SCTP_TCB_UNLOCK(stcb); 425220d5d287bff2075897105f85287230d55bdfa420t *optsize = sizeof(struct sctp_prstatus); 425320d5d287bff2075897105f85287230d55bdfa420t } else { 425420d5d287bff2075897105f85287230d55bdfa420t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 425520d5d287bff2075897105f85287230d55bdfa420t error = EINVAL; 425620d5d287bff2075897105f85287230d55bdfa420t } 425720d5d287bff2075897105f85287230d55bdfa420t break; 425820d5d287bff2075897105f85287230d55bdfa420t } 425920d5d287bff2075897105f85287230d55bdfa420t case SCTP_PR_ASSOC_STATUS: 426020d5d287bff2075897105f85287230d55bdfa420t { 426120d5d287bff2075897105f85287230d55bdfa420t struct sctp_prstatus *sprstat; 426220d5d287bff2075897105f85287230d55bdfa420t uint16_t policy; 426320d5d287bff2075897105f85287230d55bdfa420t 426420d5d287bff2075897105f85287230d55bdfa420t SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize); 426520d5d287bff2075897105f85287230d55bdfa420t SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id); 426620d5d287bff2075897105f85287230d55bdfa420t 426720d5d287bff2075897105f85287230d55bdfa420t policy = sprstat->sprstat_policy; 426820d5d287bff2075897105f85287230d55bdfa420t if ((stcb != NULL) && 426920d5d287bff2075897105f85287230d55bdfa420t (policy != SCTP_PR_SCTP_NONE) && 427020d5d287bff2075897105f85287230d55bdfa420t ((policy == SCTP_PR_SCTP_ALL) || 427120d5d287bff2075897105f85287230d55bdfa420t (PR_SCTP_VALID_POLICY(policy)))) { 427220d5d287bff2075897105f85287230d55bdfa420t if (policy == SCTP_PR_SCTP_ALL) { 427320d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0]; 427420d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0]; 427520d5d287bff2075897105f85287230d55bdfa420t } else { 427620d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[policy]; 427720d5d287bff2075897105f85287230d55bdfa420t sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[policy]; 427820d5d287bff2075897105f85287230d55bdfa420t } 427920d5d287bff2075897105f85287230d55bdfa420t SCTP_TCB_UNLOCK(stcb); 428020d5d287bff2075897105f85287230d55bdfa420t *optsize = sizeof(struct sctp_prstatus); 428120d5d287bff2075897105f85287230d55bdfa420t } else { 428220d5d287bff2075897105f85287230d55bdfa420t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 428320d5d287bff2075897105f85287230d55bdfa420t error = EINVAL; 428420d5d287bff2075897105f85287230d55bdfa420t } 428520d5d287bff2075897105f85287230d55bdfa420t break; 428620d5d287bff2075897105f85287230d55bdfa420t } 42878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 42888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 42898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 42908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 42918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end switch (sopt->sopt_name) */ 42928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 42938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = 0; 42948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 42968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 42978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 42988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Panda__) || defined(__Userspace__) 42998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 43008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 43018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 43028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 43038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, 43048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p) 43058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 43068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error, set_opt; 43078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *mopt; 43088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 4309b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct sctp_inpcb *inp = NULL; 43108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 43118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval == NULL) { 43138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("optval is NULL\n"); 43148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 43158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 43168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 43182fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 43198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("inp is NULL?\n"); 43208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4321b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 43228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 43248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 43268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 43278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 43288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 43298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 43308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 43318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 43328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 43338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 43348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the option value */ 43358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 43368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = 0; 43378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) 43388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 43408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 43418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT; 43428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 43448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 43458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NOTE: we don't really support this flag 43468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 43478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 43488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only valid for bound all sockets */ 43498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_BASE_SYSCTL(sctp_auto_asconf) == 0) && 43508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*mopt != 0)) { 43518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* forbidden by admin */ 43528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EPERM); 43538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EPERM); 43548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF; 43568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 43578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 43588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 43598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 43628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR; 43638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 43658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO; 43668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 43688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 43698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4; 43708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 43718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 43728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 43738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 43768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_NODELAY; 43778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 43798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 43808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 43818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 43828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 43838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_AUTOCLOSE; 43858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 43868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The value is in ticks. Note this does not effect 43878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * old associations, only new ones. 43888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 43898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt); 43908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 43938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*mopt != 0) { 43948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, set_opt); 43958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 43968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, set_opt); 43978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 43998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REUSE_PORT: 44018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 44038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 44048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't set it after we are bound */ 44058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 44098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't do this for a 1-m socket */ 44108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval) 44148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 44158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 44168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE); 44178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_POINT: 44208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 44228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize); 44248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*value > SCTP_SB_LIMIT_RCV(so)) { 44258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->partial_delivery_point = *value; 44308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_FRAGMENT_INTERLEAVE: 44338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not yet until we re-write sctp_recvmsg() */ 44348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *level; 44368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(level, optval, uint32_t, optsize); 44388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*level == SCTP_FRAG_LEVEL_2) { 44398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 44408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 44418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (*level == SCTP_FRAG_LEVEL_1) { 44428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 44438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 44448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (*level == SCTP_FRAG_LEVEL_0) { 44458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 44468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 44478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 44498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CMT_ON_OFF: 44558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) { 44568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 44578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 44598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value > SCTP_CMT_MAX) { 44608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 4463000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 44648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 44658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 44668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_cmt_on_off = av->assoc_value; 44678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 44688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 44698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 44708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 44718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 44728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 44738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 44748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_cmt_on_off = av->assoc_value; 44758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 44768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 44788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 44798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 44808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 44818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 44828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_cmt_on_off = av->assoc_value; 44838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 44848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 44868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 44898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 44908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 44918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_CC: 44948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 44968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 44978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 44998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_value != SCTP_CC_RFC2581) && 45008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_CC_HSTCP) && 45018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_CC_HTCP) && 45028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_CC_RTCC)) { 45038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 45048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 45058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 45088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 45098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value]; 45108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.congestion_control_module = av->assoc_value; 45118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) { 45128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 45138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net); 45148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 45178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 45188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 45198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 45208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 45218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 45228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 45238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_default_cc_module = av->assoc_value; 45248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 45258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 45278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 45288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 45298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 45308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 45318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value]; 45328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.congestion_control_module = av->assoc_value; 45338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) { 45348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 45358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net); 45368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 45398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 45418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CC_OPTION: 45468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 45478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cc_option *cc_opt; 45488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 45498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, optsize); 45508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id); 45518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 45528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cc_opt->aid_value.assoc_id == SCTP_CURRENT_ASSOC) { 45538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 45548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 45558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 45568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_cwnd_socket_option) { 45578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1, cc_opt); 45588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 45608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 45628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 45638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 45648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 45668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) { 45678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 45688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 4569000a5bac556b28e74e4e98c540f66b1743e9312dtuexen error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1, 45708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cc_opt); 45718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 45738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_SS: 45778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 45788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 45798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 45808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 45818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_value != SCTP_SS_DEFAULT) && 45828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_ROUND_ROBIN) && 45838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_ROUND_ROBIN_PACKET) && 45848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_PRIORITY) && 45858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_FAIR_BANDWITH) && 45868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_FIRST_COME)) { 45878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 45888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 45898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 45928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 45938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1, 1); 45948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value]; 45958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.stream_scheduling_module = av->assoc_value; 45968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1); 45978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 45988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 45998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 46008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 46018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 46028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 46038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 46048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_default_ss_module = av->assoc_value; 46058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 46068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 46088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 46098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 46108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 46118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 46128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1, 1); 46138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value]; 46148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.stream_scheduling_module = av->assoc_value; 46158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1); 46168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 46198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SS_VALUE: 46248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 46258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_value *av; 46268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize); 46288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 46298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 46308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], 46318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->stream_value) < 0) { 46328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 46338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 46348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 46378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_id == SCTP_CURRENT_ASSOC) { 46388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 46398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 46408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 46418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_set_value(stcb, 46428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc, 46438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.strmout[av->stream_id], 46448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->stream_value); 46458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 4648000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 46498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 46508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't set stream value without association */ 46518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 46528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 46538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CLR_STAT_LOG: 46588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 46598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 46608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONTEXT: 46628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 46638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 46648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 46668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 46678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 46698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.context = av->assoc_value; 46708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 46728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 46738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 46748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 46758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 46768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 46778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_context = av->assoc_value; 46788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 46798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 46818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 46828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 46838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 46848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 46858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.context = av->assoc_value; 46868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 46898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_VRF_ID: 46948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 46958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *default_vrfid; 46968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 46978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 46988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 46998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, optsize); 47008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*default_vrfid > SCTP_MAX_VRF_ID) { 47018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 47068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 47078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* The VRF must be in the VRF list */ 47088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*default_vrfid == inp->m_vrf_ids[i]) { 47098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 4710e2828360ea9cf8951730d46f5c14626c9425cb30t inp->def_vrf_id = *default_vrfid; 47118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 47128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto sctp_done; 47138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 47188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_vrf_id = *default_vrfid; 47198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 47208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 47218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_done: 47228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 47238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEL_VRF_ID: 47268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 47278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 47288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *del_vrfid; 47298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i, fnd = 0; 47308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 47318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(del_vrfid, optval, uint32_t, optsize); 47328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*del_vrfid > SCTP_MAX_VRF_ID) { 47338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->num_vrfs == 1) { 47388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't delete last one */ 47398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 47448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't add more once you are bound */ 47458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 47508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 47518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*del_vrfid == inp->m_vrf_ids[i]) { 47528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 47538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 47578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (i != (inp->num_vrfs - 1)) { 47628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Take bottom one and move to this slot */ 47638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids[i] = inp->m_vrf_ids[(inp->num_vrfs-1)]; 47648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*del_vrfid == inp->def_vrf_id) { 47668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Take the first one as the new default */ 47678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_vrf_id = inp->m_vrf_ids[0]; 47688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Drop the number by one killing last one */ 47708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->num_vrfs--; 47718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 47728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 47738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 47748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 47758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADD_VRF_ID: 47788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 47798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 47808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *add_vrfid; 47818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 47828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 47838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(add_vrfid, optval, uint32_t, optsize); 47848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*add_vrfid > SCTP_MAX_VRF_ID) { 47858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 47908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't add more once you are bound */ 47918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 47968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Verify its not already here */ 47978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 47988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*add_vrfid == inp->m_vrf_ids[i]) { 47998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 48008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 48018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 48038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->num_vrfs + 1) > inp->vrf_size) { 48068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* need to grow array */ 48078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *tarray; 48088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(tarray, uint32_t *, 48098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sizeof(uint32_t) * (inp->vrf_size + SCTP_DEFAULT_VRF_SIZE)), 48108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_M_MVRF); 48118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tarray == NULL) { 48128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 48138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 48148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 48168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(tarray, inp->m_vrf_ids, (sizeof(uint32_t) * inp->vrf_size)); 48188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF); 48198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids = tarray; 48208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->vrf_size += SCTP_DEFAULT_VRF_SIZE; 48218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids[inp->num_vrfs] = *add_vrfid; 48238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->num_vrfs++; 48248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 48268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 48278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 48288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4829e2828360ea9cf8951730d46f5c14626c9425cb30t break; 48308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DELAYED_SACK: 48328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 48338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sack_info *sack; 48348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize); 48368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 48378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 48388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay > SCTP_MAX_SACK_DELAY) 48398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = SCTP_MAX_SACK_DELAY; 48408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (MSEC_TO_TICKS(sack->sack_delay) < 1) { 48418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = TICKS_TO_MSEC(1); 48428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 48458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 48468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_ack = sack->sack_delay; 48478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_freq) { 48498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sack_freq = sack->sack_freq; 48508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 48528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 48538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 48548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 48558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_FUTURE_ASSOC) || 48568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_ALL_ASSOC)) { 48578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 48588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 48598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(sack->sack_delay); 48608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_freq) { 48628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_sack_freq = sack->sack_freq; 48638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sack->sack_assoc_id == SCTP_CURRENT_ASSOC) || 48678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_ALL_ASSOC)) { 48688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 48698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 48708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 48718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 48728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_ack = sack->sack_delay; 48738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_freq) { 48758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sack_freq = sack->sack_freq; 48768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 48788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 48808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 48838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_CHUNK: 48858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 48868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authchunk *sauth; 48878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sauth, optval, struct sctp_authchunk, optsize); 48898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 48918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_add_chunk(sauth->sauth_chunk, inp->sctp_ep.local_auth_chunks)) { 48928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 48938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 48948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 48978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_KEY: 48998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 49008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkey *sca; 49018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_keyhead *shared_keys; 49028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sharedkey_t *shared_key; 49038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_key_t *key = NULL; 49048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size; 49058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 49068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sca, optval, struct sctp_authkey, optsize); 49078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sca->sca_keylength == 0) { 49088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = optsize - sizeof(struct sctp_authkey); 49098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 49108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sca->sca_keylength + sizeof(struct sctp_authkey) <= optsize) { 49118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sca->sca_keylength; 49128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 49138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 49148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 49158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sca->sca_assoc_id); 49198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 49208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 49218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_keys = &stcb->asoc.shared_keys; 49228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* clear the cached keys for this key id */ 49238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 49248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 49258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * create the new shared key and 49268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * insert/replace it 49278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 49288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size > 0) { 49298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen key = sctp_set_key(sca->sca_key, (uint32_t) size); 49308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (key == NULL) { 49318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 49328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 49338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 49348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key = sctp_alloc_sharedkey(); 49388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (shared_key == NULL) { 49398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_key(key); 49408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 49418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 49428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 49438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->key = key; 49468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->keyid = sca->sca_keynumber; 49478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_insert_sharedkey(shared_keys, shared_key); 49488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 49498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 49508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 49518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 49528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sca->sca_assoc_id == SCTP_FUTURE_ASSOC) || 49538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sca->sca_assoc_id == SCTP_ALL_ASSOC)) { 49548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 49558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_keys = &inp->sctp_ep.shared_keys; 49568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 49578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * clear the cached keys on all assocs for 49588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * this key id 49598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 49608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber); 49618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 49628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * create the new shared key and 49638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * insert/replace it 49648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 49658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size > 0) { 49668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen key = sctp_set_key(sca->sca_key, (uint32_t) size); 49678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (key == NULL) { 49688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 49698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 49708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 49718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key = sctp_alloc_sharedkey(); 49758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (shared_key == NULL) { 49768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_key(key); 49778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 49788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 49798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 49808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->key = key; 49838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->keyid = sca->sca_keynumber; 49848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_insert_sharedkey(shared_keys, shared_key); 49858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 49868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sca->sca_assoc_id == SCTP_CURRENT_ASSOC) || 49888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sca->sca_assoc_id == SCTP_ALL_ASSOC)) { 49898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 49908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 49918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 49928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_keys = &stcb->asoc.shared_keys; 49938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* clear the cached keys for this key id */ 49948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 49958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 49968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * create the new shared key and 49978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * insert/replace it 49988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 49998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size > 0) { 50008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen key = sctp_set_key(sca->sca_key, (uint32_t) size); 50018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (key == NULL) { 50028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 50038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 50048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key = sctp_alloc_sharedkey(); 50078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (shared_key == NULL) { 50088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_key(key); 50098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 50108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 50118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->key = key; 50138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->keyid = sca->sca_keynumber; 50148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_insert_sharedkey(shared_keys, shared_key); 50158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 50168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 50188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 50218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_HMAC_IDENT: 50238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 50248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_hmacalgo *shmac; 50258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_hmaclist_t *hmaclist; 50268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint16_t hmacid; 50278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t i; 50288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize); 50308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) { 50318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 50328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 50338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 50348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5035000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 50368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hmaclist = sctp_alloc_hmaclist(shmac->shmac_number_of_idents); 50378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hmaclist == NULL) { 50388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 50398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 50408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 50418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < shmac->shmac_number_of_idents; i++) { 50438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hmacid = shmac->shmac_idents[i]; 50448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_add_hmacid(hmaclist, hmacid)) { 50458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* invalid HMACs were found */; 50468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 50478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 50488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_hmaclist(hmaclist); 50498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto sctp_set_hmac_done; 50508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < hmaclist->num_algo; i++) { 50538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) { 50548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* already in list */ 505517fca683d16802e8836f92ca2d9761a4798ada4bt break; 50568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 505817fca683d16802e8836f92ca2d9761a4798ada4bt if (i == hmaclist->num_algo) { 505917fca683d16802e8836f92ca2d9761a4798ada4bt /* not found in list */ 50608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_hmaclist(hmaclist); 50618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 50628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 50638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 50648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* set it on the endpoint */ 50668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 50678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_ep.local_hmacs) 50688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_hmaclist(inp->sctp_ep.local_hmacs); 50698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.local_hmacs = hmaclist; 50708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 50718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_set_hmac_done: 50728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 50738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_ACTIVE_KEY: 50758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 50768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *scact; 50778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, optsize); 50798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 50808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 50818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* set the active key on the right place */ 50828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 50838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* set the active key on the assoc */ 50848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_setactivekey(stcb, 50858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen scact->scact_keynumber)) { 50868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 50878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ, 50888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen EINVAL); 50898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 50908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 50928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 50938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 50948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 50958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_FUTURE_ASSOC) || 50968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_ALL_ASSOC)) { 50978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 50988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber)) { 50998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 51008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 51018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 51038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((scact->scact_assoc_id == SCTP_CURRENT_ASSOC) || 51058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_ALL_ASSOC)) { 51068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 51078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 51088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 51098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auth_setactivekey(stcb, scact->scact_keynumber); 51108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 51138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_DELETE_KEY: 51188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 51198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *scdel; 51208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(scdel, optval, struct sctp_authkeyid, optsize); 51228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, scdel->scact_assoc_id); 51238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* delete the key from the right place */ 51258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 51268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber)) { 51278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 51288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 51298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 51328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 51338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 51348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scdel->scact_assoc_id == SCTP_FUTURE_ASSOC) || 51358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scdel->scact_assoc_id == SCTP_ALL_ASSOC)) { 51368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 51378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber)) { 51388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 51398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 51408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 51428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((scdel->scact_assoc_id == SCTP_CURRENT_ASSOC) || 51448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scdel->scact_assoc_id == SCTP_ALL_ASSOC)) { 51458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 51468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 51478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 51488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_delete_sharedkey(stcb, scdel->scact_keynumber); 51498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 51528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_DEACTIVATE_KEY: 51578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 51588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *keyid; 51598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(keyid, optval, struct sctp_authkeyid, optsize); 51618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, keyid->scact_assoc_id); 51628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* deactivate the key from the right place */ 51648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 51658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_deact_sharedkey(stcb, keyid->scact_keynumber)) { 51668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 51678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 51688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 51718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 51728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 51738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (keyid->scact_assoc_id == SCTP_FUTURE_ASSOC) || 51748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (keyid->scact_assoc_id == SCTP_ALL_ASSOC)) { 51758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 51768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_deact_sharedkey_ep(inp, keyid->scact_keynumber)) { 51778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 51788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 51798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 51818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((keyid->scact_assoc_id == SCTP_CURRENT_ASSOC) || 51838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (keyid->scact_assoc_id == SCTP_ALL_ASSOC)) { 51848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 51858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 51868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 51878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_deact_sharedkey(stcb, keyid->scact_keynumber); 51888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 51918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5195c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen case SCTP_ENABLE_STREAM_RESET: 5196c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen { 5197c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct sctp_assoc_value *av; 51982d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen 5199c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 5200c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (av->assoc_value & (~SCTP_ENABLE_VALUE_MASK)) { 5201c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5202c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 5203c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5204c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5205c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 5206c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb) { 52072d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value; 5208c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5209c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } else { 5210c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 5211c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 5212c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 5213c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 5214c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_WLOCK(inp); 52152d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen inp->local_strreset_support = (uint8_t)av->assoc_value; 5216c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_WUNLOCK(inp); 5217c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5218c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 5219c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 5220c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_RLOCK(inp); 5221c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 5222c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_LOCK(stcb); 52232d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value; 5224c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5225c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5226c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_RUNLOCK(inp); 5227c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 52288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5229c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5230c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5231c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 52328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RESET_STREAMS: 52338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 5234000a5bac556b28e74e4e98c540f66b1743e9312dtuexen struct sctp_reset_streams *strrst; 52351de509107029a81699453f86fcced3c7b7fb534btuexen int i, send_out = 0; 52361de509107029a81699453f86fcced3c7b7fb534btuexen int send_in = 0; 52378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5238c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(strrst, optval, struct sctp_reset_streams, optsize); 5239c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, strrst->srs_assoc_id); 52408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 52418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 52428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 52438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 52448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52452344bfccffeb80545fca6a86e8cda3d56a6f50bft if (stcb->asoc.reconfig_supported == 0) { 52468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 5247c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen * Peer does not support the chunk type. 52488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 5249c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 5250c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EOPNOTSUPP; 5251c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5252c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5253c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 52548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.stream_reset_outstanding) { 52558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 52568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 52578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 52588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 52598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5260c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (strrst->srs_flags & SCTP_STREAM_RESET_INCOMING) { 52618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen send_in = 1; 5262c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5263c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (strrst->srs_flags & SCTP_STREAM_RESET_OUTGOING) { 52648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen send_out = 1; 5265c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5266c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((send_in == 0) && (send_out == 0)) { 5267c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5268c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 5269c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5270c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5271c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5272c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen for (i = 0; i < strrst->srs_number_streams; i++) { 5273c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((send_in) && 5274c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (strrst->srs_stream_list[i] > stcb->asoc.streamincnt)) { 5275c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 52768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5277c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 52788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5279c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((send_out) && 5280c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (strrst->srs_stream_list[i] > stcb->asoc.streamoutcnt)) { 5281c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5282c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 5283c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 52848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5285c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5286c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (error) { 5287c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5288c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5289c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5290c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = sctp_send_str_reset_req(stcb, strrst->srs_number_streams, 5291c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strrst->srs_stream_list, 5292c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen send_out, send_in, 0, 0, 0, 0, 0); 5293c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 5294c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 5295c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5296c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5297c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5298c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen case SCTP_ADD_STREAMS: 5299c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen { 5300c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct sctp_add_streams *stradd; 53011de509107029a81699453f86fcced3c7b7fb534btuexen uint8_t addstream = 0; 53021de509107029a81699453f86fcced3c7b7fb534btuexen uint16_t add_o_strmcnt = 0; 53031de509107029a81699453f86fcced3c7b7fb534btuexen uint16_t add_i_strmcnt = 0; 5304c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 5305c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(stradd, optval, struct sctp_add_streams, optsize); 5306c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, stradd->sas_assoc_id); 5307c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb == NULL) { 5308c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 5309c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = ENOENT; 5310c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5311c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 53122344bfccffeb80545fca6a86e8cda3d56a6f50bft if (stcb->asoc.reconfig_supported == 0) { 53131de509107029a81699453f86fcced3c7b7fb534btuexen /* 53141de509107029a81699453f86fcced3c7b7fb534btuexen * Peer does not support the chunk type. 53151de509107029a81699453f86fcced3c7b7fb534btuexen */ 53161de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 53171de509107029a81699453f86fcced3c7b7fb534btuexen error = EOPNOTSUPP; 53181de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_TCB_UNLOCK(stcb); 53191de509107029a81699453f86fcced3c7b7fb534btuexen break; 53201de509107029a81699453f86fcced3c7b7fb534btuexen } 53211de509107029a81699453f86fcced3c7b7fb534btuexen if (stcb->asoc.stream_reset_outstanding) { 53221de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 53231de509107029a81699453f86fcced3c7b7fb534btuexen error = EALREADY; 53241de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_TCB_UNLOCK(stcb); 53251de509107029a81699453f86fcced3c7b7fb534btuexen break; 53261de509107029a81699453f86fcced3c7b7fb534btuexen } 5327c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((stradd->sas_outstrms == 0) && 5328c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (stradd->sas_instrms == 0)) { 5329c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 5330c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen goto skip_stuff; 5331c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5332c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stradd->sas_outstrms) { 53338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addstream = 1; 53348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We allocate here */ 5335c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen add_o_strmcnt = stradd->sas_outstrms; 5336c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((((int)add_o_strmcnt) + ((int)stcb->asoc.streamoutcnt)) > 0x0000ffff) { 53378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* You can't have more than 64k */ 53388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 53398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto skip_stuff; 53408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5342c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stradd->sas_instrms) { 5343c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen int cnt; 53448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5345c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen addstream |= 2; 5346c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* We allocate inside sctp_send_str_reset_req() */ 5347c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen add_i_strmcnt = stradd->sas_instrms; 5348c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen cnt = add_i_strmcnt; 5349c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen cnt += stcb->asoc.streamincnt; 5350c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (cnt > 0x0000ffff) { 5351c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* You can't have more than 64k */ 53528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5353c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen goto skip_stuff; 53548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5355c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (cnt > (int)stcb->asoc.max_inbound_streams) { 5356c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* More than you are allowed */ 53578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5358c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen goto skip_stuff; 53598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5361c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 0, addstream, add_o_strmcnt, add_i_strmcnt, 0); 5362c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 53638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen skip_stuff: 5364c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5365c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5366c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5367c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen case SCTP_RESET_ASSOC: 5368c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen { 5369c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen uint32_t *value; 5370c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 5371c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize); 5372c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) *value); 5373c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb == NULL) { 5374c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 5375c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = ENOENT; 5376c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5377c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 53782344bfccffeb80545fca6a86e8cda3d56a6f50bft if (stcb->asoc.reconfig_supported == 0) { 5379c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* 5380c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen * Peer does not support the chunk type. 5381c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen */ 5382c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 5383c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EOPNOTSUPP; 53848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 53858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 53868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5387c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb->asoc.stream_reset_outstanding) { 5388c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 5389c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EALREADY; 5390c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5391c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5392c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5393c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 1, 0, 0, 0, 0); 53948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 53958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 53968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 53978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONNECT_X: 53998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 54008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 54018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 54028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_do_connect_x(so, inp, optval, optsize, p, 0); 54058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONNECT_X_DELAYED: 54078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 54088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 54098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 54108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_do_connect_x(so, inp, optval, optsize, p, 1); 54138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONNECT_X_COMPLETE: 54158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 54178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 54188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIXME MT: check correct? */ 54208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize); 54218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* find tcb */ 54238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 54248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 54258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 54268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 54278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 54288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, sa); 54298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 54318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 54328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 54338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 54348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 54358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 54368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 54378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL); 54388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 54398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 54408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 54448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 54458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 54468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.delayed_connection == 1) { 54498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_connection = 0; 54508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 54518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, 54528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.primary_destination, 54538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_9); 54548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 54558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 54568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 54578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * already expired or did not use delayed 54588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * connectx 54598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 54608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 54618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 54628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 54648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAX_BURST: 54678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 900000 54698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *burst; 54708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(burst, optval, uint8_t, optsize); 54728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 54748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_burst = *burst; 54758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 54768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 54778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 54788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 54808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 54818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 54838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.max_burst = av->assoc_value; 54848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 54858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 54868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 54878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 54888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 54898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 54908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 54918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_burst = av->assoc_value; 54928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 54938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 54958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 54968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 54978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 54988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 54998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.max_burst = av->assoc_value; 55008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 55018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 55038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 55068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAXSEG: 55098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 55108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 55118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ovh; 55128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 55148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 55158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 55178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 55188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 55208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 55228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value) { 55238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_frag_point = (av->assoc_value + ovh); 55248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 55268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 55288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 55308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 55318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 55328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 55338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIXME MT: I think this is not in tune with the API ID */ 55348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value) { 55358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_frag_point = (av->assoc_value + ovh); 55368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 55388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 55408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 55428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 55438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENTS: 55488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 55498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event_subscribe *events; 55508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, optsize); 55528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 55548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_data_io_event) { 55558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 55568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 55588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_association_event) { 55618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 55628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 55648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_address_event) { 55678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 55688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 55708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_send_failure_event) { 55738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 55748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 55768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_peer_error_event) { 55798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR); 55808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR); 55828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_shutdown_event) { 55858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 55868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 55888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_partial_delivery_event) { 55918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 55928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 55948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_adaptation_layer_event) { 55978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 55988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 56008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_authentication_event) { 56038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT); 56048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT); 56068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_sender_dry_event) { 56098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT); 56108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT); 56128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_stream_reset_event) { 56158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 56168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 56188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 56208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 56228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 56238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 56248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_association_event) { 56258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT); 56268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT); 56288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_address_event) { 56308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT); 56318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT); 56338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_send_failure_event) { 56358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 56368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 56388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_peer_error_event) { 56408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR); 56418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR); 56438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_shutdown_event) { 56458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 56468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 56488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_partial_delivery_event) { 56508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT); 56518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT); 56538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_adaptation_layer_event) { 56558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 56568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 56588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_authentication_event) { 56608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT); 56618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT); 56638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_sender_dry_event) { 56658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT); 56668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT); 56688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_stream_reset_event) { 56708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 56718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 56738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 56758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Send up the sender dry event only for 1-to-1 style sockets. */ 56778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_sender_dry_event) { 56788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 56798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 56808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 56818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 56828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 56838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&stcb->asoc.send_queue) && 56848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&stcb->asoc.sent_queue) && 56858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.stream_queue_cnt == 0)) { 56868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED); 56878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 56898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 56938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 56948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_LAYER: 56968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 56978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setadaptation *adap_bits; 56988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 56998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize); 57008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 57018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind; 57029a8642036bc992ec39f872443a35f8c545cc28c4t inp->sctp_ep.adaptation_layer_indicator_provided = 1; 57038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 57048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 57058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_DEBUG 57078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_INITIAL_DBG_SEQ: 57088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 57098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *vvv; 57108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(vvv, optval, uint32_t, optsize); 57128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 57138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.initial_sequence_debug = *vvv; 57148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 57158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 57168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SEND_PARAM: 57198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 57208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndrcvinfo *s_info; 57218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, optsize); 57238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 57248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 57268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) { 57278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send))); 57288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 57298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 57308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 57318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 57338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 57348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 57358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 57368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC) || 57378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC)) { 57388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 57398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&inp->def_send, s_info, min(optsize, sizeof(inp->def_send))); 57408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 57418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((s_info->sinfo_assoc_id == SCTP_CURRENT_ASSOC) || 57438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC)) { 57448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 57458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 57468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 57478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) { 57488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send))); 57498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 57518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 57538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 57568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_PARAMS: 57588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 57598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrparams *paddrp; 57608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 57618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize); 57638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 57648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 57658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 57668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 57678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 57688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 57698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 57708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 57718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 57728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 57738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, 57748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&paddrp->spp_address, 57758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &net, NULL, NULL); 57768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 57778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 57788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5780b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 57818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 57828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)&paddrp->spp_address; 57848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 57858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 57868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 57888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 57898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 57908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 57918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 57928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 57938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 57948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 57968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 57988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 57998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 58008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 58028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 58038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 58048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 58058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 58068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 58078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 58098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 581075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 581175cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 581275cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 581375cd23222c96d5ebe5a9082c57a263f917f1462btuexen 581475cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 581575cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 581675cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 581775cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 581875cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 581975cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 582075cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 582175cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 582275cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 58238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 58248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 58258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 58268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 58278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 58288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* sanity checks */ 58318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_HB_ENABLE) && (paddrp->spp_flags & SPP_HB_DISABLE)) { 58328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 58338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 58348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 58358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 58368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_PMTUD_ENABLE) && (paddrp->spp_flags & SPP_PMTUD_DISABLE)) { 58398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 58408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 58418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 58428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 58438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 58468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************TCB SPECIFIC SET ******************/ 58478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 58488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do we change the timer for HB, we run 58498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * only one? 58508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 5851b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int ovh = 0; 58528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 58548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 58558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 58568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 58578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* network sets ? */ 58608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 58618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************NET SPECIFIC SET ******************/ 58628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_DISABLE) { 58638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) && 58648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen !(net->dest_state & SCTP_ADDR_NOHB)) { 58658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 58668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 58678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NOHB; 58698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_ENABLE) { 58718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval) { 58728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = paddrp->spp_hbinterval; 58738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 58748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = 0; 58758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 58778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 58788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 58798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NOHB; 58808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_DEMAND) { 58828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* on demand HB */ 58838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 5884a4ffbccf5bed12adde7673f02ca4b0ca3214262ctuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED); 58858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 58868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) { 58888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 58898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 58908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 58918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NO_PMTUD; 5893b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t net->mtu = paddrp->spp_pathmtu + ovh; 5894b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t if (net->mtu < stcb->asoc.smallest_mtu) { 5895b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t sctp_pathmtu_adjustment(stcb, net->mtu); 58968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 58998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 59008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 59018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NO_PMTUD; 59038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_pathmaxrxt) { 59058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 59068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 59078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 59088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->error_count <= paddrp->spp_pathmaxrxt) && 59118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->error_count > net->pf_threshold)) { 59128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_PF; 59138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 59148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 59158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 59168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 59198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 5920e2828360ea9cf8951730d46f5c14626c9425cb30t net->dest_state &= ~SCTP_ADDR_REACHABLE; 592147674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 59228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count <= paddrp->spp_pathmaxrxt) { 59258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 592647674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 59278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = paddrp->spp_pathmaxrxt; 59308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_DSCP) { 59328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp = paddrp->spp_dscp & 0xfc; 59338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp |= 0x01; 59348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 59368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 59378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->ro._l_addr.sa.sa_family == AF_INET6) { 59388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 59398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel |= 0x80000000; 59408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 59438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/ 59458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_pathmaxrxt) { 59468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt; 59478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 59488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 59498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 59508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 59518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->error_count <= paddrp->spp_pathmaxrxt) && 59548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->error_count > net->pf_threshold)) { 59558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_PF; 59568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 59578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 59588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 59598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 59628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 5963e2828360ea9cf8951730d46f5c14626c9425cb30t net->dest_state &= ~SCTP_ADDR_REACHABLE; 596447674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 59658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count <= paddrp->spp_pathmaxrxt) { 59688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 596947674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 59708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = paddrp->spp_pathmaxrxt; 59738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_ENABLE) { 59778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval) { 59788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval; 59798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 59808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.heart_beat_delay = 0; 59818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Turn back on the timer */ 59838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 59848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval) { 59858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = paddrp->spp_hbinterval; 59868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 59878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = 0; 59888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_NOHB) { 59908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NOHB; 59918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 59938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 59948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 59958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 59978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_DISABLE) { 59998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 60008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_NOHB)) { 60018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NOHB; 60028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED)) { 60038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 60048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 60088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) { 60108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 60118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 60128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 60138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 60148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NO_PMTUD; 6016b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t net->mtu = paddrp->spp_pathmtu + ovh; 6017b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t if (net->mtu < stcb->asoc.smallest_mtu) { 6018b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t sctp_pathmtu_adjustment(stcb, net->mtu); 60198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 60228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 60248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 60258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 60268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 60278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NO_PMTUD; 60298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 60318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_DSCP) { 60338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 60348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp = paddrp->spp_dscp & 0xfc; 60358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp |= 0x01; 60368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_dscp = paddrp->spp_dscp & 0xfc; 60388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_dscp |= 0x01; 60398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 60418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 60428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 60438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->ro._l_addr.sa.sa_family == AF_INET6) { 60448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 60458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel |= 0x80000000; 60468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 60498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_flowlabel |= 0x80000000; 60508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 60548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 60558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************NO TCB, SET TO default stuff ******************/ 60568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 60578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 60588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC)) { 60598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 60608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 60618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For the TOS/FLOWLABEL stuff you set it 60628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * with the options on the socket 60638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 60648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_pathmaxrxt) { 60658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt; 60668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 60688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) 60698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0; 60708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else if (paddrp->spp_hbinterval) { 60718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL) 60728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval= SCTP_MAX_HB_INTERVAL; 60738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval); 60748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 60768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_ENABLE) { 60778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 60788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0; 60798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_hbinterval) { 60808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval); 60818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 60838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_DISABLE) { 60848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 60858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 60878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 60888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { 60898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 60908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_DSCP) { 60928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_dscp = paddrp->spp_dscp & 0xfc; 60938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_dscp |= 0x01; 60948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 60968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 60978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 60988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 60998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_flowlabel |= 0x80000000; 61008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 61048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RTOINFO: 61128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 61138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_rtoinfo *srto; 61148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t new_init, new_min, new_max; 61158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 61168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, optsize); 61178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 61188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 61198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 61208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_initial) 61218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = srto->srto_initial; 61228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 61238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = stcb->asoc.initial_rto; 61248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_max) 61258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = srto->srto_max; 61268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 61278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = stcb->asoc.maxrto; 61288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_min) 61298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = srto->srto_min; 61308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 61318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = stcb->asoc.minrto; 61328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((new_min <= new_init) && (new_init <= new_max)) { 61338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.initial_rto = new_init; 61348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.maxrto = new_max; 61358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.minrto = new_min; 61368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 61418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 61438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 61448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (srto->srto_assoc_id == SCTP_FUTURE_ASSOC)) { 61458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 61468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_initial) 61478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = srto->srto_initial; 61488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 61498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = inp->sctp_ep.initial_rto; 61508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_max) 61518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = srto->srto_max; 61528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 61538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = inp->sctp_ep.sctp_maxrto; 61548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_min) 61558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = srto->srto_min; 61568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 61578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = inp->sctp_ep.sctp_minrto; 61588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((new_min <= new_init) && (new_init <= new_max)) { 61598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.initial_rto = new_init; 61608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_maxrto = new_max; 61618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_minrto = new_min; 61628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 61678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 6170000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 61718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOCINFO: 61758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 61768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assocparams *sasoc; 61778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 61788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, optsize); 61798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 61808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life) { 61818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* boundary check the cookie life */ 61828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life < 1000) 61838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = 1000; 61848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life > SCTP_MAX_COOKIE_LIFE) { 61858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = SCTP_MAX_COOKIE_LIFE; 61868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 61898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_asocmaxrxt) 61908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt; 61918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life) { 61928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life); 61938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 61958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 61978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 61988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC)) { 61998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 62008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_asocmaxrxt) 62018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt; 62028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life) { 62038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life); 62048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 62068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 62078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 62088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 6209000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 62108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_INITMSG: 62148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 62158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_initmsg *sinit; 62168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, optsize); 62188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 62198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_num_ostreams) 62208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams; 62218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_max_instreams) 62238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams; 62248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_max_attempts) 62268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_init_times = sinit->sinit_max_attempts; 62278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_max_init_timeo) 62298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo; 62308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 62318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PRIMARY_ADDR: 62348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 62358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setprim *spa; 62368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 62378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize); 62398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id); 62408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 62428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 62438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr); 62448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 62458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 62468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 62478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 62488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 62498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 62508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, 62518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&spa->ssp_addr, 62528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &net, NULL, NULL); 62538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 62548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 62558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb) && (net)) { 62598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net != stcb->asoc.primary_destination) && 62608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) { 62618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Ok we need to set it */ 62628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) { 6263000a5bac556b28e74e4e98c540f66b1743e9312dtuexen if ((stcb->asoc.alternate) && 62648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (!(net->dest_state & SCTP_ADDR_PF)) && 62658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->dest_state & SCTP_ADDR_REACHABLE)) { 62668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(stcb->asoc.alternate); 62678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.alternate = NULL; 62688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 62728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 62738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 62748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 62768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 62778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_DYNAMIC_PRIMARY: 62818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 62828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen union sctp_sockstore *ss; 62838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 6284b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int i, fnd = 0; 62858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Windows__) && !defined(__Userspace__) 62878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 62888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct proc *proc; 62898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __FreeBSD__ 62918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version > 602000 62928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = priv_check(curthread, 62938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen PRIV_NETINET_RESERVEDPORT); 62948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif __FreeBSD_version >= 500000 62958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser((struct thread *)p); 62968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 62978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(p); 62988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__APPLE__) 63008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen proc = (struct proc *)p; 63018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (p) { 63028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(proc->p_ucred, &proc->p_acflag); 63038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 63078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(p, 0); 63088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) 63118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 63138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ss, optval, union sctp_sockstore, optsize); 63148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* SUPER USER CHECK? */ 63158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 63168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 63178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf_id == inp->m_vrf_ids[i]) { 63188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 63198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 63238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 63248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 63258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 63288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_dynamic_set_primary(&ss->sa, vrf_id); 63298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_PEER_PRIMARY_ADDR: 63328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 63338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setpeerprim *sspp; 63348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 63358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize); 63368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id); 63378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 63388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *ifa; 63398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ifa = sctp_find_ifa_by_addr((struct sockaddr *)&sspp->sspp_addr, 63408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED); 63418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ifa == NULL) { 63428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 63438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 63448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_of_it; 63458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 63478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Must validate the ifa found is in our ep */ 63488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 6349b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int found = 0; 63508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 63518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (laddr->ifa == NULL) { 63528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n", 63538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen __FUNCTION__); 63548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 63558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (laddr->ifa == ifa) { 63578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen found = 1; 63588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!found) { 63628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 63638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 63648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_of_it; 63658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6366998635733088fde643e6d807fa76679c4ceeaa00t#if defined(__FreeBSD__) 6367998635733088fde643e6d807fa76679c4ceeaa00t } else { 6368998635733088fde643e6d807fa76679c4ceeaa00t switch (sspp->sspp_addr.ss_family) { 6369998635733088fde643e6d807fa76679c4ceeaa00t#ifdef INET 6370998635733088fde643e6d807fa76679c4ceeaa00t case AF_INET: 6371998635733088fde643e6d807fa76679c4ceeaa00t { 6372998635733088fde643e6d807fa76679c4ceeaa00t struct sockaddr_in *sin; 6373998635733088fde643e6d807fa76679c4ceeaa00t 6374998635733088fde643e6d807fa76679c4ceeaa00t sin = (struct sockaddr_in *)&sspp->sspp_addr; 6375998635733088fde643e6d807fa76679c4ceeaa00t if (prison_check_ip4(inp->ip_inp.inp.inp_cred, 6376998635733088fde643e6d807fa76679c4ceeaa00t &sin->sin_addr) != 0) { 6377998635733088fde643e6d807fa76679c4ceeaa00t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6378998635733088fde643e6d807fa76679c4ceeaa00t error = EINVAL; 6379998635733088fde643e6d807fa76679c4ceeaa00t goto out_of_it; 6380998635733088fde643e6d807fa76679c4ceeaa00t } 6381998635733088fde643e6d807fa76679c4ceeaa00t break; 6382998635733088fde643e6d807fa76679c4ceeaa00t } 6383998635733088fde643e6d807fa76679c4ceeaa00t#endif 6384998635733088fde643e6d807fa76679c4ceeaa00t#ifdef INET6 6385998635733088fde643e6d807fa76679c4ceeaa00t case AF_INET6: 6386998635733088fde643e6d807fa76679c4ceeaa00t { 6387998635733088fde643e6d807fa76679c4ceeaa00t struct sockaddr_in6 *sin6; 6388998635733088fde643e6d807fa76679c4ceeaa00t 6389998635733088fde643e6d807fa76679c4ceeaa00t sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr; 6390998635733088fde643e6d807fa76679c4ceeaa00t if (prison_check_ip6(inp->ip_inp.inp.inp_cred, 6391998635733088fde643e6d807fa76679c4ceeaa00t &sin6->sin6_addr) != 0) { 6392998635733088fde643e6d807fa76679c4ceeaa00t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6393998635733088fde643e6d807fa76679c4ceeaa00t error = EINVAL; 6394998635733088fde643e6d807fa76679c4ceeaa00t goto out_of_it; 6395998635733088fde643e6d807fa76679c4ceeaa00t } 6396998635733088fde643e6d807fa76679c4ceeaa00t break; 6397998635733088fde643e6d807fa76679c4ceeaa00t } 6398998635733088fde643e6d807fa76679c4ceeaa00t#endif 6399998635733088fde643e6d807fa76679c4ceeaa00t default: 6400998635733088fde643e6d807fa76679c4ceeaa00t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6401998635733088fde643e6d807fa76679c4ceeaa00t error = EINVAL; 6402998635733088fde643e6d807fa76679c4ceeaa00t goto out_of_it; 6403998635733088fde643e6d807fa76679c4ceeaa00t } 6404998635733088fde643e6d807fa76679c4ceeaa00t#endif 64058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_set_primary_ip_address_sa(stcb, 64078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&sspp->sspp_addr) != 0) { 64088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 64098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 64108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_of_it: 64128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 64138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 64148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 64158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 64168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_BINDX_ADD_ADDR: 64208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 64218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *addrs; 64228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 64238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct thread *td; 64248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 64258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen td = (struct thread *)p; 64268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, 64288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen optsize); 64298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 64308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET) { 6431c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) { 64328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 64338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 64348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 64378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) { 64388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 64398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 64438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 64458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET6) { 6446c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) { 64478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 64488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 64498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 64528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && (error = prison_local_ip6(td->td_ucred, &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 64538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) { 64548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 64558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 64598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 64618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 6462e2828360ea9cf8951730d46f5c14626c9425cb30t break; 64638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_bindx_add_address(so, inp, addrs->addr, 64658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addrs->sget_assoc_id, vrf_id, 64668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &error, p); 64678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_BINDX_REM_ADDR: 64708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 64718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *addrs; 64728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 64738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct thread *td; 64748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen td = (struct thread *)p; 64758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 64768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize); 64788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 64798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET) { 6480c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) { 64818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 64828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 64838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 64868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) { 64878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 64888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 64928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 64938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 64948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET6) { 6495c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) { 64968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 64978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 64988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 65018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && 65028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (error = prison_local_ip6(td->td_ucred, 65038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 65048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) { 65058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 65068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 65108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 65128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 65138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65150ac02f34d6041cd0018437596a5a9a94685e6919tuexen sctp_bindx_delete_address(inp, addrs->addr, 65168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addrs->sget_assoc_id, vrf_id, 65178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &error); 65188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __APPLE__ 65218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_LISTEN_FIX: 65228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only applies to one-to-many sockets */ 65238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 65248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* make sure the ACCEPTCONN flag is OFF */ 65258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_options &= ~SO_ACCEPTCONN; 65268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 65278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* otherwise, not allowed */ 65288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 65298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 65308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* __APPLE__ */ 65338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENT: 65348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 65358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event *event; 65368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t event_type; 65378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 65388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, optsize); 65398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, event->se_assoc_id); 65408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (event->se_type) { 65418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOC_CHANGE: 65428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT; 6543000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_CHANGE: 65458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPADDREVNT; 6546000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REMOTE_ERROR: 65488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPEERERR; 6549000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SEND_FAILED: 65518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT; 6552000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SHUTDOWN_EVENT: 65548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT; 6555000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_INDICATION: 65578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT; 6558000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_EVENT: 65608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_PDAPIEVNT; 6561000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTHENTICATION_EVENT: 65638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_AUTHEVNT; 6564000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_STREAM_RESET_EVENT: 65668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT; 6567000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SENDER_DRY_EVENT: 65698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_DRYEVNT; 6570000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 65718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFICATIONS_STOPPED_EVENT: 65728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 65738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 65748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 65758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 6576298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_ASSOC_RESET_EVENT: 6577298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT; 6578298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 6579298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_STREAM_CHANGE_EVENT: 6580298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT; 6581298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 65825741e159bdf238ef4b61085d6fbfea2947386238tuexen case SCTP_SEND_FAILED_EVENT: 65835741e159bdf238ef4b61085d6fbfea2947386238tuexen event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT; 65845741e159bdf238ef4b61085d6fbfea2947386238tuexen break; 65858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 65868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 65878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 65888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 65898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event_type > 0) { 65928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 65938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event->se_on) { 65948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, event_type); 65958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event_type == SCTP_PCB_FLAGS_DRYEVNT) { 65968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&stcb->asoc.send_queue) && 65978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&stcb->asoc.sent_queue) && 65988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.stream_queue_cnt == 0)) { 65998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED); 66008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, event_type); 66048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 66068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 66088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We don't want to send up a storm of events, 66098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * so return an error for sender dry events 66108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 66118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((event_type == SCTP_PCB_FLAGS_DRYEVNT) && 66128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) && 66138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 6614000a5bac556b28e74e4e98c540f66b1743e9312dtuexen ((event->se_assoc_id == SCTP_ALL_ASSOC) || 66158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_CURRENT_ASSOC))) { 66168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 66178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 66188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 66198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 66218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 66228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_FUTURE_ASSOC) || 66238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_ALL_ASSOC)) { 66248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 66258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event->se_on) { 66268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, event_type); 66278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, event_type); 66298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 66318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((event->se_assoc_id == SCTP_CURRENT_ASSOC) || 66338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_ALL_ASSOC)) { 66348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 66358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 66368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 66378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event->se_on) { 66388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, event_type); 66398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, event_type); 66418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 66438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 66458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 66498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVRCVINFO: 66518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 66528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int *onoff; 66538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 66548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(onoff, optval, int, optsize); 66558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 66568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*onoff != 0) { 66578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 66588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 66608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 66628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 66638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVNXTINFO: 66658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 66668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int *onoff; 66678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 66688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(onoff, optval, int, optsize); 66698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 66708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*onoff != 0) { 66718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 66728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 66748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 66768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 66778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SNDINFO: 66798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 66808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndinfo *info; 66818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint16_t policy; 66828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 66838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, optsize); 66848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id); 66858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 66868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 66878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (info->snd_sid < stcb->asoc.streamoutcnt) { 66888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_stream = info->snd_sid; 66898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 66908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags = info->snd_flags; 66918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= policy; 66928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_ppid = info->snd_ppid; 66938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_context = info->snd_context; 66948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 66968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 66978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 66998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 67008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 67018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 67028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_FUTURE_ASSOC) || 67038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_ALL_ASSOC)) { 67048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 67058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_stream = info->snd_sid; 67068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags); 67078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags = info->snd_flags; 67088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags |= policy; 67098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_ppid = info->snd_ppid; 67108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_context = info->snd_context; 67118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 67128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((info->snd_assoc_id == SCTP_CURRENT_ASSOC) || 67148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_ALL_ASSOC)) { 67158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 67168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 67178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 67188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (info->snd_sid < stcb->asoc.streamoutcnt) { 67198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_stream = info->snd_sid; 67208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 67218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags = info->snd_flags; 67228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= policy; 67238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_ppid = info->snd_ppid; 67248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_context = info->snd_context; 67258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 67278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 67298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 67328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_PRINFO: 67348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 67358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_default_prinfo *info; 67368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize); 67388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id); 67398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (PR_SCTP_INVALID_POLICY(info->pr_policy)) { 67418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 67428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 67438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 67448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 67468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags &= 0xfff0; 67478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= info->pr_policy; 67488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_timetolive = info->pr_value; 67498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 67508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 67518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 67528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 67538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_FUTURE_ASSOC) || 67548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_ALL_ASSOC)) { 67558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 67568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags &= 0xfff0; 67578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags |= info->pr_policy; 67588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_timetolive = info->pr_value; 67598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 67608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((info->pr_assoc_id == SCTP_CURRENT_ASSOC) || 67628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_ALL_ASSOC)) { 67638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 67648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 67658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 67668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags &= 0xfff0; 67678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= info->pr_policy; 67688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_timetolive = info->pr_value; 67698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 67708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 67728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 67758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_THLDS: 67778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Applies to the specific association */ 67788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 67798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrthlds *thlds; 67808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 67818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize); 67838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); 67848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 67858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 678649659836bb1e9e5d1ab58f3804c47e509933c2c4t net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address); 67878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 67888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 67898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 67908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 67918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 67928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 67938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, 679449659836bb1e9e5d1ab58f3804c47e509933c2c4t (struct sockaddr *)&thlds->spt_address, 67958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &net, NULL, NULL); 67968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 67978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 67988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6800b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 68018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 68028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 680349659836bb1e9e5d1ab58f3804c47e509933c2c4t sa = (struct sockaddr *)&thlds->spt_address; 68048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 68058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 68068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 68088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 68098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 68108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 68118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 68128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 68138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 68148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 68168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 68188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 68198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 68208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 68228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 68238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 68248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 68258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 68268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 68278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 68298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 683075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 683175cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 683275cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 683375cd23222c96d5ebe5a9082c57a263f917f1462btuexen 683475cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 683575cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 683675cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 683775cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 683875cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 683975cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 684075cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 684175cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 684275cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 68438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 68448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 68458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 68468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 68478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 68488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 68518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 68528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 68538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathmaxrxt) || 68548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathpfthld)) { 68558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 68568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 68588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathpfthld) && 68598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathmaxrxt)) { 6860e2828360ea9cf8951730d46f5c14626c9425cb30t net->dest_state |= SCTP_ADDR_PF; 68618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 68628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 68638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 68648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 68678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold > thlds->spt_pathmaxrxt) { 68688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 686947674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 68708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 68728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold <= thlds->spt_pathmaxrxt) { 68738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 687447674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 68758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = thlds->spt_pathmaxrxt; 68788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->pf_threshold = thlds->spt_pathpfthld; 68798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 68808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 68818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 68828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathmaxrxt) || 68838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathpfthld)) { 68848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 68858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 68878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathpfthld) && 68888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathmaxrxt)) { 6889e2828360ea9cf8951730d46f5c14626c9425cb30t net->dest_state |= SCTP_ADDR_PF; 68908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 68918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 68928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 68938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 68968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold > thlds->spt_pathmaxrxt) { 68978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 689847674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 68998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 69018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold <= thlds->spt_pathmaxrxt) { 69028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 690347674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 69048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = thlds->spt_pathmaxrxt; 69078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->pf_threshold = thlds->spt_pathpfthld; 69088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_net_failure = thlds->spt_pathmaxrxt; 69108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_net_pf_threshold = thlds->spt_pathpfthld; 69118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 69138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 69148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 69158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC)) { 69168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 69178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_net_failure = thlds->spt_pathmaxrxt; 69188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_net_pf_threshold = thlds->spt_pathpfthld; 69198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 69208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 69218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 69228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 69238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 69268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6927153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen case SCTP_REMOTE_UDP_ENCAPS_PORT: 6928153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 6929153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_udpencaps *encaps; 6930153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_nets *net; 693181616c6a3e184f46276632dd15aa489cd06d94dftuexen 6932153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize); 6933153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); 6934153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 6935153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address); 6936153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 6937153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen /* We increment here since sctp_findassociation_ep_addr() wil 6938153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * do a decrement if it finds the stcb as long as the locked 6939153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * tcb (last argument) is NOT a TCB.. aka NULL. 6940153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen */ 6941153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = NULL; 6942153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_INCR_REF(inp); 6943153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL); 6944153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb == NULL) { 6945153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_DECR_REF(inp); 6946153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6947153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6948b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 6949153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr *sa; 6950000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 6951153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sa = (struct sockaddr *)&encaps->sue_address; 6952153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET 6953153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET) { 6954153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 6955153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in *sin; 6956153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin = (struct sockaddr_in *)sa; 6957153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sin->sin_addr.s_addr) { 6958153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6959153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 6960153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 6961153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 6962153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6963153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 6964153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 6965153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET6 6966153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET6) { 6967153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in6 *sin6; 6968153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 6969153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin6 = (struct sockaddr_in6 *)sa; 6970153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 6971153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6972153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 6973153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 6974153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 6975153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6976153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 6977153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 697875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 697975cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 698075cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 698175cd23222c96d5ebe5a9082c57a263f917f1462btuexen 698275cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 698375cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 698475cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 698575cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 698675cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 698775cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 698875cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 698975cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 699075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 6991153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 6992153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EAFNOSUPPORT; 6993153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 6994153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 6995153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 6996153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6997153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6998153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 6999153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 7000153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (net) { 7001153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net->port = encaps->sue_port; 7002153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 7003153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen stcb->asoc.port = encaps->sue_port; 7004153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 7005153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 7006153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 7007153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 7008153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 7009153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC)) { 7010153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_WLOCK(inp); 7011153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen inp->sctp_ep.port = encaps->sue_port; 7012153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_WUNLOCK(inp); 7013153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 7014153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7015153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 7016153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 7017153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 7018153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 7019153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 7020aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t case SCTP_ECN_SUPPORTED: 7021aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t { 7022aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t struct sctp_assoc_value *av; 7023aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t 7024aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 7025aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 7026aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t 7027aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t if (stcb) { 7028aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7029aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t error = EINVAL; 7030aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_TCB_UNLOCK(stcb); 7031aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } else { 7032aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 7033aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 7034aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 7035aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_INP_WLOCK(inp); 7036aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t if (av->assoc_value == 0) { 7037aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t inp->ecn_supported = 0; 7038aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } else { 7039a8657c4fc04fb9cc82100f648810d51ec6ab155at inp->ecn_supported = 1; 7040a8657c4fc04fb9cc82100f648810d51ec6ab155at } 7041a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_INP_WUNLOCK(inp); 7042a8657c4fc04fb9cc82100f648810d51ec6ab155at } else { 7043a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7044a8657c4fc04fb9cc82100f648810d51ec6ab155at error = EINVAL; 7045a8657c4fc04fb9cc82100f648810d51ec6ab155at } 7046a8657c4fc04fb9cc82100f648810d51ec6ab155at } 7047a8657c4fc04fb9cc82100f648810d51ec6ab155at break; 7048a8657c4fc04fb9cc82100f648810d51ec6ab155at } 7049a8657c4fc04fb9cc82100f648810d51ec6ab155at case SCTP_PR_SUPPORTED: 7050a8657c4fc04fb9cc82100f648810d51ec6ab155at { 7051a8657c4fc04fb9cc82100f648810d51ec6ab155at struct sctp_assoc_value *av; 7052a8657c4fc04fb9cc82100f648810d51ec6ab155at 7053a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 7054a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_FIND_STCB(inp, stcb, av->assoc_id); 7055a8657c4fc04fb9cc82100f648810d51ec6ab155at 7056a8657c4fc04fb9cc82100f648810d51ec6ab155at if (stcb) { 7057a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7058a8657c4fc04fb9cc82100f648810d51ec6ab155at error = EINVAL; 7059a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_TCB_UNLOCK(stcb); 7060a8657c4fc04fb9cc82100f648810d51ec6ab155at } else { 7061a8657c4fc04fb9cc82100f648810d51ec6ab155at if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 7062a8657c4fc04fb9cc82100f648810d51ec6ab155at (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 7063a8657c4fc04fb9cc82100f648810d51ec6ab155at (av->assoc_id == SCTP_FUTURE_ASSOC)) { 7064a8657c4fc04fb9cc82100f648810d51ec6ab155at SCTP_INP_WLOCK(inp); 7065a8657c4fc04fb9cc82100f648810d51ec6ab155at if (av->assoc_value == 0) { 7066a8657c4fc04fb9cc82100f648810d51ec6ab155at inp->prsctp_supported = 0; 7067a8657c4fc04fb9cc82100f648810d51ec6ab155at } else { 7068a8657c4fc04fb9cc82100f648810d51ec6ab155at inp->prsctp_supported = 1; 7069aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 7070aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_INP_WUNLOCK(inp); 7071aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } else { 7072aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7073aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t error = EINVAL; 7074aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 7075aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 7076aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t break; 7077aba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67t } 7078fb3816eaffe5878bb1286adb120fd160da178a05t case SCTP_AUTH_SUPPORTED: 7079fb3816eaffe5878bb1286adb120fd160da178a05t { 7080fb3816eaffe5878bb1286adb120fd160da178a05t struct sctp_assoc_value *av; 7081fb3816eaffe5878bb1286adb120fd160da178a05t 7082fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 7083fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 7084fb3816eaffe5878bb1286adb120fd160da178a05t 7085fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb) { 7086fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7087fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 7088fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_TCB_UNLOCK(stcb); 7089fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7090fb3816eaffe5878bb1286adb120fd160da178a05t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 7091fb3816eaffe5878bb1286adb120fd160da178a05t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 7092fb3816eaffe5878bb1286adb120fd160da178a05t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 7093fb3816eaffe5878bb1286adb120fd160da178a05t if ((av->assoc_value == 0) && 7094fb3816eaffe5878bb1286adb120fd160da178a05t (inp->asconf_supported == 1)) { 7095fb3816eaffe5878bb1286adb120fd160da178a05t /* AUTH is required for ASCONF */ 7096fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7097fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 7098fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7099fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_WLOCK(inp); 7100fb3816eaffe5878bb1286adb120fd160da178a05t if (av->assoc_value == 0) { 7101fb3816eaffe5878bb1286adb120fd160da178a05t inp->auth_supported = 0; 7102fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7103fb3816eaffe5878bb1286adb120fd160da178a05t inp->auth_supported = 1; 7104fb3816eaffe5878bb1286adb120fd160da178a05t } 7105fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_WUNLOCK(inp); 7106fb3816eaffe5878bb1286adb120fd160da178a05t } 7107fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7108fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7109fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 7110fb3816eaffe5878bb1286adb120fd160da178a05t } 7111fb3816eaffe5878bb1286adb120fd160da178a05t } 7112fb3816eaffe5878bb1286adb120fd160da178a05t break; 7113fb3816eaffe5878bb1286adb120fd160da178a05t } 7114fb3816eaffe5878bb1286adb120fd160da178a05t case SCTP_ASCONF_SUPPORTED: 7115fb3816eaffe5878bb1286adb120fd160da178a05t { 7116fb3816eaffe5878bb1286adb120fd160da178a05t struct sctp_assoc_value *av; 7117fb3816eaffe5878bb1286adb120fd160da178a05t 7118fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 7119fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 7120fb3816eaffe5878bb1286adb120fd160da178a05t 7121fb3816eaffe5878bb1286adb120fd160da178a05t if (stcb) { 7122fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7123fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 7124fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_TCB_UNLOCK(stcb); 7125fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7126fb3816eaffe5878bb1286adb120fd160da178a05t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 7127fb3816eaffe5878bb1286adb120fd160da178a05t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 7128fb3816eaffe5878bb1286adb120fd160da178a05t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 7129fb3816eaffe5878bb1286adb120fd160da178a05t if ((av->assoc_value != 0) && 7130fb3816eaffe5878bb1286adb120fd160da178a05t (inp->auth_supported == 0)) { 7131fb3816eaffe5878bb1286adb120fd160da178a05t /* AUTH is required for ASCONF */ 7132fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7133fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 7134fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7135fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_WLOCK(inp); 7136fb3816eaffe5878bb1286adb120fd160da178a05t if (av->assoc_value == 0) { 7137fb3816eaffe5878bb1286adb120fd160da178a05t inp->asconf_supported = 0; 7138fb3816eaffe5878bb1286adb120fd160da178a05t sctp_auth_delete_chunk(SCTP_ASCONF, 7139fb3816eaffe5878bb1286adb120fd160da178a05t inp->sctp_ep.local_auth_chunks); 7140fb3816eaffe5878bb1286adb120fd160da178a05t sctp_auth_delete_chunk(SCTP_ASCONF_ACK, 7141fb3816eaffe5878bb1286adb120fd160da178a05t inp->sctp_ep.local_auth_chunks); 7142fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7143fb3816eaffe5878bb1286adb120fd160da178a05t inp->asconf_supported = 1; 7144fb3816eaffe5878bb1286adb120fd160da178a05t sctp_auth_add_chunk(SCTP_ASCONF, 7145fb3816eaffe5878bb1286adb120fd160da178a05t inp->sctp_ep.local_auth_chunks); 7146fb3816eaffe5878bb1286adb120fd160da178a05t sctp_auth_add_chunk(SCTP_ASCONF_ACK, 7147fb3816eaffe5878bb1286adb120fd160da178a05t inp->sctp_ep.local_auth_chunks); 7148fb3816eaffe5878bb1286adb120fd160da178a05t } 7149fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_INP_WUNLOCK(inp); 7150fb3816eaffe5878bb1286adb120fd160da178a05t } 7151fb3816eaffe5878bb1286adb120fd160da178a05t } else { 7152fb3816eaffe5878bb1286adb120fd160da178a05t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7153fb3816eaffe5878bb1286adb120fd160da178a05t error = EINVAL; 7154fb3816eaffe5878bb1286adb120fd160da178a05t } 7155fb3816eaffe5878bb1286adb120fd160da178a05t } 7156fb3816eaffe5878bb1286adb120fd160da178a05t break; 7157fb3816eaffe5878bb1286adb120fd160da178a05t } 71582344bfccffeb80545fca6a86e8cda3d56a6f50bft case SCTP_RECONFIG_SUPPORTED: 71592344bfccffeb80545fca6a86e8cda3d56a6f50bft { 71602344bfccffeb80545fca6a86e8cda3d56a6f50bft struct sctp_assoc_value *av; 71612344bfccffeb80545fca6a86e8cda3d56a6f50bft 71622344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 71632344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_FIND_STCB(inp, stcb, av->assoc_id); 71642344bfccffeb80545fca6a86e8cda3d56a6f50bft 71652344bfccffeb80545fca6a86e8cda3d56a6f50bft if (stcb) { 71662344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 71672344bfccffeb80545fca6a86e8cda3d56a6f50bft error = EINVAL; 71682344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_TCB_UNLOCK(stcb); 71692344bfccffeb80545fca6a86e8cda3d56a6f50bft } else { 71702344bfccffeb80545fca6a86e8cda3d56a6f50bft if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 71712344bfccffeb80545fca6a86e8cda3d56a6f50bft (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 71722344bfccffeb80545fca6a86e8cda3d56a6f50bft (av->assoc_id == SCTP_FUTURE_ASSOC)) { 71732344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_INP_WLOCK(inp); 71742344bfccffeb80545fca6a86e8cda3d56a6f50bft if (av->assoc_value == 0) { 71752344bfccffeb80545fca6a86e8cda3d56a6f50bft inp->reconfig_supported = 0; 71762344bfccffeb80545fca6a86e8cda3d56a6f50bft } else { 71772344bfccffeb80545fca6a86e8cda3d56a6f50bft inp->reconfig_supported = 1; 71782344bfccffeb80545fca6a86e8cda3d56a6f50bft } 71792344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_INP_WUNLOCK(inp); 71802344bfccffeb80545fca6a86e8cda3d56a6f50bft } else { 71812344bfccffeb80545fca6a86e8cda3d56a6f50bft SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 71822344bfccffeb80545fca6a86e8cda3d56a6f50bft error = EINVAL; 71832344bfccffeb80545fca6a86e8cda3d56a6f50bft } 71842344bfccffeb80545fca6a86e8cda3d56a6f50bft } 71852344bfccffeb80545fca6a86e8cda3d56a6f50bft break; 71862344bfccffeb80545fca6a86e8cda3d56a6f50bft } 718744318e900a771ba1a5bafb510c38f33fd5cd8a39t case SCTP_NRSACK_SUPPORTED: 718844318e900a771ba1a5bafb510c38f33fd5cd8a39t { 718944318e900a771ba1a5bafb510c38f33fd5cd8a39t struct sctp_assoc_value *av; 719044318e900a771ba1a5bafb510c38f33fd5cd8a39t 719144318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 719244318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 719344318e900a771ba1a5bafb510c38f33fd5cd8a39t 719444318e900a771ba1a5bafb510c38f33fd5cd8a39t if (stcb) { 719544318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 719644318e900a771ba1a5bafb510c38f33fd5cd8a39t error = EINVAL; 719744318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_TCB_UNLOCK(stcb); 719844318e900a771ba1a5bafb510c38f33fd5cd8a39t } else { 719944318e900a771ba1a5bafb510c38f33fd5cd8a39t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 720044318e900a771ba1a5bafb510c38f33fd5cd8a39t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 720144318e900a771ba1a5bafb510c38f33fd5cd8a39t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 720244318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_INP_WLOCK(inp); 720344318e900a771ba1a5bafb510c38f33fd5cd8a39t if (av->assoc_value == 0) { 720444318e900a771ba1a5bafb510c38f33fd5cd8a39t inp->nrsack_supported = 0; 720544318e900a771ba1a5bafb510c38f33fd5cd8a39t } else { 720644318e900a771ba1a5bafb510c38f33fd5cd8a39t inp->nrsack_supported = 1; 720744318e900a771ba1a5bafb510c38f33fd5cd8a39t } 720844318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_INP_WUNLOCK(inp); 720944318e900a771ba1a5bafb510c38f33fd5cd8a39t } else { 721044318e900a771ba1a5bafb510c38f33fd5cd8a39t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 721144318e900a771ba1a5bafb510c38f33fd5cd8a39t error = EINVAL; 721244318e900a771ba1a5bafb510c38f33fd5cd8a39t } 721344318e900a771ba1a5bafb510c38f33fd5cd8a39t } 721444318e900a771ba1a5bafb510c38f33fd5cd8a39t break; 721544318e900a771ba1a5bafb510c38f33fd5cd8a39t } 7216669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t case SCTP_PKTDROP_SUPPORTED: 7217669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t { 7218669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t struct sctp_assoc_value *av; 7219669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t 7220669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 7221669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_FIND_STCB(inp, stcb, av->assoc_id); 7222669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t 7223669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t if (stcb) { 7224669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7225669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t error = EINVAL; 7226669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_TCB_UNLOCK(stcb); 7227669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } else { 7228669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 7229669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 7230669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t (av->assoc_id == SCTP_FUTURE_ASSOC)) { 7231669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_INP_WLOCK(inp); 7232669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t if (av->assoc_value == 0) { 7233669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t inp->pktdrop_supported = 0; 7234669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } else { 7235669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t inp->pktdrop_supported = 1; 7236669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 7237669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_INP_WUNLOCK(inp); 7238669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } else { 7239669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7240669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t error = EINVAL; 7241669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 7242669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 7243669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t break; 7244669cffca0ac8ad73a3c16bb63d1fa0f829f84c10t } 72458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 72468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 72478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 72488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end switch (opt) */ 72508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 72518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 72528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 72548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 72558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ctloutput(struct socket *so, struct sockopt *sopt) 72568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 72578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *optval = NULL; 72588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t optsize = 0; 72598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p; 72608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 72618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sopt->sopt_level != IPPROTO_SCTP) { 72638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* wrong proto level... send back up to IP */ 72648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 72658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (INP_CHECK_SOCKAF(so, AF_INET6)) 72668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ip6_ctloutput(so, sopt); 72678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* INET6 */ 72680612043f643c9b26245564c05defca64d472060etuexen#if defined(INET) && defined(INET6) 72698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 72708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 72728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ip_ctloutput(so, sopt); 72738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 72758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen optsize = sopt->sopt_valsize; 72778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize) { 72788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT); 72798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval == NULL) { 72808a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS); 72818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOBUFS); 72828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sooptcopyin(sopt, optval, optsize, optsize); 72848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 72858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(optval, SCTP_M_SOCKOPT); 72868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 72878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__Windows__) 72908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen p = (void *)sopt->sopt_td; 72918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 72928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen p = (void *)sopt->sopt_p; 72938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sopt->sopt_dir == SOPT_SET) { 72958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p); 72968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (sopt->sopt_dir == SOPT_GET) { 72978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p); 72988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 72998a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 73008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 73018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((error == 0) && (optval != NULL)) { 73038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sooptcopyout(sopt, optval, optsize); 73048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(optval, SCTP_M_SOCKOPT); 73058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (optval != NULL) { 73068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(optval, SCTP_M_SOCKOPT); 73078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenout: 73098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 73108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 73118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 73148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 73158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 73168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) 73178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 73198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) 73208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 73218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr, struct proc *p) 73228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) || defined(__Userspace__) 73248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 73258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr) 73268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p = NULL; 73288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 73298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 73308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr, PKTHREAD p) 73318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 73338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 73348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct mbuf *nam, struct proc *p) 73358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 73378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 7341b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int i, fnd = 0; 73428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 73448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int create_lock_on = 0; 73458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 73468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 7347b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct sctp_tcb *stcb = NULL; 73488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 73502fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 73518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* I made the same as TCP since we are not setup? */ 73528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 73538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 73548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr == NULL) { 73568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 73578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return EINVAL; 73588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 73618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TODO __Userspace__ falls into this code for IPv6 stuff at the moment... */ 73628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 736323273859c39742f09cc5ec7c9bf32ff225661e82tuexen#if !defined(__Windows__) && !defined(__Userspace_os_Linux) && !defined(__Userspace_os_Windows) 73648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (addr->sa_family) { 73658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 73668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 73678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 73688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 73698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6p; 73708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_len != sizeof(struct sockaddr_in6)) { 73738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 73748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 73758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 73778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6p = (struct sockaddr_in6 *)addr; 73788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6p->sin6_addr)) != 0) { 73798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 73808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 73818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 73848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 73878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 73888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 73898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 73908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sinp; 73918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73930612043f643c9b26245564c05defca64d472060etuexen#if !defined(__Userspace_os_Windows) 73948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_len != sizeof(struct sockaddr_in)) { 73958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 73968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 73978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 739881616c6a3e184f46276632dd15aa489cd06d94dftuexen#endif 73998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 74008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinp = (struct sockaddr_in *)addr; 74018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (p != NULL && (error = prison_remote_ip4(p->td_ucred, &sinp->sin_addr)) != 0) { 74028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 74038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 74048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 74078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 74108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 7411e2828360ea9cf8951730d46f5c14626c9425cb30t return (EAFNOSUPPORT); 74128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 74158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_LOCK(inp); 74168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen create_lock_on = 1; 74178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 74188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 74198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 74208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 74218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Should I really unlock ? */ 74228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 74238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EFAULT; 74248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 74258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 74278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 74288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (addr->sa_family == AF_INET6)) { 74298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 74308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 74318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 74328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74337988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 74347988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 74357988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) && 74367988ea8f0c067cf3757e798b473b1ae4d34b6dfdt (addr->sa_family != AF_CONN)) { 74377988ea8f0c067cf3757e798b473b1ae4d34b6dfdt SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 74387988ea8f0c067cf3757e798b473b1ae4d34b6dfdt error = EINVAL; 74397988ea8f0c067cf3757e798b473b1ae4d34b6dfdt goto out_now; 74407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 74417988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 74428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 74438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PCB_FLAGS_UNBOUND) { 74448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Bind a ephemeral port */ 74458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_inpcb_bind(so, NULL, NULL, p); 74468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 74478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 74488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now do we connect? */ 74518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 74528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 74538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 74548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 74558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 74568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 74588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 74598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are already connected AND the TCP model */ 74608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 74618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EADDRINUSE; 74628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 74638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 74658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 74668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 74678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 74688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 74698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() will 74708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 74718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 74728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 74738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 74748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 74758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 74768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 74778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 74788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 74798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 74828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Already have or am bring up an association */ 74838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 74848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 74858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 74868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 74888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 74898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 74908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 74918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf_id == inp->m_vrf_ids[i]) { 74928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 74938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 74948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 74978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 74988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 74998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 75008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are GOOD to go */ 75038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p); 75048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 75058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak! no memory */ 75068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 75078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 75098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 75108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Set the connected flag so we can queue data */ 75118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen soisconnecting(so); 75128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 75148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 75158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* initialize authentication parameters for the assoc */ 75178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_initialize_auth_params(inp, stcb); 75188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 75208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 75218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_now: 75228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (create_lock_on) { 75238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_UNLOCK(inp); 75248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 7527b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (error); 75288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 75298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75317a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#if defined(__Userspace__) 75327a9f1edd34bf82c194a2f9d0c64394f431175138tuexenint 75337a9f1edd34bf82c194a2f9d0c64394f431175138tuexensctpconn_connect(struct socket *so, struct sockaddr *addr) 75347a9f1edd34bf82c194a2f9d0c64394f431175138tuexen{ 75357a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#ifdef SCTP_MVRF 75367a9f1edd34bf82c194a2f9d0c64394f431175138tuexen int i, fnd = 0; 75377a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 75387a9f1edd34bf82c194a2f9d0c64394f431175138tuexen void *p = NULL; 75397a9f1edd34bf82c194a2f9d0c64394f431175138tuexen int error = 0; 75407a9f1edd34bf82c194a2f9d0c64394f431175138tuexen int create_lock_on = 0; 75417a9f1edd34bf82c194a2f9d0c64394f431175138tuexen uint32_t vrf_id; 75427a9f1edd34bf82c194a2f9d0c64394f431175138tuexen struct sctp_inpcb *inp; 75437a9f1edd34bf82c194a2f9d0c64394f431175138tuexen struct sctp_tcb *stcb = NULL; 75447a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 75457a9f1edd34bf82c194a2f9d0c64394f431175138tuexen inp = (struct sctp_inpcb *)so->so_pcb; 75467a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (inp == NULL) { 75477a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* I made the same as TCP since we are not setup? */ 75487a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 75497a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (ECONNRESET); 75507a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 75517a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (addr == NULL) { 75527a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 75537a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return EINVAL; 75547a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 75557a9f1edd34bf82c194a2f9d0c64394f431175138tuexen switch (addr->sa_family) { 7556f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef INET 7557f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t case AF_INET: 7558f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 7559f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t if (addr->sa_len != sizeof(struct sockaddr_in)) { 75607a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 75617a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EINVAL); 75627a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 7563f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#endif 75647a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 75657a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 7566f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef INET6 7567f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t case AF_INET6: 7568f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 7569f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t if (addr->sa_len != sizeof(struct sockaddr_in6)) { 75707a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 75717a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EINVAL); 75727a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 7573f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#endif 75747a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 75757a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 75767a9f1edd34bf82c194a2f9d0c64394f431175138tuexen case AF_CONN: 7577f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 75787a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (addr->sa_len != sizeof(struct sockaddr_conn)) { 75797a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 75807a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EINVAL); 75817a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 7582f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#endif 75837a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 75847a9f1edd34bf82c194a2f9d0c64394f431175138tuexen default: 75857a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 7586e2828360ea9cf8951730d46f5c14626c9425cb30t return (EAFNOSUPPORT); 75877a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 75887a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_INCR_REF(inp); 75897a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_ASOC_CREATE_LOCK(inp); 75907a9f1edd34bf82c194a2f9d0c64394f431175138tuexen create_lock_on = 1; 75917a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 75927a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 75937a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 75947a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 75957a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Should I really unlock ? */ 75967a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 75977a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EFAULT; 75987a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 75997a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76007a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#ifdef INET6 76017a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 76027a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (addr->sa_family == AF_INET6)) { 76037a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 76047a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EINVAL; 76057a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 76067a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76077a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 76087a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == SCTP_PCB_FLAGS_UNBOUND) { 76097a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Bind a ephemeral port */ 76107a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = sctp_inpcb_bind(so, NULL, NULL, p); 76117a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (error) { 76127a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 76137a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76147a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76157a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Now do we connect? */ 76167a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 76177a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 76187a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 76197a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EINVAL; 76207a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 76217a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76227a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 76237a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 76247a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* We are already connected AND the TCP model */ 76257a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 76267a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EADDRINUSE; 76277a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 76287a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76297a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 76307a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_RLOCK(inp); 76317a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 76327a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_RUNLOCK(inp); 76337a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } else { 76347a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* We increment here since sctp_findassociation_ep_addr() will 76357a9f1edd34bf82c194a2f9d0c64394f431175138tuexen * do a decrement if it finds the stcb as long as the locked 76367a9f1edd34bf82c194a2f9d0c64394f431175138tuexen * tcb (last argument) is NOT a TCB.. aka NULL. 76377a9f1edd34bf82c194a2f9d0c64394f431175138tuexen */ 76387a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_INCR_REF(inp); 76397a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 76407a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb == NULL) { 76417a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_DECR_REF(inp); 76427a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } else { 76437a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_TCB_UNLOCK(stcb); 76447a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76457a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76467a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb != NULL) { 76477a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Already have or am bring up an association */ 76487a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 76497a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EALREADY; 76507a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 76517a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76527a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 76537a9f1edd34bf82c194a2f9d0c64394f431175138tuexen vrf_id = inp->def_vrf_id; 76547a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#ifdef SCTP_MVRF 76557a9f1edd34bf82c194a2f9d0c64394f431175138tuexen for (i = 0; i < inp->num_vrfs; i++) { 76567a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (vrf_id == inp->m_vrf_ids[i]) { 76577a9f1edd34bf82c194a2f9d0c64394f431175138tuexen fnd = 1; 76587a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 76597a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76607a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76617a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (!fnd) { 76627a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 76637a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EINVAL; 76647a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 76657a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76667a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 76677a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* We are GOOD to go */ 76687a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p); 76697a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb == NULL) { 76707a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Gak! no memory */ 76717a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 76727a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76737a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 76747a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 76757a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Set the connected flag so we can queue data */ 76767a9f1edd34bf82c194a2f9d0c64394f431175138tuexen soisconnecting(so); 76777a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76787a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 76797a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 76807a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 76817a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* initialize authentication parameters for the assoc */ 76827a9f1edd34bf82c194a2f9d0c64394f431175138tuexen sctp_initialize_auth_params(inp, stcb); 76837a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 76847a9f1edd34bf82c194a2f9d0c64394f431175138tuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 76857a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_TCB_UNLOCK(stcb); 76867a9f1edd34bf82c194a2f9d0c64394f431175138tuexen out_now: 76877a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (create_lock_on) { 76887a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 76897a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 76907a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 76917a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_DECR_REF(inp); 76927a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (error); 76937a9f1edd34bf82c194a2f9d0c64394f431175138tuexen} 76947a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 76958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 76968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 76978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 700000 76988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, int backlog, struct thread *p) 76998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 77008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, struct thread *p) 77018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 77038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, int backlog, PKTHREAD p) 77048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Userspace__) 77058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, int backlog, struct proc *p) 77068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 77078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, struct proc *p) 77088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 77108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 77118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Note this module depends on the protocol processing being called 77128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * AFTER any socket level flags and backlog are applied to the 77138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * socket. The traditional way that the socket flags are applied is 77148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * AFTER protocol processing. We have made a change to the 77158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sys/kern/uipc_socket.c module to reverse this but this MUST be in 77168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * place if the socket API for SCTP is to work properly. 77178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 77188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 77208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 7721000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 77228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 77232fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 77248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* I made the same as TCP since we are not setup? */ 77258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 77268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 77278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) { 77298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* See if we have a listener */ 77308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *tinp; 7731828732282b383285a904f1cdcdaa2e633b2eb38at union sctp_sockstore store; 77328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 77348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not bound all */ 77358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 77368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 77388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&store, &laddr->ifa->address, sizeof(store)); 7739828732282b383285a904f1cdcdaa2e633b2eb38at switch (store.sa.sa_family) { 77408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 77418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 7742828732282b383285a904f1cdcdaa2e633b2eb38at store.sin.sin_port = inp->sctp_lport; 77438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 77448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 77468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 7747828732282b383285a904f1cdcdaa2e633b2eb38at store.sin6.sin6_port = inp->sctp_lport; 77488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 77498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 775075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 775175cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 7752828732282b383285a904f1cdcdaa2e633b2eb38at store.sconn.sconn_port = inp->sctp_lport; 775375cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 775475cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 77558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 77568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 77578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 7758828732282b383285a904f1cdcdaa2e633b2eb38at tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); 77598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tinp && (tinp != inp) && 77608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 77618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 77628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tinp->sctp_socket->so_qlimit)) { 77638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we have a listener already and its not this inp. */ 77648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(tinp); 77658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 77668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (tinp) { 77678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(tinp); 77688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 77718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Setup a local addr bound all */ 77728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(&store, 0, sizeof(store)); 77738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 77748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 77758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_family = AF_INET6; 7776f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 77778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_len = sizeof(struct sockaddr_in6); 77788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7781828732282b383285a904f1cdcdaa2e633b2eb38at#if defined(__Userspace__) 7782828732282b383285a904f1cdcdaa2e633b2eb38at if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) { 7783828732282b383285a904f1cdcdaa2e633b2eb38at store.sa.sa_family = AF_CONN; 7784828732282b383285a904f1cdcdaa2e633b2eb38at#ifdef HAVE_SA_LEN 7785828732282b383285a904f1cdcdaa2e633b2eb38at store.sa.sa_len = sizeof(struct sockaddr_conn); 7786828732282b383285a904f1cdcdaa2e633b2eb38at#endif 7787828732282b383285a904f1cdcdaa2e633b2eb38at } 7788828732282b383285a904f1cdcdaa2e633b2eb38at#endif 77898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 7790828732282b383285a904f1cdcdaa2e633b2eb38at#if defined(__Userspace__) 7791828732282b383285a904f1cdcdaa2e633b2eb38at if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 7792828732282b383285a904f1cdcdaa2e633b2eb38at ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) == 0)) { 7793828732282b383285a904f1cdcdaa2e633b2eb38at#else 77948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 7795828732282b383285a904f1cdcdaa2e633b2eb38at#endif 77968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_family = AF_INET; 7797f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 77988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_len = sizeof(struct sockaddr_in); 77998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7802828732282b383285a904f1cdcdaa2e633b2eb38at switch (store.sa.sa_family) { 7803828732282b383285a904f1cdcdaa2e633b2eb38at#ifdef INET 7804828732282b383285a904f1cdcdaa2e633b2eb38at case AF_INET: 7805828732282b383285a904f1cdcdaa2e633b2eb38at store.sin.sin_port = inp->sctp_lport; 7806828732282b383285a904f1cdcdaa2e633b2eb38at break; 7807828732282b383285a904f1cdcdaa2e633b2eb38at#endif 7808828732282b383285a904f1cdcdaa2e633b2eb38at#ifdef INET6 7809828732282b383285a904f1cdcdaa2e633b2eb38at case AF_INET6: 7810828732282b383285a904f1cdcdaa2e633b2eb38at store.sin6.sin6_port = inp->sctp_lport; 7811828732282b383285a904f1cdcdaa2e633b2eb38at break; 7812828732282b383285a904f1cdcdaa2e633b2eb38at#endif 7813828732282b383285a904f1cdcdaa2e633b2eb38at#if defined(__Userspace__) 7814828732282b383285a904f1cdcdaa2e633b2eb38at case AF_CONN: 7815828732282b383285a904f1cdcdaa2e633b2eb38at store.sconn.sconn_port = inp->sctp_lport; 7816828732282b383285a904f1cdcdaa2e633b2eb38at break; 7817828732282b383285a904f1cdcdaa2e633b2eb38at#endif 7818828732282b383285a904f1cdcdaa2e633b2eb38at default: 7819828732282b383285a904f1cdcdaa2e633b2eb38at break; 7820828732282b383285a904f1cdcdaa2e633b2eb38at } 7821828732282b383285a904f1cdcdaa2e633b2eb38at tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id); 78228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tinp && (tinp != inp) && 78238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 78248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 78258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tinp->sctp_socket->so_qlimit)) { 78268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we have a listener already and its not this inp. */ 78278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(tinp); 78288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 78298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (tinp) { 78308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 78318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 78358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOCK_LOGGING 78368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) { 78378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK); 78388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_LOCK(so); 78418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Userspace__) 78428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = solisten_proto_check(so); 78438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 78448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 78458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 78468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 78478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) && 78508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 78518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* The unlucky case 78528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - We are in the tcp pool with this guy. 78538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - Someone else is in the main inp slot. 78548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - We must move this guy (the listener) to the main slot 78558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - We must then move the guy that was listener to the TCP Pool. 78568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 78578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_swap_inpcb_for_listen(inp)) { 78588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto in_use; 78598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 78628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 78638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 78648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are already connected AND the TCP model */ 78658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in_use: 78668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 78678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 78688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 78698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 78708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 78728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 78738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We must do a bind. */ 78748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 78758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((error = sctp_inpcb_bind(so, NULL, NULL, p))) { 78768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* bind error, probably perm */ 78778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 78788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_LOCK(so); 7880000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 78818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__) || defined(__Userspace__) 78828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 700000 || defined(__Windows__) || defined(__Userspace__) 78838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It appears for 7.0 and on, we must always call this. */ 78848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen solisten_proto(so, backlog); 78858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 78868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) == 0) { 78878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen solisten_proto(so); 78888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 78928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* remove the ACCEPTCONN flag for one-to-many sockets */ 7893907b9e7d7c75f02c3d1f6c70016127990e8fe648t#if defined(__Userspace__) 78946435cc0024abc9f2dabba9feb634081e246d342bt so->so_options &= ~SCTP_SO_ACCEPTCONN; 7895907b9e7d7c75f02c3d1f6c70016127990e8fe648t#else 78968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_options &= ~SO_ACCEPTCONN; 7897907b9e7d7c75f02c3d1f6c70016127990e8fe648t#endif 78988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 700000 || defined(__Windows__) || defined(__Userspace__) 79018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (backlog == 0) { 79028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* turning off listen */ 7903907b9e7d7c75f02c3d1f6c70016127990e8fe648t#if defined(__Userspace__) 7904907b9e7d7c75f02c3d1f6c70016127990e8fe648t so->so_options &= ~SCTP_SO_ACCEPTCONN; 7905907b9e7d7c75f02c3d1f6c70016127990e8fe648t#else 79068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_options &= ~SO_ACCEPTCONN; 7907907b9e7d7c75f02c3d1f6c70016127990e8fe648t#endif 79088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 79118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 79128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 79138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int sctp_defered_wakeup_cnt = 0; 79158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 79178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 79188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_accept(struct socket *so, struct sockaddr **addr) 79198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 79208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 79218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_accept(struct socket *so, struct sockaddr *addr, int *namelen, 79228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *accept_info, int *accept_info_len) 79238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 79248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 79258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_accept(struct socket *so, struct mbuf *nam) 79268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 79278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 79288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 79308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 79318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen union sctp_sockstore store; 79328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 79338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 79348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error; 79358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 79368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 79388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79392fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 79408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 79418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 79428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 79448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 79458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 79468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 79478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EOPNOTSUPP); 79488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_state & SS_ISDISCONNECTED) { 79508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 79518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ECONNABORTED); 79528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNABORTED); 79538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 79558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 79568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 79578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 79588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 79598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 79618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 79628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store = stcb->asoc.primary_destination->ro._l_addr; 79638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE; 79648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 79658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (store.sa.sa_family) { 79668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 79678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 79688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 79698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 79708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 79728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 79738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin == NULL) 79748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 79758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 79768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)addr; 79778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero((caddr_t)sin, sizeof(*sin)); 79788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_family = AF_INET; 79807b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 79818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_len = sizeof(*sin); 79828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79837988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin->sin_port = store.sin.sin_port; 79847988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin->sin_addr = store.sin.sin_addr; 79858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 79868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *addr = (struct sockaddr *)sin; 79878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif !defined(__Panda__) 79888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin); 79898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 79948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 79958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 79968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 79978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 79998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); 80008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin6 == NULL) 80018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 80028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 80038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)addr; 80048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero((caddr_t)sin6, sizeof(*sin6)); 80058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_family = AF_INET6; 80077b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 80088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_len = sizeof(*sin6); 80098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80107988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin6->sin6_port = store.sin6.sin6_port; 80117988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin6->sin6_addr = store.sin6.sin6_addr; 80128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 80138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 80148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((error = sa6_recoverscope(sin6)) != 0) { 80158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin6); 80168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 80178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 80188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 80198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) 80208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 80218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sin6->sin6_scope_id = 80228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ntohs(sin6->sin6_addr.s6_addr16[1]); 80238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 80248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_recoverscope(sin6, &sin6->sin6_addr, NULL); /* skip ifp check */ 80258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 80268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_scope_id = 0; /* XXX */ 80278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 80288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 80290612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 80308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *addr = (struct sockaddr *)sin6; 80318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif !defined(__Panda__) 80328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin6); 80338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 80358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 80368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80377988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 80387988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 80397988ea8f0c067cf3757e798b473b1ae4d34b6dfdt { 80407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt struct sockaddr_conn *sconn; 80417988ea8f0c067cf3757e798b473b1ae4d34b6dfdt 80427988ea8f0c067cf3757e798b473b1ae4d34b6dfdt SCTP_MALLOC_SONAME(sconn, struct sockaddr_conn *, sizeof(struct sockaddr_conn)); 80437988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (sconn == NULL) { 80447988ea8f0c067cf3757e798b473b1ae4d34b6dfdt return (ENOMEM); 80457988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 80467988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_family = AF_CONN; 80477988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef HAVE_SCONN_LEN 80487988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_len = sizeof(struct sockaddr_conn); 80497988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 80507988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_port = store.sconn.sconn_port; 80517988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_addr = store.sconn.sconn_addr; 80527988ea8f0c067cf3757e798b473b1ae4d34b6dfdt *addr = (struct sockaddr *)sconn; 80537988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 80547988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 80557988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 80568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 80578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TSNH */ 80588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 80598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 80608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Wake any delayed sleep action */ 80618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { 80628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 80638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE; 80648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) { 80658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; 80668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 80678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&inp->sctp_socket->so_snd); 80688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sowriteable(inp->sctp_socket)) { 80698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 80708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*__Userspace__ calling sowwakup_locked because of SOCKBUF_LOCK above. */ 80718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) 80738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sowwakeup_locked(inp->sctp_socket); 80748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 80758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 80768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* socket is locked */ 80778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sowwakeup(inp->sctp_socket); 80798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 80818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd); 80828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 80838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 80848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 80858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) { 80868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; 80878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 80888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&inp->sctp_socket->so_rcv); 80898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (soreadable(inp->sctp_socket)) { 80908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_defered_wakeup_cnt++; 80918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 80928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*__Userspace__ calling sorwakup_locked because of SOCKBUF_LOCK above */ 80938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 80948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) 80958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sorwakeup_locked(inp->sctp_socket); 80968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 80978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 80988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* socket is locked */ 80998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 81008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sorwakeup(inp->sctp_socket); 81018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 81028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 81038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv); 81048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 81068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 81088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 81108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 81118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_7); 81128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 81148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 81158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 81168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 81178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 81188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 81198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ingetaddr(struct socket *so, struct sockaddr **addr) 81208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 81218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 81228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 81238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ingetaddr(struct socket *so, struct sockaddr *addr) 81248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 81258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = (struct sockaddr_in *)addr; 81268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 81278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ingetaddr(struct socket *so, struct mbuf *nam) 81288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 81298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 81308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 81318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 81328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 81338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *sctp_ifa; 81348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 81358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 81368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Do the malloc first in case it blocks. 81378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 81388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 81398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 81408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin == NULL) 81418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 81428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 81438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero(sin, sizeof(*sin)); 81448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 81458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin); 81468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(sin, 0, sizeof(*sin)); 81478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 81488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_family = AF_INET; 81497b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 81508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_len = sizeof(*sin); 81518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 81528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 81538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!inp) { 81548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 81558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 81568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 81578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 8158b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ECONNRESET); 81598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 81618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_port = inp->sctp_lport; 81628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 81638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 81648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 81658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin_a; 81668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 81678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int fnd; 81688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 81698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 81708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 81718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto notConn; 81728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 0; 81748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_a = NULL; 81758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 81768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 81778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_a = (struct sockaddr_in *)&net->ro._l_addr; 81788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin_a == NULL) 81798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* this will make coverity happy */ 81808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 81818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 81828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin_a->sin_family == AF_INET) { 81838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 81848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 81858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((!fnd) || (sin_a == NULL)) { 81888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* punt */ 81898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 81908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto notConn; 81918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 81928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 81938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 81948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ifa = sctp_source_address_selection(inp, 81958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb, 81968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_route_t *)&net->ro, 81978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net, 0, vrf_id); 81988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_ifa) { 81998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr = sctp_ifa->address.sin.sin_addr; 82008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_ifa(sctp_ifa); 82018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 82038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 82048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* For the bound all case you get back 0 */ 82058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen notConn: 82068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr.s_addr = 0; 82078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 82098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 82108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Take the first IPv4 address in the list */ 82118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 82128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int fnd = 0; 82138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 82148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 82158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (laddr->ifa->address.sa.sa_family == AF_INET) { 82168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin_a; 82178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 8218bfb1bf7e665a02b48026482bf33d05c83dfad73bt sin_a = &laddr->ifa->address.sin; 82198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr = sin_a->sin_addr; 82208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 82218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 82228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 82258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 82268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 82278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 82288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 82298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 8230b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ENOENT); 82318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 82348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 82358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*addr) = (struct sockaddr *)sin; 82368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 82378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 82388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 82398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 82408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 82418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 82428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_peeraddr(struct socket *so, struct sockaddr **addr) 82438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 8244845436a72b5767f30403c3b77c457488703143a9tuexen struct sockaddr_in *sin; 82458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 82468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_peeraddr(struct socket *so, struct sockaddr *addr) 82478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 82488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = (struct sockaddr_in *)addr; 82498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 82508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_peeraddr(struct socket *so, struct mbuf *nam) 82518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 82528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 82538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 82548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 82558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int fnd; 82568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin_a; 82578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 82588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 82598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 82608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 82618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Do the malloc first in case it blocks. */ 82628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 82638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 82648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin == NULL) 82658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 82668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 82678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(sin, 0, sizeof(*sin)); 82688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 82698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin); 82708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(sin, 0, sizeof(*sin)); 82718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 82728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_family = AF_INET; 82737b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 82748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_len = sizeof(*sin); 82758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 82768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 82778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 8278b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((inp == NULL) || 8279b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) { 8280b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen /* UDP type and listeners will drop out here */ 82818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 82828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 82838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 8284b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 8285b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ENOTCONN); 82868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 82888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 82898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 82908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 82918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 82928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 82938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 82948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 82958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 82968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 82978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 8298b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ECONNRESET); 82998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 83008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 0; 83018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 83028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_a = (struct sockaddr_in *)&net->ro._l_addr; 83038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin_a->sin_family == AF_INET) { 83048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 83058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_port = stcb->rport; 83068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr = sin_a->sin_addr; 83078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 83088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 83098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 83108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 83118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 83128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* No IPv4 address */ 83138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 83148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 83158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 83168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 8317b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ENOENT); 83188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 83198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 83208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*addr) = (struct sockaddr *)sin; 83218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 83228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 83238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 83248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 83258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 83268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct pr_usrreqs sctp_usrreqs = { 83277fbcb406549bdf370031d2ad5befb44e39b95ffft#if defined(__FreeBSD__) 83288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_abort = sctp_abort, 83298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_accept = sctp_accept, 83308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_attach = sctp_attach, 83318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_bind = sctp_bind, 83328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_connect = sctp_connect, 83338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_control = in_control, 83348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 690000 83358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_close = sctp_close, 83368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_detach = sctp_close, 83378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sopoll = sopoll_generic, 83388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_flush = sctp_flush, 83398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 83408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_detach = sctp_detach, 83418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sopoll = sopoll, 83428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 83438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_disconnect = sctp_disconnect, 83448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_listen = sctp_listen, 83458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_peeraddr = sctp_peeraddr, 83468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_send = sctp_sendm, 83478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_shutdown = sctp_shutdown, 83488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sockaddr = sctp_ingetaddr, 83498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sosend = sctp_sosend, 83508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_soreceive = sctp_soreceive 83517fbcb406549bdf370031d2ad5befb44e39b95ffft#elif defined(__APPLE__) 83527fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_abort = sctp_abort, 83537fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_accept = sctp_accept, 83547fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_attach = sctp_attach, 83557fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_bind = sctp_bind, 83567fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_connect = sctp_connect, 83577fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_connect2 = pru_connect2_notsupp, 83587fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_control = in_control, 83597fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_detach = sctp_detach, 83607fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_disconnect = sctp_disconnect, 83617fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_listen = sctp_listen, 83627fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_peeraddr = sctp_peeraddr, 83637fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_rcvd = NULL, 83647fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_rcvoob = pru_rcvoob_notsupp, 83657fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_send = sctp_sendm, 83667fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sense = pru_sense_null, 83677fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_shutdown = sctp_shutdown, 83687fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sockaddr = sctp_ingetaddr, 83697fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sosend = sctp_sosend, 83707fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_soreceive = sctp_soreceive, 83717fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sopoll = sopoll 83727fbcb406549bdf370031d2ad5befb44e39b95ffft#elif defined(__Windows__) 83738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_abort, 83748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_accept, 83758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_attach, 83768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_bind, 83778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_connect, 83788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pru_connect2_notsupp, 83798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 83808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 83818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_disconnect, 83828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_listen, 83838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_peeraddr, 83848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 83858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pru_rcvoob_notsupp, 83868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 83878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pru_sense_null, 83888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_shutdown, 83898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_flush, 83908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ingetaddr, 83918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sosend, 83928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_soreceive, 83938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sopoll_generic, 83948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 83958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_close 83968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 83978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}; 83988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif !defined(__Panda__) && !defined(__Userspace__) 83998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 84008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_usrreq(so, req, m, nam, control) 84018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 84028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int req; 84038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m, *nam, *control; 84048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 84058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct proc *p = curproc; 84068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 84078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_vrf *vrf; 84088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error; 84098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int family; 84108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp = (struct sctp_inpcb *)so->so_pcb; 84118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 84128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 84138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen family = so->so_proto->pr_domain->dom_family; 84148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (req == PRU_CONTROL) { 84158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (family) { 84168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PF_INET: 84178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = in_control(so, (long)m, (caddr_t)nam, 8418b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen (struct ifnet *)control); 84198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 84218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PF_INET6: 84228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = in6_control(so, (long)m, (caddr_t)nam, 84238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct ifnet *)control, p); 84248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 84268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 84278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 84288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 84298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 84308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 84318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 84328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (req) { 84338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_ATTACH: 84348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_attach(so, family, p); 84358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_DETACH: 84378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_detach(so); 84388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_BIND: 84408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) { 84418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 84428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 84438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 84448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_bind(so, nam, p); 84458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_LISTEN: 84478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_listen(so, p); 84488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_CONNECT: 84508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) { 84518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 84528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 84538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 84548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_connect(so, nam, p); 84558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_DISCONNECT: 84578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_disconnect(so); 84588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_ACCEPT: 84608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) { 84618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 84628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 84638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 84648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_accept(so, nam); 84658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SHUTDOWN: 84678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_shutdown(so); 84688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 84708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_RCVD: 84718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 84728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For Open and Net BSD, this is real ugly. The mbuf *nam 84738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * that is passed (by soreceive()) is the int flags c ast as 84748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a (mbuf *) yuck! 84758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 84768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 84788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SEND: 84798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Flags are ignored */ 84808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 84818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr; 84828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 84838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) 84848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr = NULL; 84858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 84868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr = mtod(nam, struct sockaddr *); 84878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 84888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_sendm(so, 0, m, addr, control, p); 84898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 84908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_ABORT: 84928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_abort(so); 84938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 84958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SENSE: 84968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 84978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 84988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_RCVOOB: 84998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 85008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 85018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 85028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SENDOOB: 85038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 85048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 85058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 85068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_PEERADDR: 85078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_peeraddr(so, nam); 85088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 85098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SOCKADDR: 85108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_ingetaddr(so, nam); 85118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 85128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SLOWTIMO: 85138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 85148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 85158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 85168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 85178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 85188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 85198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 85208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 85218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 85228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 852360416fb97d019e56677da96dbdac6d48048822d3tuexen 852432a191a90b5c914a02047389c5b3197e08fc9841tuexen#if defined(__Userspace__) 852560416fb97d019e56677da96dbdac6d48048822d3tuexenint 8526d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenregister_recv_cb(struct socket *so, 8527d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data, 8528d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info)) 852960416fb97d019e56677da96dbdac6d48048822d3tuexen{ 8530d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen struct sctp_inpcb *inp; 853160416fb97d019e56677da96dbdac6d48048822d3tuexen 853260416fb97d019e56677da96dbdac6d48048822d3tuexen inp = (struct sctp_inpcb *) so->so_pcb; 853332a191a90b5c914a02047389c5b3197e08fc9841tuexen if (inp == NULL) { 853432a191a90b5c914a02047389c5b3197e08fc9841tuexen return (0); 853532a191a90b5c914a02047389c5b3197e08fc9841tuexen } 853632a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WLOCK(inp); 853760416fb97d019e56677da96dbdac6d48048822d3tuexen inp->recv_callback = receive_cb; 853832a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WUNLOCK(inp); 8539f57cf83923be449d11806a31f62bcc17e58832d6t return (1); 854060416fb97d019e56677da96dbdac6d48048822d3tuexen} 854160416fb97d019e56677da96dbdac6d48048822d3tuexen 854260416fb97d019e56677da96dbdac6d48048822d3tuexenint 8543d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenregister_send_cb(struct socket *so, uint32_t sb_threshold, int (*send_cb)(struct socket *sock, uint32_t sb_free)) 854460416fb97d019e56677da96dbdac6d48048822d3tuexen{ 8545d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen struct sctp_inpcb *inp; 854660416fb97d019e56677da96dbdac6d48048822d3tuexen 854760416fb97d019e56677da96dbdac6d48048822d3tuexen inp = (struct sctp_inpcb *) so->so_pcb; 854832a191a90b5c914a02047389c5b3197e08fc9841tuexen if (inp == NULL) { 854932a191a90b5c914a02047389c5b3197e08fc9841tuexen return (0); 855032a191a90b5c914a02047389c5b3197e08fc9841tuexen } 855132a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WLOCK(inp); 855260416fb97d019e56677da96dbdac6d48048822d3tuexen inp->send_callback = send_cb; 855360416fb97d019e56677da96dbdac6d48048822d3tuexen inp->send_sb_threshold = sb_threshold; 855432a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WUNLOCK(inp); 855560416fb97d019e56677da96dbdac6d48048822d3tuexen /* FIXME change to current amount free. This will be the full buffer 855660416fb97d019e56677da96dbdac6d48048822d3tuexen * the first time this is registered but it could be only a portion 855760416fb97d019e56677da96dbdac6d48048822d3tuexen * of the send buffer if this is called a second time e.g. if the 855860416fb97d019e56677da96dbdac6d48048822d3tuexen * threshold changes. 855960416fb97d019e56677da96dbdac6d48048822d3tuexen */ 8560f57cf83923be449d11806a31f62bcc17e58832d6t return (1); 856160416fb97d019e56677da96dbdac6d48048822d3tuexen} 8562d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen 8563d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenint 8564d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenregister_ulp_info (struct socket *so, void *ulp_info) 8565d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen{ 8566d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen struct sctp_inpcb *inp; 8567d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen 8568d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen inp = (struct sctp_inpcb *) so->so_pcb; 8569d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen if (inp == NULL) { 8570d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen return (0); 8571d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen } 8572d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen SCTP_INP_WLOCK(inp); 8573d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen inp->ulp_info = ulp_info; 8574d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen SCTP_INP_WUNLOCK(inp); 8575f57cf83923be449d11806a31f62bcc17e58832d6t return (1); 8576d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen} 857760416fb97d019e56677da96dbdac6d48048822d3tuexen#endif 8578