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> 358f9e45fea288542b24a6bda01269c6fc184d991at__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 263237 2014-03-16 12:32:16Z 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> 590612043f643c9b26245564c05defca64d472060etuexen#if !defined(__Userspace_os_Windows) 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#endif 39714ba474e7d8520db1b04d650c6a788bdc5dab9e0tuexen#endif 3988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 3998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenvoid 4008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_notify(struct sctp_inpcb *inp, 4018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct ip *ip, 4028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctphdr *sh, 4038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *to, 4048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 4058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net) 4068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 4070612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 4098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct icmp *icmph; 4128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41347674b651417d493ff4e0318113fd7beeef119dbtuexen /* protection */ 4148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 4158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sh == NULL) || (to == NULL)) { 4168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 4178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 4198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* First job is to verify the vtag matches what I would send */ 4218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 4228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 4248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen icmph = (struct icmp *)((caddr_t)ip - (sizeof(struct icmp) - 4278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct ip))); 4288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (icmph->icmp_type != ICMP_UNREACH) { 4298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We only care about unreachable */ 4308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return; 4328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((icmph->icmp_code == ICMP_UNREACH_NET) || 4348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_HOST) || 4358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_NET_UNKNOWN) || 4368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_HOST_UNKNOWN) || 4378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_ISOLATED) || 4388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_NET_PROHIB) || 4398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_HOST_PROHIB) || 44022a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Panda__) 4418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_ADMIN)) { 44222a33a1debfe70529be4aa018a2912bfe5dcd8dat#elif defined(__Userspace_os_NetBSD) 44322a33a1debfe70529be4aa018a2912bfe5dcd8dat (icmph->icmp_code == ICMP_UNREACH_ADMIN_PROHIBIT)) { 4448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 4458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_FILTER_PROHIB)) { 4468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 4498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Hmm reachablity problems we must examine closely. If its 4508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * not reachable, we may have lost a network. Or if there is 4518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NO protocol at the other end named SCTP. well we consider 4528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * it a OOTB abort. 4538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 4548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 4558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Ok that destination is NOT reachable */ 4568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 4578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 4588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 45947674b651417d493ff4e0318113fd7beeef119dbtuexen stcb, 0, 4608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void *)net, SCTP_SO_NOT_LOCKED); 4618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if ((icmph->icmp_code == ICMP_UNREACH_PROTOCOL) || 4648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (icmph->icmp_code == ICMP_UNREACH_PORT)) { 4658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 4668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Here the peer is either playing tricks on us, 4678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * including an address that belongs to someone who 4688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * does not support SCTP OR was a userland 4698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * implementation that shutdown and now is dead. In 4708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * either case treat it like a OOTB abort with no 4718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * TCB 4728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 47347674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED); 4740612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so = SCTP_INP_SO(inp); 4768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_add_int(&stcb->asoc.refcnt, 1); 4778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_LOCK(so, 1); 4798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 4808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 4818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_2); 4830612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 4848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SOCKET_UNLOCK(so, 1); 4858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed.*/ 4868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 4878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no need to unlock here, since the TCB is gone */ 4888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 4898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 4908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 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 16798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)&sctp_ifa->address.sa; 16808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr == 0) { 16818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 16828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we skip unspecifed 16838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * addresses 16848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 16858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 16868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((ipv4_local_scope == 0) && 16888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 16898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 16908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 16918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 16928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 16938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas); 16948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 16958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6)); 16968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sizeof(struct sockaddr_in6); 16978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 16988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 16998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(sas, sin, sizeof(*sin)); 17008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 17018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin)); 17028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sizeof(*sin); 17038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 17048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (actual >= limit) { 17078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 17088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 17108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 17158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 17168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ipv6_addr_legal) { 17178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 17188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 17198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME) 17208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 lsa6; 17218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa; 17238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 17248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * we skip unspecifed 17268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * addresses 17278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 17318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (local_scope == 0) 17328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 17348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin6->sin6_scope_id == 0) { 17358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 17368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa6_recoverscope(sin6) != 0) 17378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bad link 17398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * local 17408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * address 17418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 17448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen lsa6 = *sin6; 17458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (in6_recoverscope(&lsa6, 17468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &lsa6.sin6_addr, 17478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL)) 17488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 17498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bad link 17508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * local 17518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * address 17528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 17538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = &lsa6; 17558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 17568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 17588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((site_scope == 0) && 17608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 17618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(sas, sin6, sizeof(*sin6)); 17647988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 17658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6)); 17668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sizeof(*sin6); 17678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (actual >= limit) { 17688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 17698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 17718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 17728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 17757988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 17767988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 17777988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (conn_addr_legal) { 17787988ea8f0c067cf3757e798b473b1ae4d34b6dfdt memcpy(sas, &sctp_ifa->address.sconn, sizeof(struct sockaddr_conn)); 17797988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_conn *)sas)->sconn_port = inp->sctp_lport; 17807988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_conn)); 17817988ea8f0c067cf3757e798b473b1ae4d34b6dfdt actual += sizeof(struct sockaddr_conn); 17827988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (actual >= limit) { 17837988ea8f0c067cf3757e798b473b1ae4d34b6dfdt return (actual); 17847988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 17857988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } else { 17867988ea8f0c067cf3757e798b473b1ae4d34b6dfdt continue; 17877988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 17887988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 17898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 17908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TSNH */ 17918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 17928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 17958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 17968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 1797f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifndef HAVE_SA_LEN 17988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t sa_len = 0; 17998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18007988ea8f0c067cf3757e798b473b1ae4d34b6dfdt 18018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 18028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 18038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_addr_restricted(stcb, laddr->ifa)) { 18048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 18058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_fill_user_address(sas, &laddr->ifa->address.sa)) 18088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 18097988ea8f0c067cf3757e798b473b1ae4d34b6dfdt switch (laddr->ifa->address.sa.sa_family) { 18107988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET 18117988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET: 18127988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; 18137988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18157988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET6 18167988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET6: 18177988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; 18187988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18197988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18207988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 18217988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 18227988ea8f0c067cf3757e798b473b1ae4d34b6dfdt ((struct sockaddr_conn *)sas)->sconn_port = inp->sctp_lport; 18237988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18247988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18257988ea8f0c067cf3757e798b473b1ae4d34b6dfdt default: 18267988ea8f0c067cf3757e798b473b1ae4d34b6dfdt /* TSNH */ 18277988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18287988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 1829f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 18308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + 18318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen laddr->ifa->address.sa.sa_len); 18328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += laddr->ifa->address.sa.sa_len; 18338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 18347988ea8f0c067cf3757e798b473b1ae4d34b6dfdt switch (laddr->ifa->address.sa.sa_family) { 18357988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET 18367988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET: 18377988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sa_len = sizeof(struct sockaddr_in); 18387988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18397988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef INET6 18417988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_INET6: 18427988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sa_len = sizeof(struct sockaddr_in6); 18437988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18447988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18457988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 18467988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 18477988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sa_len = sizeof(struct sockaddr_conn); 18487988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18497988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 18507988ea8f0c067cf3757e798b473b1ae4d34b6dfdt default: 18517988ea8f0c067cf3757e798b473b1ae4d34b6dfdt /* TSNH */ 18527988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 18537988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 18548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + sa_len); 18558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual += sa_len; 18568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (actual >= limit) { 18588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 18598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (actual); 18638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 18648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 18658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic size_t 18668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_fill_up_addresses(struct sctp_inpcb *inp, 18678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb, 18688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t limit, 18698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_storage *sas) 18708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 18718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size = 0; 18728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 18738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t id; 18748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 18768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RLOCK(); 18778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 18788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 18798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * FIX ME: ?? this WILL report duplicate addresses if they appear 18808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * in more than one VRF. 18818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 18828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* fill up addresses for all VRFs on the endpoint */ 18838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (id = 0; (id < inp->num_vrfs) && (size < limit); id++) { 18848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sctp_fill_up_addresses_vrf(inp, stcb, limit, sas, 18858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids[id]); 18868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + size); 18878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 18888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 18898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* fill up addresses for the endpoint's default vrf */ 18908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_fill_up_addresses_vrf(inp, stcb, limit, sas, 18918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_vrf_id); 18928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 18938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 18948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (size); 18958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 18968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 18978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 18988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NOTE: assumes addr lock is held 18998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 19018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id) 19028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 19038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int cnt = 0; 19048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_vrf *vrf = NULL; 19058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 19078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * In both sub-set bound an bound_all cases we return the MAXIMUM 19088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * number of addresses that you COULD get. In reality the sub-set 19098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bound may have an exclusion list for a given TCB OR in the 19108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * bound-all case a TCB may NOT include the loopback or other 19118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * addresses as well. 19128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf = sctp_find_vrf(vrf_id); 19148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf == NULL) { 19158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 19168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 19188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifn *sctp_ifn; 19198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *sctp_ifa; 19208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 19228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 19238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Count them if they are the right type */ 19248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sctp_ifa->address.sa.sa_family) { 19258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 19268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 19278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 19288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 19308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in); 19318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 19348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 19358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19387988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 19397988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 19407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt cnt += sizeof(struct sockaddr_conn); 19417988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 19427988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 19438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 19448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 19498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 19508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 19528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (laddr->ifa->address.sa.sa_family) { 19538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 19548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 19558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp,SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) 19568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 19588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in); 19598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 19628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 19638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sizeof(struct sockaddr_in6); 19648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 196675cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 196775cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 196875cd23222c96d5ebe5a9082c57a263f917f1462btuexen cnt += sizeof(struct sockaddr_conn); 196975cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 197075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 19718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 19728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 19738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (cnt); 19778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 19788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 19808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_count_max_addresses(struct sctp_inpcb *inp) 19818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 19828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int cnt = 0; 19838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 19848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int id; 19858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 19868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 19878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RLOCK(); 19888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 19898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen/* 19908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * FIX ME: ?? this WILL count duplicate addresses if they appear 19918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * in more than one VRF. 19928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 19938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* count addresses for all VRFs on the endpoint */ 19948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (id = 0; id < inp->num_vrfs; id++) { 19958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt += sctp_count_max_addresses_vrf(inp, inp->m_vrf_ids[id]); 19968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 19978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 19988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* count addresses for the endpoint's default VRF */ 19998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = sctp_count_max_addresses_vrf(inp, inp->def_vrf_id); 20008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 20018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_IPI_ADDR_RUNLOCK(); 20028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (cnt); 20038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 20048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 20068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval, 20078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t optsize, void *p, int delay) 20088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 20098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 20108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int creat_lock_on = 0; 20118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 20128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 20138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr; 20148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 2015b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int bad_addresses = 0; 20168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_assoc_t *a_id; 20178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_PCB1, "Connectx called\n"); 20198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 20218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 20228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are already connected AND the TCP model */ 20238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 20248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 20258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 20288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 20298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 2030b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 20318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 20348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 20358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 20368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 20378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 20398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 20408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EALREADY); 20418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 20438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_LOCK(inp); 20448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen creat_lock_on = 1; 20458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 20468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 20478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 20488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EFAULT; 20498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen totaddrp = (int *)optval; 20528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen totaddr = *totaddrp; 20538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)(totaddrp + 1); 2054b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen stcb = sctp_connectx_helper_find(inp, sa, &totaddr, &num_v4, &num_v6, &error, (optsize - sizeof(int)), &bad_addresses); 2055b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((stcb != NULL) || bad_addresses) { 20568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Already have or am bring up an association */ 20578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_UNLOCK(inp); 20588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen creat_lock_on = 0; 20598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 20608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 20618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (bad_addresses == 0) { 20628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 20638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 20648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 20688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 20698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (num_v6 > 0)) { 20708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 20718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 20748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (num_v4 > 0)) { 20758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct in6pcb *inp6; 20768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp6 = (struct in6pcb *)inp; 20788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_IPV6_V6ONLY(inp6)) { 20798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 20808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * if IPV6_V6ONLY flag, ignore connections destined 20818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * to a v4 addr or v4-mapped addr 20828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 20838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 20848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 20858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* INET6 */ 20898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 20908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PCB_FLAGS_UNBOUND) { 20918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Bind a ephemeral port */ 20928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_inpcb_bind(so, NULL, NULL, p); 20938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 20948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 20958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 20978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 20988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIX ME: do we want to pass in a vrf on the connect call? */ 20998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 2100000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 21018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are GOOD to go */ 21038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id, 21048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 21058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct thread *)p 21068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 21078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (PKTHREAD)p 21088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 21098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct proc *)p 21108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 21118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ); 21128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 21138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak! no memory */ 21148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 21158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 21178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 21188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Set the connected flag so we can queue data */ 21198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen soisconnecting(so); 21208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 21228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* move to second address */ 21238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sa->sa_family) { 21248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 21258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 21268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in)); 21278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 21298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 21308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 21318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6)); 21328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 21348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 21358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 21368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 21398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_connectx_helper_add(stcb, sa, (totaddr-1), &error); 21408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Fill in the return id */ 21418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 21428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_6); 21438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 21448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen a_id = (sctp_assoc_t *)optval; 21468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *a_id = sctp_get_associd(stcb); 21478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* initialize authentication parameters for the assoc */ 21498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_initialize_auth_params(inp, stcb); 21508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (delay) { 21528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* doing delayed connection */ 21538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_connection = 1; 21548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination); 21558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 21568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 21578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 21588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 21608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 21618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 21628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Set the connected flag so we can queue data */ 21638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen soisconnecting(so); 21648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_now: 21668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (creat_lock_on) { 21678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_UNLOCK(inp); 21688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 2170b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (error); 21718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 21728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#define SCTP_FIND_STCB(inp, stcb, assoc_id) { \ 21748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||\ 21758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { \ 21768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); \ 21778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); \ 21788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { \ 21798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); \ 21808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 21818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); \ 21828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (assoc_id > SCTP_ALL_ASSOC) { \ 21838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \ 21848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { \ 21858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \ 21868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; \ 21878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; \ 21888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 21898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { \ 21908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = NULL; \ 21918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 21928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 21938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 21950ffb57b9ad94ecba97f46f7a6f5134833f2089a7tuexen#define SCTP_CHECK_AND_CAST(destp, srcp, type, size) {\ 21968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size < sizeof(type)) { \ 21978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); \ 21988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; \ 21998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; \ 22008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { \ 22018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen destp = (type *)srcp; \ 22028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } \ 22038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Panda__) || defined(__Userspace__) 22068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 22078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 22088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 22098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 22108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, 22118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p) { 22128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp = NULL; 22138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error, val = 0; 22148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 22158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval == NULL) { 22178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 22198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 22222fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 22238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return EINVAL; 22258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 22278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 22298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 22308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 22318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 22328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 22338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 22348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 22358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 22368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 22378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 22388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 22398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT); 22408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 22428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4); 22438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 22458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 22468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only valid for bound all sockets */ 22478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 22488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 22498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 22518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto flags_out; 22528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 22558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); 22568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 22588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY); 22598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 22618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO); 22628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 22648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) 22658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = TICKS_TO_SEC(inp->sctp_ep.auto_close_time); 22668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 22678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen val = 0; 22688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 22718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 22728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 22738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end switch (sopt->sopt_name) */ 22748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < sizeof(val)) { 22758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 22768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 22778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen flags_out: 22798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 22808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 22818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* return the option value */ 22828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *(int *)optval = val; 22838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(val); 22848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 22858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 22868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_PACKET_LOG: 22878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 22888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_PACKET_LOGGING 22898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *target; 22908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ret; 22918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 22928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize); 22938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ret = sctp_copy_out_packet_log(target , (int)*optsize); 22948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = ret; 22958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 22968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 22978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 22988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 22998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REUSE_PORT: 23028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 23048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 23068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't do this for a 1-m socket */ 23078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 23088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 23118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 23128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 23138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_POINT: 23168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 23188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 23208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->partial_delivery_point; 23218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 23228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_FRAGMENT_INTERLEAVE: 23258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 23278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 23298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) { 23308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) { 23318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = SCTP_FRAG_LEVEL_2; 23328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = SCTP_FRAG_LEVEL_1; 23348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = SCTP_FRAG_LEVEL_0; 23378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 23398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CMT_ON_OFF: 23428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 23448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 23468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 23478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 23488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.sctp_cmt_on_off; 23498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 23508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 23528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 23538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 23548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 23558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_cmt_on_off; 23568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 23578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 23598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 23608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 23638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 23648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_CC: 23688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 23708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 23728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 23738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 23748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.congestion_control_module; 23758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 23768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 23788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 23798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 23808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 23818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_ep.sctp_default_cc_module; 23828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 23838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 23848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 23858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 23868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 23898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 23908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 23928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 23938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CC_OPTION: 23948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 23958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cc_option *cc_opt; 23968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 23978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, *optsize); 23988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id); 23998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 24008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) { 24038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 24048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 0, cc_opt); 24068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_cc_option); 24078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 24098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_SS: 24138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 24158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 24178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 24188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 24198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.stream_scheduling_module; 24208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 24218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 24238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 24248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 24258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 24268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_ep.sctp_default_ss_module; 24278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 24288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 24308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 24348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 24358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SS_VALUE: 24398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_value *av; 24418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize); 24438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 24448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 24458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], 24468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &av->stream_value) < 0) { 24478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 24488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_stream_value); 24518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 24538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't get stream value without association */ 24558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 24568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ADDR_LEN: 24618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 24638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 24658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 24668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 24678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value == AF_INET) { 24688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = sizeof(struct sockaddr_in); 24698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 24708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 24728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 24738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value == AF_INET6) { 24748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = sizeof(struct sockaddr_in6); 24758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 24768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 247875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 247975cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (av->assoc_value == AF_CONN) { 248075cd23222c96d5ebe5a9082c57a263f917f1462btuexen av->assoc_value = sizeof(struct sockaddr_conn); 248175cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = 0; 248275cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 248375cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 24848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 24858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 24868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 24878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 24888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 24908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 24918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ASSOC_NUMBER: 24928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 24938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value, cnt; 24948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 24958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 24968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt = 0; 24978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 24988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 24998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cnt++; 25008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 25028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = cnt; 25038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 25048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ASSOC_ID_LIST: 25078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_ids *ids; 25098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen unsigned int at, limit; 2510000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 25118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ids, optval, struct sctp_assoc_ids, *optsize); 25128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen at = 0; 25138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen limit = (*optsize-sizeof(uint32_t))/ sizeof(sctp_assoc_t); 25148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 25158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 25168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (at < limit) { 25178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ids->gaids_assoc_id[at++] = sctp_get_associd(stcb); 25188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 25208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 25218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 25258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 25268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ids->gaids_number_of_ids = at; 25278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = ((at * sizeof(sctp_assoc_t)) + sizeof(uint32_t)); 25288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONTEXT: 25328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 25348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 25368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 25378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 25398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.context; 25408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 25418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 25438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 25448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 25458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 25468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_context; 25478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 25488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 25508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 25518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 25548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 25558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_VRF_ID: 25598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *default_vrfid; 25618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, *optsize); 25638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *default_vrfid = inp->def_vrf_id; 25648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 25658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_ASOC_VRF: 25688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *id; 25708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(id, optval, struct sctp_assoc_value, *optsize); 25728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, id->assoc_id); 25738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 25748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 25758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 25768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen id->assoc_value = stcb->asoc.vrf_id; 25788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 25798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 25818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_VRF_IDS: 25838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 25848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 25858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int siz_needed; 25868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *vrf_ids; 25878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 25888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(vrf_ids, optval, uint32_t, *optsize); 25898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen siz_needed = inp->num_vrfs * sizeof(uint32_t); 25908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < siz_needed) { 25918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 25928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 25938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 25948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(vrf_ids, inp->m_vrf_ids, siz_needed); 25958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = siz_needed; 25968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 25978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 25988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 25998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 26008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 26018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_NONCE_VALUES: 26048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_get_nonce_values *gnv; 26068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(gnv, optval, struct sctp_get_nonce_values, *optsize); 26088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, gnv->gn_assoc_id); 26098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 26118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen gnv->gn_peers_tag = stcb->asoc.peer_vtag; 26128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen gnv->gn_local_tag = stcb->asoc.my_vtag; 26138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 26148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_get_nonce_values); 26158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 26178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 26188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DELAYED_SACK: 26228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sack_info *sack; 26248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, *optsize); 26268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 26278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 26288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = stcb->asoc.delayed_ack; 26298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_freq = stcb->asoc.sack_freq; 26308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 26318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 26338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 26348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_FUTURE_ASSOC)) { 26358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 26368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 26378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_freq = inp->sctp_ep.sctp_sack_freq; 26388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 26398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 26418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 26428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 26458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sack_info); 26468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_SNDBUF_USE: 26508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sockstat *ss; 26528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ss, optval, struct sctp_sockstat, *optsize); 26548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, ss->ss_assoc_id); 26558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 26578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ss->ss_total_sndbuf = stcb->asoc.total_output_queue_size; 26588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ss->ss_total_recv_buf = (stcb->asoc.size_on_reasm_queue + 26598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.size_on_all_streams); 26608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 26618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sockstat); 26628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 26648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 26658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 26678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAX_BURST: 26698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 26708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 900000 26718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *value; 26728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint8_t, *optsize); 26748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 26768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_ep.max_burst < 256) { 26778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->sctp_ep.max_burst; 26788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = 255; 26808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 26818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 26828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint8_t); 26838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 26848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 26858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 26878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 26888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 26898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 26908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = stcb->asoc.max_burst; 26918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 26928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 26938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 26948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 26958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 26968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 26978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_ep.max_burst; 26988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 26998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 27018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 27028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 27058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 27068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 27088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 27098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAXSEG: 27118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 27128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 27138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ovh; 27148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 27168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 27178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 27198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = sctp_get_frag_point(stcb, &stcb->asoc); 27208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 27218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 27238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 27248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 27258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 27268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 27278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 27288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 27308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_frag_point >= SCTP_DEFAULT_MAXSEGMENT) 27328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = 0; 27338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 27348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->assoc_value = inp->sctp_frag_point - ovh; 27358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 27368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 27378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 27388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 27398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 27428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assoc_value); 27438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 27458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_STAT_LOG: 27478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_fill_stat_log(optval, optsize); 27488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 27498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENTS: 27508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 27518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event_subscribe *events; 27528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, *optsize); 27548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(events, 0, sizeof(struct sctp_event_subscribe)); 27558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 27568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT)) 27578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_data_io_event = 1; 27588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT)) 27608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_association_event = 1; 27618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT)) 27638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_address_event = 1; 27648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) 27668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_send_failure_event = 1; 27678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR)) 27698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_peer_error_event = 1; 27708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) 27728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_shutdown_event = 1; 27738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT)) 27758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_partial_delivery_event = 1; 27768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) 27788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_adaptation_layer_event = 1; 27798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT)) 27818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_authentication_event = 1; 27828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT)) 27848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_sender_dry_event = 1; 27858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT)) 27878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen events->sctp_stream_reset_event = 1; 27888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 27898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_event_subscribe); 27908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 27918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 27928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_LAYER: 27938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 27948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 27958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 27978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 27988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 27998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->sctp_ep.adaptation_layer_indicator; 28008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 28018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_INITIAL_DBG_SEQ: 28058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 28078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 28098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 28108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = inp->sctp_ep.initial_sequence_debug; 28118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 28128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_LOCAL_ADDR_SIZE: 28168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 28188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 28208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 28218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = sctp_count_max_addresses(inp); 28228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 28238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_REMOTE_ADDR_SIZE: 28278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 28298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size; 28308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 28318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize); 28338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIXME MT: change to sctp_assoc_value? */ 28348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) *value); 28358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 28378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = 0; 28388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Count the sizes */ 28398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 28408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 28418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sizeof(struct sockaddr_in6); 28428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 28438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) { 28448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 28458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 28468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sizeof(struct sockaddr_in); 28478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 28498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 28508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 28518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size += sizeof(struct sockaddr_in6); 28528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 285475cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 285575cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 285675cd23222c96d5ebe5a9082c57a263f917f1462btuexen size += sizeof(struct sockaddr_conn); 285775cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 285875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 28598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 28608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 28658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *value = (uint32_t) size; 28668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(uint32_t); 28678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 28688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 28698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTCONN; 28708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 28728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 28738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_PEER_ADDRESSES: 28748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 28758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Get the address information, an array is passed in to 28768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * fill up we pack it. 28778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 28788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 28798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t cpsz, left; 28808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_storage *sas; 28818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 28828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *saddr; 28838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 28858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 28868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 28888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen left = (*optsize) - sizeof(struct sctp_getaddresses); 28898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_getaddresses); 28908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)&saddr->addr[0]; 28918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 28928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 28938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) { 28948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = sizeof(struct sockaddr_in6); 28958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 28968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) { 28978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 28988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 28998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = sizeof(struct sockaddr_in); 29008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 29038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 29048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = sizeof(struct sockaddr_in6); 29058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 290775cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 290875cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 290975cd23222c96d5ebe5a9082c57a263f917f1462btuexen cpsz = sizeof(struct sockaddr_conn); 291075cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 291175cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 29128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 29138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cpsz = 0; 29148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cpsz == 0) { 29188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (left < cpsz) { 29218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not enough room. */ 29228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(INET) && defined(INET6) 29258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) && 29268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) { 29278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Must map the address */ 29288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr, 29298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr_in6 *)sas); 29308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(sas, &net->ro._l_addr, cpsz); 29338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(INET) && defined(INET6) 29348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 29368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)sas)->sin_port = stcb->rport; 29378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz); 29398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen left -= cpsz; 29408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize += cpsz; 29418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 29438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 29458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 29468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_LOCAL_ADDRESSES: 29508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 29518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t limit, actual; 29528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_storage *sas; 29538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *saddr; 29548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); 29568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); 29578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sas = (struct sockaddr_storage *)&saddr->addr[0]; 29598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen limit = *optsize - sizeof(sctp_assoc_t); 29608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen actual = sctp_fill_up_addresses(inp, stcb, limit, sas); 29618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 29628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 29638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sockaddr_storage) + actual; 29658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 29668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_PARAMS: 29688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 29698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrparams *paddrp; 29708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 29718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize); 29738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 29748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 29768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 29778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 29788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 29798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 29808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 29818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 29828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 29838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 29848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddrp->spp_address, &net, NULL, NULL); 29858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 29868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 29878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 29898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb && (net == NULL)) { 29908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 29918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)&paddrp->spp_address; 29938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 29948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 29958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 29968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 29978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 29988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 29998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 30008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 30018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 30028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 30038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 30058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 30068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 30078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 30088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 30098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 30118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 30128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 30138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 30148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 30158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 30168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 30188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 301975cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 302075cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 302175cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 302275cd23222c96d5ebe5a9082c57a263f917f1462btuexen 302375cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 302475cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 302575cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 302675cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 302775cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 302875cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 302975cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 303075cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 303175cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 30328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 30338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 30348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 30358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 30368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 30378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 30418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Applies to the specific association */ 30428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags = 0; 30438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 30448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ovh; 30458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 30468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 30478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 30498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 30518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval = net->heart_beat_delay; 30528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmaxrxt = net->failure_threshold; 30538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmtu = net->mtu - ovh; 30548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get flags for HB */ 30558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_NOHB) { 30568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_DISABLE; 30578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_ENABLE; 30598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get flags for PMTU */ 30618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_NO_PMTUD) { 30628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_ENABLE; 30638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_DISABLE; 30658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dscp & 0x01) { 30678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_dscp = net->dscp & 0xfc; 30688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_DSCP; 30698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 30718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->ro._l_addr.sa.sa_family == AF_INET6) && 30728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->flowlabel & 0x80000000)) { 30738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_ipv6_flowlabel = net->flowlabel & 0x000fffff; 30748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 30758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 30778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 30798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * No destination so return default 30808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * value 30818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 30828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure; 30838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc); 30848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.default_dscp & 0x01) { 30858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc; 30868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_DSCP; 30878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 30898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.default_flowlabel & 0x80000000) { 30908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel & 0x000fffff; 30918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 30928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 30938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 30948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* default settings should be these */ 30958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { 30968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_DISABLE; 30978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 30988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_ENABLE; 30998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) { 31018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_DISABLE; 31028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_ENABLE; 31048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay; 31068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_assoc_id = sctp_get_associd(stcb); 31088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 31098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 31118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 31128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC)) { 31138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Use endpoint defaults */ 31148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 31158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure; 31168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 31178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC; 31188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get inp's default */ 31198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_ep.default_dscp & 0x01) { 31208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_dscp = inp->sctp_ep.default_dscp & 0xfc; 31218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_DSCP; 31228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 31248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 31258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_ep.default_flowlabel & 0x80000000)) { 31268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_ipv6_flowlabel = inp->sctp_ep.default_flowlabel & 0x000fffff; 31278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; 31288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 31308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* can't return this */ 31318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_pathmtu = 0; 31328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { 31348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_ENABLE; 31358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_HB_DISABLE; 31378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) { 31398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_ENABLE; 31408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_flags |= SPP_PMTUD_DISABLE; 31428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 31448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 31468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 31478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 31508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_paddrparams); 31518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 31538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_GET_PEER_ADDR_INFO: 31558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 31568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrinfo *paddri; 31578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 31588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize); 31608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id); 31618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 31638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 31648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&paddri->spinfo_address); 31658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 31678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 31688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 31698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 31708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 31718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&paddri->spinfo_address, &net, NULL, NULL); 31728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 31738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 31748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 31778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb) && (net)) { 31788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { 31798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's unconfirmed */ 31808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_state = SCTP_UNCONFIRMED; 31818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (net->dest_state & SCTP_ADDR_REACHABLE) { 31828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's active */ 31838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_state = SCTP_ACTIVE; 31848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's inactive */ 31868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_state = SCTP_INACTIVE; 31878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_cwnd = net->cwnd; 31898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT; 31908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_rto = net->RTO; 31918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_assoc_id = sctp_get_associd(stcb); 31928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddri->spinfo_mtu = net->mtu; 31938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 31948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_paddrinfo); 31958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 31968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 31978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 31988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 31998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 32008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 32018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PCB_STATUS: 32058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 32068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_pcbinfo *spcb; 32078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(spcb, optval, struct sctp_pcbinfo, *optsize); 32098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_fill_pcbinfo(spcb); 32108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_pcbinfo); 32118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_STATUS: 32148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 32158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 32168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_status *sstat; 32178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sstat, optval, struct sctp_status, *optsize); 32198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sstat->sstat_assoc_id); 32208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 32228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 32238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 32248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 32278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * I think passing the state is fine since 32288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sctp_constants.h will be available to the user 32298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * land. 32308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 32318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_state = stcb->asoc.state; 32328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_assoc_id = sctp_get_associd(stcb); 32338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_rwnd = stcb->asoc.peers_rwnd; 32348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt; 32358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 32368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We can't include chunks that have been passed to 32378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * the socket layer. Only things in queue. 32388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 32398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue + 32408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cnt_on_all_streams); 32418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_instrms = stcb->asoc.streamincnt; 32448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_outstrms = stcb->asoc.streamoutcnt; 32458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc); 3246f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 32478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&sstat->sstat_primary.spinfo_address, 32488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 32498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len); 32508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 32518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET) { 32528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&sstat->sstat_primary.spinfo_address, 32538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 32548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct sockaddr_in)); 32558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 32568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&sstat->sstat_primary.spinfo_address, 32578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 32588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(struct sockaddr_in6)); 32598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 32618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = stcb->asoc.primary_destination; 32628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport; 32638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 32648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Again the user can get info from sctp_constants.h 32658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * for what the state of the network is. 32668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 32678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { 32688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's unconfirmed */ 32698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_state = SCTP_UNCONFIRMED; 32708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (net->dest_state & SCTP_ADDR_REACHABLE) { 32718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's active */ 32728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_state = SCTP_ACTIVE; 32738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 32748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It's inactive */ 32758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_state = SCTP_INACTIVE; 32768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_cwnd = net->cwnd; 32788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT; 32798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_rto = net->RTO; 32808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_mtu = net->mtu; 32818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb); 32828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 32838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_status); 32848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 32858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 32868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RTOINFO: 32878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 32888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_rtoinfo *srto; 32898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, *optsize); 32918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 32928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 32938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 32948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_initial = stcb->asoc.initial_rto; 32958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_max = stcb->asoc.maxrto; 32968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_min = stcb->asoc.minrto; 32978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 32988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 32998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 33008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 33018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (srto->srto_assoc_id == SCTP_FUTURE_ASSOC)) { 33028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 33038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_initial = inp->sctp_ep.initial_rto; 33048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_max = inp->sctp_ep.sctp_maxrto; 33058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen srto->srto_min = inp->sctp_ep.sctp_minrto; 33068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 33078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 33098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 33108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 33138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_rtoinfo); 33148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 33168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_TIMEOUTS: 33188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 33198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_timeouts *stimo; 33208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(stimo, optval, struct sctp_timeouts, *optsize); 33228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, stimo->stimo_assoc_id); 33238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 33258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_init= stcb->asoc.timoinit; 33268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_data= stcb->asoc.timodata; 33278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_sack= stcb->asoc.timosack; 33288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_shutdown= stcb->asoc.timoshutdown; 33298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_heartbeat= stcb->asoc.timoheartbeat; 33308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_cookie= stcb->asoc.timocookie; 33318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stimo->stimo_shutdownack= stcb->asoc.timoshutdownack; 33328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_timeouts); 33348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 33368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 33378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 33398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOCINFO: 33418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 33428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assocparams *sasoc; 33438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, *optsize); 33458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 33468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 33488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = TICKS_TO_MSEC(stcb->asoc.cookie_life); 33498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times; 33508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets; 33518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd; 33528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd; 33538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 33568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 33578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC)) { 33588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 33598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = TICKS_TO_MSEC(inp->sctp_ep.def_cookie_life); 33608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times; 33618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_number_peer_destinations = 0; 33628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_peer_rwnd = 0; 33638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv); 33648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 33658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 33678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 33688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 33718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_assocparams); 33728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 33748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SEND_PARAM: 33768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 33778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndrcvinfo *s_info; 33788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, *optsize); 33808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 33818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 33828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 33838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(s_info, &stcb->asoc.def_send, sizeof(stcb->asoc.def_send)); 33848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 33858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 33878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 33888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC)) { 33898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 33908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(s_info, &inp->def_send, sizeof(inp->def_send)); 33918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 33928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 33938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 33948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 3395000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 33968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 33978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 33988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sndrcvinfo); 33998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_INITMSG: 34038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 34048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_initmsg *sinit; 34058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, *optsize); 34078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 34088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count; 34098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome; 34108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_max_attempts = inp->sctp_ep.max_init_times; 34118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max; 34128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_initmsg); 34148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PRIMARY_ADDR: 34178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we allow a "get" operation on this */ 34188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 34198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setprim *ssp; 34208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ssp, optval, struct sctp_setprim, *optsize); 34228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id); 34238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 34258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* simply copy out the sockaddr_storage... */ 342618818c8dd0d4cafdb259fa73f01f7825948faadct size_t len; 34278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = *optsize; 3429f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 34308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (len > stcb->asoc.primary_destination->ro._l_addr.sa.sa_len) 34318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = stcb->asoc.primary_destination->ro._l_addr.sa.sa_len; 34328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 34338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET && 34348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len > sizeof(struct sockaddr_in)) 34358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = sizeof(struct sockaddr_in); 34368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else if ( 34378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET6 && 34388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len > sizeof(struct sockaddr_in6)) 34398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len = sizeof(struct sockaddr_in6); 34408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 34418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&ssp->ssp_addr, 34438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.primary_destination->ro._l_addr, 34448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen len); 34458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 34468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_setprim); 34478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 34488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 34498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 34508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_HMAC_IDENT: 34548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 34558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_hmacalgo *shmac; 34568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_hmaclist_t *hmaclist; 34578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t size; 34588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 34598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize); 34618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 34638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hmaclist = inp->sctp_ep.local_hmacs; 34648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hmaclist == NULL) { 34658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* no HMACs to return */ 34668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(*shmac); 34678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there room for all of the hmac ids? */ 34718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sizeof(*shmac) + (hmaclist->num_algo * 34728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sizeof(shmac->shmac_idents[0])); 34738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((size_t)(*optsize) < size) { 34748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 34758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 34768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the list */ 34808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shmac->shmac_number_of_idents = hmaclist->num_algo; 34818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < hmaclist->num_algo; i++) { 34828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shmac->shmac_idents[i] = hmaclist->hmac[i]; 34838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 34858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = size; 34868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 34878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 34888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_ACTIVE_KEY: 34898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 34908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *scact; 34918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, *optsize); 34938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 34948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 34958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 34968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get the active key on the assoc */ 34978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen scact->scact_keynumber = stcb->asoc.authinfo.active_keyid; 34988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 34998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 35018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 35028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_FUTURE_ASSOC)) { 35038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get the endpoint active key */ 35048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 35058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen scact->scact_keynumber = inp->sctp_ep.default_keyid; 35068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 35078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 35098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 35138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authkeyid); 35148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 35168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_LOCAL_AUTH_CHUNKS: 35188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 35198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authchunks *sac; 35208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auth_chklist_t *chklist = NULL; 35218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size = 0; 35228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 35248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 35258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 35278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get off the assoc */ 35288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chklist = stcb->asoc.local_auth_chunks; 35298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there enough space? */ 35308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_auth_get_chklist_size(chklist); 35318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 35328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 35348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the chunks */ 35368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 35371a2e446bdbc52cc6178a3f80092943a84706ece9tuexen sac->gauth_number_of_chunks = (uint32_t)size; 35388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authchunks) + size; 35398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 35418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 35438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 35448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sac->gauth_assoc_id == SCTP_FUTURE_ASSOC)) { 35458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get off the endpoint */ 35468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 35478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chklist = inp->sctp_ep.local_auth_chunks; 35488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there enough space? */ 35498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_auth_get_chklist_size(chklist); 35508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 35518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 35538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the chunks */ 35558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 35561a2e446bdbc52cc6178a3f80092943a84706ece9tuexen sac->gauth_number_of_chunks = (uint32_t)size; 35578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authchunks) + size; 35588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 35608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 35628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 35668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_AUTH_CHUNKS: 35688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 35698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authchunks *sac; 35708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auth_chklist_t *chklist = NULL; 35718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size = 0; 35728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize); 35748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id); 35758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 35768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 35778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* get off the assoc */ 35788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen chklist = stcb->asoc.peer_auth_chunks; 35798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* is there enough space? */ 35808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sctp_auth_get_chklist_size(chklist); 35818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < (sizeof(struct sctp_authchunks) + size)) { 35828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 35838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 35848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the chunks */ 35868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks); 35871a2e446bdbc52cc6178a3f80092943a84706ece9tuexen sac->gauth_number_of_chunks = (uint32_t)size; 35888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_authchunks) + size; 35898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 35918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 35928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 35938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 35948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 35968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 35978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(HAVE_SCTP_PEELOFF_SOCKOPT) 35988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEELOFF: 35998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 36008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_peeloff_opt *peeloff; 36018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(peeloff, optval, struct sctp_peeloff_opt, *optsize); 36038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* do the peeloff */ 36048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_peeloff_option(p, peeloff); 36058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 36068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_peeloff_opt); 36078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 36108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* HAVE_SCTP_PEELOFF_SOCKOPT */ 36118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENT: 36128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 36138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event *event; 36148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t event_type; 36158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, *optsize); 36178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, event->se_assoc_id); 36188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (event->se_type) { 36208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOC_CHANGE: 36218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT; 3622000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_CHANGE: 36248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPADDREVNT; 3625000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REMOTE_ERROR: 36278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPEERERR; 3628000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SEND_FAILED: 36308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT; 3631000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SHUTDOWN_EVENT: 36338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT; 3634000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_INDICATION: 36368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT; 3637000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_EVENT: 36398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_PDAPIEVNT; 3640000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTHENTICATION_EVENT: 36428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_AUTHEVNT; 3643000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_STREAM_RESET_EVENT: 36458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT; 3646000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SENDER_DRY_EVENT: 36488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_DRYEVNT; 3649000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 36508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFICATIONS_STOPPED_EVENT: 36518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 36528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 36538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 36548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 3655298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_ASSOC_RESET_EVENT: 3656298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT; 3657298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 3658298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_STREAM_CHANGE_EVENT: 3659298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT; 3660298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 36615741e159bdf238ef4b61085d6fbfea2947386238tuexen case SCTP_SEND_FAILED_EVENT: 36625741e159bdf238ef4b61085d6fbfea2947386238tuexen event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT; 36635741e159bdf238ef4b61085d6fbfea2947386238tuexen break; 36648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 36658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 36668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 36678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 36688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 36698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event_type > 0) { 36718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 36728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->se_on = sctp_stcb_is_feature_on(inp, stcb, event_type); 36738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 36748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 36758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 36768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 36778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_FUTURE_ASSOC)) { 36788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 36798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event->se_on = sctp_is_feature_on(inp, event_type); 36808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 36818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 36828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 36838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 36848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 36888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_event); 36898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 36918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 36928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVRCVINFO: 36938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 36948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int onoff; 36958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 36968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < sizeof(int)) { 36978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 36988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 36998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37006f63c1f0e9307e260e6d8724b12d0153cedb4a9atuexen SCTP_INP_RLOCK(inp); 37018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 37028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* return the option value */ 37068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *(int *)optval = onoff; 37078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(int); 37088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVNXTINFO: 37128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int onoff; 37148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*optsize < sizeof(int)) { 37168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 37178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 37188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37196f63c1f0e9307e260e6d8724b12d0153cedb4a9atuexen SCTP_INP_RLOCK(inp); 37208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen onoff = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 37218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* return the option value */ 37258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *(int *)optval = onoff; 37268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(int); 37278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SNDINFO: 37318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndinfo *info; 37338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, *optsize); 37358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id); 37368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 37388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_sid = stcb->asoc.def_send.sinfo_stream; 37398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags = stcb->asoc.def_send.sinfo_flags; 37408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags &= 0xfff0; 37418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_ppid = stcb->asoc.def_send.sinfo_ppid; 37428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_context = stcb->asoc.def_send.sinfo_context; 37438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 37448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 37468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 37478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_FUTURE_ASSOC)) { 37488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 37498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_sid = inp->def_send.sinfo_stream; 37508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags = inp->def_send.sinfo_flags; 37518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_flags &= 0xfff0; 37528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_ppid = inp->def_send.sinfo_ppid; 37538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->snd_context = inp->def_send.sinfo_context; 37548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 37578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 37588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_sndinfo); 37628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_PRINFO: 37668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_default_prinfo *info; 37688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, *optsize); 37708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id); 37718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 37738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 37748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_value = stcb->asoc.def_send.sinfo_timetolive; 37758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 37768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 37788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 37798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_FUTURE_ASSOC)) { 37808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 37818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags); 37828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen info->pr_value = inp->def_send.sinfo_timetolive; 37838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 37848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 37858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 37868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 37878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 37908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_default_prinfo); 37918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 37938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 37948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_THLDS: 37958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 37968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrthlds *thlds; 37978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 37988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 37998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize); 38008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); 38018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 38038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 38048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_address); 38058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 38078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 38088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 38098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 38108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 38118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&thlds->spt_address, &net, NULL, NULL); 38128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 38138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 38148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3816b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 38178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 38188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)&thlds->spt_address; 38208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 38218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 38228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 38238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 38258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 38268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 38278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 38298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 38328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 38338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 38348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 38358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 38368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 38388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 38398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 38408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 38428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 38458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 384675cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 384775cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 384875cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 384975cd23222c96d5ebe5a9082c57a263f917f1462btuexen 385075cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 385175cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 385275cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 385375cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 385475cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 385575cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 385675cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 385775cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 385875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 38598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 38608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 38618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 38638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 38678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 38688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 38698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathmaxrxt = net->failure_threshold; 38708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathpfthld = net->pf_threshold; 38718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathmaxrxt = stcb->asoc.def_net_failure; 38738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathpfthld = stcb->asoc.def_net_pf_threshold; 38748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_assoc_id = sctp_get_associd(stcb); 38768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 38778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 38798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 38808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC)) { 38818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Use endpoint defaults */ 38828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 38838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen thlds->spt_pathmaxrxt = inp->sctp_ep.def_net_failure; 3884000a5bac556b28e74e4e98c540f66b1743e9312dtuexen thlds->spt_pathpfthld = inp->sctp_ep.def_net_pf_threshold; 38858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 38868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 38878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 38888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 38898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error == 0) { 38928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = sizeof(struct sctp_paddrthlds); 38938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 38948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 38958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 3896153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen case SCTP_REMOTE_UDP_ENCAPS_PORT: 3897153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 3898153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_udpencaps *encaps; 3899153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_nets *net; 3900000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 3901153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize); 3902153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); 3903153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3904153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 3905153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address); 3906153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3907153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen /* We increment here since sctp_findassociation_ep_addr() wil 3908153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * do a decrement if it finds the stcb as long as the locked 3909153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * tcb (last argument) is NOT a TCB.. aka NULL. 3910153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen */ 3911153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = NULL; 3912153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_INCR_REF(inp); 3913153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL); 3914153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb == NULL) { 3915153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_DECR_REF(inp); 3916153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3917153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3918153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb && (net == NULL)) { 3919153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr *sa; 3920000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 3921153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sa = (struct sockaddr *)&encaps->sue_address; 3922153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET 3923153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET) { 3924153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in *sin; 3925153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3926153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin = (struct sockaddr_in *)sa; 3927153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sin->sin_addr.s_addr) { 3928153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 3929153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3930153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3931153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 3932153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3933153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 3934153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 3935153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET6 3936153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET6) { 3937153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in6 *sin6; 3938153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3939153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin6 = (struct sockaddr_in6 *)sa; 3940153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 3941153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 3942153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3943153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3944153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 3945153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3946153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 3947153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 394875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 394975cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 395075cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 395175cd23222c96d5ebe5a9082c57a263f917f1462btuexen 395275cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 395375cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 395475cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 395575cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 395675cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 395775cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 395875cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 395975cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 396075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 3961153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 3962153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EAFNOSUPPORT; 3963153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3964153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 3965153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 3966153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3967153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3968153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 3969153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 3970153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (net) { 3971153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen encaps->sue_port = net->port; 3972153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3973153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen encaps->sue_port = stcb->asoc.port; 3974153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3975153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 3976153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3977153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3978153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 3979153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC)) { 3980153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_RLOCK(inp); 3981153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen encaps->sue_port = inp->sctp_ep.port; 3982153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_RUNLOCK(inp); 3983153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 3984153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 3985153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 3986153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3987153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3988153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (error == 0) { 3989443f94da739e8e8968e5eb93c2f82f73287cfd5dt *optsize = sizeof(struct sctp_udpencaps); 3990153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 3991153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 3992153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 39932d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen case SCTP_ENABLE_STREAM_RESET: 39942d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen { 39952d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen struct sctp_assoc_value *av; 39962d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen 39972d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize); 39982d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 39992d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen 40002d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen if (stcb) { 40012d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen av->assoc_value = (uint32_t)stcb->asoc.local_strreset_support; 40022d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_TCB_UNLOCK(stcb); 40032d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } else { 40042d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 40052d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 40062d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 40072d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_INP_RLOCK(inp); 40082d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen av->assoc_value = (uint32_t)inp->local_strreset_support; 40092d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_INP_RUNLOCK(inp); 40102d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } else { 40112d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 40122d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen error = EINVAL; 40132d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 40142d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 40152d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen if (error == 0) { 40162d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen *optsize = sizeof(struct sctp_assoc_value); 40172d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 40182d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen break; 40192d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen } 40208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 40218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 40228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 40238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 40248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end switch (sopt->sopt_name) */ 40258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 40268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *optsize = 0; 40278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 40298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 40308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 40318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Panda__) || defined(__Userspace__) 40328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 40338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 40348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 40358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 40368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, 40378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p) 40388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 40398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error, set_opt; 40408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *mopt; 40418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb = NULL; 4042b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct sctp_inpcb *inp = NULL; 40438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 40448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 40458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval == NULL) { 40468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("optval is NULL\n"); 40478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 40488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 40498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 40512fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 40528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PRINTF("inp is NULL?\n"); 40538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4054b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (EINVAL); 40558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 40578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 40588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 40598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 40608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 40618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 40628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 40638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 40648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 40658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 40668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 40678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* copy in the option value */ 40688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 40698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = 0; 40708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) 40718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 40728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (optname) { 40738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DISABLE_FRAGMENTS: 40748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT; 40758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 40768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTO_ASCONF: 40778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 40788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * NOTE: we don't really support this flag 40798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 40808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 40818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only valid for bound all sockets */ 40828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((SCTP_BASE_SYSCTL(sctp_auto_asconf) == 0) && 40838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*mopt != 0)) { 40848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* forbidden by admin */ 40858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EPERM); 40868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EPERM); 40878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF; 40898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 40908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 40918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 40928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 40938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 40948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EXPLICIT_EOR: 40958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR; 40968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 40978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_USE_EXT_RCVINFO: 40988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO; 40998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_I_WANT_MAPPED_V4_ADDR: 41018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 41028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4; 41038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 41048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 41058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 41068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NODELAY: 41098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_NODELAY; 41108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTOCLOSE: 41128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 41138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 41148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 41158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 41168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen set_opt = SCTP_PCB_FLAGS_AUTOCLOSE; 41188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 41198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * The value is in ticks. Note this does not effect 41208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * old associations, only new ones. 41218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 41228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt); 41238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 41268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*mopt != 0) { 41278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, set_opt); 41288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 41298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, set_opt); 41308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 41328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REUSE_PORT: 41348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 41358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize); 41368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 41378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't set it after we are bound */ 41388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 41398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) { 41428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't do this for a 1-m socket */ 41438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 41448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval) 41478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE); 41488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 41498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE); 41508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_POINT: 41538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 41548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *value; 41558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize); 41578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*value > SCTP_SB_LIMIT_RCV(so)) { 41588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 41598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 41608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->partial_delivery_point = *value; 41638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_FRAGMENT_INTERLEAVE: 41668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not yet until we re-write sctp_recvmsg() */ 41678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 41688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *level; 41698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(level, optval, uint32_t, optsize); 41718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*level == SCTP_FRAG_LEVEL_2) { 41728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 41738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 41748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (*level == SCTP_FRAG_LEVEL_1) { 41758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 41768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 41778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (*level == SCTP_FRAG_LEVEL_0) { 41788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE); 41798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS); 41808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 41828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 41838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 41848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 41868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 41878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CMT_ON_OFF: 41888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) { 41898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 41908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 41918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 41928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value > SCTP_CMT_MAX) { 41938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 41948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 41958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 4196000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 41978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 41988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 41998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_cmt_on_off = av->assoc_value; 42008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 42018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 42028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 42038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 42048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 42058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 42068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 42078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_cmt_on_off = av->assoc_value; 42088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 42098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 42118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 42128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 42138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 42148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 42158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_cmt_on_off = av->assoc_value; 42168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 42178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 42198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 42228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 42238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 42248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 42268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_CC: 42278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 42288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 42298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 42308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 42318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 42328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_value != SCTP_CC_RFC2581) && 42338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_CC_HSTCP) && 42348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_CC_HTCP) && 42358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_CC_RTCC)) { 42368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 42378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 42388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 42398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 42418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 42428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value]; 42438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.congestion_control_module = av->assoc_value; 42448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) { 42458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 42468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net); 42478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 42508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 42518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 42528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 42538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 42548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 42558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 42568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_default_cc_module = av->assoc_value; 42578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 42588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 42608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 42618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 42628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 42638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 42648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value]; 42658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.congestion_control_module = av->assoc_value; 42668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) { 42678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 42688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net); 42698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 42728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 42748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 42778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CC_OPTION: 42798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 42808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_cc_option *cc_opt; 42818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 42828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, optsize); 42838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id); 42848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 42858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (cc_opt->aid_value.assoc_id == SCTP_CURRENT_ASSOC) { 42868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 42878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 42888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 42898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_cwnd_socket_option) { 42908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1, cc_opt); 42918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 42938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 42958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 42968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 42978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 42988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 42998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) { 43008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 43018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 4302000a5bac556b28e74e4e98c540f66b1743e9312dtuexen error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1, 43038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen cc_opt); 43048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 43068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PLUGGABLE_SS: 43108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 43118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 43128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 43148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_value != SCTP_SS_DEFAULT) && 43158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_ROUND_ROBIN) && 43168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_ROUND_ROBIN_PACKET) && 43178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_PRIORITY) && 43188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_FAIR_BANDWITH) && 43198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_value != SCTP_SS_FIRST_COME)) { 43208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 43218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 43228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 43258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 43268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1, 1); 43278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value]; 43288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.stream_scheduling_module = av->assoc_value; 43298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1); 43308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 43318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 43328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 43338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 43348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 43358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 43368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 43378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_default_ss_module = av->assoc_value; 43388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 43398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 43418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 43428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 43438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 43448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 43458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1, 1); 43468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value]; 43478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.stream_scheduling_module = av->assoc_value; 43488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1); 43498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 43508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 43528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SS_VALUE: 43578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 43588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_stream_value *av; 43598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize); 43618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 43628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 43638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id], 43648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->stream_value) < 0) { 43658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 43668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 43678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 43698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 43708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_id == SCTP_CURRENT_ASSOC) { 43718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 43728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 43738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 43748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.ss_functions.sctp_ss_set_value(stcb, 43758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc, 43768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &stcb->asoc.strmout[av->stream_id], 43778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen av->stream_value); 43788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 43798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 4381000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 43828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 43838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't set stream value without association */ 43848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 43858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 43868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 43908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CLR_STAT_LOG: 43918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 43928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 43938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 43948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONTEXT: 43958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 43968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 43978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 43988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 43998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 44008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 44028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.context = av->assoc_value; 44038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 44048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 44058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 44068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 44078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 44088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 44098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 44108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_context = av->assoc_value; 44118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 44128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 44148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 44158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 44168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 44178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 44188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.context = av->assoc_value; 44198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 44208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 44228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_VRF_ID: 44278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *default_vrfid; 44298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 44308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 44318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 44328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, optsize); 44338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*default_vrfid > SCTP_MAX_VRF_ID) { 44348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 44398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 44408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* The VRF must be in the VRF list */ 44418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*default_vrfid == inp->m_vrf_ids[i]) { 44428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 44438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_vrf_id = *default_vrfid; 44448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 44458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto sctp_done; 44468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 44518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_vrf_id = *default_vrfid; 44528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 44538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 44548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_done: 44558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 44568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEL_VRF_ID: 44598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 44608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 44618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *del_vrfid; 44628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i, fnd = 0; 44638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 44648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(del_vrfid, optval, uint32_t, optsize); 44658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*del_vrfid > SCTP_MAX_VRF_ID) { 44668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->num_vrfs == 1) { 44718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't delete last one */ 44728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 44778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't add more once you are bound */ 44788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 44838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 44848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*del_vrfid == inp->m_vrf_ids[i]) { 44858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 44868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 44908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 44918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 44928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 44938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (i != (inp->num_vrfs - 1)) { 44958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Take bottom one and move to this slot */ 44968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids[i] = inp->m_vrf_ids[(inp->num_vrfs-1)]; 44978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 44988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*del_vrfid == inp->def_vrf_id) { 44998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Take the first one as the new default */ 45008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_vrf_id = inp->m_vrf_ids[0]; 45018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Drop the number by one killing last one */ 45038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->num_vrfs--; 45048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 45058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 45068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 45078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 45088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADD_VRF_ID: 45118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 45128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 45138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *add_vrfid; 45148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int i; 45158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 45168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(add_vrfid, optval, uint32_t, optsize); 45178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*add_vrfid > SCTP_MAX_VRF_ID) { 45188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 45198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 45208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) { 45238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Can't add more once you are bound */ 45248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 45258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 45268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 45298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Verify its not already here */ 45308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 45318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*add_vrfid == inp->m_vrf_ids[i]) { 45328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 45338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 45348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 45358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->num_vrfs + 1) > inp->vrf_size) { 45398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* need to grow array */ 45408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *tarray; 45418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(tarray, uint32_t *, 45428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sizeof(uint32_t) * (inp->vrf_size + SCTP_DEFAULT_VRF_SIZE)), 45438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_M_MVRF); 45448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tarray == NULL) { 45458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 45468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 45478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 45488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(tarray, inp->m_vrf_ids, (sizeof(uint32_t) * inp->vrf_size)); 45518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF); 45528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids = tarray; 45538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->vrf_size += SCTP_DEFAULT_VRF_SIZE; 45548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->m_vrf_ids[inp->num_vrfs] = *add_vrfid; 45568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->num_vrfs++; 45578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 45588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 45598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 45608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EOPNOTSUPP; 45618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 45628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 45638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DELAYED_SACK: 45658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 45668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sack_info *sack; 45678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 45688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize); 45698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id); 45708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 45718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay > SCTP_MAX_SACK_DELAY) 45728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = SCTP_MAX_SACK_DELAY; 45738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (MSEC_TO_TICKS(sack->sack_delay) < 1) { 45748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sack->sack_delay = TICKS_TO_MSEC(1); 45758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 45788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 45798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_ack = sack->sack_delay; 45808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_freq) { 45828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sack_freq = sack->sack_freq; 45838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 45858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 45868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 45878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 45888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_FUTURE_ASSOC) || 45898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_ALL_ASSOC)) { 45908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 45918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 45928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(sack->sack_delay); 45938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_freq) { 45958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_sack_freq = sack->sack_freq; 45968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 45988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 45998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sack->sack_assoc_id == SCTP_CURRENT_ASSOC) || 46008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sack->sack_assoc_id == SCTP_ALL_ASSOC)) { 46018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 46028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 46038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 46048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_delay) { 46058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_ack = sack->sack_delay; 46068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sack->sack_freq) { 46088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sack_freq = sack->sack_freq; 46098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 46138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_CHUNK: 46188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 46198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authchunk *sauth; 46208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sauth, optval, struct sctp_authchunk, optsize); 46228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 46248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_add_chunk(sauth->sauth_chunk, inp->sctp_ep.local_auth_chunks)) { 46258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 46268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 46278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 46298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_KEY: 46328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 46338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkey *sca; 46348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_keyhead *shared_keys; 46358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sharedkey_t *shared_key; 46368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_key_t *key = NULL; 46378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t size; 46388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sca, optval, struct sctp_authkey, optsize); 46408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sca->sca_keylength == 0) { 46418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = optsize - sizeof(struct sctp_authkey); 46428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 46438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sca->sca_keylength + sizeof(struct sctp_authkey) <= optsize) { 46448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size = sca->sca_keylength; 46458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 46468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 46478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 46488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sca->sca_assoc_id); 46528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 46538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 46548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_keys = &stcb->asoc.shared_keys; 46558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* clear the cached keys for this key id */ 46568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 46578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 46588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * create the new shared key and 46598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * insert/replace it 46608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 46618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size > 0) { 46628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen key = sctp_set_key(sca->sca_key, (uint32_t) size); 46638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (key == NULL) { 46648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 46658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 46668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key = sctp_alloc_sharedkey(); 46718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (shared_key == NULL) { 46728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_key(key); 46738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 46748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 46758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 46778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 46788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->key = key; 46798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->keyid = sca->sca_keynumber; 46808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_insert_sharedkey(shared_keys, shared_key); 46818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 46828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 46838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 46848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 46858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sca->sca_assoc_id == SCTP_FUTURE_ASSOC) || 46868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sca->sca_assoc_id == SCTP_ALL_ASSOC)) { 46878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 46888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_keys = &inp->sctp_ep.shared_keys; 46898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 46908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * clear the cached keys on all assocs for 46918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * this key id 46928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 46938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber); 46948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 46958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * create the new shared key and 46968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * insert/replace it 46978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 46988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size > 0) { 46998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen key = sctp_set_key(sca->sca_key, (uint32_t) size); 47008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (key == NULL) { 47018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 47028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 47038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 47048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key = sctp_alloc_sharedkey(); 47088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (shared_key == NULL) { 47098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_key(key); 47108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 47118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 47128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 47138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->key = key; 47168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->keyid = sca->sca_keynumber; 47178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_insert_sharedkey(shared_keys, shared_key); 47188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 47198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sca->sca_assoc_id == SCTP_CURRENT_ASSOC) || 47218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sca->sca_assoc_id == SCTP_ALL_ASSOC)) { 47228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 47238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 47248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 47258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_keys = &stcb->asoc.shared_keys; 47268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* clear the cached keys for this key id */ 47278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_clear_cachedkeys(stcb, sca->sca_keynumber); 47288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 47298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * create the new shared key and 47308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * insert/replace it 47318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 47328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (size > 0) { 47338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen key = sctp_set_key(sca->sca_key, (uint32_t) size); 47348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (key == NULL) { 47358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 47368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 47378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key = sctp_alloc_sharedkey(); 47408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (shared_key == NULL) { 47418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_key(key); 47428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 47438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 47448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->key = key; 47468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen shared_key->keyid = sca->sca_keynumber; 47478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_insert_sharedkey(shared_keys, shared_key); 47488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 47498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 47518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_HMAC_IDENT: 47568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 47578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_hmacalgo *shmac; 47588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_hmaclist_t *hmaclist; 47598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint16_t hmacid; 47608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t i; 47618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 47628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize); 47638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) { 47648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4768000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 47698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hmaclist = sctp_alloc_hmaclist(shmac->shmac_number_of_idents); 47708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hmaclist == NULL) { 47718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM); 47728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOMEM; 47738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < shmac->shmac_number_of_idents; i++) { 47768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen hmacid = shmac->shmac_idents[i]; 47778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_add_hmacid(hmaclist, hmacid)) { 47788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* invalid HMACs were found */; 47798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_hmaclist(hmaclist); 47828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto sctp_set_hmac_done; 47838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < hmaclist->num_algo; i++) { 47868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) { 47878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* already in list */ 478817fca683d16802e8836f92ca2d9761a4798ada4bt break; 47898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 479117fca683d16802e8836f92ca2d9761a4798ada4bt if (i == hmaclist->num_algo) { 479217fca683d16802e8836f92ca2d9761a4798ada4bt /* not found in list */ 47938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_hmaclist(hmaclist); 47948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 47958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 47968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 47978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 47988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* set it on the endpoint */ 47998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 48008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_ep.local_hmacs) 48018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_hmaclist(inp->sctp_ep.local_hmacs); 48028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.local_hmacs = hmaclist; 48038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_set_hmac_done: 48058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 48068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_ACTIVE_KEY: 48088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 48098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *scact; 48108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, optsize); 48128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id); 48138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* set the active key on the right place */ 48158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 48168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* set the active key on the assoc */ 48178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_setactivekey(stcb, 48188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen scact->scact_keynumber)) { 48198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 48208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ, 48218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen EINVAL); 48228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 48238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 48258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 48268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 48278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 48288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_FUTURE_ASSOC) || 48298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_ALL_ASSOC)) { 48308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 48318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber)) { 48328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 48338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 48348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((scact->scact_assoc_id == SCTP_CURRENT_ASSOC) || 48388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scact->scact_assoc_id == SCTP_ALL_ASSOC)) { 48398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 48408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 48418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 48428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_auth_setactivekey(stcb, scact->scact_keynumber); 48438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 48448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 48468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 48498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_DELETE_KEY: 48518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 48528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *scdel; 48538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(scdel, optval, struct sctp_authkeyid, optsize); 48558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, scdel->scact_assoc_id); 48568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* delete the key from the right place */ 48588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 48598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber)) { 48608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 48618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 48628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 48648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 48658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 48668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 48678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scdel->scact_assoc_id == SCTP_FUTURE_ASSOC) || 48688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scdel->scact_assoc_id == SCTP_ALL_ASSOC)) { 48698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 48708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber)) { 48718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 48728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 48738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 48758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((scdel->scact_assoc_id == SCTP_CURRENT_ASSOC) || 48778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (scdel->scact_assoc_id == SCTP_ALL_ASSOC)) { 48788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 48798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 48808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 48818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_delete_sharedkey(stcb, scdel->scact_keynumber); 48828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 48838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 48858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 48888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 48898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTH_DEACTIVATE_KEY: 48908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 48918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_authkeyid *keyid; 48928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(keyid, optval, struct sctp_authkeyid, optsize); 48948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, keyid->scact_assoc_id); 48958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 48968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* deactivate the key from the right place */ 48978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 48988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_deact_sharedkey(stcb, keyid->scact_keynumber)) { 48998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 49008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 49018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 49038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 49048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 49058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 49068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (keyid->scact_assoc_id == SCTP_FUTURE_ASSOC) || 49078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (keyid->scact_assoc_id == SCTP_ALL_ASSOC)) { 49088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 49098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_deact_sharedkey_ep(inp, keyid->scact_keynumber)) { 49108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 49118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 49128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 49148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((keyid->scact_assoc_id == SCTP_CURRENT_ASSOC) || 49168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (keyid->scact_assoc_id == SCTP_ALL_ASSOC)) { 49178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 49188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 49198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 49208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_deact_sharedkey(stcb, keyid->scact_keynumber); 49218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 49228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 49248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4928c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen case SCTP_ENABLE_STREAM_RESET: 4929c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen { 4930c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct sctp_assoc_value *av; 49312d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen 4932c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 4933c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (av->assoc_value & (~SCTP_ENABLE_VALUE_MASK)) { 4934c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 4935c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 4936c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 4937c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 4938c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 4939c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb) { 49402d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value; 4941c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 4942c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } else { 4943c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4944c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 4945c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 4946c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 4947c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_WLOCK(inp); 49482d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen inp->local_strreset_support = (uint8_t)av->assoc_value; 4949c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_WUNLOCK(inp); 4950c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 4951c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 4952c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 4953c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_RLOCK(inp); 4954c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 4955c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_LOCK(stcb); 49562d0d9bb5933907b2ca1c951b8ab47ba48437e72btuexen stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value; 4957c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 4958c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 4959c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_INP_RUNLOCK(inp); 4960c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 49618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4962c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 4963c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 4964c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 49658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RESET_STREAMS: 49668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 4967000a5bac556b28e74e4e98c540f66b1743e9312dtuexen struct sctp_reset_streams *strrst; 49681de509107029a81699453f86fcced3c7b7fb534btuexen int i, send_out = 0; 49691de509107029a81699453f86fcced3c7b7fb534btuexen int send_in = 0; 49708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 4971c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(strrst, optval, struct sctp_reset_streams, optsize); 4972c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, strrst->srs_assoc_id); 49738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 49748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 49758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 49768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 49788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.peer_supports_strreset == 0) { 49798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 4980c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen * Peer does not support the chunk type. 49818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 4982c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 4983c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EOPNOTSUPP; 4984c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 4985c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 4986c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 49878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.stream_reset_outstanding) { 49888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 49898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 49908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 49918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 49928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 4993c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (strrst->srs_flags & SCTP_STREAM_RESET_INCOMING) { 49948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen send_in = 1; 4995c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 4996c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (strrst->srs_flags & SCTP_STREAM_RESET_OUTGOING) { 49978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen send_out = 1; 4998c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 4999c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((send_in == 0) && (send_out == 0)) { 5000c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5001c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 5002c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5003c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5004c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5005c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen for (i = 0; i < strrst->srs_number_streams; i++) { 5006c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((send_in) && 5007c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (strrst->srs_stream_list[i] > stcb->asoc.streamincnt)) { 5008c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 50098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5010c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 50118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5012c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((send_out) && 5013c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (strrst->srs_stream_list[i] > stcb->asoc.streamoutcnt)) { 5014c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 5015c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 5016c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 50178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5018c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5019c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (error) { 5020c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5021c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5022c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5023c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = sctp_send_str_reset_req(stcb, strrst->srs_number_streams, 5024c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen strrst->srs_stream_list, 5025c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen send_out, send_in, 0, 0, 0, 0, 0); 5026c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 5027c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 5028c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5029c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5030c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5031c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen case SCTP_ADD_STREAMS: 5032c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen { 5033c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen struct sctp_add_streams *stradd; 50341de509107029a81699453f86fcced3c7b7fb534btuexen uint8_t addstream = 0; 50351de509107029a81699453f86fcced3c7b7fb534btuexen uint16_t add_o_strmcnt = 0; 50361de509107029a81699453f86fcced3c7b7fb534btuexen uint16_t add_i_strmcnt = 0; 5037c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 5038c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(stradd, optval, struct sctp_add_streams, optsize); 5039c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, stradd->sas_assoc_id); 5040c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb == NULL) { 5041c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 5042c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = ENOENT; 5043c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5044c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 50451de509107029a81699453f86fcced3c7b7fb534btuexen if (stcb->asoc.peer_supports_strreset == 0) { 50461de509107029a81699453f86fcced3c7b7fb534btuexen /* 50471de509107029a81699453f86fcced3c7b7fb534btuexen * Peer does not support the chunk type. 50481de509107029a81699453f86fcced3c7b7fb534btuexen */ 50491de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 50501de509107029a81699453f86fcced3c7b7fb534btuexen error = EOPNOTSUPP; 50511de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_TCB_UNLOCK(stcb); 50521de509107029a81699453f86fcced3c7b7fb534btuexen break; 50531de509107029a81699453f86fcced3c7b7fb534btuexen } 50541de509107029a81699453f86fcced3c7b7fb534btuexen if (stcb->asoc.stream_reset_outstanding) { 50551de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 50561de509107029a81699453f86fcced3c7b7fb534btuexen error = EALREADY; 50571de509107029a81699453f86fcced3c7b7fb534btuexen SCTP_TCB_UNLOCK(stcb); 50581de509107029a81699453f86fcced3c7b7fb534btuexen break; 50591de509107029a81699453f86fcced3c7b7fb534btuexen } 5060c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((stradd->sas_outstrms == 0) && 5061c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen (stradd->sas_instrms == 0)) { 5062c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EINVAL; 5063c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen goto skip_stuff; 5064c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5065c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stradd->sas_outstrms) { 50668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addstream = 1; 50678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We allocate here */ 5068c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen add_o_strmcnt = stradd->sas_outstrms; 5069c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if ((((int)add_o_strmcnt) + ((int)stcb->asoc.streamoutcnt)) > 0x0000ffff) { 50708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* You can't have more than 64k */ 50718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 50728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto skip_stuff; 50738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5075c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stradd->sas_instrms) { 5076c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen int cnt; 50778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 5078c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen addstream |= 2; 5079c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* We allocate inside sctp_send_str_reset_req() */ 5080c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen add_i_strmcnt = stradd->sas_instrms; 5081c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen cnt = add_i_strmcnt; 5082c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen cnt += stcb->asoc.streamincnt; 5083c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (cnt > 0x0000ffff) { 5084c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* You can't have more than 64k */ 50858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5086c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen goto skip_stuff; 50878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5088c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (cnt > (int)stcb->asoc.max_inbound_streams) { 5089c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* More than you are allowed */ 50908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5091c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen goto skip_stuff; 50928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 50938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5094c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 0, addstream, add_o_strmcnt, add_i_strmcnt, 0); 5095c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 50968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen skip_stuff: 5097c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5098c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5099c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5100c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen case SCTP_RESET_ASSOC: 5101c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen { 5102c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen uint32_t *value; 5103c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen 5104c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize); 5105c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) *value); 5106c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb == NULL) { 5107c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 5108c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = ENOENT; 5109c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5110c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5111c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb->asoc.peer_supports_strreset == 0) { 5112c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen /* 5113c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen * Peer does not support the chunk type. 5114c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen */ 5115c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 5116c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EOPNOTSUPP; 51178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5120c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen if (stcb->asoc.stream_reset_outstanding) { 5121c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 5122c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = EALREADY; 5123c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen SCTP_TCB_UNLOCK(stcb); 5124c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen break; 5125c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen } 5126c2352ecab1d9ed208f1d33f5dc0088689b2f210etuexen error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, 1, 0, 0, 0, 0); 51278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED); 51288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONNECT_X: 51328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 51338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 51348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 51358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_do_connect_x(so, inp, optval, optsize, p, 0); 51388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONNECT_X_DELAYED: 51408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) { 51418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 51428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 51438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_do_connect_x(so, inp, optval, optsize, p, 1); 51468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_CONNECT_X_COMPLETE: 51488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 51498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 51508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 51518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIXME MT: check correct? */ 51538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize); 51548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* find tcb */ 51568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 51578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 51588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 51598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 51608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 51618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, sa); 51628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 51648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 51658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 51668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 51678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 51688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 51698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 51708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL); 51718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 51728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 51738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 51768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 51778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 51788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOENT; 51798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.delayed_connection == 1) { 51828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.delayed_connection = 0; 51838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 51848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, 51858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.primary_destination, 51868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_9); 51878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 51888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 51898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 51908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * already expired or did not use delayed 51918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * connectx 51928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 51938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 51948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 51958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 51978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 51988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 51998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAX_BURST: 52008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 52018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version < 900000 52028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint8_t *burst; 52038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(burst, optval, uint8_t, optsize); 52058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 52078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_burst = *burst; 52088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 52098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 52108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 52118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 52138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 52148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 52168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.max_burst = av->assoc_value; 52178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 52188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 52208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 52218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC) || 52228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 52238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 52248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_burst = av->assoc_value; 52258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 52268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((av->assoc_id == SCTP_CURRENT_ASSOC) || 52288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_ALL_ASSOC)) { 52298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 52308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 52318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 52328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.max_burst = av->assoc_value; 52338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 52348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 52368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 52398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 52408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_MAXSEG: 52428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 52438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assoc_value *av; 52448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int ovh; 52458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize); 52478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, av->assoc_id); 52488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 52508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 52518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 52538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 52558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value) { 52568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_frag_point = (av->assoc_value + ovh); 52578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 52598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 52618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 52638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 52648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (av->assoc_id == SCTP_FUTURE_ASSOC)) { 52658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 52668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* FIXME MT: I think this is not in tune with the API ID */ 52678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (av->assoc_value) { 52688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_frag_point = (av->assoc_value + ovh); 52698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT; 52718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 52738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 52758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 52768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 52798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENTS: 52818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 52828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event_subscribe *events; 52838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, optsize); 52858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 52878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_data_io_event) { 52888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 52898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 52918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_association_event) { 52948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 52958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 52968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT); 52978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 52988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 52998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_address_event) { 53008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 53018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT); 53038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_send_failure_event) { 53068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 53078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 53098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_peer_error_event) { 53128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR); 53138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR); 53158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_shutdown_event) { 53188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 53198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 53218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_partial_delivery_event) { 53248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 53258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT); 53278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_adaptation_layer_event) { 53308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 53318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 53338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_authentication_event) { 53368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT); 53378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT); 53398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_sender_dry_event) { 53428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT); 53438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT); 53458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_stream_reset_event) { 53488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 53498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 53518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 53538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 53548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 53558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 53568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 53578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_association_event) { 53588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT); 53598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT); 53618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_address_event) { 53638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT); 53648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT); 53668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_send_failure_event) { 53688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 53698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT); 53718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_peer_error_event) { 53738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR); 53748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR); 53768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_shutdown_event) { 53788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 53798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT); 53818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_partial_delivery_event) { 53838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT); 53848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT); 53868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_adaptation_layer_event) { 53888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 53898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT); 53918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_authentication_event) { 53938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT); 53948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 53958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT); 53968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 53978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_sender_dry_event) { 53988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT); 53998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 54008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT); 54018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_stream_reset_event) { 54038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 54048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 54058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT); 54068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 54088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Send up the sender dry event only for 1-to-1 style sockets. */ 54108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (events->sctp_sender_dry_event) { 54118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 54128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 54138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 54148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 54158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 54168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&stcb->asoc.send_queue) && 54178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&stcb->asoc.sent_queue) && 54188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.stream_queue_cnt == 0)) { 54198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED); 54208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 54228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 54268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_LAYER: 54298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setadaptation *adap_bits; 54318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize); 54338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 54348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind; 54359a8642036bc992ec39f872443a35f8c545cc28c4t inp->sctp_ep.adaptation_layer_indicator_provided = 1; 54368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 54378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_DEBUG 54408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_INITIAL_DBG_SEQ: 54418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t *vvv; 54438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(vvv, optval, uint32_t, optsize); 54458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 54468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.initial_sequence_debug = *vvv; 54478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 54488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 54518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SEND_PARAM: 54528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndrcvinfo *s_info; 54548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, optsize); 54568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id); 54578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 54598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) { 54608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send))); 54618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 54628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 54638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 54648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 54668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 54678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 54688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 54698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC) || 54708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC)) { 54718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 54728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&inp->def_send, s_info, min(optsize, sizeof(inp->def_send))); 54738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 54748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((s_info->sinfo_assoc_id == SCTP_CURRENT_ASSOC) || 54768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC)) { 54778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 54788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 54798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 54808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) { 54818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send))); 54828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 54848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 54868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 54898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 54908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_PARAMS: 54918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 54928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrparams *paddrp; 54938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 54948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 54958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize); 54968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id); 54978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 54988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 54998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address); 55008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 55028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 55038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 55048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 55058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 55068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, 55078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&paddrp->spp_address, 55088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &net, NULL, NULL); 55098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 55108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 55118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 5513b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 55148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 55158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)&paddrp->spp_address; 55178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 55188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 55198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 55218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 55228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 55238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 55248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 55258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 55268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 55298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 55308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 55318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 55328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 55338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 55358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 55368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 55378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 55388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 55398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 55428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 554375cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 554475cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 554575cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 554675cd23222c96d5ebe5a9082c57a263f917f1462btuexen 554775cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 554875cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 554975cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 555075cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 555175cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 555275cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 555375cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 555475cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 555575cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 55568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 55578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 55588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 55598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 55608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 55618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* sanity checks */ 55648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_HB_ENABLE) && (paddrp->spp_flags & SPP_HB_DISABLE)) { 55658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 55668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 55678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 55688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 55698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_PMTUD_ENABLE) && (paddrp->spp_flags & SPP_PMTUD_DISABLE)) { 55728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) 55738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 55748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 55758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 55768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 55798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************TCB SPECIFIC SET ******************/ 55808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 55818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do we change the timer for HB, we run 55828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * only one? 55838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 5584b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int ovh = 0; 55858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 55878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_OVERHEAD; 55888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 55898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ovh = SCTP_MED_V4_OVERHEAD; 55908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 55918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 55928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* network sets ? */ 55938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 55948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************NET SPECIFIC SET ******************/ 55958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_DISABLE) { 55968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) && 55978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen !(net->dest_state & SCTP_ADDR_NOHB)) { 55988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 55998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 56008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NOHB; 56028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_ENABLE) { 56048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval) { 56058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = paddrp->spp_hbinterval; 56068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 56078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = 0; 56088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 56108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 56118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 56128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NOHB; 56138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_DEMAND) { 56158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* on demand HB */ 56168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 5617a4ffbccf5bed12adde7673f02ca4b0ca3214262ctuexen sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED); 56188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 56198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) { 56218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 56228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 56238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 56248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NO_PMTUD; 5626b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t net->mtu = paddrp->spp_pathmtu + ovh; 5627b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t if (net->mtu < stcb->asoc.smallest_mtu) { 5628b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t sctp_pathmtu_adjustment(stcb, net->mtu); 56298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 56328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 56338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 56348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NO_PMTUD; 56368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_pathmaxrxt) { 56388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 56398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 56408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 56418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->error_count <= paddrp->spp_pathmaxrxt) && 56448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->error_count > net->pf_threshold)) { 56458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_PF; 56468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 56478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 56488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 56498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 56528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 56538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 565447674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 56558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count <= paddrp->spp_pathmaxrxt) { 56588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 565947674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 56608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = paddrp->spp_pathmaxrxt; 56638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_DSCP) { 56658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp = paddrp->spp_dscp & 0xfc; 56668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp |= 0x01; 56678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 56698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 56708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->ro._l_addr.sa.sa_family == AF_INET6) { 56718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 56728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel |= 0x80000000; 56738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 56768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/ 56788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_pathmaxrxt) { 56798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt; 56808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 56818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 56828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 56838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 56848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 56868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->error_count <= paddrp->spp_pathmaxrxt) && 56878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->error_count > net->pf_threshold)) { 56888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_PF; 56898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 56908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 56918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 56928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 56958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count > paddrp->spp_pathmaxrxt) { 56968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 569747674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 56988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 56998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 57008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->error_count <= paddrp->spp_pathmaxrxt) { 57018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 570247674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 57038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = paddrp->spp_pathmaxrxt; 57068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 57098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_ENABLE) { 57108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval) { 57118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval; 57128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 57138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.heart_beat_delay = 0; 57148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Turn back on the timer */ 57168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 57178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval) { 57188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = paddrp->spp_hbinterval; 57198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 57208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->heart_beat_delay = 0; 57218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_NOHB) { 57238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NOHB; 57248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, 57268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 57278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net); 57288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 57308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_DISABLE) { 57328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 57338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_NOHB)) { 57348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NOHB; 57358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED)) { 57368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 57378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 57418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) { 57438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 57448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 57458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net, 57468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10); 57478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_NO_PMTUD; 5749b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t net->mtu = paddrp->spp_pathmtu + ovh; 5750b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t if (net->mtu < stcb->asoc.smallest_mtu) { 5751b0ecb3b4b8b93d682b7175db3ac8711eb74e8502t sctp_pathmtu_adjustment(stcb, net->mtu); 57528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 57558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 57578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 57588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { 57598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net); 57608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_NO_PMTUD; 57628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 57648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_DSCP) { 57668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 57678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp = paddrp->spp_dscp & 0xfc; 57688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dscp |= 0x01; 57698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_dscp = paddrp->spp_dscp & 0xfc; 57718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_dscp |= 0x01; 57728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 57748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 57758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 57768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->ro._l_addr.sa.sa_family == AF_INET6) { 57778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 57788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->flowlabel |= 0x80000000; 57798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 57828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.default_flowlabel |= 0x80000000; 57838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 57858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 57868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 57878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 57888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /************************NO TCB, SET TO default stuff ******************/ 57898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 57908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 57918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC)) { 57928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 57938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 57948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For the TOS/FLOWLABEL stuff you set it 57958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * with the options on the socket 57968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 57978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_pathmaxrxt) { 57988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt; 57998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) 58028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0; 58038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else if (paddrp->spp_hbinterval) { 58048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL) 58058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen paddrp->spp_hbinterval= SCTP_MAX_HB_INTERVAL; 58068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval); 58078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_ENABLE) { 58108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) { 58118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0; 58128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_hbinterval) { 58138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval); 58148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 58168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_HB_DISABLE) { 58178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); 58188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { 58208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 58218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { 58228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); 58238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_DSCP) { 58258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_dscp = paddrp->spp_dscp & 0xfc; 58268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_dscp |= 0x01; 58278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 58298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) { 58308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 58318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff; 58328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.default_flowlabel |= 0x80000000; 58338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 58368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 58378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 58388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 58398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 58408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 58438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RTOINFO: 58458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 58468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_rtoinfo *srto; 58478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t new_init, new_min, new_max; 58488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, optsize); 58508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id); 58518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 58528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 58538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_initial) 58548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = srto->srto_initial; 58558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 58568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = stcb->asoc.initial_rto; 58578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_max) 58588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = srto->srto_max; 58598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 58608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = stcb->asoc.maxrto; 58618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_min) 58628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = srto->srto_min; 58638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 58648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = stcb->asoc.minrto; 58658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((new_min <= new_init) && (new_init <= new_max)) { 58668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.initial_rto = new_init; 58678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.maxrto = new_max; 58688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.minrto = new_min; 58698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 58708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 58718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 58728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 58748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 58758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 58768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 58778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (srto->srto_assoc_id == SCTP_FUTURE_ASSOC)) { 58788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 58798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_initial) 58808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = srto->srto_initial; 58818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 58828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_init = inp->sctp_ep.initial_rto; 58838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_max) 58848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = srto->srto_max; 58858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 58868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_max = inp->sctp_ep.sctp_maxrto; 58878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (srto->srto_min) 58888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = srto->srto_min; 58898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 58908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen new_min = inp->sctp_ep.sctp_minrto; 58918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((new_min <= new_init) && (new_init <= new_max)) { 58928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.initial_rto = new_init; 58938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_maxrto = new_max; 58948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.sctp_minrto = new_min; 58958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 58968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 58978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 58988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 58998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 59008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 59028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5903000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 59048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 59068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOCINFO: 59088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 59098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_assocparams *sasoc; 59108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, optsize); 59128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id); 59138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life) { 59148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* boundary check the cookie life */ 59158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life < 1000) 59168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = 1000; 59178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life > SCTP_MAX_COOKIE_LIFE) { 59188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sasoc->sasoc_cookie_life = SCTP_MAX_COOKIE_LIFE; 59198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 59228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_asocmaxrxt) 59238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt; 59248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life) { 59258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life); 59268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 59288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 59308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 59318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC)) { 59328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 59338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_asocmaxrxt) 59348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt; 59358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sasoc->sasoc_cookie_life) { 59368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life); 59378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 59398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 59418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 5942000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 59438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 59458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_INITMSG: 59478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 59488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_initmsg *sinit; 59498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, optsize); 59518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 59528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_num_ostreams) 59538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams; 59548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_max_instreams) 59568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams; 59578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_max_attempts) 59598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.max_init_times = sinit->sinit_max_attempts; 59608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sinit->sinit_max_init_timeo) 59628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo; 59638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 59648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 59658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PRIMARY_ADDR: 59678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 59688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setprim *spa; 59698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 59708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize); 59728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id); 59738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 59758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 59768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr); 59778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 59788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 59798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 59808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 59818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 59828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 59838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, 59848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&spa->ssp_addr, 59858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &net, NULL, NULL); 59868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 59878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 59888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 59908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 59918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((stcb) && (net)) { 59928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net != stcb->asoc.primary_destination) && 59938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) { 59948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Ok we need to set it */ 59958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) { 5996000a5bac556b28e74e4e98c540f66b1743e9312dtuexen if ((stcb->asoc.alternate) && 59978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (!(net->dest_state & SCTP_ADDR_PF)) && 59988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->dest_state & SCTP_ADDR_REACHABLE)) { 59998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_remote_addr(stcb->asoc.alternate); 60008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.alternate = NULL; 60018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 60058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 60068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 60078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 60098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 60108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 60128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_DYNAMIC_PRIMARY: 60148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 60158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen union sctp_sockstore *ss; 60168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 6017b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int i, fnd = 0; 60188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if !defined(__Windows__) && !defined(__Userspace__) 60208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 60218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct proc *proc; 60228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __FreeBSD__ 60248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version > 602000 60258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = priv_check(curthread, 60268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen PRIV_NETINET_RESERVEDPORT); 60278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif __FreeBSD_version >= 500000 60288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser((struct thread *)p); 60298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 60308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(p); 60318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__APPLE__) 60338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen proc = (struct proc *)p; 60348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (p) { 60358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(proc->p_ucred, &proc->p_acflag); 60368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 60378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 60388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 60408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = suser(p, 0); 60418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) 60448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 60458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 60468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(ss, optval, union sctp_sockstore, optsize); 60478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* SUPER USER CHECK? */ 60488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 60498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 60508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf_id == inp->m_vrf_ids[i]) { 60518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 60528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 60538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 60568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 60578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 60588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 60598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 60618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_dynamic_set_primary(&ss->sa, vrf_id); 60628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 60638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SET_PEER_PRIMARY_ADDR: 60658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 60668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_setpeerprim *sspp; 60678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 60688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize); 60698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id); 60708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 60718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *ifa; 60728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ifa = sctp_find_ifa_by_addr((struct sockaddr *)&sspp->sspp_addr, 60738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED); 60748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (ifa == NULL) { 60758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 60768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 60778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_of_it; 60788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 60808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Must validate the ifa found is in our ep */ 60818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 6082b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int found = 0; 60838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 60848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (laddr->ifa == NULL) { 60858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n", 60868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen __FUNCTION__); 60878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 60888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (laddr->ifa == ifa) { 60908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen found = 1; 60918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 60928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!found) { 60958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 60968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 60978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_of_it; 60988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 60998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_set_primary_ip_address_sa(stcb, 61018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&sspp->sspp_addr) != 0) { 61028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_of_it: 61068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 61078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 61088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_BINDX_ADD_ADDR: 61148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 61158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *addrs; 61168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 61178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct thread *td; 61188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 61198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen td = (struct thread *)p; 61208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, 61228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen optsize); 61238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 61248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET) { 6125c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) { 61268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 61318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) { 61328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 61338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 61378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 61398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET6) { 6140c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) { 61418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 61468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && (error = prison_local_ip6(td->td_ucred, &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 61478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) { 61488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 61498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 61538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 61558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 61568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_bindx_add_address(so, inp, addrs->addr, 61598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addrs->sget_assoc_id, vrf_id, 61608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &error, p); 61618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_BINDX_REM_ADDR: 61648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 61658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_getaddresses *addrs; 61668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 61678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct thread *td; 61688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen td = (struct thread *)p; 61698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 61708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize); 61728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 61738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET) { 6174c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in)) { 61758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 61808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)(addrs->addr))->sin_addr)))) { 61818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 61828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 61868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 61878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 61888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addrs->addr->sa_family == AF_INET6) { 6189c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen if (optsize < sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6)) { 61908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 61918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 61928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 61938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 61948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 61958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (td != NULL && 61968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (error = prison_local_ip6(td->td_ucred, 61978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &(((struct sockaddr_in6 *)(addrs->addr))->sin6_addr), 61988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) { 61998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error); 62008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 62048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 62058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 62068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 62078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62090ac02f34d6041cd0018437596a5a9a94685e6919tuexen sctp_bindx_delete_address(inp, addrs->addr, 62108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addrs->sget_assoc_id, vrf_id, 62118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &error); 62128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef __APPLE__ 62158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_LISTEN_FIX: 62168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* only applies to one-to-many sockets */ 62178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 62188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* make sure the ACCEPTCONN flag is OFF */ 62198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_options &= ~SO_ACCEPTCONN; 62208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 62218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* otherwise, not allowed */ 62228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 62238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 62248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* __APPLE__ */ 62278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_EVENT: 62288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 62298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_event *event; 62308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t event_type; 62318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 62328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, optsize); 62338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, event->se_assoc_id); 62348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (event->se_type) { 62358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ASSOC_CHANGE: 62368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT; 6237000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_CHANGE: 62398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPADDREVNT; 6240000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_REMOTE_ERROR: 62428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVPEERERR; 6243000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SEND_FAILED: 62458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT; 6246000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SHUTDOWN_EVENT: 62488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT; 6249000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_ADAPTATION_INDICATION: 62518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT; 6252000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PARTIAL_DELIVERY_EVENT: 62548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_PDAPIEVNT; 6255000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_AUTHENTICATION_EVENT: 62578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_AUTHEVNT; 6258000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_STREAM_RESET_EVENT: 62608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT; 6261000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_SENDER_DRY_EVENT: 62638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = SCTP_PCB_FLAGS_DRYEVNT; 6264000a5bac556b28e74e4e98c540f66b1743e9312dtuexen break; 62658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_NOTIFICATIONS_STOPPED_EVENT: 62668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 62678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 62688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 62698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 6270298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_ASSOC_RESET_EVENT: 6271298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT; 6272298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 6273298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen case SCTP_STREAM_CHANGE_EVENT: 6274298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT; 6275298df7f2536ca4836a5f1909e4ea2f32f5a3ffcftuexen break; 62765741e159bdf238ef4b61085d6fbfea2947386238tuexen case SCTP_SEND_FAILED_EVENT: 62775741e159bdf238ef4b61085d6fbfea2947386238tuexen event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT; 62785741e159bdf238ef4b61085d6fbfea2947386238tuexen break; 62798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 62808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen event_type = 0; 62818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 62828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 62838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 62848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event_type > 0) { 62868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 62878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event->se_on) { 62888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, event_type); 62898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event_type == SCTP_PCB_FLAGS_DRYEVNT) { 62908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (TAILQ_EMPTY(&stcb->asoc.send_queue) && 62918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_EMPTY(&stcb->asoc.sent_queue) && 62928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (stcb->asoc.stream_queue_cnt == 0)) { 62938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED); 62948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 62978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, event_type); 62988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 62998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 63008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 63028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * We don't want to send up a storm of events, 63038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * so return an error for sender dry events 63048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 63058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((event_type == SCTP_PCB_FLAGS_DRYEVNT) && 63068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) && 63078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 6308000a5bac556b28e74e4e98c540f66b1743e9312dtuexen ((event->se_assoc_id == SCTP_ALL_ASSOC) || 63098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_CURRENT_ASSOC))) { 63108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP); 63118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOTSUP; 63128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 63158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 63168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_FUTURE_ASSOC) || 63178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_ALL_ASSOC)) { 63188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 63198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event->se_on) { 63208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, event_type); 63218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, event_type); 63238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 63258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((event->se_assoc_id == SCTP_CURRENT_ASSOC) || 63278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (event->se_assoc_id == SCTP_ALL_ASSOC)) { 63288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 63298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 63308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 63318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (event->se_on) { 63328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_on(inp, stcb, event_type); 63338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_stcb_feature_off(inp, stcb, event_type); 63358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 63378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 63398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVRCVINFO: 63458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 63468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int *onoff; 63478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 63488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(onoff, optval, int, optsize); 63498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 63508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*onoff != 0) { 63518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 63528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO); 63548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 63568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_RECVNXTINFO: 63598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 63608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int *onoff; 63618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 63628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(onoff, optval, int, optsize); 63638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 63648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (*onoff != 0) { 63658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 63668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO); 63688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 63708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 63718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_SNDINFO: 63738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 63748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_sndinfo *info; 63758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint16_t policy; 63768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 63778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, optsize); 63788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id); 63798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 63808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 63818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (info->snd_sid < stcb->asoc.streamoutcnt) { 63828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_stream = info->snd_sid; 63838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 63848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags = info->snd_flags; 63858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= policy; 63868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_ppid = info->snd_ppid; 63878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_context = info->snd_context; 63888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 63908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 63918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 63928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 63938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 63948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 63958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 63968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_FUTURE_ASSOC) || 63978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_ALL_ASSOC)) { 63988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 63998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_stream = info->snd_sid; 64008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags); 64018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags = info->snd_flags; 64028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags |= policy; 64038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_ppid = info->snd_ppid; 64048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_context = info->snd_context; 64058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 64068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((info->snd_assoc_id == SCTP_CURRENT_ASSOC) || 64088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->snd_assoc_id == SCTP_ALL_ASSOC)) { 64098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 64108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 64118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 64128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (info->snd_sid < stcb->asoc.streamoutcnt) { 64138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_stream = info->snd_sid; 64148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags); 64158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags = info->snd_flags; 64168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= policy; 64178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_ppid = info->snd_ppid; 64188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_context = info->snd_context; 64198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 64218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 64238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_DEFAULT_PRINFO: 64288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 64298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_default_prinfo *info; 64308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 64318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize); 64328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id); 64338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 64348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (PR_SCTP_INVALID_POLICY(info->pr_policy)) { 64358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 64368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 64378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 64408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags &= 0xfff0; 64418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= info->pr_policy; 64428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_timetolive = info->pr_value; 64438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 64448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 64458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 64468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 64478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_FUTURE_ASSOC) || 64488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_ALL_ASSOC)) { 64498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 64508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags &= 0xfff0; 64518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_flags |= info->pr_policy; 64528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->def_send.sinfo_timetolive = info->pr_value; 64538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 64548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((info->pr_assoc_id == SCTP_CURRENT_ASSOC) || 64568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (info->pr_assoc_id == SCTP_ALL_ASSOC)) { 64578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 64588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 64598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 64608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags &= 0xfff0; 64618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_flags |= info->pr_policy; 64628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_send.sinfo_timetolive = info->pr_value; 64638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 64648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 64668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 64698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case SCTP_PEER_ADDR_THLDS: 64718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Applies to the specific association */ 64728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 64738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_paddrthlds *thlds; 64748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 64758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 64768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize); 64778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id); 64788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = NULL; 64798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 64808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net = sctp_findnet(stcb, (struct sockaddr *)&thlds->spt_assoc_id); 64818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 64828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() wil 64838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 64848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 64858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 64868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 64878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, 64888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct sockaddr *)&thlds->spt_assoc_id, 64898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen &net, NULL, NULL); 64908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 64918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 64928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 64938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6494b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 64958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *sa; 64968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 64978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sa = (struct sockaddr *)&thlds->spt_assoc_id; 64988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 64998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET) { 65008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 65018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 65028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)sa; 65038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin->sin_addr.s_addr) { 65048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 65058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 65068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 65078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 65108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 65118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 65128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sa->sa_family == AF_INET6) { 65138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 65148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 65158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)sa; 65168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 65178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 65188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 65198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 65208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else 65238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 652475cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 652575cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 652675cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 652775cd23222c96d5ebe5a9082c57a263f917f1462btuexen 652875cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 652975cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 653075cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 653175cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 653275cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 653375cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 653475cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 653575cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 653675cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 65378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 65388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 65398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 65408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 65418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 65428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 65458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net) { 65468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 65478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathmaxrxt) || 65488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathpfthld)) { 65498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 65508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 65528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathpfthld) && 65538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathmaxrxt)) { 65548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_PF; 65558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 65568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 65578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 65588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 65618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold > thlds->spt_pathmaxrxt) { 65628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 656347674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 65648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 65668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold <= thlds->spt_pathmaxrxt) { 65678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 656847674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 65698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = thlds->spt_pathmaxrxt; 65728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->pf_threshold = thlds->spt_pathpfthld; 65738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 65748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 65758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_PF) { 65768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathmaxrxt) || 65778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathpfthld)) { 65788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_PF; 65798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 65818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((net->failure_threshold > thlds->spt_pathpfthld) && 65828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (net->failure_threshold <= thlds->spt_pathmaxrxt)) { 65838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_PF; 65848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_hb(stcb, net, SCTP_SO_LOCKED); 65858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3); 65868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); 65878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 65908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold > thlds->spt_pathmaxrxt) { 65918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 659247674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED); 65938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 65958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (net->failure_threshold <= thlds->spt_pathmaxrxt) { 65968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->dest_state |= SCTP_ADDR_REACHABLE; 659747674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED); 65988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 65998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->failure_threshold = thlds->spt_pathmaxrxt; 66018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net->pf_threshold = thlds->spt_pathpfthld; 66028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_net_failure = thlds->spt_pathmaxrxt; 66048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.def_net_pf_threshold = thlds->spt_pathpfthld; 66058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 66088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 66098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC)) { 66108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 66118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_net_failure = thlds->spt_pathmaxrxt; 66128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_ep.def_net_pf_threshold = thlds->spt_pathpfthld; 66138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 66148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 66158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 66168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 66178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 66198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 66208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 6621153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen case SCTP_REMOTE_UDP_ENCAPS_PORT: 6622153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 6623153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_udpencaps *encaps; 6624153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sctp_nets *net; 662581616c6a3e184f46276632dd15aa489cd06d94dftuexen 6626153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize); 6627153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id); 6628153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 6629153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = sctp_findnet(stcb, (struct sockaddr *)&encaps->sue_address); 6630153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 6631153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen /* We increment here since sctp_findassociation_ep_addr() wil 6632153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * do a decrement if it finds the stcb as long as the locked 6633153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen * tcb (last argument) is NOT a TCB.. aka NULL. 6634153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen */ 6635153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net = NULL; 6636153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_INCR_REF(inp); 6637153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen stcb = sctp_findassociation_ep_addr(&inp, (struct sockaddr *)&encaps->sue_address, &net, NULL, NULL); 6638153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb == NULL) { 6639153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_DECR_REF(inp); 6640153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6641153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6642b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if (stcb && (net == NULL)) { 6643153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr *sa; 6644000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 6645153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sa = (struct sockaddr *)&encaps->sue_address; 6646153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET 6647153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET) { 6648153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 6649153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in *sin; 6650153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin = (struct sockaddr_in *)sa; 6651153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sin->sin_addr.s_addr) { 6652153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6653153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 6654153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 6655153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 6656153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6657153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 6658153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 6659153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#ifdef INET6 6660153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (sa->sa_family == AF_INET6) { 6661153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen struct sockaddr_in6 *sin6; 6662153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 6663153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen sin6 = (struct sockaddr_in6 *)sa; 6664153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 6665153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6666153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 6667153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 6668153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 6669153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6670153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else 6671153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen#endif 667275cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 667375cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sa->sa_family == AF_CONN) { 667475cd23222c96d5ebe5a9082c57a263f917f1462btuexen struct sockaddr_conn *sconn; 667575cd23222c96d5ebe5a9082c57a263f917f1462btuexen 667675cd23222c96d5ebe5a9082c57a263f917f1462btuexen sconn = (struct sockaddr_conn *)sa; 667775cd23222c96d5ebe5a9082c57a263f917f1462btuexen if (sconn->sconn_addr != NULL) { 667875cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 667975cd23222c96d5ebe5a9082c57a263f917f1462btuexen SCTP_TCB_UNLOCK(stcb); 668075cd23222c96d5ebe5a9082c57a263f917f1462btuexen error = EINVAL; 668175cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 668275cd23222c96d5ebe5a9082c57a263f917f1462btuexen } 668375cd23222c96d5ebe5a9082c57a263f917f1462btuexen } else 668475cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 6685153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen { 6686153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EAFNOSUPPORT; 6687153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 6688153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 6689153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 6690153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6691153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6692153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen 6693153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (stcb) { 6694153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if (net) { 6695153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen net->port = encaps->sue_port; 6696153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 6697153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen stcb->asoc.port = encaps->sue_port; 6698153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6699153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_TCB_UNLOCK(stcb); 6700153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 6701153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 6702153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || 6703153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC)) { 6704153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_WLOCK(inp); 6705153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen inp->sctp_ep.port = encaps->sue_port; 6706153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_INP_WUNLOCK(inp); 6707153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } else { 6708153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 6709153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen error = EINVAL; 6710153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6711153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 6712153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen break; 6713153408b8be3c05b43cd0703fa015f6b3d7f2404btuexen } 67148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 67158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); 67168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ENOPROTOOPT; 67178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 67188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } /* end switch (opt) */ 67198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 67208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 67218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 67238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 67248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ctloutput(struct socket *so, struct sockopt *sopt) 67258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 67268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *optval = NULL; 67278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen size_t optsize = 0; 67288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p; 67298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 67308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sopt->sopt_level != IPPROTO_SCTP) { 67328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* wrong proto level... send back up to IP */ 67338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 67348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (INP_CHECK_SOCKAF(so, AF_INET6)) 67358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ip6_ctloutput(so, sopt); 67368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* INET6 */ 67370612043f643c9b26245564c05defca64d472060etuexen#if defined(INET) && defined(INET6) 67388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 67398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 67418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = ip_ctloutput(so, sopt); 67428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 67448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen optsize = sopt->sopt_valsize; 67468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optsize) { 67478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT); 67488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (optval == NULL) { 67498a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS); 67508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOBUFS); 67518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sooptcopyin(sopt, optval, optsize, optsize); 67538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 67548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(optval, SCTP_M_SOCKOPT); 67558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out; 67568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version >= 500000) || defined(__Windows__) 67598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen p = (void *)sopt->sopt_td; 67608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 67618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen p = (void *)sopt->sopt_p; 67628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sopt->sopt_dir == SOPT_SET) { 67648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p); 67658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (sopt->sopt_dir == SOPT_GET) { 67668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p); 67678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 67688a29867a84996e7ee31a638ab89256ca7d2dc9b0tuexen SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 67698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 67708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((error == 0) && (optval != NULL)) { 67728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sooptcopyout(sopt, optval, optsize); 67738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(optval, SCTP_M_SOCKOPT); 67748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (optval != NULL) { 67758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE(optval, SCTP_M_SOCKOPT); 67768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 67778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenout: 67788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 67798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 67808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 67818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 67828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 67838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 67848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 67858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) 67868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 67878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 67888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) 67898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 67908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr, struct proc *p) 67918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 67928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) || defined(__Userspace__) 67938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 67948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr) 67958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 67968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *p = NULL; 67978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 67988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 67998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct sockaddr *addr, PKTHREAD p) 68008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 68018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 68028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int 68038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_connect(struct socket *so, struct mbuf *nam, struct proc *p) 68048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 68058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 68068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 6810b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen int i, fnd = 0; 68118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 68138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int create_lock_on = 0; 68148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 68158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 6816b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen struct sctp_tcb *stcb = NULL; 68178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 68192fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 68208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* I made the same as TCP since we are not setup? */ 68218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 68228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 68238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr == NULL) { 68258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 68268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return EINVAL; 68278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 68308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TODO __Userspace__ falls into this code for IPv6 stuff at the moment... */ 68318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 683223273859c39742f09cc5ec7c9bf32ff225661e82tuexen#if !defined(__Windows__) && !defined(__Userspace_os_Linux) && !defined(__Userspace_os_Windows) 68338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (addr->sa_family) { 68348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 68358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 68368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 68378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 68388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6p; 68398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_len != sizeof(struct sockaddr_in6)) { 68428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 68438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 68448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 68468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6p = (struct sockaddr_in6 *)addr; 68478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6p->sin6_addr)) != 0) { 68488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 68498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 68508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 68538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 68568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 68578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 68588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 68598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sinp; 68608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68620612043f643c9b26245564c05defca64d472060etuexen#if !defined(__Userspace_os_Windows) 68638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (addr->sa_len != sizeof(struct sockaddr_in)) { 68648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 68658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 68668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 686781616c6a3e184f46276632dd15aa489cd06d94dftuexen#endif 68688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 68698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sinp = (struct sockaddr_in *)addr; 68708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (p != NULL && (error = prison_remote_ip4(p->td_ucred, &sinp->sin_addr)) != 0) { 68718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error); 68728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 68738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 68768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 68798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 68808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EAFNOSUPPORT); 68818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 68838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 68848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_LOCK(inp); 68858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen create_lock_on = 1; 68868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 68888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 68898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 68908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Should I really unlock ? */ 68918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 68928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EFAULT; 68938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 68948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 68958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 68968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 68978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (addr->sa_family == AF_INET6)) { 68988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 68998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 69008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 69018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69027988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 69037988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 69047988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) && 69057988ea8f0c067cf3757e798b473b1ae4d34b6dfdt (addr->sa_family != AF_CONN)) { 69067988ea8f0c067cf3757e798b473b1ae4d34b6dfdt SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 69077988ea8f0c067cf3757e798b473b1ae4d34b6dfdt error = EINVAL; 69087988ea8f0c067cf3757e798b473b1ae4d34b6dfdt goto out_now; 69097988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 69107988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 69118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 69128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_PCB_FLAGS_UNBOUND) { 69138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Bind a ephemeral port */ 69148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_inpcb_bind(so, NULL, NULL, p); 69158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 69168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 69178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Now do we connect? */ 69208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 69218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 69228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 69238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 69248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 69258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 69278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 69288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are already connected AND the TCP model */ 69298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 69308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EADDRINUSE; 69318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 69328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 69348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 69358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 69368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 69378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 69388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We increment here since sctp_findassociation_ep_addr() will 69398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * do a decrement if it finds the stcb as long as the locked 69408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * tcb (last argument) is NOT a TCB.. aka NULL. 69418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 69428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_INCR_REF(inp); 69438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 69448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 69458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 69468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 69478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 69488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb != NULL) { 69518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Already have or am bring up an association */ 69528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 69538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EALREADY; 69548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 69558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 69588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_MVRF 69598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen for (i = 0; i < inp->num_vrfs; i++) { 69608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (vrf_id == inp->m_vrf_ids[i]) { 69618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 69628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 69638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 69668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 69678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EINVAL; 69688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 69698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are GOOD to go */ 69728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p); 69738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 69748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Gak! no memory */ 69758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto out_now; 69768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 69788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 69798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Set the connected flag so we can queue data */ 69808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen soisconnecting(so); 69818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 69838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 69848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* initialize authentication parameters for the assoc */ 69868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_initialize_auth_params(inp, stcb); 69878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 69898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 69908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen out_now: 69918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (create_lock_on) { 69928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_ASOC_CREATE_UNLOCK(inp); 69938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 69948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 69958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 6996b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (error); 69978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 69988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 69998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 70007a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#if defined(__Userspace__) 70017a9f1edd34bf82c194a2f9d0c64394f431175138tuexenint 70027a9f1edd34bf82c194a2f9d0c64394f431175138tuexensctpconn_connect(struct socket *so, struct sockaddr *addr) 70037a9f1edd34bf82c194a2f9d0c64394f431175138tuexen{ 70047a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#ifdef SCTP_MVRF 70057a9f1edd34bf82c194a2f9d0c64394f431175138tuexen int i, fnd = 0; 70067a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 70077a9f1edd34bf82c194a2f9d0c64394f431175138tuexen void *p = NULL; 70087a9f1edd34bf82c194a2f9d0c64394f431175138tuexen int error = 0; 70097a9f1edd34bf82c194a2f9d0c64394f431175138tuexen int create_lock_on = 0; 70107a9f1edd34bf82c194a2f9d0c64394f431175138tuexen uint32_t vrf_id; 70117a9f1edd34bf82c194a2f9d0c64394f431175138tuexen struct sctp_inpcb *inp; 70127a9f1edd34bf82c194a2f9d0c64394f431175138tuexen struct sctp_tcb *stcb = NULL; 70137a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 70147a9f1edd34bf82c194a2f9d0c64394f431175138tuexen inp = (struct sctp_inpcb *)so->so_pcb; 70157a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (inp == NULL) { 70167a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* I made the same as TCP since we are not setup? */ 70177a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 70187a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (ECONNRESET); 70197a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70207a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (addr == NULL) { 70217a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 70227a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return EINVAL; 70237a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70247a9f1edd34bf82c194a2f9d0c64394f431175138tuexen switch (addr->sa_family) { 7025f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef INET 7026f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t case AF_INET: 7027f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 7028f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t if (addr->sa_len != sizeof(struct sockaddr_in)) { 70297a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 70307a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EINVAL); 70317a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 7032f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#endif 70337a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 70347a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 7035f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef INET6 7036f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t case AF_INET6: 7037f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 7038f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t if (addr->sa_len != sizeof(struct sockaddr_in6)) { 70397a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 70407a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EINVAL); 70417a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 7042f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#endif 70437a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 70447a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 70457a9f1edd34bf82c194a2f9d0c64394f431175138tuexen case AF_CONN: 7046f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 70477a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (addr->sa_len != sizeof(struct sockaddr_conn)) { 70487a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 70497a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EINVAL); 70507a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 7051f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#endif 70527a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 70537a9f1edd34bf82c194a2f9d0c64394f431175138tuexen default: 70547a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 70557a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (EAFNOSUPPORT); 70567a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70577a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_INCR_REF(inp); 70587a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_ASOC_CREATE_LOCK(inp); 70597a9f1edd34bf82c194a2f9d0c64394f431175138tuexen create_lock_on = 1; 70607a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 70617a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 70627a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || 70637a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 70647a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Should I really unlock ? */ 70657a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT); 70667a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EFAULT; 70677a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 70687a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70697a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#ifdef INET6 70707a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && 70717a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (addr->sa_family == AF_INET6)) { 70727a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 70737a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EINVAL; 70747a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 70757a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70767a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 70777a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == SCTP_PCB_FLAGS_UNBOUND) { 70787a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Bind a ephemeral port */ 70797a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = sctp_inpcb_bind(so, NULL, NULL, p); 70807a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (error) { 70817a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 70827a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70837a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70847a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Now do we connect? */ 70857a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) && 70867a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) { 70877a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 70887a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EINVAL; 70897a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 70907a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70917a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 70927a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 70937a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* We are already connected AND the TCP model */ 70947a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 70957a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EADDRINUSE; 70967a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 70977a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 70987a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 70997a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_RLOCK(inp); 71007a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 71017a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_RUNLOCK(inp); 71027a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } else { 71037a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* We increment here since sctp_findassociation_ep_addr() will 71047a9f1edd34bf82c194a2f9d0c64394f431175138tuexen * do a decrement if it finds the stcb as long as the locked 71057a9f1edd34bf82c194a2f9d0c64394f431175138tuexen * tcb (last argument) is NOT a TCB.. aka NULL. 71067a9f1edd34bf82c194a2f9d0c64394f431175138tuexen */ 71077a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_INCR_REF(inp); 71087a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 71097a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb == NULL) { 71107a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_DECR_REF(inp); 71117a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } else { 71127a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_TCB_UNLOCK(stcb); 71137a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71147a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71157a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb != NULL) { 71167a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Already have or am bring up an association */ 71177a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY); 71187a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EALREADY; 71197a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 71207a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71217a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 71227a9f1edd34bf82c194a2f9d0c64394f431175138tuexen vrf_id = inp->def_vrf_id; 71237a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#ifdef SCTP_MVRF 71247a9f1edd34bf82c194a2f9d0c64394f431175138tuexen for (i = 0; i < inp->num_vrfs; i++) { 71257a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (vrf_id == inp->m_vrf_ids[i]) { 71267a9f1edd34bf82c194a2f9d0c64394f431175138tuexen fnd = 1; 71277a9f1edd34bf82c194a2f9d0c64394f431175138tuexen break; 71287a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71297a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71307a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (!fnd) { 71317a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 71327a9f1edd34bf82c194a2f9d0c64394f431175138tuexen error = EINVAL; 71337a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 71347a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71357a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 71367a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* We are GOOD to go */ 71377a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p); 71387a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb == NULL) { 71397a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Gak! no memory */ 71407a9f1edd34bf82c194a2f9d0c64394f431175138tuexen goto out_now; 71417a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71427a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 71437a9f1edd34bf82c194a2f9d0c64394f431175138tuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 71447a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* Set the connected flag so we can queue data */ 71457a9f1edd34bf82c194a2f9d0c64394f431175138tuexen soisconnecting(so); 71467a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71477a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT); 71487a9f1edd34bf82c194a2f9d0c64394f431175138tuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 71497a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 71507a9f1edd34bf82c194a2f9d0c64394f431175138tuexen /* initialize authentication parameters for the assoc */ 71517a9f1edd34bf82c194a2f9d0c64394f431175138tuexen sctp_initialize_auth_params(inp, stcb); 71527a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 71537a9f1edd34bf82c194a2f9d0c64394f431175138tuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 71547a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_TCB_UNLOCK(stcb); 71557a9f1edd34bf82c194a2f9d0c64394f431175138tuexen out_now: 71567a9f1edd34bf82c194a2f9d0c64394f431175138tuexen if (create_lock_on) { 71577a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 71587a9f1edd34bf82c194a2f9d0c64394f431175138tuexen } 71597a9f1edd34bf82c194a2f9d0c64394f431175138tuexen 71607a9f1edd34bf82c194a2f9d0c64394f431175138tuexen SCTP_INP_DECR_REF(inp); 71617a9f1edd34bf82c194a2f9d0c64394f431175138tuexen return (error); 71627a9f1edd34bf82c194a2f9d0c64394f431175138tuexen} 71637a9f1edd34bf82c194a2f9d0c64394f431175138tuexen#endif 71648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 71658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 71668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 700000 71678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, int backlog, struct thread *p) 71688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 71698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, struct thread *p) 71708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 71718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Windows__) 71728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, int backlog, PKTHREAD p) 71738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Userspace__) 71748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, int backlog, struct proc *p) 71758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 71768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_listen(struct socket *so, struct proc *p) 71778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 71788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 71798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 71808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Note this module depends on the protocol processing being called 71818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * AFTER any socket level flags and backlog are applied to the 71828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * socket. The traditional way that the socket flags are applied is 71838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * AFTER protocol processing. We have made a change to the 71848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sys/kern/uipc_socket.c module to reverse this but this MUST be in 71858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * place if the socket API for SCTP is to work properly. 71868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 71878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 71888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error = 0; 71898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 7190000a5bac556b28e74e4e98c540f66b1743e9312dtuexen 71918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 71922fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 71938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* I made the same as TCP since we are not setup? */ 71948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 71958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 71968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 71978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) { 71988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* See if we have a listener */ 71998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *tinp; 72008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen union sctp_sockstore store, *sp; 72018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp = &store; 72038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 72048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* not bound all */ 72058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 72068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 72078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 72088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memcpy(&store, &laddr->ifa->address, sizeof(store)); 72098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sp->sa.sa_family) { 72108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 72118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 72128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp->sin.sin_port = inp->sctp_lport; 72138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 72168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 72178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp->sin6.sin6_port = inp->sctp_lport; 72188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 722075cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 722175cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 722275cd23222c96d5ebe5a9082c57a263f917f1462btuexen sp->sconn.sconn_port = inp->sctp_lport; 722375cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 722475cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 72258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 72268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); 72298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tinp && (tinp != inp) && 72308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 72318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 72328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tinp->sctp_socket->so_qlimit)) { 72338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we have a listener already and its not this inp. */ 72348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(tinp); 72358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 72368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (tinp) { 72378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(tinp); 72388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 72418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Setup a local addr bound all */ 72428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(&store, 0, sizeof(store)); 72438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (sp->sa.sa_family) { 72448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 72458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 72468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sin.sin_port = inp->sctp_lport; 72478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 72508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 72518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sp->sin6.sin6_port = inp->sctp_lport; 72528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 725475cd23222c96d5ebe5a9082c57a263f917f1462btuexen#if defined(__Userspace__) 725575cd23222c96d5ebe5a9082c57a263f917f1462btuexen case AF_CONN: 725675cd23222c96d5ebe5a9082c57a263f917f1462btuexen sp->sconn.sconn_port = inp->sctp_lport; 725775cd23222c96d5ebe5a9082c57a263f917f1462btuexen break; 725875cd23222c96d5ebe5a9082c57a263f917f1462btuexen#endif 72598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 72608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 72618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 72638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 72648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_family = AF_INET6; 7265f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 72668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_len = sizeof(struct sockaddr_in6); 72678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 72718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 72728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_family = AF_INET; 7273f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 72748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store.sa.sa_len = sizeof(struct sockaddr_in); 72758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id); 72798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (tinp && (tinp != inp) && 72808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) && 72818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 72828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (tinp->sctp_socket->so_qlimit)) { 72838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* we have a listener already and its not this inp. */ 72848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(tinp); 72858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 72868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else if (tinp) { 72878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_DECR_REF(inp); 72888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 72928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_LOCK_LOGGING 72938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) { 72948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK); 72958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 72968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 72978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_LOCK(so); 72988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Userspace__) 72998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = solisten_proto_check(so); 73008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (error) { 73018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 73028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 73038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 73048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) && 73078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 73088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* The unlucky case 73098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - We are in the tcp pool with this guy. 73108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - Someone else is in the main inp slot. 73118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - We must move this guy (the listener) to the main slot 73128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * - We must then move the guy that was listener to the TCP Pool. 73138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 73148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_swap_inpcb_for_listen(inp)) { 73158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto in_use; 73168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 73208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 73218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We are already connected AND the TCP model */ 73228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in_use: 73238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 73248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 73258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE); 73268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EADDRINUSE); 73278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 73298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) { 73308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* We must do a bind. */ 73318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 73328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((error = sctp_inpcb_bind(so, NULL, NULL, p))) { 73338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* bind error, probably perm */ 73348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 73358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_LOCK(so); 7337000a5bac556b28e74e4e98c540f66b1743e9312dtuexen } 73388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 500000) || defined(__Windows__) || defined(__Userspace__) 73398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 700000 || defined(__Windows__) || defined(__Userspace__) 73408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* It appears for 7.0 and on, we must always call this. */ 73418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen solisten_proto(so, backlog); 73428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 73438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) == 0) { 73448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen solisten_proto(so); 73458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 73498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* remove the ACCEPTCONN flag for one-to-many sockets */ 7350907b9e7d7c75f02c3d1f6c70016127990e8fe648t#if defined(__Userspace__) 73516435cc0024abc9f2dabba9feb634081e246d342bt so->so_options &= ~SCTP_SO_ACCEPTCONN; 7352907b9e7d7c75f02c3d1f6c70016127990e8fe648t#else 73538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_options &= ~SO_ACCEPTCONN; 7354907b9e7d7c75f02c3d1f6c70016127990e8fe648t#endif 73558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 700000 || defined(__Windows__) || defined(__Userspace__) 73588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (backlog == 0) { 73598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* turning off listen */ 7360907b9e7d7c75f02c3d1f6c70016127990e8fe648t#if defined(__Userspace__) 7361907b9e7d7c75f02c3d1f6c70016127990e8fe648t so->so_options &= ~SCTP_SO_ACCEPTCONN; 7362907b9e7d7c75f02c3d1f6c70016127990e8fe648t#else 73638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen so->so_options &= ~SO_ACCEPTCONN; 7364907b9e7d7c75f02c3d1f6c70016127990e8fe648t#endif 73658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 73668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCK_UNLOCK(so); 73688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 73698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 73708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstatic int sctp_defered_wakeup_cnt = 0; 73728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 73748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 73758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_accept(struct socket *so, struct sockaddr **addr) 73768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 73788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_accept(struct socket *so, struct sockaddr *addr, int *namelen, 73798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen void *accept_info, int *accept_info_len) 73808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 73828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_accept(struct socket *so, struct mbuf *nam) 73838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 73848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 73858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 73878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 73888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen union sctp_sockstore store; 73898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 73908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 73918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error; 73928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 73938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 73948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 73958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 73962fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 73978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 73988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 73998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 74018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { 74028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 74038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP); 74048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EOPNOTSUPP); 74058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (so->so_state & SS_ISDISCONNECTED) { 74078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 74088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ECONNABORTED); 74098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNABORTED); 74108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 74128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 74138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 74148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 74158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ECONNRESET); 74168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 74188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 74198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen store = stcb->asoc.primary_destination->ro._l_addr; 74208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE; 74218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 74228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (store.sa.sa_family) { 74238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 74248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET: 74258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 74268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 74278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 74288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 74298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 74308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin == NULL) 74318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 74328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 74338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin = (struct sockaddr_in *)addr; 74348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero((caddr_t)sin, sizeof(*sin)); 74358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_family = AF_INET; 74377b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 74388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_len = sizeof(*sin); 74398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74407988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin->sin_port = store.sin.sin_port; 74417988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin->sin_addr = store.sin.sin_addr; 74428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 74438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *addr = (struct sockaddr *)sin; 74448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif !defined(__Panda__) 74458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin); 74468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 74488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 74518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case AF_INET6: 74528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 74538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in6 *sin6; 74548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 74558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 74568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); 74578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin6 == NULL) 74588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 74598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 74608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6 = (struct sockaddr_in6 *)addr; 74618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero((caddr_t)sin6, sizeof(*sin6)); 74628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_family = AF_INET6; 74647b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 74658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_len = sizeof(*sin6); 74668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74677988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin6->sin6_port = store.sin6.sin6_port; 74687988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sin6->sin6_addr = store.sin6.sin6_addr; 74698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(SCTP_EMBEDDED_V6_SCOPE) 74708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef SCTP_KAME 74718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((error = sa6_recoverscope(sin6)) != 0) { 74728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin6); 74738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 74748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 74768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) 74778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 74788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * sin6->sin6_scope_id = 74798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * ntohs(sin6->sin6_addr.s6_addr16[1]); 74808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 74818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen in6_recoverscope(sin6, &sin6->sin6_addr, NULL); /* skip ifp check */ 74828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 74838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin6->sin6_scope_id = 0; /* XXX */ 74848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_KAME */ 74858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 74860612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 74878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen *addr = (struct sockaddr *)sin6; 74888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif !defined(__Panda__) 74898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin6); 74908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 74928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 74938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 74947988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#if defined(__Userspace__) 74957988ea8f0c067cf3757e798b473b1ae4d34b6dfdt case AF_CONN: 74967988ea8f0c067cf3757e798b473b1ae4d34b6dfdt { 74977988ea8f0c067cf3757e798b473b1ae4d34b6dfdt struct sockaddr_conn *sconn; 74987988ea8f0c067cf3757e798b473b1ae4d34b6dfdt 74997988ea8f0c067cf3757e798b473b1ae4d34b6dfdt SCTP_MALLOC_SONAME(sconn, struct sockaddr_conn *, sizeof(struct sockaddr_conn)); 75007988ea8f0c067cf3757e798b473b1ae4d34b6dfdt if (sconn == NULL) { 75017988ea8f0c067cf3757e798b473b1ae4d34b6dfdt return (ENOMEM); 75027988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 75037988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_family = AF_CONN; 75047988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#ifdef HAVE_SCONN_LEN 75057988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_len = sizeof(struct sockaddr_conn); 75067988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 75077988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_port = store.sconn.sconn_port; 75087988ea8f0c067cf3757e798b473b1ae4d34b6dfdt sconn->sconn_addr = store.sconn.sconn_addr; 75097988ea8f0c067cf3757e798b473b1ae4d34b6dfdt *addr = (struct sockaddr *)sconn; 75107988ea8f0c067cf3757e798b473b1ae4d34b6dfdt break; 75117988ea8f0c067cf3757e798b473b1ae4d34b6dfdt } 75127988ea8f0c067cf3757e798b473b1ae4d34b6dfdt#endif 75138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 75148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* TSNH */ 75158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 75168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Wake any delayed sleep action */ 75188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { 75198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 75208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE; 75218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) { 75228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; 75238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 75248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&inp->sctp_socket->so_snd); 75258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sowriteable(inp->sctp_socket)) { 75268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 75278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*__Userspace__ calling sowwakup_locked because of SOCKBUF_LOCK above. */ 75288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) 75308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sowwakeup_locked(inp->sctp_socket); 75318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 75328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 75338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* socket is locked */ 75348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sowwakeup(inp->sctp_socket); 75368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 75388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd); 75398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 75418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) { 75438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; 75448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 75458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_LOCK(&inp->sctp_socket->so_rcv); 75468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (soreadable(inp->sctp_socket)) { 75478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_defered_wakeup_cnt++; 75488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__Userspace__) 75498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /*__Userspace__ calling sorwakup_locked because of SOCKBUF_LOCK above */ 75508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__) 75528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sorwakeup_locked(inp->sctp_socket); 75538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 75548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__APPLE__) 75558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* socket is locked */ 75568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sorwakeup(inp->sctp_socket); 75588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 75608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv); 75618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WLOCK(inp); 75638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_WUNLOCK(inp); 75658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { 75678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 75688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_7); 75698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 75708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 75718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 75728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET 75748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 75758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 75768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ingetaddr(struct socket *so, struct sockaddr **addr) 75778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 75788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin; 75798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 75808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ingetaddr(struct socket *so, struct sockaddr *addr) 75818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 75828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = (struct sockaddr_in *)addr; 75838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 75848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_ingetaddr(struct socket *so, struct mbuf *nam) 75858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 75868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 75878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 75888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 75898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 75908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_ifa *sctp_ifa; 75918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 75928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 75938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * Do the malloc first in case it blocks. 75948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 75958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 75968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 75978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin == NULL) 75988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 75998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 76008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen bzero(sin, sizeof(*sin)); 76018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 76028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin); 76038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(sin, 0, sizeof(*sin)); 76048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 76058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_family = AF_INET; 76067b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 76078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_len = sizeof(*sin); 76088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 76098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 76108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!inp) { 76118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 76128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 76138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 76148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7615b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ECONNRESET); 76168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 76188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_port = inp->sctp_lport; 76198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 76208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 76218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 76228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin_a; 76238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 76248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int fnd; 76258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 76278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 76288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto notConn; 76298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 0; 76318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_a = NULL; 76328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 76338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 76348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_a = (struct sockaddr_in *)&net->ro._l_addr; 76358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin_a == NULL) 76368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* this will make coverity happy */ 76378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen continue; 76388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin_a->sin_family == AF_INET) { 76408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 76418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 76428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if ((!fnd) || (sin_a == NULL)) { 76458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* punt */ 76468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 76478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen goto notConn; 76488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen vrf_id = inp->def_vrf_id; 76518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ifa = sctp_source_address_selection(inp, 76528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb, 76538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (sctp_route_t *)&net->ro, 76548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen net, 0, vrf_id); 76558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sctp_ifa) { 76568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr = sctp_ifa->address.sin.sin_addr; 76578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_free_ifa(sctp_ifa); 76588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 76608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 76618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* For the bound all case you get back 0 */ 76628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen notConn: 76638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr.s_addr = 0; 76648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } else { 76678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Take the first IPv4 address in the list */ 76688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_laddr *laddr; 76698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int fnd = 0; 76708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 76728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (laddr->ifa->address.sa.sa_family == AF_INET) { 76738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin_a; 76748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_a = (struct sockaddr_in *)&laddr->ifa->address.sa; 76768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr = sin_a->sin_addr; 76778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 76788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 76798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 76828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 76838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 76848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 76858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 76868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 7687b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ENOENT); 76888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 76908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 76918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 76928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*addr) = (struct sockaddr *)sin; 76938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 76948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 76958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 76968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 76978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 76988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 76998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_peeraddr(struct socket *so, struct sockaddr **addr) 77008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 7701845436a72b5767f30403c3b77c457488703143a9tuexen struct sockaddr_in *sin; 77028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 77038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_peeraddr(struct socket *so, struct sockaddr *addr) 77048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 77058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = (struct sockaddr_in *)addr; 77068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 77078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_peeraddr(struct socket *so, struct mbuf *nam) 77088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 77098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 77108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int fnd; 77138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr_in *sin_a; 77148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp; 77158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_tcb *stcb; 77168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_nets *net; 77178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Do the malloc first in case it blocks. */ 77198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 77208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); 77218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin == NULL) 77228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (ENOMEM); 77238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif defined(__Panda__) 77248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(sin, 0, sizeof(*sin)); 77258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 77268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_BUF_LEN(nam) = sizeof(*sin); 77278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen memset(sin, 0, sizeof(*sin)); 77288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_family = AF_INET; 77307b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 77318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_len = sizeof(*sin); 77328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen inp = (struct sctp_inpcb *)so->so_pcb; 7735b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen if ((inp == NULL) || 7736b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) { 7737b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen /* UDP type and listeners will drop out here */ 77388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 77398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 77408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 7741b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN); 7742b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ENOTCONN); 77438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RLOCK(inp); 77458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 77468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb) { 77478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_LOCK(stcb); 77488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_INP_RUNLOCK(inp); 77508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (stcb == NULL) { 77518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 77528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 77538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 7755b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ECONNRESET); 77568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 0; 77588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 77598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin_a = (struct sockaddr_in *)&net->ro._l_addr; 77608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (sin_a->sin_family == AF_INET) { 77618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen fnd = 1; 77628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_port = stcb->rport; 77638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sin->sin_addr = sin_a->sin_addr; 77648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 77658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_TCB_UNLOCK(stcb); 77688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (!fnd) { 77698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* No IPv4 address */ 77708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 77718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_FREE_SONAME(sin); 77728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); 7774b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen return (ENOENT); 77758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 77768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 77778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (*addr) = (struct sockaddr *)sin; 77788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 77798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (0); 77808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 77818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 77828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 77838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenstruct pr_usrreqs sctp_usrreqs = { 77847fbcb406549bdf370031d2ad5befb44e39b95ffft#if defined(__FreeBSD__) 77858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_abort = sctp_abort, 77868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_accept = sctp_accept, 77878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_attach = sctp_attach, 77888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_bind = sctp_bind, 77898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_connect = sctp_connect, 77908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_control = in_control, 77918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#if __FreeBSD_version >= 690000 77928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_close = sctp_close, 77938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_detach = sctp_close, 77948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sopoll = sopoll_generic, 77958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_flush = sctp_flush, 77968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#else 77978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_detach = sctp_detach, 77988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sopoll = sopoll, 77998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_disconnect = sctp_disconnect, 78018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_listen = sctp_listen, 78028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_peeraddr = sctp_peeraddr, 78038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_send = sctp_sendm, 78048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_shutdown = sctp_shutdown, 78058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sockaddr = sctp_ingetaddr, 78068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_sosend = sctp_sosend, 78078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen .pru_soreceive = sctp_soreceive 78087fbcb406549bdf370031d2ad5befb44e39b95ffft#elif defined(__APPLE__) 78097fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_abort = sctp_abort, 78107fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_accept = sctp_accept, 78117fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_attach = sctp_attach, 78127fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_bind = sctp_bind, 78137fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_connect = sctp_connect, 78147fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_connect2 = pru_connect2_notsupp, 78157fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_control = in_control, 78167fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_detach = sctp_detach, 78177fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_disconnect = sctp_disconnect, 78187fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_listen = sctp_listen, 78197fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_peeraddr = sctp_peeraddr, 78207fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_rcvd = NULL, 78217fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_rcvoob = pru_rcvoob_notsupp, 78227fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_send = sctp_sendm, 78237fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sense = pru_sense_null, 78247fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_shutdown = sctp_shutdown, 78257fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sockaddr = sctp_ingetaddr, 78267fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sosend = sctp_sosend, 78277fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_soreceive = sctp_soreceive, 78287fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sopoll = sopoll 78297fbcb406549bdf370031d2ad5befb44e39b95ffft#elif defined(__Windows__) 78308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_abort, 78318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_accept, 78328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_attach, 78338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_bind, 78348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_connect, 78358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pru_connect2_notsupp, 78368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 78378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 78388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_disconnect, 78398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_listen, 78408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_peeraddr, 78418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 78428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pru_rcvoob_notsupp, 78438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 78448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen pru_sense_null, 78458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_shutdown, 78468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_flush, 78478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_ingetaddr, 78488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_sosend, 78498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_soreceive, 78508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sopoll_generic, 78518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen NULL, 78528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen sctp_close 78538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen}; 78558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#elif !defined(__Panda__) && !defined(__Userspace__) 78568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexenint 78578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexensctp_usrreq(so, req, m, nam, control) 78588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct socket *so; 78598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int req; 78608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct mbuf *m, *nam, *control; 78618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen{ 78628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct proc *p = curproc; 78638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen uint32_t vrf_id; 78648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_vrf *vrf; 78658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int error; 78668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen int family; 78678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sctp_inpcb *inp = (struct sctp_inpcb *)so->so_pcb; 78688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 78698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 78708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen family = so->so_proto->pr_domain->dom_family; 78718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (req == PRU_CONTROL) { 78728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (family) { 78738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PF_INET: 78748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = in_control(so, (long)m, (caddr_t)nam, 7875b7ebbfc1bd4420174e2a11b3b2bfd64281f44032tuexen (struct ifnet *)control); 78768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 78778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#ifdef INET6 78788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PF_INET6: 78798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = in6_control(so, (long)m, (caddr_t)nam, 78808c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen (struct ifnet *)control, p); 78818c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 78828c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 78838c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 78848c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 78858c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 78868c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78878c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 78888c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 78898c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen switch (req) { 78908c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_ATTACH: 78918c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_attach(so, family, p); 78928c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 78938c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_DETACH: 78948c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_detach(so); 78958c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 78968c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_BIND: 78978c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) { 78988c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 78998c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 79008c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79018c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_bind(so, nam, p); 79028c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79038c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_LISTEN: 79048c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_listen(so, p); 79058c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79068c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_CONNECT: 79078c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) { 79088c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 79098c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 79108c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79118c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_connect(so, nam, p); 79128c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79138c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_DISCONNECT: 79148c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_disconnect(so); 79158c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79168c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_ACCEPT: 79178c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) { 79188c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); 79198c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (EINVAL); 79208c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79218c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_accept(so, nam); 79228c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79238c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SHUTDOWN: 79248c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_shutdown(so); 79258c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79268c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79278c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_RCVD: 79288c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* 79298c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * For Open and Net BSD, this is real ugly. The mbuf *nam 79308c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * that is passed (by soreceive()) is the int flags c ast as 79318c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen * a (mbuf *) yuck! 79328c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen */ 79338c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79348c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79358c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SEND: 79368c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen /* Flags are ignored */ 79378c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen { 79388c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen struct sockaddr *addr; 79398c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79408c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen if (nam == NULL) 79418c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr = NULL; 79428c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen else 79438c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen addr = mtod(nam, struct sockaddr *); 79448c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79458c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_sendm(so, 0, m, addr, control, p); 79468c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79478c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79488c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_ABORT: 79498c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_abort(so); 79508c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79518c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79528c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SENSE: 79538c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 79548c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79558c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_RCVOOB: 79568c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 79578c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 79588c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79598c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SENDOOB: 79608c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT); 79618c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = EAFNOSUPPORT; 79628c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79638c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_PEERADDR: 79648c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_peeraddr(so, nam); 79658c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79668c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SOCKADDR: 79678c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = sctp_ingetaddr(so, nam); 79688c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79698c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen case PRU_SLOWTIMO: 79708c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen error = 0; 79718c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79728c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen default: 79738c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen break; 79748c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen } 79758c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen return (error); 79768c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen} 79778c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen 79788c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 79798c8a4cae58a2deed148551d56cb1ab315a55dbbdtuexen#endif 798060416fb97d019e56677da96dbdac6d48048822d3tuexen 798132a191a90b5c914a02047389c5b3197e08fc9841tuexen#if defined(__Userspace__) 798260416fb97d019e56677da96dbdac6d48048822d3tuexenint 7983d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenregister_recv_cb(struct socket *so, 7984d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data, 7985d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info)) 798660416fb97d019e56677da96dbdac6d48048822d3tuexen{ 7987d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen struct sctp_inpcb *inp; 798860416fb97d019e56677da96dbdac6d48048822d3tuexen 798960416fb97d019e56677da96dbdac6d48048822d3tuexen inp = (struct sctp_inpcb *) so->so_pcb; 799032a191a90b5c914a02047389c5b3197e08fc9841tuexen if (inp == NULL) { 799132a191a90b5c914a02047389c5b3197e08fc9841tuexen return (0); 799232a191a90b5c914a02047389c5b3197e08fc9841tuexen } 799332a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WLOCK(inp); 799460416fb97d019e56677da96dbdac6d48048822d3tuexen inp->recv_callback = receive_cb; 799532a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WUNLOCK(inp); 7996f57cf83923be449d11806a31f62bcc17e58832d6t return (1); 799760416fb97d019e56677da96dbdac6d48048822d3tuexen} 799860416fb97d019e56677da96dbdac6d48048822d3tuexen 799960416fb97d019e56677da96dbdac6d48048822d3tuexenint 8000d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenregister_send_cb(struct socket *so, uint32_t sb_threshold, int (*send_cb)(struct socket *sock, uint32_t sb_free)) 800160416fb97d019e56677da96dbdac6d48048822d3tuexen{ 8002d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen struct sctp_inpcb *inp; 800360416fb97d019e56677da96dbdac6d48048822d3tuexen 800460416fb97d019e56677da96dbdac6d48048822d3tuexen inp = (struct sctp_inpcb *) so->so_pcb; 800532a191a90b5c914a02047389c5b3197e08fc9841tuexen if (inp == NULL) { 800632a191a90b5c914a02047389c5b3197e08fc9841tuexen return (0); 800732a191a90b5c914a02047389c5b3197e08fc9841tuexen } 800832a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WLOCK(inp); 800960416fb97d019e56677da96dbdac6d48048822d3tuexen inp->send_callback = send_cb; 801060416fb97d019e56677da96dbdac6d48048822d3tuexen inp->send_sb_threshold = sb_threshold; 801132a191a90b5c914a02047389c5b3197e08fc9841tuexen SCTP_INP_WUNLOCK(inp); 801260416fb97d019e56677da96dbdac6d48048822d3tuexen /* FIXME change to current amount free. This will be the full buffer 801360416fb97d019e56677da96dbdac6d48048822d3tuexen * the first time this is registered but it could be only a portion 801460416fb97d019e56677da96dbdac6d48048822d3tuexen * of the send buffer if this is called a second time e.g. if the 801560416fb97d019e56677da96dbdac6d48048822d3tuexen * threshold changes. 801660416fb97d019e56677da96dbdac6d48048822d3tuexen */ 8017f57cf83923be449d11806a31f62bcc17e58832d6t return (1); 801860416fb97d019e56677da96dbdac6d48048822d3tuexen} 8019d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen 8020d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenint 8021d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexenregister_ulp_info (struct socket *so, void *ulp_info) 8022d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen{ 8023d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen struct sctp_inpcb *inp; 8024d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen 8025d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen inp = (struct sctp_inpcb *) so->so_pcb; 8026d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen if (inp == NULL) { 8027d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen return (0); 8028d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen } 8029d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen SCTP_INP_WLOCK(inp); 8030d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen inp->ulp_info = ulp_info; 8031d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen SCTP_INP_WUNLOCK(inp); 8032f57cf83923be449d11806a31f62bcc17e58832d6t return (1); 8033d47a4475eeacc9978923e35a6c44a6c5cb6c2227tuexen} 803460416fb97d019e56677da96dbdac6d48048822d3tuexen#endif 8035