1 1.1 rjs /* $KAME: sctputil.c,v 1.39 2005/06/16 20:54:06 jinmei Exp $ */ 2 1.21 andvar /* $NetBSD: sctputil.c,v 1.21 2025/07/11 22:19:54 andvar Exp $ */ 3 1.1 rjs 4 1.1 rjs /* 5 1.1 rjs * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc. 6 1.1 rjs * All rights reserved. 7 1.1 rjs * 8 1.1 rjs * Redistribution and use in source and binary forms, with or without 9 1.1 rjs * modification, are permitted provided that the following conditions 10 1.1 rjs * are met: 11 1.1 rjs * 1. Redistributions of source code must retain the above copyright 12 1.1 rjs * notice, this list of conditions and the following disclaimer. 13 1.1 rjs * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 rjs * notice, this list of conditions and the following disclaimer in the 15 1.1 rjs * documentation and/or other materials provided with the distribution. 16 1.1 rjs * 3. All advertising materials mentioning features or use of this software 17 1.1 rjs * must display the following acknowledgement: 18 1.1 rjs * This product includes software developed by Cisco Systems, Inc. 19 1.1 rjs * 4. Neither the name of the project nor the names of its contributors 20 1.1 rjs * may be used to endorse or promote products derived from this software 21 1.1 rjs * without specific prior written permission. 22 1.1 rjs * 23 1.1 rjs * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND 24 1.1 rjs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 rjs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 rjs * ARE DISCLAIMED. IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE 27 1.1 rjs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 rjs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 rjs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 rjs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 rjs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 rjs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 rjs * SUCH DAMAGE. 34 1.1 rjs */ 35 1.1 rjs 36 1.1 rjs #include <sys/cdefs.h> 37 1.21 andvar __KERNEL_RCSID(0, "$NetBSD: sctputil.c,v 1.21 2025/07/11 22:19:54 andvar Exp $"); 38 1.1 rjs 39 1.1 rjs #ifdef _KERNEL_OPT 40 1.1 rjs #include "opt_inet.h" 41 1.1 rjs #include "opt_ipsec.h" 42 1.1 rjs #include "opt_sctp.h" 43 1.1 rjs #endif /* _KERNEL_OPT */ 44 1.1 rjs 45 1.1 rjs #include <sys/param.h> 46 1.1 rjs #include <sys/systm.h> 47 1.1 rjs #include <sys/malloc.h> 48 1.1 rjs #include <sys/mbuf.h> 49 1.1 rjs #include <sys/domain.h> 50 1.1 rjs #include <sys/protosw.h> 51 1.1 rjs #include <sys/socket.h> 52 1.1 rjs #include <sys/socketvar.h> 53 1.1 rjs #include <sys/mutex.h> 54 1.1 rjs #include <sys/proc.h> 55 1.1 rjs #include <sys/kernel.h> 56 1.1 rjs #include <sys/sysctl.h> 57 1.16 riastrad #include <sys/cprng.h> 58 1.1 rjs 59 1.1 rjs #include <sys/callout.h> 60 1.1 rjs 61 1.1 rjs #include <net/route.h> 62 1.1 rjs 63 1.1 rjs #ifdef INET6 64 1.1 rjs #include <sys/domain.h> 65 1.1 rjs #endif 66 1.1 rjs 67 1.1 rjs #include <machine/limits.h> 68 1.1 rjs 69 1.1 rjs #include <net/if.h> 70 1.1 rjs #include <net/if_types.h> 71 1.1 rjs #include <net/route.h> 72 1.1 rjs 73 1.1 rjs #include <netinet/in.h> 74 1.1 rjs #include <netinet/in_systm.h> 75 1.1 rjs #include <netinet/ip.h> 76 1.1 rjs #include <netinet/in_pcb.h> 77 1.1 rjs #include <netinet/in_var.h> 78 1.1 rjs #include <netinet/ip_var.h> 79 1.1 rjs 80 1.1 rjs #ifdef INET6 81 1.1 rjs #include <netinet/ip6.h> 82 1.1 rjs #include <netinet6/ip6_var.h> 83 1.1 rjs #include <netinet6/scope6_var.h> 84 1.1 rjs #include <netinet6/in6_pcb.h> 85 1.1 rjs 86 1.1 rjs #endif /* INET6 */ 87 1.1 rjs 88 1.1 rjs #include <netinet/sctp_pcb.h> 89 1.1 rjs 90 1.1 rjs #ifdef IPSEC 91 1.6 rjs #include <netipsec/ipsec.h> 92 1.6 rjs #include <netipsec/key.h> 93 1.1 rjs #endif /* IPSEC */ 94 1.1 rjs 95 1.1 rjs #include <netinet/sctputil.h> 96 1.1 rjs #include <netinet/sctp_var.h> 97 1.1 rjs #ifdef INET6 98 1.1 rjs #include <netinet6/sctp6_var.h> 99 1.1 rjs #endif 100 1.1 rjs #include <netinet/sctp_header.h> 101 1.1 rjs #include <netinet/sctp_output.h> 102 1.1 rjs #include <netinet/sctp_hashdriver.h> 103 1.1 rjs #include <netinet/sctp_uio.h> 104 1.1 rjs #include <netinet/sctp_timer.h> 105 1.1 rjs #include <netinet/sctp_crc32.h> 106 1.1 rjs #include <netinet/sctp_indata.h> /* for sctp_deliver_data() */ 107 1.1 rjs #define NUMBER_OF_MTU_SIZES 18 108 1.1 rjs 109 1.1 rjs #ifdef SCTP_DEBUG 110 1.1 rjs extern u_int32_t sctp_debug_on; 111 1.1 rjs #endif 112 1.1 rjs 113 1.1 rjs #ifdef SCTP_STAT_LOGGING 114 1.1 rjs int sctp_cwnd_log_at=0; 115 1.1 rjs int sctp_cwnd_log_rolled=0; 116 1.1 rjs struct sctp_cwnd_log sctp_clog[SCTP_STAT_LOG_SIZE]; 117 1.1 rjs 118 1.1 rjs void sctp_clr_stat_log(void) 119 1.1 rjs { 120 1.1 rjs sctp_cwnd_log_at=0; 121 1.1 rjs sctp_cwnd_log_rolled=0; 122 1.1 rjs } 123 1.1 rjs 124 1.1 rjs void 125 1.1 rjs sctp_log_strm_del_alt(u_int32_t tsn, u_int16_t sseq, int from) 126 1.1 rjs { 127 1.1 rjs 128 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 129 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM; 130 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = tsn; 131 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = sseq; 132 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0; 133 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0; 134 1.1 rjs sctp_cwnd_log_at++; 135 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 136 1.1 rjs sctp_cwnd_log_at = 0; 137 1.1 rjs sctp_cwnd_log_rolled = 1; 138 1.1 rjs } 139 1.1 rjs 140 1.1 rjs } 141 1.1 rjs 142 1.1 rjs void 143 1.1 rjs sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from) 144 1.1 rjs { 145 1.1 rjs 146 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 147 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAP; 148 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.base = map; 149 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.cum = cum; 150 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.map.high = high; 151 1.1 rjs sctp_cwnd_log_at++; 152 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 153 1.1 rjs sctp_cwnd_log_at = 0; 154 1.1 rjs sctp_cwnd_log_rolled = 1; 155 1.1 rjs } 156 1.1 rjs } 157 1.1 rjs 158 1.1 rjs void 159 1.1 rjs sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn, 160 1.1 rjs int from) 161 1.1 rjs { 162 1.1 rjs 163 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 164 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_FR; 165 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.largest_tsn = biggest_tsn; 166 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.largest_new_tsn = biggest_new_tsn; 167 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.fr.tsn = tsn; 168 1.1 rjs sctp_cwnd_log_at++; 169 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 170 1.1 rjs sctp_cwnd_log_at = 0; 171 1.1 rjs sctp_cwnd_log_rolled = 1; 172 1.1 rjs } 173 1.1 rjs } 174 1.1 rjs 175 1.1 rjs void 176 1.1 rjs sctp_log_strm_del(struct sctp_tmit_chunk *chk, struct sctp_tmit_chunk *poschk, 177 1.1 rjs int from) 178 1.1 rjs { 179 1.1 rjs 180 1.1 rjs if (chk == NULL) { 181 1.1 rjs printf("Gak log of NULL?\n"); 182 1.1 rjs return; 183 1.1 rjs } 184 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 185 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_STRM; 186 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_tsn = chk->rec.data.TSN_seq; 187 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.n_sseq = chk->rec.data.stream_seq; 188 1.1 rjs if (poschk != NULL) { 189 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 190 1.1 rjs poschk->rec.data.TSN_seq; 191 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 192 1.1 rjs poschk->rec.data.stream_seq; 193 1.1 rjs } else { 194 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_tsn = 0; 195 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.strlog.e_sseq = 0; 196 1.1 rjs } 197 1.1 rjs sctp_cwnd_log_at++; 198 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 199 1.1 rjs sctp_cwnd_log_at = 0; 200 1.1 rjs sctp_cwnd_log_rolled = 1; 201 1.1 rjs } 202 1.1 rjs } 203 1.1 rjs 204 1.1 rjs void 205 1.1 rjs sctp_log_cwnd(struct sctp_nets *net, int augment, uint8_t from) 206 1.1 rjs { 207 1.1 rjs 208 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 209 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_CWND; 210 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net; 211 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = net->cwnd; 212 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size; 213 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = augment; 214 1.1 rjs sctp_cwnd_log_at++; 215 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 216 1.1 rjs sctp_cwnd_log_at = 0; 217 1.1 rjs sctp_cwnd_log_rolled = 1; 218 1.1 rjs } 219 1.1 rjs } 220 1.1 rjs 221 1.1 rjs void 222 1.1 rjs sctp_log_maxburst(struct sctp_nets *net, int error, int burst, uint8_t from) 223 1.1 rjs { 224 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 225 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MAXBURST; 226 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.net = net; 227 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_new_value = error; 228 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.inflight = net->flight_size; 229 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.cwnd.cwnd_augment = burst; 230 1.1 rjs sctp_cwnd_log_at++; 231 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 232 1.1 rjs sctp_cwnd_log_at = 0; 233 1.1 rjs sctp_cwnd_log_rolled = 1; 234 1.1 rjs } 235 1.1 rjs } 236 1.1 rjs 237 1.1 rjs void 238 1.1 rjs sctp_log_rwnd(uint8_t from, u_int32_t peers_rwnd , u_int32_t snd_size, u_int32_t overhead) 239 1.1 rjs { 240 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 241 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND; 242 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd; 243 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = snd_size; 244 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead; 245 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = 0; 246 1.1 rjs sctp_cwnd_log_at++; 247 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 248 1.1 rjs sctp_cwnd_log_at = 0; 249 1.1 rjs sctp_cwnd_log_rolled = 1; 250 1.1 rjs } 251 1.1 rjs } 252 1.1 rjs 253 1.1 rjs void 254 1.1 rjs sctp_log_rwnd_set(uint8_t from, u_int32_t peers_rwnd , u_int32_t flight_size, u_int32_t overhead, u_int32_t a_rwndval) 255 1.1 rjs { 256 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 257 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_RWND; 258 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.rwnd = peers_rwnd; 259 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.send_size = flight_size; 260 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.overhead = overhead; 261 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.rwnd.new_rwnd = a_rwndval; 262 1.1 rjs sctp_cwnd_log_at++; 263 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 264 1.1 rjs sctp_cwnd_log_at = 0; 265 1.1 rjs sctp_cwnd_log_rolled = 1; 266 1.1 rjs } 267 1.1 rjs } 268 1.1 rjs 269 1.1 rjs void 270 1.1 rjs sctp_log_mbcnt(uint8_t from, u_int32_t total_oq , u_int32_t book, u_int32_t total_mbcnt_q, u_int32_t mbcnt) 271 1.1 rjs { 272 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 273 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_MBCNT; 274 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_size = total_oq; 275 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.size_change = book; 276 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.total_queue_mb_size = total_mbcnt_q; 277 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.mbcnt.mbcnt_change = mbcnt; 278 1.1 rjs sctp_cwnd_log_at++; 279 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 280 1.1 rjs sctp_cwnd_log_at = 0; 281 1.1 rjs sctp_cwnd_log_rolled = 1; 282 1.1 rjs } 283 1.1 rjs } 284 1.1 rjs 285 1.1 rjs void 286 1.1 rjs sctp_log_block(uint8_t from, struct socket *so, struct sctp_association *asoc) 287 1.1 rjs { 288 1.1 rjs 289 1.1 rjs sctp_clog[sctp_cwnd_log_at].from = (u_int8_t)from; 290 1.1 rjs sctp_clog[sctp_cwnd_log_at].event_type = (u_int8_t)SCTP_LOG_EVENT_BLOCK; 291 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.maxmb = (u_int16_t)(so->so_snd.sb_mbmax/1024); 292 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.onmb = asoc->total_output_mbuf_queue_size; 293 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.maxsb = (u_int16_t)(so->so_snd.sb_hiwat/1024); 294 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.onsb = asoc->total_output_queue_size; 295 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.send_sent_qcnt = (u_int16_t)(asoc->send_queue_cnt + asoc->sent_queue_cnt); 296 1.1 rjs sctp_clog[sctp_cwnd_log_at].x.blk.stream_qcnt = (u_int16_t)asoc->stream_queue_cnt; 297 1.1 rjs sctp_cwnd_log_at++; 298 1.1 rjs if (sctp_cwnd_log_at >= SCTP_STAT_LOG_SIZE) { 299 1.1 rjs sctp_cwnd_log_at = 0; 300 1.1 rjs sctp_cwnd_log_rolled = 1; 301 1.1 rjs } 302 1.1 rjs } 303 1.1 rjs 304 1.1 rjs int 305 1.1 rjs sctp_fill_stat_log(struct mbuf *m) 306 1.1 rjs { 307 1.1 rjs struct sctp_cwnd_log_req *req; 308 1.1 rjs int size_limit, num, i, at, cnt_out=0; 309 1.1 rjs 310 1.1 rjs if (m == NULL) 311 1.1 rjs return (EINVAL); 312 1.1 rjs 313 1.1 rjs size_limit = (m->m_len - sizeof(struct sctp_cwnd_log_req)); 314 1.1 rjs if (size_limit < sizeof(struct sctp_cwnd_log)) { 315 1.1 rjs return (EINVAL); 316 1.1 rjs } 317 1.1 rjs req = mtod(m, struct sctp_cwnd_log_req *); 318 1.1 rjs num = size_limit/sizeof(struct sctp_cwnd_log); 319 1.1 rjs if (sctp_cwnd_log_rolled) { 320 1.1 rjs req->num_in_log = SCTP_STAT_LOG_SIZE; 321 1.1 rjs } else { 322 1.1 rjs req->num_in_log = sctp_cwnd_log_at; 323 1.1 rjs /* if the log has not rolled, we don't 324 1.1 rjs * let you have old data. 325 1.1 rjs */ 326 1.1 rjs if (req->end_at > sctp_cwnd_log_at) { 327 1.1 rjs req->end_at = sctp_cwnd_log_at; 328 1.1 rjs } 329 1.1 rjs } 330 1.1 rjs if ((num < SCTP_STAT_LOG_SIZE) && 331 1.1 rjs ((sctp_cwnd_log_rolled) || (sctp_cwnd_log_at > num))) { 332 1.1 rjs /* we can't return all of it */ 333 1.1 rjs if (((req->start_at == 0) && (req->end_at == 0)) || 334 1.1 rjs (req->start_at >= SCTP_STAT_LOG_SIZE) || 335 1.1 rjs (req->end_at >= SCTP_STAT_LOG_SIZE)) { 336 1.1 rjs /* No user request or user is wacked. */ 337 1.1 rjs req->num_ret = num; 338 1.1 rjs req->end_at = sctp_cwnd_log_at - 1; 339 1.1 rjs if ((sctp_cwnd_log_at - num) < 0) { 340 1.1 rjs int cc; 341 1.1 rjs cc = num - sctp_cwnd_log_at; 342 1.1 rjs req->start_at = SCTP_STAT_LOG_SIZE - cc; 343 1.1 rjs } else { 344 1.1 rjs req->start_at = sctp_cwnd_log_at - num; 345 1.1 rjs } 346 1.1 rjs } else { 347 1.1 rjs /* a user request */ 348 1.1 rjs int cc; 349 1.1 rjs if (req->start_at > req->end_at) { 350 1.1 rjs cc = (SCTP_STAT_LOG_SIZE - req->start_at) + 351 1.1 rjs (req->end_at + 1); 352 1.1 rjs } else { 353 1.1 rjs 354 1.1 rjs cc = req->end_at - req->start_at; 355 1.1 rjs } 356 1.1 rjs if (cc < num) { 357 1.1 rjs num = cc; 358 1.1 rjs } 359 1.1 rjs req->num_ret = num; 360 1.1 rjs } 361 1.1 rjs } else { 362 1.1 rjs /* We can return all of it */ 363 1.1 rjs req->start_at = 0; 364 1.1 rjs req->end_at = sctp_cwnd_log_at - 1; 365 1.1 rjs req->num_ret = sctp_cwnd_log_at; 366 1.1 rjs } 367 1.1 rjs for (i = 0, at = req->start_at; i < req->num_ret; i++) { 368 1.1 rjs req->log[i] = sctp_clog[at]; 369 1.1 rjs cnt_out++; 370 1.1 rjs at++; 371 1.1 rjs if (at >= SCTP_STAT_LOG_SIZE) 372 1.1 rjs at = 0; 373 1.1 rjs } 374 1.1 rjs m->m_len = (cnt_out * sizeof(struct sctp_cwnd_log_req)) + sizeof(struct sctp_cwnd_log_req); 375 1.1 rjs return (0); 376 1.1 rjs } 377 1.1 rjs 378 1.1 rjs #endif 379 1.1 rjs 380 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 381 1.1 rjs u_int8_t sctp_audit_data[SCTP_AUDIT_SIZE][2]; 382 1.1 rjs static int sctp_audit_indx = 0; 383 1.1 rjs 384 1.1 rjs static 385 1.1 rjs void sctp_print_audit_report(void) 386 1.1 rjs { 387 1.1 rjs int i; 388 1.1 rjs int cnt; 389 1.1 rjs cnt = 0; 390 1.1 rjs for (i=sctp_audit_indx;i<SCTP_AUDIT_SIZE;i++) { 391 1.1 rjs if ((sctp_audit_data[i][0] == 0xe0) && 392 1.1 rjs (sctp_audit_data[i][1] == 0x01)) { 393 1.1 rjs cnt = 0; 394 1.1 rjs printf("\n"); 395 1.1 rjs } else if (sctp_audit_data[i][0] == 0xf0) { 396 1.1 rjs cnt = 0; 397 1.1 rjs printf("\n"); 398 1.1 rjs } else if ((sctp_audit_data[i][0] == 0xc0) && 399 1.1 rjs (sctp_audit_data[i][1] == 0x01)) { 400 1.1 rjs printf("\n"); 401 1.1 rjs cnt = 0; 402 1.1 rjs } 403 1.1 rjs printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0], 404 1.1 rjs (uint32_t)sctp_audit_data[i][1]); 405 1.1 rjs cnt++; 406 1.1 rjs if ((cnt % 14) == 0) 407 1.1 rjs printf("\n"); 408 1.1 rjs } 409 1.1 rjs for (i=0;i<sctp_audit_indx;i++) { 410 1.1 rjs if ((sctp_audit_data[i][0] == 0xe0) && 411 1.1 rjs (sctp_audit_data[i][1] == 0x01)) { 412 1.1 rjs cnt = 0; 413 1.1 rjs printf("\n"); 414 1.1 rjs } else if (sctp_audit_data[i][0] == 0xf0) { 415 1.1 rjs cnt = 0; 416 1.1 rjs printf("\n"); 417 1.1 rjs } else if ((sctp_audit_data[i][0] == 0xc0) && 418 1.1 rjs (sctp_audit_data[i][1] == 0x01)) { 419 1.1 rjs printf("\n"); 420 1.1 rjs cnt = 0; 421 1.1 rjs } 422 1.1 rjs printf("%2.2x%2.2x ", (uint32_t)sctp_audit_data[i][0], 423 1.1 rjs (uint32_t)sctp_audit_data[i][1]); 424 1.1 rjs cnt++; 425 1.1 rjs if ((cnt % 14) == 0) 426 1.1 rjs printf("\n"); 427 1.1 rjs } 428 1.1 rjs printf("\n"); 429 1.1 rjs } 430 1.1 rjs 431 1.1 rjs void sctp_auditing(int from, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 432 1.1 rjs struct sctp_nets *net) 433 1.1 rjs { 434 1.1 rjs int resend_cnt, tot_out, rep, tot_book_cnt; 435 1.1 rjs struct sctp_nets *lnet; 436 1.1 rjs struct sctp_tmit_chunk *chk; 437 1.1 rjs 438 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAA; 439 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x000000ff & from; 440 1.1 rjs sctp_audit_indx++; 441 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 442 1.1 rjs sctp_audit_indx = 0; 443 1.1 rjs } 444 1.1 rjs if (inp == NULL) { 445 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF; 446 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x01; 447 1.1 rjs sctp_audit_indx++; 448 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 449 1.1 rjs sctp_audit_indx = 0; 450 1.1 rjs } 451 1.1 rjs return; 452 1.1 rjs } 453 1.1 rjs if (stcb == NULL) { 454 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF; 455 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0x02; 456 1.1 rjs sctp_audit_indx++; 457 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 458 1.1 rjs sctp_audit_indx = 0; 459 1.1 rjs } 460 1.1 rjs return; 461 1.1 rjs } 462 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xA1; 463 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 464 1.1 rjs (0x000000ff & stcb->asoc.sent_queue_retran_cnt); 465 1.1 rjs sctp_audit_indx++; 466 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 467 1.1 rjs sctp_audit_indx = 0; 468 1.1 rjs } 469 1.1 rjs rep = 0; 470 1.1 rjs tot_book_cnt = 0; 471 1.1 rjs resend_cnt = tot_out = 0; 472 1.1 rjs TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 473 1.1 rjs if (chk->sent == SCTP_DATAGRAM_RESEND) { 474 1.1 rjs resend_cnt++; 475 1.1 rjs } else if (chk->sent < SCTP_DATAGRAM_RESEND) { 476 1.1 rjs tot_out += chk->book_size; 477 1.1 rjs tot_book_cnt++; 478 1.1 rjs } 479 1.1 rjs } 480 1.1 rjs if (resend_cnt != stcb->asoc.sent_queue_retran_cnt) { 481 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF; 482 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA1; 483 1.1 rjs sctp_audit_indx++; 484 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 485 1.1 rjs sctp_audit_indx = 0; 486 1.1 rjs } 487 1.1 rjs printf("resend_cnt:%d asoc-tot:%d\n", 488 1.1 rjs resend_cnt, stcb->asoc.sent_queue_retran_cnt); 489 1.1 rjs rep = 1; 490 1.1 rjs stcb->asoc.sent_queue_retran_cnt = resend_cnt; 491 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xA2; 492 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 493 1.1 rjs (0x000000ff & stcb->asoc.sent_queue_retran_cnt); 494 1.1 rjs sctp_audit_indx++; 495 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 496 1.1 rjs sctp_audit_indx = 0; 497 1.1 rjs } 498 1.1 rjs } 499 1.1 rjs if (tot_out != stcb->asoc.total_flight) { 500 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF; 501 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA2; 502 1.1 rjs sctp_audit_indx++; 503 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 504 1.1 rjs sctp_audit_indx = 0; 505 1.1 rjs } 506 1.1 rjs rep = 1; 507 1.1 rjs printf("tot_flt:%d asoc_tot:%d\n", tot_out, 508 1.1 rjs (int)stcb->asoc.total_flight); 509 1.1 rjs stcb->asoc.total_flight = tot_out; 510 1.1 rjs } 511 1.1 rjs if (tot_book_cnt != stcb->asoc.total_flight_count) { 512 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF; 513 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA5; 514 1.1 rjs sctp_audit_indx++; 515 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 516 1.1 rjs sctp_audit_indx = 0; 517 1.1 rjs } 518 1.1 rjs rep = 1; 519 1.1 rjs printf("tot_flt_book:%d\n", tot_book); 520 1.1 rjs 521 1.1 rjs stcb->asoc.total_flight_count = tot_book_cnt; 522 1.1 rjs } 523 1.1 rjs tot_out = 0; 524 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 525 1.1 rjs tot_out += lnet->flight_size; 526 1.1 rjs } 527 1.1 rjs if (tot_out != stcb->asoc.total_flight) { 528 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = 0xAF; 529 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = 0xA3; 530 1.1 rjs sctp_audit_indx++; 531 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 532 1.1 rjs sctp_audit_indx = 0; 533 1.1 rjs } 534 1.1 rjs rep = 1; 535 1.1 rjs printf("real flight:%d net total was %d\n", 536 1.1 rjs stcb->asoc.total_flight, tot_out); 537 1.1 rjs /* now corrective action */ 538 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 539 1.1 rjs tot_out = 0; 540 1.1 rjs TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 541 1.1 rjs if ((chk->whoTo == lnet) && 542 1.1 rjs (chk->sent < SCTP_DATAGRAM_RESEND)) { 543 1.1 rjs tot_out += chk->book_size; 544 1.1 rjs } 545 1.1 rjs } 546 1.1 rjs if (lnet->flight_size != tot_out) { 547 1.1 rjs printf("net:%x flight was %d corrected to %d\n", 548 1.1 rjs (uint32_t)lnet, lnet->flight_size, tot_out); 549 1.1 rjs lnet->flight_size = tot_out; 550 1.1 rjs } 551 1.1 rjs 552 1.1 rjs } 553 1.1 rjs } 554 1.1 rjs 555 1.1 rjs if (rep) { 556 1.1 rjs sctp_print_audit_report(); 557 1.1 rjs } 558 1.1 rjs } 559 1.1 rjs 560 1.1 rjs void 561 1.1 rjs sctp_audit_log(u_int8_t ev, u_int8_t fd) 562 1.1 rjs { 563 1.1 rjs sctp_audit_data[sctp_audit_indx][0] = ev; 564 1.1 rjs sctp_audit_data[sctp_audit_indx][1] = fd; 565 1.1 rjs sctp_audit_indx++; 566 1.1 rjs if (sctp_audit_indx >= SCTP_AUDIT_SIZE) { 567 1.1 rjs sctp_audit_indx = 0; 568 1.1 rjs } 569 1.1 rjs } 570 1.1 rjs 571 1.1 rjs #endif 572 1.1 rjs 573 1.1 rjs /* 574 1.1 rjs * a list of sizes based on typical mtu's, used only if next hop 575 1.1 rjs * size not returned. 576 1.1 rjs */ 577 1.1 rjs static int sctp_mtu_sizes[] = { 578 1.1 rjs 68, 579 1.1 rjs 296, 580 1.1 rjs 508, 581 1.1 rjs 512, 582 1.1 rjs 544, 583 1.1 rjs 576, 584 1.1 rjs 1006, 585 1.1 rjs 1492, 586 1.1 rjs 1500, 587 1.1 rjs 1536, 588 1.1 rjs 2002, 589 1.1 rjs 2048, 590 1.1 rjs 4352, 591 1.1 rjs 4464, 592 1.1 rjs 8166, 593 1.1 rjs 17914, 594 1.1 rjs 32000, 595 1.1 rjs 65535 596 1.1 rjs }; 597 1.1 rjs 598 1.1 rjs int 599 1.1 rjs find_next_best_mtu(int totsz) 600 1.1 rjs { 601 1.1 rjs int i, perfer; 602 1.1 rjs /* 603 1.1 rjs * if we are in here we must find the next best fit based on the 604 1.1 rjs * size of the dg that failed to be sent. 605 1.1 rjs */ 606 1.1 rjs perfer = 0; 607 1.1 rjs for (i = 0; i < NUMBER_OF_MTU_SIZES; i++) { 608 1.1 rjs if (totsz < sctp_mtu_sizes[i]) { 609 1.1 rjs perfer = i - 1; 610 1.1 rjs if (perfer < 0) 611 1.1 rjs perfer = 0; 612 1.1 rjs break; 613 1.1 rjs } 614 1.1 rjs } 615 1.1 rjs return (sctp_mtu_sizes[perfer]); 616 1.1 rjs } 617 1.1 rjs 618 1.1 rjs uint32_t 619 1.1 rjs sctp_select_initial_TSN(struct sctp_pcb *m) 620 1.1 rjs { 621 1.16 riastrad return cprng_strong32(); 622 1.1 rjs } 623 1.1 rjs 624 1.1 rjs u_int32_t sctp_select_a_tag(struct sctp_inpcb *m) 625 1.1 rjs { 626 1.1 rjs u_long x, not_done; 627 1.1 rjs struct timeval now; 628 1.1 rjs 629 1.1 rjs SCTP_GETTIME_TIMEVAL(&now); 630 1.1 rjs not_done = 1; 631 1.1 rjs while (not_done) { 632 1.1 rjs x = sctp_select_initial_TSN(&m->sctp_ep); 633 1.1 rjs if (x == 0) { 634 1.1 rjs /* we never use 0 */ 635 1.1 rjs continue; 636 1.1 rjs } 637 1.1 rjs if (sctp_is_vtag_good(m, x, &now)) { 638 1.1 rjs not_done = 0; 639 1.1 rjs } 640 1.1 rjs } 641 1.1 rjs return (x); 642 1.1 rjs } 643 1.1 rjs 644 1.1 rjs 645 1.1 rjs int 646 1.1 rjs sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc, 647 1.1 rjs int for_a_init, uint32_t override_tag ) 648 1.1 rjs { 649 1.1 rjs /* 650 1.1 rjs * Anything set to zero is taken care of by the allocation 651 1.1 rjs * routine's bzero 652 1.1 rjs */ 653 1.1 rjs 654 1.1 rjs /* 655 1.1 rjs * Up front select what scoping to apply on addresses I tell my peer 656 1.1 rjs * Not sure what to do with these right now, we will need to come up 657 1.1 rjs * with a way to set them. We may need to pass them through from the 658 1.1 rjs * caller in the sctp_aloc_assoc() function. 659 1.1 rjs */ 660 1.1 rjs int i; 661 1.1 rjs /* init all variables to a known value.*/ 662 1.1 rjs asoc->state = SCTP_STATE_INUSE; 663 1.1 rjs asoc->max_burst = m->sctp_ep.max_burst; 664 1.1 rjs asoc->heart_beat_delay = m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]; 665 1.1 rjs asoc->cookie_life = m->sctp_ep.def_cookie_life; 666 1.1 rjs 667 1.1 rjs if (override_tag) { 668 1.1 rjs asoc->my_vtag = override_tag; 669 1.1 rjs } else { 670 1.1 rjs asoc->my_vtag = sctp_select_a_tag(m); 671 1.1 rjs } 672 1.1 rjs asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number = asoc->sending_seq = 673 1.1 rjs sctp_select_initial_TSN(&m->sctp_ep); 674 1.1 rjs asoc->t3timeout_highest_marked = asoc->asconf_seq_out; 675 1.1 rjs /* we are opptimisitic here */ 676 1.1 rjs asoc->peer_supports_asconf = 1; 677 1.1 rjs asoc->peer_supports_asconf_setprim = 1; 678 1.1 rjs asoc->peer_supports_pktdrop = 1; 679 1.1 rjs 680 1.1 rjs asoc->sent_queue_retran_cnt = 0; 681 1.1 rjs /* This will need to be adjusted */ 682 1.1 rjs asoc->last_cwr_tsn = asoc->init_seq_number - 1; 683 1.1 rjs asoc->last_acked_seq = asoc->init_seq_number - 1; 684 1.1 rjs asoc->advanced_peer_ack_point = asoc->last_acked_seq; 685 1.1 rjs asoc->asconf_seq_in = asoc->last_acked_seq; 686 1.1 rjs 687 1.1 rjs /* here we are different, we hold the next one we expect */ 688 1.1 rjs asoc->str_reset_seq_in = asoc->last_acked_seq + 1; 689 1.1 rjs 690 1.1 rjs asoc->initial_init_rto_max = m->sctp_ep.initial_init_rto_max; 691 1.1 rjs asoc->initial_rto = m->sctp_ep.initial_rto; 692 1.1 rjs 693 1.1 rjs asoc->max_init_times = m->sctp_ep.max_init_times; 694 1.1 rjs asoc->max_send_times = m->sctp_ep.max_send_times; 695 1.1 rjs asoc->def_net_failure = m->sctp_ep.def_net_failure; 696 1.1 rjs 697 1.1 rjs /* ECN Nonce initialization */ 698 1.1 rjs asoc->ecn_nonce_allowed = 0; 699 1.1 rjs asoc->receiver_nonce_sum = 1; 700 1.1 rjs asoc->nonce_sum_expect_base = 1; 701 1.1 rjs asoc->nonce_sum_check = 1; 702 1.1 rjs asoc->nonce_resync_tsn = 0; 703 1.1 rjs asoc->nonce_wait_for_ecne = 0; 704 1.1 rjs asoc->nonce_wait_tsn = 0; 705 1.1 rjs 706 1.1 rjs if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 707 1.1 rjs struct in6pcb *inp6; 708 1.1 rjs 709 1.1 rjs 710 1.1 rjs /* Its a V6 socket */ 711 1.1 rjs inp6 = (struct in6pcb *)m; 712 1.1 rjs asoc->ipv6_addr_legal = 1; 713 1.1 rjs /* Now look at the binding flag to see if V4 will be legal */ 714 1.1 rjs if ( 715 1.1 rjs #if defined(__OpenBSD__) 716 1.1 rjs (0) /* we always do dual bind */ 717 1.1 rjs #elif defined (__NetBSD__) 718 1.1 rjs (inp6->in6p_flags & IN6P_IPV6_V6ONLY) 719 1.1 rjs #else 720 1.1 rjs (inp6->inp_flags & IN6P_IPV6_V6ONLY) 721 1.1 rjs #endif 722 1.1 rjs == 0) { 723 1.1 rjs asoc->ipv4_addr_legal = 1; 724 1.1 rjs } else { 725 1.1 rjs /* V4 addresses are NOT legal on the association */ 726 1.1 rjs asoc->ipv4_addr_legal = 0; 727 1.1 rjs } 728 1.1 rjs } else { 729 1.1 rjs /* Its a V4 socket, no - V6 */ 730 1.1 rjs asoc->ipv4_addr_legal = 1; 731 1.1 rjs asoc->ipv6_addr_legal = 0; 732 1.1 rjs } 733 1.1 rjs 734 1.1 rjs 735 1.13 riastrad asoc->my_rwnd = uimax(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND); 736 1.1 rjs asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat; 737 1.1 rjs 738 1.1 rjs asoc->smallest_mtu = m->sctp_frag_point; 739 1.1 rjs asoc->minrto = m->sctp_ep.sctp_minrto; 740 1.1 rjs asoc->maxrto = m->sctp_ep.sctp_maxrto; 741 1.1 rjs 742 1.1 rjs LIST_INIT(&asoc->sctp_local_addr_list); 743 1.1 rjs TAILQ_INIT(&asoc->nets); 744 1.1 rjs TAILQ_INIT(&asoc->pending_reply_queue); 745 1.1 rjs asoc->last_asconf_ack_sent = NULL; 746 1.1 rjs /* Setup to fill the hb random cache at first HB */ 747 1.1 rjs asoc->hb_random_idx = 4; 748 1.1 rjs 749 1.1 rjs asoc->sctp_autoclose_ticks = m->sctp_ep.auto_close_time; 750 1.1 rjs 751 1.1 rjs /* 752 1.1 rjs * Now the stream parameters, here we allocate space for all 753 1.1 rjs * streams that we request by default. 754 1.1 rjs */ 755 1.1 rjs asoc->streamoutcnt = asoc->pre_open_streams = 756 1.1 rjs m->sctp_ep.pre_open_stream_count; 757 1.1 rjs asoc->strmout = malloc(asoc->streamoutcnt * 758 1.1 rjs sizeof(struct sctp_stream_out), M_PCB, M_NOWAIT); 759 1.1 rjs if (asoc->strmout == NULL) { 760 1.1 rjs /* big trouble no memory */ 761 1.1 rjs return (ENOMEM); 762 1.1 rjs } 763 1.1 rjs for (i = 0; i < asoc->streamoutcnt; i++) { 764 1.1 rjs /* 765 1.1 rjs * inbound side must be set to 0xffff, 766 1.1 rjs * also NOTE when we get the INIT-ACK back (for INIT sender) 767 1.1 rjs * we MUST reduce the count (streamoutcnt) but first check 768 1.1 rjs * if we sent to any of the upper streams that were dropped 769 1.1 rjs * (if some were). Those that were dropped must be notified 770 1.1 rjs * to the upper layer as failed to send. 771 1.1 rjs */ 772 1.1 rjs asoc->strmout[i].next_sequence_sent = 0x0; 773 1.1 rjs TAILQ_INIT(&asoc->strmout[i].outqueue); 774 1.1 rjs asoc->strmout[i].stream_no = i; 775 1.1 rjs asoc->strmout[i].next_spoke.tqe_next = 0; 776 1.1 rjs asoc->strmout[i].next_spoke.tqe_prev = 0; 777 1.1 rjs } 778 1.1 rjs /* Now the mapping array */ 779 1.1 rjs asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY; 780 1.1 rjs asoc->mapping_array = malloc(asoc->mapping_array_size, 781 1.1 rjs M_PCB, M_NOWAIT); 782 1.1 rjs if (asoc->mapping_array == NULL) { 783 1.1 rjs free(asoc->strmout, M_PCB); 784 1.1 rjs return (ENOMEM); 785 1.1 rjs } 786 1.1 rjs memset(asoc->mapping_array, 0, asoc->mapping_array_size); 787 1.1 rjs /* Now the init of the other outqueues */ 788 1.1 rjs TAILQ_INIT(&asoc->out_wheel); 789 1.1 rjs TAILQ_INIT(&asoc->control_send_queue); 790 1.1 rjs TAILQ_INIT(&asoc->send_queue); 791 1.1 rjs TAILQ_INIT(&asoc->sent_queue); 792 1.1 rjs TAILQ_INIT(&asoc->reasmqueue); 793 1.1 rjs TAILQ_INIT(&asoc->delivery_queue); 794 1.1 rjs asoc->max_inbound_streams = m->sctp_ep.max_open_streams_intome; 795 1.1 rjs 796 1.1 rjs TAILQ_INIT(&asoc->asconf_queue); 797 1.1 rjs return (0); 798 1.1 rjs } 799 1.1 rjs 800 1.1 rjs int 801 1.1 rjs sctp_expand_mapping_array(struct sctp_association *asoc) 802 1.1 rjs { 803 1.1 rjs /* mapping array needs to grow */ 804 1.1 rjs u_int8_t *new_array; 805 1.3 christos uint16_t new_size, old_size; 806 1.1 rjs 807 1.3 christos old_size = asoc->mapping_array_size; 808 1.3 christos new_size = old_size + SCTP_MAPPING_ARRAY_INCR; 809 1.1 rjs new_array = malloc(new_size, M_PCB, M_NOWAIT); 810 1.1 rjs if (new_array == NULL) { 811 1.1 rjs /* can't get more, forget it */ 812 1.1 rjs printf("No memory for expansion of SCTP mapping array %d\n", 813 1.1 rjs new_size); 814 1.1 rjs return (-1); 815 1.1 rjs } 816 1.3 christos memcpy(new_array, asoc->mapping_array, old_size); 817 1.3 christos memset(new_array + old_size, 0, SCTP_MAPPING_ARRAY_INCR); 818 1.1 rjs free(asoc->mapping_array, M_PCB); 819 1.1 rjs asoc->mapping_array = new_array; 820 1.1 rjs asoc->mapping_array_size = new_size; 821 1.1 rjs return (0); 822 1.1 rjs } 823 1.1 rjs 824 1.1 rjs static void 825 1.1 rjs sctp_timeout_handler(void *t) 826 1.1 rjs { 827 1.1 rjs struct sctp_inpcb *inp; 828 1.1 rjs struct sctp_tcb *stcb; 829 1.1 rjs struct sctp_nets *net; 830 1.1 rjs struct sctp_timer *tmr; 831 1.1 rjs int did_output; 832 1.1 rjs 833 1.1 rjs mutex_enter(softnet_lock); 834 1.1 rjs tmr = (struct sctp_timer *)t; 835 1.1 rjs inp = (struct sctp_inpcb *)tmr->ep; 836 1.1 rjs stcb = (struct sctp_tcb *)tmr->tcb; 837 1.1 rjs net = (struct sctp_nets *)tmr->net; 838 1.1 rjs did_output = 1; 839 1.1 rjs 840 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 841 1.1 rjs sctp_audit_log(0xF0, (u_int8_t)tmr->type); 842 1.1 rjs sctp_auditing(3, inp, stcb, net); 843 1.1 rjs #endif 844 1.1 rjs sctp_pegs[SCTP_TIMERS_EXP]++; 845 1.1 rjs 846 1.1 rjs if (inp == NULL) { 847 1.1 rjs return; 848 1.1 rjs } 849 1.1 rjs 850 1.1 rjs SCTP_INP_WLOCK(inp); 851 1.1 rjs if (inp->sctp_socket == 0) { 852 1.1 rjs mutex_exit(softnet_lock); 853 1.1 rjs SCTP_INP_WUNLOCK(inp); 854 1.1 rjs return; 855 1.1 rjs } 856 1.1 rjs if (stcb) { 857 1.1 rjs if (stcb->asoc.state == 0) { 858 1.1 rjs mutex_exit(softnet_lock); 859 1.1 rjs SCTP_INP_WUNLOCK(inp); 860 1.1 rjs return; 861 1.1 rjs } 862 1.1 rjs } 863 1.1 rjs #ifdef SCTP_DEBUG 864 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) { 865 1.1 rjs printf("Timer type %d goes off\n", tmr->type); 866 1.1 rjs } 867 1.1 rjs #endif /* SCTP_DEBUG */ 868 1.1 rjs #ifndef __NetBSD__ 869 1.1 rjs if (!callout_active(&tmr->timer)) { 870 1.1 rjs SCTP_INP_WUNLOCK(inp); 871 1.1 rjs return; 872 1.1 rjs } 873 1.1 rjs #endif 874 1.1 rjs if (stcb) { 875 1.1 rjs SCTP_TCB_LOCK(stcb); 876 1.1 rjs } 877 1.1 rjs SCTP_INP_INCR_REF(inp); 878 1.1 rjs SCTP_INP_WUNLOCK(inp); 879 1.1 rjs 880 1.1 rjs switch (tmr->type) { 881 1.1 rjs case SCTP_TIMER_TYPE_ITERATOR: 882 1.1 rjs { 883 1.1 rjs struct sctp_iterator *it; 884 1.1 rjs it = (struct sctp_iterator *)inp; 885 1.1 rjs sctp_iterator_timer(it); 886 1.1 rjs } 887 1.1 rjs break; 888 1.1 rjs /* call the handler for the appropriate timer type */ 889 1.1 rjs case SCTP_TIMER_TYPE_SEND: 890 1.1 rjs sctp_pegs[SCTP_TMIT_TIMER]++; 891 1.1 rjs stcb->asoc.num_send_timers_up--; 892 1.1 rjs if (stcb->asoc.num_send_timers_up < 0) { 893 1.1 rjs stcb->asoc.num_send_timers_up = 0; 894 1.1 rjs } 895 1.1 rjs if (sctp_t3rxt_timer(inp, stcb, net)) { 896 1.1 rjs /* no need to unlock on tcb its gone */ 897 1.1 rjs 898 1.1 rjs goto out_decr; 899 1.1 rjs } 900 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 901 1.1 rjs sctp_auditing(4, inp, stcb, net); 902 1.1 rjs #endif 903 1.1 rjs sctp_chunk_output(inp, stcb, 1); 904 1.1 rjs if ((stcb->asoc.num_send_timers_up == 0) && 905 1.1 rjs (stcb->asoc.sent_queue_cnt > 0) 906 1.1 rjs ) { 907 1.1 rjs struct sctp_tmit_chunk *chk; 908 1.1 rjs /* 909 1.1 rjs * safeguard. If there on some on the sent queue 910 1.1 rjs * somewhere but no timers running something is 911 1.1 rjs * wrong... so we start a timer on the first chunk 912 1.1 rjs * on the send queue on whatever net it is sent to. 913 1.1 rjs */ 914 1.1 rjs sctp_pegs[SCTP_T3_SAFEGRD]++; 915 1.1 rjs chk = TAILQ_FIRST(&stcb->asoc.sent_queue); 916 1.1 rjs sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, 917 1.1 rjs chk->whoTo); 918 1.1 rjs } 919 1.1 rjs break; 920 1.1 rjs case SCTP_TIMER_TYPE_INIT: 921 1.1 rjs if (sctp_t1init_timer(inp, stcb, net)) { 922 1.1 rjs /* no need to unlock on tcb its gone */ 923 1.1 rjs goto out_decr; 924 1.1 rjs } 925 1.1 rjs /* We do output but not here */ 926 1.1 rjs did_output = 0; 927 1.1 rjs break; 928 1.1 rjs case SCTP_TIMER_TYPE_RECV: 929 1.1 rjs sctp_pegs[SCTP_RECV_TIMER]++; 930 1.1 rjs sctp_send_sack(stcb); 931 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 932 1.1 rjs sctp_auditing(4, inp, stcb, net); 933 1.1 rjs #endif 934 1.1 rjs sctp_chunk_output(inp, stcb, 4); 935 1.1 rjs break; 936 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWN: 937 1.1 rjs if (sctp_shutdown_timer(inp, stcb, net) ) { 938 1.1 rjs /* no need to unlock on tcb its gone */ 939 1.1 rjs goto out_decr; 940 1.1 rjs } 941 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 942 1.1 rjs sctp_auditing(4, inp, stcb, net); 943 1.1 rjs #endif 944 1.1 rjs sctp_chunk_output(inp, stcb, 5); 945 1.1 rjs break; 946 1.1 rjs case SCTP_TIMER_TYPE_HEARTBEAT: 947 1.1 rjs if (sctp_heartbeat_timer(inp, stcb, net)) { 948 1.1 rjs /* no need to unlock on tcb its gone */ 949 1.1 rjs goto out_decr; 950 1.1 rjs } 951 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 952 1.1 rjs sctp_auditing(4, inp, stcb, net); 953 1.1 rjs #endif 954 1.1 rjs sctp_chunk_output(inp, stcb, 6); 955 1.1 rjs break; 956 1.1 rjs case SCTP_TIMER_TYPE_COOKIE: 957 1.1 rjs if (sctp_cookie_timer(inp, stcb, net)) { 958 1.1 rjs /* no need to unlock on tcb its gone */ 959 1.1 rjs goto out_decr; 960 1.1 rjs } 961 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 962 1.1 rjs sctp_auditing(4, inp, stcb, net); 963 1.1 rjs #endif 964 1.1 rjs sctp_chunk_output(inp, stcb, 1); 965 1.1 rjs break; 966 1.1 rjs case SCTP_TIMER_TYPE_NEWCOOKIE: 967 1.1 rjs { 968 1.1 rjs struct timeval tv; 969 1.1 rjs int i, secret; 970 1.1 rjs SCTP_GETTIME_TIMEVAL(&tv); 971 1.1 rjs SCTP_INP_WLOCK(inp); 972 1.1 rjs inp->sctp_ep.time_of_secret_change = tv.tv_sec; 973 1.1 rjs inp->sctp_ep.last_secret_number = 974 1.1 rjs inp->sctp_ep.current_secret_number; 975 1.1 rjs inp->sctp_ep.current_secret_number++; 976 1.1 rjs if (inp->sctp_ep.current_secret_number >= 977 1.1 rjs SCTP_HOW_MANY_SECRETS) { 978 1.1 rjs inp->sctp_ep.current_secret_number = 0; 979 1.1 rjs } 980 1.1 rjs secret = (int)inp->sctp_ep.current_secret_number; 981 1.1 rjs for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) { 982 1.1 rjs inp->sctp_ep.secret_key[secret][i] = 983 1.1 rjs sctp_select_initial_TSN(&inp->sctp_ep); 984 1.1 rjs } 985 1.1 rjs SCTP_INP_WUNLOCK(inp); 986 1.1 rjs sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, stcb, net); 987 1.1 rjs } 988 1.1 rjs did_output = 0; 989 1.1 rjs break; 990 1.1 rjs case SCTP_TIMER_TYPE_PATHMTURAISE: 991 1.1 rjs sctp_pathmtu_timer(inp, stcb, net); 992 1.1 rjs did_output = 0; 993 1.1 rjs break; 994 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNACK: 995 1.1 rjs if (sctp_shutdownack_timer(inp, stcb, net)) { 996 1.1 rjs /* no need to unlock on tcb its gone */ 997 1.1 rjs goto out_decr; 998 1.1 rjs } 999 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 1000 1.1 rjs sctp_auditing(4, inp, stcb, net); 1001 1.1 rjs #endif 1002 1.1 rjs sctp_chunk_output(inp, stcb, 7); 1003 1.1 rjs break; 1004 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 1005 1.1 rjs sctp_abort_an_association(inp, stcb, 1006 1.1 rjs SCTP_SHUTDOWN_GUARD_EXPIRES, NULL); 1007 1.1 rjs /* no need to unlock on tcb its gone */ 1008 1.1 rjs goto out_decr; 1009 1.1 rjs break; 1010 1.1 rjs 1011 1.1 rjs case SCTP_TIMER_TYPE_STRRESET: 1012 1.1 rjs if (sctp_strreset_timer(inp, stcb, net)) { 1013 1.1 rjs /* no need to unlock on tcb its gone */ 1014 1.1 rjs goto out_decr; 1015 1.1 rjs } 1016 1.1 rjs sctp_chunk_output(inp, stcb, 9); 1017 1.1 rjs break; 1018 1.1 rjs 1019 1.1 rjs case SCTP_TIMER_TYPE_ASCONF: 1020 1.1 rjs if (sctp_asconf_timer(inp, stcb, net)) { 1021 1.1 rjs /* no need to unlock on tcb its gone */ 1022 1.1 rjs goto out_decr; 1023 1.1 rjs } 1024 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 1025 1.1 rjs sctp_auditing(4, inp, stcb, net); 1026 1.1 rjs #endif 1027 1.1 rjs sctp_chunk_output(inp, stcb, 8); 1028 1.1 rjs break; 1029 1.1 rjs 1030 1.1 rjs case SCTP_TIMER_TYPE_AUTOCLOSE: 1031 1.1 rjs sctp_autoclose_timer(inp, stcb, net); 1032 1.1 rjs sctp_chunk_output(inp, stcb, 10); 1033 1.1 rjs did_output = 0; 1034 1.1 rjs break; 1035 1.1 rjs case SCTP_TIMER_TYPE_INPKILL: 1036 1.1 rjs /* special case, take away our 1037 1.1 rjs * increment since WE are the killer 1038 1.1 rjs */ 1039 1.1 rjs SCTP_INP_WLOCK(inp); 1040 1.1 rjs SCTP_INP_DECR_REF(inp); 1041 1.1 rjs SCTP_INP_WUNLOCK(inp); 1042 1.1 rjs sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL); 1043 1.1 rjs sctp_inpcb_free(inp, 1); 1044 1.1 rjs goto out_no_decr; 1045 1.1 rjs break; 1046 1.1 rjs default: 1047 1.1 rjs #ifdef SCTP_DEBUG 1048 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) { 1049 1.1 rjs printf("sctp_timeout_handler:unknown timer %d\n", 1050 1.1 rjs tmr->type); 1051 1.1 rjs } 1052 1.1 rjs #endif /* SCTP_DEBUG */ 1053 1.1 rjs break; 1054 1.1 rjs }; 1055 1.1 rjs #ifdef SCTP_AUDITING_ENABLED 1056 1.1 rjs sctp_audit_log(0xF1, (u_int8_t)tmr->type); 1057 1.1 rjs sctp_auditing(5, inp, stcb, net); 1058 1.1 rjs #endif 1059 1.1 rjs if (did_output) { 1060 1.1 rjs /* 1061 1.1 rjs * Now we need to clean up the control chunk chain if an 1062 1.1 rjs * ECNE is on it. It must be marked as UNSENT again so next 1063 1.1 rjs * call will continue to send it until such time that we get 1064 1.1 rjs * a CWR, to remove it. It is, however, less likely that we 1065 1.1 rjs * will find a ecn echo on the chain though. 1066 1.1 rjs */ 1067 1.1 rjs sctp_fix_ecn_echo(&stcb->asoc); 1068 1.1 rjs } 1069 1.1 rjs if (stcb) { 1070 1.1 rjs SCTP_TCB_UNLOCK(stcb); 1071 1.1 rjs } 1072 1.1 rjs out_decr: 1073 1.1 rjs SCTP_INP_WLOCK(inp); 1074 1.1 rjs SCTP_INP_DECR_REF(inp); 1075 1.1 rjs SCTP_INP_WUNLOCK(inp); 1076 1.1 rjs 1077 1.1 rjs out_no_decr: 1078 1.1 rjs 1079 1.1 rjs mutex_exit(softnet_lock); 1080 1.1 rjs } 1081 1.1 rjs 1082 1.1 rjs int 1083 1.1 rjs sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1084 1.1 rjs struct sctp_nets *net) 1085 1.1 rjs { 1086 1.1 rjs int to_ticks; 1087 1.1 rjs struct sctp_timer *tmr; 1088 1.1 rjs 1089 1.1 rjs if (inp == NULL) 1090 1.1 rjs return (EFAULT); 1091 1.1 rjs 1092 1.1 rjs to_ticks = 0; 1093 1.1 rjs 1094 1.1 rjs tmr = NULL; 1095 1.1 rjs switch (t_type) { 1096 1.1 rjs case SCTP_TIMER_TYPE_ITERATOR: 1097 1.1 rjs { 1098 1.1 rjs struct sctp_iterator *it; 1099 1.1 rjs it = (struct sctp_iterator *)inp; 1100 1.1 rjs tmr = &it->tmr; 1101 1.1 rjs to_ticks = SCTP_ITERATOR_TICKS; 1102 1.1 rjs } 1103 1.1 rjs break; 1104 1.1 rjs case SCTP_TIMER_TYPE_SEND: 1105 1.1 rjs /* Here we use the RTO timer */ 1106 1.1 rjs { 1107 1.1 rjs int rto_val; 1108 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1109 1.1 rjs return (EFAULT); 1110 1.1 rjs } 1111 1.1 rjs tmr = &net->rxt_timer; 1112 1.1 rjs if (net->RTO == 0) { 1113 1.1 rjs rto_val = stcb->asoc.initial_rto; 1114 1.1 rjs } else { 1115 1.1 rjs rto_val = net->RTO; 1116 1.1 rjs } 1117 1.1 rjs to_ticks = MSEC_TO_TICKS(rto_val); 1118 1.1 rjs } 1119 1.1 rjs break; 1120 1.1 rjs case SCTP_TIMER_TYPE_INIT: 1121 1.1 rjs /* 1122 1.1 rjs * Here we use the INIT timer default 1123 1.1 rjs * usually about 1 minute. 1124 1.1 rjs */ 1125 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1126 1.1 rjs return (EFAULT); 1127 1.1 rjs } 1128 1.1 rjs tmr = &net->rxt_timer; 1129 1.1 rjs if (net->RTO == 0) { 1130 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 1131 1.1 rjs } else { 1132 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO); 1133 1.1 rjs } 1134 1.1 rjs break; 1135 1.1 rjs case SCTP_TIMER_TYPE_RECV: 1136 1.1 rjs /* 1137 1.1 rjs * Here we use the Delayed-Ack timer value from the inp 1138 1.1 rjs * ususually about 200ms. 1139 1.1 rjs */ 1140 1.1 rjs if (stcb == NULL) { 1141 1.1 rjs return (EFAULT); 1142 1.1 rjs } 1143 1.1 rjs tmr = &stcb->asoc.dack_timer; 1144 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]; 1145 1.1 rjs break; 1146 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWN: 1147 1.1 rjs /* Here we use the RTO of the destination. */ 1148 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1149 1.1 rjs return (EFAULT); 1150 1.1 rjs } 1151 1.1 rjs 1152 1.1 rjs if (net->RTO == 0) { 1153 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 1154 1.1 rjs } else { 1155 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO); 1156 1.1 rjs } 1157 1.1 rjs tmr = &net->rxt_timer; 1158 1.1 rjs break; 1159 1.1 rjs case SCTP_TIMER_TYPE_HEARTBEAT: 1160 1.1 rjs /* 1161 1.1 rjs * the net is used here so that we can add in the RTO. 1162 1.1 rjs * Even though we use a different timer. We also add the 1163 1.1 rjs * HB timer PLUS a random jitter. 1164 1.1 rjs */ 1165 1.1 rjs if (stcb == NULL) { 1166 1.1 rjs return (EFAULT); 1167 1.1 rjs } 1168 1.1 rjs { 1169 1.1 rjs uint32_t rndval; 1170 1.1 rjs uint8_t this_random; 1171 1.1 rjs int cnt_of_unconf=0; 1172 1.1 rjs struct sctp_nets *lnet; 1173 1.1 rjs 1174 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 1175 1.1 rjs if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) { 1176 1.1 rjs cnt_of_unconf++; 1177 1.1 rjs } 1178 1.1 rjs } 1179 1.1 rjs #ifdef SCTP_DEBUG 1180 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) { 1181 1.1 rjs printf("HB timer to start unconfirmed:%d hb_delay:%d\n", 1182 1.1 rjs cnt_of_unconf, stcb->asoc.heart_beat_delay); 1183 1.1 rjs } 1184 1.1 rjs #endif 1185 1.1 rjs if (stcb->asoc.hb_random_idx > 3) { 1186 1.1 rjs rndval = sctp_select_initial_TSN(&inp->sctp_ep); 1187 1.1 rjs memcpy(stcb->asoc.hb_random_values, &rndval, 1188 1.1 rjs sizeof(stcb->asoc.hb_random_values)); 1189 1.1 rjs this_random = stcb->asoc.hb_random_values[0]; 1190 1.1 rjs stcb->asoc.hb_random_idx = 0; 1191 1.1 rjs stcb->asoc.hb_ect_randombit = 0; 1192 1.1 rjs } else { 1193 1.1 rjs this_random = stcb->asoc.hb_random_values[stcb->asoc.hb_random_idx]; 1194 1.1 rjs stcb->asoc.hb_random_idx++; 1195 1.1 rjs stcb->asoc.hb_ect_randombit = 0; 1196 1.1 rjs } 1197 1.1 rjs /* 1198 1.1 rjs * this_random will be 0 - 256 ms 1199 1.1 rjs * RTO is in ms. 1200 1.1 rjs */ 1201 1.1 rjs if ((stcb->asoc.heart_beat_delay == 0) && 1202 1.1 rjs (cnt_of_unconf == 0)) { 1203 1.1 rjs /* no HB on this inp after confirmations */ 1204 1.1 rjs return (0); 1205 1.1 rjs } 1206 1.1 rjs if (net) { 1207 1.1 rjs int delay; 1208 1.1 rjs delay = stcb->asoc.heart_beat_delay; 1209 1.1 rjs TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) { 1210 1.1 rjs if ((lnet->dest_state & SCTP_ADDR_UNCONFIRMED) && 1211 1.1 rjs ((lnet->dest_state & SCTP_ADDR_OUT_OF_SCOPE) == 0) && 1212 1.1 rjs (lnet->dest_state & SCTP_ADDR_REACHABLE)) { 1213 1.1 rjs delay = 0; 1214 1.1 rjs } 1215 1.1 rjs } 1216 1.1 rjs if (net->RTO == 0) { 1217 1.1 rjs /* Never been checked */ 1218 1.1 rjs to_ticks = this_random + stcb->asoc.initial_rto + delay; 1219 1.1 rjs } else { 1220 1.1 rjs /* set rto_val to the ms */ 1221 1.1 rjs to_ticks = delay + net->RTO + this_random; 1222 1.1 rjs } 1223 1.1 rjs } else { 1224 1.1 rjs if (cnt_of_unconf) { 1225 1.1 rjs to_ticks = this_random + stcb->asoc.initial_rto; 1226 1.1 rjs } else { 1227 1.1 rjs to_ticks = stcb->asoc.heart_beat_delay + this_random + stcb->asoc.initial_rto; 1228 1.1 rjs } 1229 1.1 rjs } 1230 1.1 rjs /* 1231 1.1 rjs * Now we must convert the to_ticks that are now in 1232 1.1 rjs * ms to ticks. 1233 1.1 rjs */ 1234 1.1 rjs to_ticks *= hz; 1235 1.1 rjs to_ticks /= 1000; 1236 1.1 rjs #ifdef SCTP_DEBUG 1237 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) { 1238 1.1 rjs printf("Timer to expire in %d ticks\n", to_ticks); 1239 1.1 rjs } 1240 1.1 rjs #endif 1241 1.1 rjs tmr = &stcb->asoc.hb_timer; 1242 1.1 rjs } 1243 1.1 rjs break; 1244 1.1 rjs case SCTP_TIMER_TYPE_COOKIE: 1245 1.1 rjs /* 1246 1.1 rjs * Here we can use the RTO timer from the network since 1247 1.21 andvar * one RTT was complete. If a retran happened then we will 1248 1.1 rjs * be using the RTO initial value. 1249 1.1 rjs */ 1250 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1251 1.1 rjs return (EFAULT); 1252 1.1 rjs } 1253 1.1 rjs if (net->RTO == 0) { 1254 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 1255 1.1 rjs } else { 1256 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO); 1257 1.1 rjs } 1258 1.1 rjs tmr = &net->rxt_timer; 1259 1.1 rjs break; 1260 1.1 rjs case SCTP_TIMER_TYPE_NEWCOOKIE: 1261 1.1 rjs /* 1262 1.1 rjs * nothing needed but the endpoint here 1263 1.1 rjs * ususually about 60 minutes. 1264 1.1 rjs */ 1265 1.1 rjs tmr = &inp->sctp_ep.signature_change; 1266 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE]; 1267 1.1 rjs break; 1268 1.1 rjs case SCTP_TIMER_TYPE_INPKILL: 1269 1.1 rjs /* 1270 1.1 rjs * The inp is setup to die. We re-use the 1271 1.17 andvar * signature_change timer since that has 1272 1.1 rjs * stopped and we are in the GONE state. 1273 1.1 rjs */ 1274 1.1 rjs tmr = &inp->sctp_ep.signature_change; 1275 1.1 rjs to_ticks = (SCTP_INP_KILL_TIMEOUT * hz) / 1000; 1276 1.1 rjs break; 1277 1.1 rjs case SCTP_TIMER_TYPE_PATHMTURAISE: 1278 1.1 rjs /* 1279 1.1 rjs * Here we use the value found in the EP for PMTU 1280 1.1 rjs * ususually about 10 minutes. 1281 1.1 rjs */ 1282 1.1 rjs if (stcb == NULL) { 1283 1.1 rjs return (EFAULT); 1284 1.1 rjs } 1285 1.1 rjs if (net == NULL) { 1286 1.1 rjs return (EFAULT); 1287 1.1 rjs } 1288 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU]; 1289 1.1 rjs tmr = &net->pmtu_timer; 1290 1.1 rjs break; 1291 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNACK: 1292 1.1 rjs /* Here we use the RTO of the destination */ 1293 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1294 1.1 rjs return (EFAULT); 1295 1.1 rjs } 1296 1.1 rjs if (net->RTO == 0) { 1297 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 1298 1.1 rjs } else { 1299 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO); 1300 1.1 rjs } 1301 1.1 rjs tmr = &net->rxt_timer; 1302 1.1 rjs break; 1303 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 1304 1.1 rjs /* 1305 1.1 rjs * Here we use the endpoints shutdown guard timer 1306 1.1 rjs * usually about 3 minutes. 1307 1.1 rjs */ 1308 1.1 rjs if (stcb == NULL) { 1309 1.1 rjs return (EFAULT); 1310 1.1 rjs } 1311 1.1 rjs to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN]; 1312 1.1 rjs tmr = &stcb->asoc.shut_guard_timer; 1313 1.1 rjs break; 1314 1.1 rjs case SCTP_TIMER_TYPE_STRRESET: 1315 1.1 rjs /* 1316 1.1 rjs * Here the timer comes from the inp 1317 1.1 rjs * but its value is from the RTO. 1318 1.1 rjs */ 1319 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1320 1.1 rjs return (EFAULT); 1321 1.1 rjs } 1322 1.1 rjs if (net->RTO == 0) { 1323 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 1324 1.1 rjs } else { 1325 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO); 1326 1.1 rjs } 1327 1.1 rjs tmr = &stcb->asoc.strreset_timer; 1328 1.1 rjs break; 1329 1.1 rjs 1330 1.1 rjs case SCTP_TIMER_TYPE_ASCONF: 1331 1.1 rjs /* 1332 1.1 rjs * Here the timer comes from the inp 1333 1.1 rjs * but its value is from the RTO. 1334 1.1 rjs */ 1335 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1336 1.1 rjs return (EFAULT); 1337 1.1 rjs } 1338 1.1 rjs if (net->RTO == 0) { 1339 1.1 rjs to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto); 1340 1.1 rjs } else { 1341 1.1 rjs to_ticks = MSEC_TO_TICKS(net->RTO); 1342 1.1 rjs } 1343 1.1 rjs tmr = &stcb->asoc.asconf_timer; 1344 1.1 rjs break; 1345 1.1 rjs case SCTP_TIMER_TYPE_AUTOCLOSE: 1346 1.1 rjs if (stcb == NULL) { 1347 1.1 rjs return (EFAULT); 1348 1.1 rjs } 1349 1.1 rjs if (stcb->asoc.sctp_autoclose_ticks == 0) { 1350 1.1 rjs /* Really an error since stcb is NOT set to autoclose */ 1351 1.1 rjs return (0); 1352 1.1 rjs } 1353 1.1 rjs to_ticks = stcb->asoc.sctp_autoclose_ticks; 1354 1.1 rjs tmr = &stcb->asoc.autoclose_timer; 1355 1.1 rjs break; 1356 1.1 rjs default: 1357 1.1 rjs #ifdef SCTP_DEBUG 1358 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) { 1359 1.1 rjs printf("sctp_timer_start:Unknown timer type %d\n", 1360 1.1 rjs t_type); 1361 1.1 rjs } 1362 1.1 rjs #endif /* SCTP_DEBUG */ 1363 1.1 rjs return (EFAULT); 1364 1.1 rjs break; 1365 1.1 rjs }; 1366 1.1 rjs if ((to_ticks <= 0) || (tmr == NULL)) { 1367 1.1 rjs #ifdef SCTP_DEBUG 1368 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) { 1369 1.1 rjs printf("sctp_timer_start:%d:software error to_ticks:%d tmr:%p not set ??\n", 1370 1.1 rjs t_type, to_ticks, tmr); 1371 1.1 rjs } 1372 1.1 rjs #endif /* SCTP_DEBUG */ 1373 1.1 rjs return (EFAULT); 1374 1.1 rjs } 1375 1.1 rjs if (callout_pending(&tmr->timer)) { 1376 1.1 rjs /* 1377 1.1 rjs * we do NOT allow you to have it already running. 1378 1.1 rjs * if it is we leave the current one up unchanged 1379 1.1 rjs */ 1380 1.1 rjs return (EALREADY); 1381 1.1 rjs } 1382 1.1 rjs /* At this point we can proceed */ 1383 1.1 rjs if (t_type == SCTP_TIMER_TYPE_SEND) { 1384 1.1 rjs stcb->asoc.num_send_timers_up++; 1385 1.1 rjs } 1386 1.1 rjs tmr->type = t_type; 1387 1.1 rjs tmr->ep = (void *)inp; 1388 1.1 rjs tmr->tcb = (void *)stcb; 1389 1.1 rjs tmr->net = (void *)net; 1390 1.1 rjs callout_reset(&tmr->timer, to_ticks, sctp_timeout_handler, tmr); 1391 1.1 rjs return (0); 1392 1.1 rjs } 1393 1.1 rjs 1394 1.1 rjs int 1395 1.1 rjs sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1396 1.1 rjs struct sctp_nets *net) 1397 1.1 rjs { 1398 1.1 rjs struct sctp_timer *tmr; 1399 1.1 rjs 1400 1.1 rjs if (inp == NULL) 1401 1.1 rjs return (EFAULT); 1402 1.1 rjs 1403 1.1 rjs tmr = NULL; 1404 1.1 rjs switch (t_type) { 1405 1.1 rjs case SCTP_TIMER_TYPE_ITERATOR: 1406 1.1 rjs { 1407 1.1 rjs struct sctp_iterator *it; 1408 1.1 rjs it = (struct sctp_iterator *)inp; 1409 1.1 rjs tmr = &it->tmr; 1410 1.1 rjs } 1411 1.1 rjs break; 1412 1.1 rjs case SCTP_TIMER_TYPE_SEND: 1413 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1414 1.1 rjs return (EFAULT); 1415 1.1 rjs } 1416 1.1 rjs tmr = &net->rxt_timer; 1417 1.1 rjs break; 1418 1.1 rjs case SCTP_TIMER_TYPE_INIT: 1419 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1420 1.1 rjs return (EFAULT); 1421 1.1 rjs } 1422 1.1 rjs tmr = &net->rxt_timer; 1423 1.1 rjs break; 1424 1.1 rjs case SCTP_TIMER_TYPE_RECV: 1425 1.1 rjs if (stcb == NULL) { 1426 1.1 rjs return (EFAULT); 1427 1.1 rjs } 1428 1.1 rjs tmr = &stcb->asoc.dack_timer; 1429 1.1 rjs break; 1430 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWN: 1431 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1432 1.1 rjs return (EFAULT); 1433 1.1 rjs } 1434 1.1 rjs tmr = &net->rxt_timer; 1435 1.1 rjs break; 1436 1.1 rjs case SCTP_TIMER_TYPE_HEARTBEAT: 1437 1.1 rjs if (stcb == NULL) { 1438 1.1 rjs return (EFAULT); 1439 1.1 rjs } 1440 1.1 rjs tmr = &stcb->asoc.hb_timer; 1441 1.1 rjs break; 1442 1.1 rjs case SCTP_TIMER_TYPE_COOKIE: 1443 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1444 1.1 rjs return (EFAULT); 1445 1.1 rjs } 1446 1.1 rjs tmr = &net->rxt_timer; 1447 1.1 rjs break; 1448 1.1 rjs case SCTP_TIMER_TYPE_NEWCOOKIE: 1449 1.1 rjs /* nothing needed but the endpoint here */ 1450 1.1 rjs tmr = &inp->sctp_ep.signature_change; 1451 1.1 rjs /* We re-use the newcookie timer for 1452 1.1 rjs * the INP kill timer. We must assure 1453 1.1 rjs * that we do not kill it by accident. 1454 1.1 rjs */ 1455 1.1 rjs break; 1456 1.1 rjs case SCTP_TIMER_TYPE_INPKILL: 1457 1.1 rjs /* 1458 1.1 rjs * The inp is setup to die. We re-use the 1459 1.17 andvar * signature_change timer since that has 1460 1.1 rjs * stopped and we are in the GONE state. 1461 1.1 rjs */ 1462 1.1 rjs tmr = &inp->sctp_ep.signature_change; 1463 1.1 rjs break; 1464 1.1 rjs case SCTP_TIMER_TYPE_PATHMTURAISE: 1465 1.1 rjs if (stcb == NULL) { 1466 1.1 rjs return (EFAULT); 1467 1.1 rjs } 1468 1.1 rjs if (net == NULL) { 1469 1.1 rjs return (EFAULT); 1470 1.1 rjs } 1471 1.1 rjs tmr = &net->pmtu_timer; 1472 1.1 rjs break; 1473 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNACK: 1474 1.1 rjs if ((stcb == NULL) || (net == NULL)) { 1475 1.1 rjs return (EFAULT); 1476 1.1 rjs } 1477 1.1 rjs tmr = &net->rxt_timer; 1478 1.1 rjs break; 1479 1.1 rjs case SCTP_TIMER_TYPE_SHUTDOWNGUARD: 1480 1.1 rjs if (stcb == NULL) { 1481 1.1 rjs return (EFAULT); 1482 1.1 rjs } 1483 1.1 rjs tmr = &stcb->asoc.shut_guard_timer; 1484 1.1 rjs break; 1485 1.1 rjs case SCTP_TIMER_TYPE_STRRESET: 1486 1.1 rjs if (stcb == NULL) { 1487 1.1 rjs return (EFAULT); 1488 1.1 rjs } 1489 1.1 rjs tmr = &stcb->asoc.strreset_timer; 1490 1.1 rjs break; 1491 1.1 rjs case SCTP_TIMER_TYPE_ASCONF: 1492 1.1 rjs if (stcb == NULL) { 1493 1.1 rjs return (EFAULT); 1494 1.1 rjs } 1495 1.1 rjs tmr = &stcb->asoc.asconf_timer; 1496 1.1 rjs break; 1497 1.1 rjs case SCTP_TIMER_TYPE_AUTOCLOSE: 1498 1.1 rjs if (stcb == NULL) { 1499 1.1 rjs return (EFAULT); 1500 1.1 rjs } 1501 1.1 rjs tmr = &stcb->asoc.autoclose_timer; 1502 1.1 rjs break; 1503 1.1 rjs default: 1504 1.1 rjs #ifdef SCTP_DEBUG 1505 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_TIMER1) { 1506 1.1 rjs printf("sctp_timer_stop:Unknown timer type %d\n", 1507 1.1 rjs t_type); 1508 1.1 rjs } 1509 1.1 rjs #endif /* SCTP_DEBUG */ 1510 1.1 rjs break; 1511 1.1 rjs }; 1512 1.1 rjs if (tmr == NULL) 1513 1.1 rjs return (EFAULT); 1514 1.1 rjs 1515 1.1 rjs if ((tmr->type != t_type) && tmr->type) { 1516 1.1 rjs /* 1517 1.1 rjs * Ok we have a timer that is under joint use. Cookie timer 1518 1.1 rjs * per chance with the SEND timer. We therefore are NOT 1519 1.1 rjs * running the timer that the caller wants stopped. So just 1520 1.1 rjs * return. 1521 1.1 rjs */ 1522 1.1 rjs return (0); 1523 1.1 rjs } 1524 1.1 rjs if (t_type == SCTP_TIMER_TYPE_SEND) { 1525 1.1 rjs stcb->asoc.num_send_timers_up--; 1526 1.1 rjs if (stcb->asoc.num_send_timers_up < 0) { 1527 1.1 rjs stcb->asoc.num_send_timers_up = 0; 1528 1.1 rjs } 1529 1.1 rjs } 1530 1.1 rjs callout_stop(&tmr->timer); 1531 1.1 rjs return (0); 1532 1.1 rjs } 1533 1.1 rjs 1534 1.1 rjs u_int32_t 1535 1.1 rjs sctp_calculate_len(struct mbuf *m) 1536 1.1 rjs { 1537 1.1 rjs u_int32_t tlen=0; 1538 1.1 rjs struct mbuf *at; 1539 1.1 rjs at = m; 1540 1.1 rjs while (at) { 1541 1.1 rjs tlen += at->m_len; 1542 1.1 rjs at = at->m_next; 1543 1.1 rjs } 1544 1.1 rjs return (tlen); 1545 1.1 rjs } 1546 1.1 rjs 1547 1.1 rjs uint32_t 1548 1.1 rjs sctp_calculate_sum(struct mbuf *m, int32_t *pktlen, uint32_t offset) 1549 1.1 rjs { 1550 1.1 rjs /* 1551 1.1 rjs * given a mbuf chain with a packetheader offset by 'offset' 1552 1.1 rjs * pointing at a sctphdr (with csum set to 0) go through 1553 1.1 rjs * the chain of m_next's and calculate the SCTP checksum. 1554 1.15 rjs * This is CRC32c. 1555 1.15 rjs * Also has a side bonus calculate the total length 1556 1.1 rjs * of the mbuf chain. 1557 1.1 rjs * Note: if offset is greater than the total mbuf length, 1558 1.1 rjs * checksum=1, pktlen=0 is returned (ie. no real error code) 1559 1.1 rjs */ 1560 1.1 rjs int32_t tlen=0; 1561 1.1 rjs uint32_t base = 0xffffffff; 1562 1.1 rjs struct mbuf *at; 1563 1.1 rjs at = m; 1564 1.1 rjs /* find the correct mbuf and offset into mbuf */ 1565 1.1 rjs while ((at != NULL) && (offset > (uint32_t)at->m_len)) { 1566 1.1 rjs offset -= at->m_len; /* update remaining offset left */ 1567 1.1 rjs at = at->m_next; 1568 1.1 rjs } 1569 1.1 rjs 1570 1.1 rjs while (at != NULL) { 1571 1.1 rjs base = update_crc32(base, at->m_data + offset, 1572 1.1 rjs at->m_len - offset); 1573 1.1 rjs tlen += at->m_len - offset; 1574 1.1 rjs /* we only offset once into the first mbuf */ 1575 1.1 rjs if (offset) { 1576 1.1 rjs offset = 0; 1577 1.1 rjs } 1578 1.1 rjs at = at->m_next; 1579 1.1 rjs } 1580 1.1 rjs if (pktlen != NULL) { 1581 1.1 rjs *pktlen = tlen; 1582 1.1 rjs } 1583 1.1 rjs /* CRC-32c */ 1584 1.1 rjs base = sctp_csum_finalize(base); 1585 1.1 rjs return (base); 1586 1.1 rjs } 1587 1.1 rjs 1588 1.1 rjs void 1589 1.1 rjs sctp_mtu_size_reset(struct sctp_inpcb *inp, 1590 1.1 rjs struct sctp_association *asoc, u_long mtu) 1591 1.1 rjs { 1592 1.1 rjs /* 1593 1.1 rjs * Reset the P-MTU size on this association, this involves changing 1594 1.1 rjs * the asoc MTU, going through ANY chunk+overhead larger than mtu 1595 1.1 rjs * to allow the DF flag to be cleared. 1596 1.1 rjs */ 1597 1.1 rjs struct sctp_tmit_chunk *chk; 1598 1.1 rjs struct sctp_stream_out *strm; 1599 1.1 rjs unsigned int eff_mtu, ovh; 1600 1.1 rjs asoc->smallest_mtu = mtu; 1601 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1602 1.1 rjs ovh = SCTP_MIN_OVERHEAD; 1603 1.1 rjs } else { 1604 1.1 rjs ovh = SCTP_MIN_V4_OVERHEAD; 1605 1.1 rjs } 1606 1.1 rjs eff_mtu = mtu - ovh; 1607 1.1 rjs /* Now mark any chunks that need to let IP fragment */ 1608 1.1 rjs TAILQ_FOREACH(strm, &asoc->out_wheel, next_spoke) { 1609 1.1 rjs TAILQ_FOREACH(chk, &strm->outqueue, sctp_next) { 1610 1.1 rjs if (chk->send_size > eff_mtu) { 1611 1.1 rjs chk->flags &= SCTP_DONT_FRAGMENT; 1612 1.1 rjs chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 1613 1.1 rjs } 1614 1.1 rjs } 1615 1.1 rjs } 1616 1.1 rjs TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) { 1617 1.1 rjs if (chk->send_size > eff_mtu) { 1618 1.1 rjs chk->flags &= SCTP_DONT_FRAGMENT; 1619 1.1 rjs chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 1620 1.1 rjs } 1621 1.1 rjs } 1622 1.1 rjs TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { 1623 1.1 rjs if (chk->send_size > eff_mtu) { 1624 1.1 rjs chk->flags &= SCTP_DONT_FRAGMENT; 1625 1.1 rjs chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 1626 1.1 rjs } 1627 1.1 rjs } 1628 1.1 rjs } 1629 1.1 rjs 1630 1.1 rjs 1631 1.1 rjs /* 1632 1.1 rjs * given an association and starting time of the current RTT period 1633 1.1 rjs * return RTO in number of usecs 1634 1.1 rjs * net should point to the current network 1635 1.1 rjs */ 1636 1.1 rjs u_int32_t 1637 1.1 rjs sctp_calculate_rto(struct sctp_tcb *stcb, 1638 1.1 rjs struct sctp_association *asoc, 1639 1.1 rjs struct sctp_nets *net, 1640 1.1 rjs struct timeval *old) 1641 1.1 rjs { 1642 1.1 rjs /* 1643 1.1 rjs * given an association and the starting time of the current RTT 1644 1.1 rjs * period (in value1/value2) return RTO in number of usecs. 1645 1.1 rjs */ 1646 1.1 rjs int calc_time = 0; 1647 1.1 rjs unsigned int new_rto = 0; 1648 1.1 rjs int first_measure = 0; 1649 1.1 rjs struct timeval now; 1650 1.1 rjs 1651 1.1 rjs /************************/ 1652 1.1 rjs /* 1. calculate new RTT */ 1653 1.1 rjs /************************/ 1654 1.1 rjs /* get the current time */ 1655 1.1 rjs SCTP_GETTIME_TIMEVAL(&now); 1656 1.1 rjs /* compute the RTT value */ 1657 1.1 rjs if ((u_long)now.tv_sec > (u_long)old->tv_sec) { 1658 1.1 rjs calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000; 1659 1.1 rjs if ((u_long)now.tv_usec > (u_long)old->tv_usec) { 1660 1.1 rjs calc_time += (((u_long)now.tv_usec - 1661 1.1 rjs (u_long)old->tv_usec)/1000); 1662 1.1 rjs } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) { 1663 1.1 rjs /* Borrow 1,000ms from current calculation */ 1664 1.1 rjs calc_time -= 1000; 1665 1.1 rjs /* Add in the slop over */ 1666 1.1 rjs calc_time += ((int)now.tv_usec/1000); 1667 1.1 rjs /* Add in the pre-second ms's */ 1668 1.1 rjs calc_time += (((int)1000000 - (int)old->tv_usec)/1000); 1669 1.1 rjs } 1670 1.1 rjs } else if ((u_long)now.tv_sec == (u_long)old->tv_sec) { 1671 1.1 rjs if ((u_long)now.tv_usec > (u_long)old->tv_usec) { 1672 1.1 rjs calc_time = ((u_long)now.tv_usec - 1673 1.1 rjs (u_long)old->tv_usec)/1000; 1674 1.1 rjs } else if ((u_long)now.tv_usec < (u_long)old->tv_usec) { 1675 1.1 rjs /* impossible .. garbage in nothing out */ 1676 1.1 rjs return (((net->lastsa >> 2) + net->lastsv) >> 1); 1677 1.1 rjs } else { 1678 1.1 rjs /* impossible .. garbage in nothing out */ 1679 1.1 rjs return (((net->lastsa >> 2) + net->lastsv) >> 1); 1680 1.1 rjs } 1681 1.1 rjs } else { 1682 1.1 rjs /* Clock wrapped? */ 1683 1.1 rjs return (((net->lastsa >> 2) + net->lastsv) >> 1); 1684 1.1 rjs } 1685 1.1 rjs /***************************/ 1686 1.1 rjs /* 2. update RTTVAR & SRTT */ 1687 1.1 rjs /***************************/ 1688 1.1 rjs #if 0 1689 1.1 rjs /* if (net->lastsv || net->lastsa) {*/ 1690 1.1 rjs /* per Section 5.3.1 C3 in SCTP */ 1691 1.1 rjs /* net->lastsv = (int) *//* RTTVAR */ 1692 1.1 rjs /* (((double)(1.0 - 0.25) * (double)net->lastsv) + 1693 1.1 rjs (double)(0.25 * (double)abs(net->lastsa - calc_time))); 1694 1.1 rjs net->lastsa = (int) */ /* SRTT */ 1695 1.1 rjs /*(((double)(1.0 - 0.125) * (double)net->lastsa) + 1696 1.1 rjs (double)(0.125 * (double)calc_time)); 1697 1.1 rjs } else { 1698 1.1 rjs *//* the first RTT calculation, per C2 Section 5.3.1 */ 1699 1.1 rjs /* net->lastsa = calc_time; *//* SRTT */ 1700 1.1 rjs /* net->lastsv = calc_time / 2; *//* RTTVAR */ 1701 1.1 rjs /* }*/ 1702 1.1 rjs /* if RTTVAR goes to 0 you set to clock grainularity */ 1703 1.1 rjs /* if (net->lastsv == 0) { 1704 1.1 rjs net->lastsv = SCTP_CLOCK_GRANULARITY; 1705 1.1 rjs } 1706 1.1 rjs new_rto = net->lastsa + 4 * net->lastsv; 1707 1.1 rjs */ 1708 1.1 rjs #endif 1709 1.1 rjs /* this is Van Jacobson's integer version */ 1710 1.1 rjs if (net->RTO) { 1711 1.1 rjs calc_time -= (net->lastsa >> 3); 1712 1.1 rjs net->lastsa += calc_time; 1713 1.1 rjs if (calc_time < 0) { 1714 1.1 rjs calc_time = -calc_time; 1715 1.1 rjs } 1716 1.1 rjs calc_time -= (net->lastsv >> 2); 1717 1.1 rjs net->lastsv += calc_time; 1718 1.1 rjs if (net->lastsv == 0) { 1719 1.1 rjs net->lastsv = SCTP_CLOCK_GRANULARITY; 1720 1.1 rjs } 1721 1.1 rjs } else { 1722 1.18 msaitoh /* First RTO measurement */ 1723 1.1 rjs net->lastsa = calc_time; 1724 1.1 rjs net->lastsv = calc_time >> 1; 1725 1.1 rjs first_measure = 1; 1726 1.1 rjs } 1727 1.1 rjs new_rto = ((net->lastsa >> 2) + net->lastsv) >> 1; 1728 1.1 rjs if ((new_rto > SCTP_SAT_NETWORK_MIN) && 1729 1.1 rjs (stcb->asoc.sat_network_lockout == 0)) { 1730 1.1 rjs stcb->asoc.sat_network = 1; 1731 1.1 rjs } else if ((!first_measure) && stcb->asoc.sat_network) { 1732 1.1 rjs stcb->asoc.sat_network = 0; 1733 1.1 rjs stcb->asoc.sat_network_lockout = 1; 1734 1.1 rjs } 1735 1.1 rjs /* bound it, per C6/C7 in Section 5.3.1 */ 1736 1.1 rjs if (new_rto < stcb->asoc.minrto) { 1737 1.1 rjs new_rto = stcb->asoc.minrto; 1738 1.1 rjs } 1739 1.1 rjs if (new_rto > stcb->asoc.maxrto) { 1740 1.1 rjs new_rto = stcb->asoc.maxrto; 1741 1.1 rjs } 1742 1.1 rjs /* we are now returning the RTT Smoothed */ 1743 1.1 rjs return ((u_int32_t)new_rto); 1744 1.1 rjs } 1745 1.1 rjs 1746 1.1 rjs 1747 1.1 rjs /* 1748 1.1 rjs * return a pointer to a contiguous piece of data from the given 1749 1.1 rjs * mbuf chain starting at 'off' for 'len' bytes. If the desired 1750 1.1 rjs * piece spans more than one mbuf, a copy is made at 'ptr'. 1751 1.1 rjs * caller must ensure that the buffer size is >= 'len' 1752 1.1 rjs * returns NULL if there there isn't 'len' bytes in the chain. 1753 1.1 rjs */ 1754 1.1 rjs void * 1755 1.1 rjs sctp_m_getptr(struct mbuf *m, int off, int len, u_int8_t *in_ptr) 1756 1.1 rjs { 1757 1.1 rjs uint32_t count; 1758 1.1 rjs uint8_t *ptr; 1759 1.1 rjs ptr = in_ptr; 1760 1.1 rjs if ((off < 0) || (len <= 0)) 1761 1.1 rjs return (NULL); 1762 1.1 rjs 1763 1.1 rjs /* find the desired start location */ 1764 1.1 rjs while ((m != NULL) && (off > 0)) { 1765 1.1 rjs if (off < m->m_len) 1766 1.1 rjs break; 1767 1.1 rjs off -= m->m_len; 1768 1.1 rjs m = m->m_next; 1769 1.1 rjs } 1770 1.1 rjs if (m == NULL) 1771 1.1 rjs return (NULL); 1772 1.1 rjs 1773 1.1 rjs /* is the current mbuf large enough (eg. contiguous)? */ 1774 1.1 rjs if ((m->m_len - off) >= len) { 1775 1.1 rjs return ((void *)(mtod(m, vaddr_t) + off)); 1776 1.1 rjs } else { 1777 1.1 rjs /* else, it spans more than one mbuf, so save a temp copy... */ 1778 1.1 rjs while ((m != NULL) && (len > 0)) { 1779 1.13 riastrad count = uimin(m->m_len - off, len); 1780 1.1 rjs memcpy(ptr, (void *)(mtod(m, vaddr_t) + off), count); 1781 1.1 rjs len -= count; 1782 1.1 rjs ptr += count; 1783 1.1 rjs off = 0; 1784 1.1 rjs m = m->m_next; 1785 1.1 rjs } 1786 1.1 rjs if ((m == NULL) && (len > 0)) 1787 1.1 rjs return (NULL); 1788 1.1 rjs else 1789 1.1 rjs return ((void *)in_ptr); 1790 1.1 rjs } 1791 1.1 rjs } 1792 1.1 rjs 1793 1.1 rjs 1794 1.1 rjs struct sctp_paramhdr * 1795 1.1 rjs sctp_get_next_param(struct mbuf *m, 1796 1.1 rjs int offset, 1797 1.1 rjs struct sctp_paramhdr *pull, 1798 1.1 rjs int pull_limit) 1799 1.1 rjs { 1800 1.1 rjs /* This just provides a typed signature to Peter's Pull routine */ 1801 1.1 rjs return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit, 1802 1.1 rjs (u_int8_t *)pull)); 1803 1.1 rjs } 1804 1.1 rjs 1805 1.1 rjs 1806 1.1 rjs int 1807 1.1 rjs sctp_add_pad_tombuf(struct mbuf *m, int padlen) 1808 1.1 rjs { 1809 1.1 rjs /* 1810 1.1 rjs * add padlen bytes of 0 filled padding to the end of the mbuf. 1811 1.1 rjs * If padlen is > 3 this routine will fail. 1812 1.1 rjs */ 1813 1.1 rjs u_int8_t *dp; 1814 1.1 rjs int i; 1815 1.1 rjs if (padlen > 3) { 1816 1.1 rjs return (ENOBUFS); 1817 1.1 rjs } 1818 1.1 rjs if (M_TRAILINGSPACE(m)) { 1819 1.1 rjs /* 1820 1.1 rjs * The easy way. 1821 1.1 rjs * We hope the majority of the time we hit here :) 1822 1.1 rjs */ 1823 1.1 rjs dp = (u_int8_t *)(mtod(m, vaddr_t) + m->m_len); 1824 1.1 rjs m->m_len += padlen; 1825 1.1 rjs } else { 1826 1.1 rjs /* Hard way we must grow the mbuf */ 1827 1.1 rjs struct mbuf *tmp; 1828 1.1 rjs MGET(tmp, M_DONTWAIT, MT_DATA); 1829 1.1 rjs if (tmp == NULL) { 1830 1.1 rjs /* Out of space GAK! we are in big trouble. */ 1831 1.1 rjs return (ENOSPC); 1832 1.1 rjs } 1833 1.1 rjs /* setup and insert in middle */ 1834 1.1 rjs tmp->m_next = m->m_next; 1835 1.1 rjs tmp->m_len = padlen; 1836 1.1 rjs m->m_next = tmp; 1837 1.1 rjs dp = mtod(tmp, u_int8_t *); 1838 1.1 rjs } 1839 1.1 rjs /* zero out the pad */ 1840 1.1 rjs for (i= 0; i < padlen; i++) { 1841 1.1 rjs *dp = 0; 1842 1.1 rjs dp++; 1843 1.1 rjs } 1844 1.1 rjs return (0); 1845 1.1 rjs } 1846 1.1 rjs 1847 1.1 rjs int 1848 1.1 rjs sctp_pad_lastmbuf(struct mbuf *m, int padval) 1849 1.1 rjs { 1850 1.1 rjs /* find the last mbuf in chain and pad it */ 1851 1.1 rjs struct mbuf *m_at; 1852 1.1 rjs m_at = m; 1853 1.1 rjs while (m_at) { 1854 1.1 rjs if (m_at->m_next == NULL) { 1855 1.1 rjs return (sctp_add_pad_tombuf(m_at, padval)); 1856 1.1 rjs } 1857 1.1 rjs m_at = m_at->m_next; 1858 1.1 rjs } 1859 1.1 rjs return (EFAULT); 1860 1.1 rjs } 1861 1.1 rjs 1862 1.1 rjs static void 1863 1.1 rjs sctp_notify_assoc_change(u_int32_t event, struct sctp_tcb *stcb, 1864 1.1 rjs u_int32_t error) 1865 1.1 rjs { 1866 1.1 rjs struct mbuf *m_notify; 1867 1.1 rjs struct sctp_assoc_change *sac; 1868 1.1 rjs const struct sockaddr *to; 1869 1.1 rjs struct sockaddr_in6 sin6, lsa6; 1870 1.1 rjs 1871 1.1 rjs #ifdef SCTP_DEBUG 1872 1.1 rjs printf("notify: %d\n", event); 1873 1.1 rjs #endif 1874 1.1 rjs /* 1875 1.14 msaitoh * First if we are going down dump everything we 1876 1.1 rjs * can to the socket rcv queue. 1877 1.1 rjs */ 1878 1.1 rjs if ((event == SCTP_SHUTDOWN_COMP) || (event == SCTP_COMM_LOST)) { 1879 1.1 rjs sctp_deliver_data(stcb, &stcb->asoc, NULL, 0); 1880 1.1 rjs } 1881 1.1 rjs 1882 1.1 rjs /* 1883 1.1 rjs * For TCP model AND UDP connected sockets we will send 1884 1.1 rjs * an error up when an ABORT comes in. 1885 1.1 rjs */ 1886 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 1887 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && 1888 1.1 rjs (event == SCTP_COMM_LOST)) { 1889 1.1 rjs stcb->sctp_socket->so_error = ECONNRESET; 1890 1.1 rjs /* Wake ANY sleepers */ 1891 1.1 rjs sowwakeup(stcb->sctp_socket); 1892 1.1 rjs sorwakeup(stcb->sctp_socket); 1893 1.1 rjs } 1894 1.1 rjs #if 0 1895 1.1 rjs if ((event == SCTP_COMM_UP) && 1896 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 1897 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 1898 1.1 rjs soisconnected(stcb->sctp_socket); 1899 1.1 rjs } 1900 1.1 rjs #endif 1901 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVASSOCEVNT)) { 1902 1.1 rjs /* event not enabled */ 1903 1.1 rjs return; 1904 1.1 rjs } 1905 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA); 1906 1.1 rjs if (m_notify == NULL) 1907 1.1 rjs /* no space left */ 1908 1.1 rjs return; 1909 1.1 rjs m_notify->m_len = 0; 1910 1.1 rjs 1911 1.1 rjs sac = mtod(m_notify, struct sctp_assoc_change *); 1912 1.1 rjs sac->sac_type = SCTP_ASSOC_CHANGE; 1913 1.1 rjs sac->sac_flags = 0; 1914 1.1 rjs sac->sac_length = sizeof(struct sctp_assoc_change); 1915 1.1 rjs sac->sac_state = event; 1916 1.1 rjs sac->sac_error = error; 1917 1.1 rjs /* XXX verify these stream counts */ 1918 1.1 rjs sac->sac_outbound_streams = stcb->asoc.streamoutcnt; 1919 1.1 rjs sac->sac_inbound_streams = stcb->asoc.streamincnt; 1920 1.1 rjs sac->sac_assoc_id = sctp_get_associd(stcb); 1921 1.1 rjs 1922 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION; 1923 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_assoc_change); 1924 1.9 ozaki m_reset_rcvif(m_notify); 1925 1.1 rjs m_notify->m_len = sizeof(struct sctp_assoc_change); 1926 1.1 rjs m_notify->m_next = NULL; 1927 1.1 rjs 1928 1.1 rjs /* append to socket */ 1929 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro); 1930 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 1931 1.1 rjs to->sa_family == AF_INET) { 1932 1.1 rjs const struct sockaddr_in *sin; 1933 1.1 rjs 1934 1.1 rjs sin = (const struct sockaddr_in *)to; 1935 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6); 1936 1.1 rjs to = (struct sockaddr *)&sin6; 1937 1.1 rjs } 1938 1.1 rjs /* check and strip embedded scope junk */ 1939 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to, 1940 1.1 rjs &lsa6); 1941 1.1 rjs /* 1942 1.1 rjs * We need to always notify comm changes. 1943 1.1 rjs * if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) { 1944 1.1 rjs * sctp_m_freem(m_notify); 1945 1.1 rjs * return; 1946 1.1 rjs * } 1947 1.1 rjs */ 1948 1.1 rjs SCTP_TCB_UNLOCK(stcb); 1949 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep); 1950 1.1 rjs SCTP_TCB_LOCK(stcb); 1951 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, 1952 1.1 rjs to, m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) { 1953 1.1 rjs /* not enough room */ 1954 1.1 rjs sctp_m_freem(m_notify); 1955 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 1956 1.1 rjs return; 1957 1.1 rjs } 1958 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 1959 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){ 1960 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) { 1961 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 1962 1.1 rjs } 1963 1.1 rjs } else { 1964 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 1965 1.1 rjs } 1966 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 1967 1.1 rjs /* Wake up any sleeper */ 1968 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 1969 1.1 rjs sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket); 1970 1.1 rjs } 1971 1.1 rjs 1972 1.1 rjs static void 1973 1.1 rjs sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state, 1974 1.1 rjs const struct sockaddr *sa, uint32_t error) 1975 1.1 rjs { 1976 1.1 rjs struct mbuf *m_notify; 1977 1.1 rjs struct sctp_paddr_change *spc; 1978 1.1 rjs const struct sockaddr *to; 1979 1.1 rjs struct sockaddr_in6 sin6, lsa6; 1980 1.1 rjs 1981 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT)) 1982 1.1 rjs /* event not enabled */ 1983 1.1 rjs return; 1984 1.1 rjs 1985 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA); 1986 1.1 rjs if (m_notify == NULL) 1987 1.1 rjs return; 1988 1.1 rjs m_notify->m_len = 0; 1989 1.1 rjs 1990 1.1 rjs MCLGET(m_notify, M_DONTWAIT); 1991 1.1 rjs if ((m_notify->m_flags & M_EXT) != M_EXT) { 1992 1.1 rjs sctp_m_freem(m_notify); 1993 1.1 rjs return; 1994 1.1 rjs } 1995 1.1 rjs 1996 1.1 rjs spc = mtod(m_notify, struct sctp_paddr_change *); 1997 1.1 rjs spc->spc_type = SCTP_PEER_ADDR_CHANGE; 1998 1.1 rjs spc->spc_flags = 0; 1999 1.1 rjs spc->spc_length = sizeof(struct sctp_paddr_change); 2000 1.1 rjs if (sa->sa_family == AF_INET) { 2001 1.1 rjs memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in)); 2002 1.1 rjs } else { 2003 1.1 rjs memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6)); 2004 1.1 rjs } 2005 1.1 rjs spc->spc_state = state; 2006 1.1 rjs spc->spc_error = error; 2007 1.1 rjs spc->spc_assoc_id = sctp_get_associd(stcb); 2008 1.1 rjs 2009 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION; 2010 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_paddr_change); 2011 1.9 ozaki m_reset_rcvif(m_notify); 2012 1.1 rjs m_notify->m_len = sizeof(struct sctp_paddr_change); 2013 1.1 rjs m_notify->m_next = NULL; 2014 1.1 rjs 2015 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro); 2016 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 2017 1.1 rjs to->sa_family == AF_INET) { 2018 1.1 rjs const struct sockaddr_in *sin; 2019 1.1 rjs 2020 1.1 rjs sin = (const struct sockaddr_in *)to; 2021 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6); 2022 1.1 rjs to = (struct sockaddr *)&sin6; 2023 1.1 rjs } 2024 1.1 rjs /* check and strip embedded scope junk */ 2025 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to, 2026 1.1 rjs &lsa6); 2027 1.1 rjs 2028 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) { 2029 1.1 rjs sctp_m_freem(m_notify); 2030 1.1 rjs return; 2031 1.1 rjs } 2032 1.1 rjs /* append to socket */ 2033 1.1 rjs SCTP_TCB_UNLOCK(stcb); 2034 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep); 2035 1.1 rjs SCTP_TCB_LOCK(stcb); 2036 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to, 2037 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) { 2038 1.1 rjs /* not enough room */ 2039 1.1 rjs sctp_m_freem(m_notify); 2040 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2041 1.1 rjs return; 2042 1.1 rjs } 2043 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 2044 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){ 2045 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) { 2046 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2047 1.1 rjs } 2048 1.1 rjs } else { 2049 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2050 1.1 rjs } 2051 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2052 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 2053 1.1 rjs } 2054 1.1 rjs 2055 1.1 rjs 2056 1.1 rjs static void 2057 1.1 rjs sctp_notify_send_failed(struct sctp_tcb *stcb, u_int32_t error, 2058 1.1 rjs struct sctp_tmit_chunk *chk) 2059 1.1 rjs { 2060 1.1 rjs struct mbuf *m_notify; 2061 1.1 rjs struct sctp_send_failed *ssf; 2062 1.1 rjs struct sockaddr_in6 sin6, lsa6; 2063 1.1 rjs const struct sockaddr *to; 2064 1.1 rjs int length; 2065 1.1 rjs 2066 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) 2067 1.1 rjs /* event not enabled */ 2068 1.1 rjs return; 2069 1.1 rjs 2070 1.1 rjs length = sizeof(struct sctp_send_failed) + chk->send_size; 2071 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA); 2072 1.1 rjs if (m_notify == NULL) 2073 1.1 rjs /* no space left */ 2074 1.1 rjs return; 2075 1.1 rjs m_notify->m_len = 0; 2076 1.1 rjs ssf = mtod(m_notify, struct sctp_send_failed *); 2077 1.1 rjs ssf->ssf_type = SCTP_SEND_FAILED; 2078 1.1 rjs if (error == SCTP_NOTIFY_DATAGRAM_UNSENT) 2079 1.1 rjs ssf->ssf_flags = SCTP_DATA_UNSENT; 2080 1.1 rjs else 2081 1.1 rjs ssf->ssf_flags = SCTP_DATA_SENT; 2082 1.1 rjs ssf->ssf_length = length; 2083 1.1 rjs ssf->ssf_error = error; 2084 1.1 rjs /* not exactly what the user sent in, but should be close :) */ 2085 1.1 rjs ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number; 2086 1.1 rjs ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq; 2087 1.1 rjs ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags; 2088 1.1 rjs ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype; 2089 1.1 rjs ssf->ssf_info.sinfo_context = chk->rec.data.context; 2090 1.1 rjs ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb); 2091 1.1 rjs ssf->ssf_assoc_id = sctp_get_associd(stcb); 2092 1.1 rjs m_notify->m_next = chk->data; 2093 1.1 rjs if (m_notify->m_next == NULL) 2094 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION; 2095 1.1 rjs else { 2096 1.1 rjs struct mbuf *m; 2097 1.1 rjs m_notify->m_flags |= M_NOTIFICATION; 2098 1.1 rjs m = m_notify; 2099 1.1 rjs while (m->m_next != NULL) 2100 1.1 rjs m = m->m_next; 2101 1.1 rjs m->m_flags |= M_EOR; 2102 1.1 rjs } 2103 1.1 rjs m_notify->m_pkthdr.len = length; 2104 1.9 ozaki m_reset_rcvif(m_notify); 2105 1.1 rjs m_notify->m_len = sizeof(struct sctp_send_failed); 2106 1.1 rjs 2107 1.1 rjs /* Steal off the mbuf */ 2108 1.1 rjs chk->data = NULL; 2109 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro); 2110 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 2111 1.1 rjs to->sa_family == AF_INET) { 2112 1.1 rjs const struct sockaddr_in *sin; 2113 1.1 rjs 2114 1.1 rjs sin = satocsin(to); 2115 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6); 2116 1.1 rjs to = (struct sockaddr *)&sin6; 2117 1.1 rjs } 2118 1.1 rjs /* check and strip embedded scope junk */ 2119 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to, 2120 1.1 rjs &lsa6); 2121 1.1 rjs 2122 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) { 2123 1.1 rjs sctp_m_freem(m_notify); 2124 1.1 rjs return; 2125 1.1 rjs } 2126 1.1 rjs 2127 1.1 rjs /* append to socket */ 2128 1.1 rjs SCTP_TCB_UNLOCK(stcb); 2129 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep); 2130 1.1 rjs SCTP_TCB_LOCK(stcb); 2131 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to, 2132 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) { 2133 1.1 rjs /* not enough room */ 2134 1.1 rjs sctp_m_freem(m_notify); 2135 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2136 1.1 rjs return; 2137 1.1 rjs } 2138 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 2139 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){ 2140 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) { 2141 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2142 1.1 rjs } 2143 1.1 rjs } else { 2144 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2145 1.1 rjs } 2146 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2147 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 2148 1.1 rjs } 2149 1.1 rjs 2150 1.1 rjs static void 2151 1.1 rjs sctp_notify_adaption_layer(struct sctp_tcb *stcb, 2152 1.1 rjs u_int32_t error) 2153 1.1 rjs { 2154 1.1 rjs struct mbuf *m_notify; 2155 1.1 rjs struct sctp_adaption_event *sai; 2156 1.1 rjs struct sockaddr_in6 sin6, lsa6; 2157 1.1 rjs const struct sockaddr *to; 2158 1.1 rjs 2159 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT)) 2160 1.1 rjs /* event not enabled */ 2161 1.1 rjs return; 2162 1.1 rjs 2163 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA); 2164 1.1 rjs if (m_notify == NULL) 2165 1.1 rjs /* no space left */ 2166 1.1 rjs return; 2167 1.1 rjs m_notify->m_len = 0; 2168 1.1 rjs sai = mtod(m_notify, struct sctp_adaption_event *); 2169 1.1 rjs sai->sai_type = SCTP_ADAPTION_INDICATION; 2170 1.1 rjs sai->sai_flags = 0; 2171 1.1 rjs sai->sai_length = sizeof(struct sctp_adaption_event); 2172 1.1 rjs sai->sai_adaption_ind = error; 2173 1.1 rjs sai->sai_assoc_id = sctp_get_associd(stcb); 2174 1.1 rjs 2175 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION; 2176 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_adaption_event); 2177 1.9 ozaki m_reset_rcvif(m_notify); 2178 1.1 rjs m_notify->m_len = sizeof(struct sctp_adaption_event); 2179 1.1 rjs m_notify->m_next = NULL; 2180 1.1 rjs 2181 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro); 2182 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 2183 1.1 rjs (to->sa_family == AF_INET)) { 2184 1.1 rjs const struct sockaddr_in *sin; 2185 1.1 rjs 2186 1.1 rjs sin = satocsin(to); 2187 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6); 2188 1.1 rjs to = (struct sockaddr *)&sin6; 2189 1.1 rjs } 2190 1.1 rjs /* check and strip embedded scope junk */ 2191 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to, 2192 1.1 rjs &lsa6); 2193 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) { 2194 1.1 rjs sctp_m_freem(m_notify); 2195 1.1 rjs return; 2196 1.1 rjs } 2197 1.1 rjs /* append to socket */ 2198 1.1 rjs SCTP_TCB_UNLOCK(stcb); 2199 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep); 2200 1.1 rjs SCTP_TCB_LOCK(stcb); 2201 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to, 2202 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) { 2203 1.1 rjs /* not enough room */ 2204 1.1 rjs sctp_m_freem(m_notify); 2205 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2206 1.1 rjs return; 2207 1.1 rjs } 2208 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 2209 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){ 2210 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) { 2211 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2212 1.1 rjs } 2213 1.1 rjs } else { 2214 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2215 1.1 rjs } 2216 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2217 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 2218 1.1 rjs } 2219 1.1 rjs 2220 1.1 rjs static void 2221 1.1 rjs sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, 2222 1.1 rjs u_int32_t error) 2223 1.1 rjs { 2224 1.1 rjs struct mbuf *m_notify; 2225 1.1 rjs struct sctp_pdapi_event *pdapi; 2226 1.1 rjs struct sockaddr_in6 sin6, lsa6; 2227 1.1 rjs const struct sockaddr *to; 2228 1.1 rjs 2229 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT)) 2230 1.1 rjs /* event not enabled */ 2231 1.1 rjs return; 2232 1.1 rjs 2233 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA); 2234 1.1 rjs if (m_notify == NULL) 2235 1.1 rjs /* no space left */ 2236 1.1 rjs return; 2237 1.1 rjs m_notify->m_len = 0; 2238 1.1 rjs pdapi = mtod(m_notify, struct sctp_pdapi_event *); 2239 1.1 rjs pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT; 2240 1.1 rjs pdapi->pdapi_flags = 0; 2241 1.1 rjs pdapi->pdapi_length = sizeof(struct sctp_pdapi_event); 2242 1.1 rjs pdapi->pdapi_indication = error; 2243 1.1 rjs pdapi->pdapi_assoc_id = sctp_get_associd(stcb); 2244 1.1 rjs 2245 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION; 2246 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_pdapi_event); 2247 1.9 ozaki m_reset_rcvif(m_notify); 2248 1.1 rjs m_notify->m_len = sizeof(struct sctp_pdapi_event); 2249 1.1 rjs m_notify->m_next = NULL; 2250 1.1 rjs 2251 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro); 2252 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 2253 1.1 rjs (to->sa_family == AF_INET)) { 2254 1.1 rjs const struct sockaddr_in *sin; 2255 1.1 rjs 2256 1.1 rjs sin = satocsin(to); 2257 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6); 2258 1.1 rjs to = (struct sockaddr *)&sin6; 2259 1.1 rjs } 2260 1.1 rjs /* check and strip embedded scope junk */ 2261 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to, 2262 1.1 rjs &lsa6); 2263 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) { 2264 1.1 rjs sctp_m_freem(m_notify); 2265 1.1 rjs return; 2266 1.1 rjs } 2267 1.1 rjs /* append to socket */ 2268 1.1 rjs SCTP_TCB_UNLOCK(stcb); 2269 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep); 2270 1.1 rjs SCTP_TCB_LOCK(stcb); 2271 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to, 2272 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) { 2273 1.1 rjs /* not enough room */ 2274 1.1 rjs sctp_m_freem(m_notify); 2275 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2276 1.1 rjs return; 2277 1.1 rjs } 2278 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 2279 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){ 2280 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) { 2281 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2282 1.1 rjs } 2283 1.1 rjs } else { 2284 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2285 1.1 rjs } 2286 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2287 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 2288 1.1 rjs } 2289 1.1 rjs 2290 1.1 rjs static void 2291 1.1 rjs sctp_notify_shutdown_event(struct sctp_tcb *stcb) 2292 1.1 rjs { 2293 1.1 rjs struct mbuf *m_notify; 2294 1.1 rjs struct sctp_shutdown_event *sse; 2295 1.1 rjs struct sockaddr_in6 sin6, lsa6; 2296 1.1 rjs const struct sockaddr *to; 2297 1.1 rjs 2298 1.1 rjs /* 2299 1.1 rjs * For TCP model AND UDP connected sockets we will send 2300 1.1 rjs * an error up when an SHUTDOWN completes 2301 1.1 rjs */ 2302 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2303 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 2304 1.1 rjs /* mark socket closed for read/write and wakeup! */ 2305 1.1 rjs socantrcvmore(stcb->sctp_socket); 2306 1.1 rjs socantsendmore(stcb->sctp_socket); 2307 1.1 rjs } 2308 1.1 rjs 2309 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) 2310 1.1 rjs /* event not enabled */ 2311 1.1 rjs return; 2312 1.1 rjs 2313 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA); 2314 1.1 rjs if (m_notify == NULL) 2315 1.1 rjs /* no space left */ 2316 1.1 rjs return; 2317 1.1 rjs m_notify->m_len = 0; 2318 1.1 rjs sse = mtod(m_notify, struct sctp_shutdown_event *); 2319 1.1 rjs sse->sse_type = SCTP_SHUTDOWN_EVENT; 2320 1.1 rjs sse->sse_flags = 0; 2321 1.1 rjs sse->sse_length = sizeof(struct sctp_shutdown_event); 2322 1.1 rjs sse->sse_assoc_id = sctp_get_associd(stcb); 2323 1.1 rjs 2324 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION; 2325 1.1 rjs m_notify->m_pkthdr.len = sizeof(struct sctp_shutdown_event); 2326 1.9 ozaki m_reset_rcvif(m_notify); 2327 1.1 rjs m_notify->m_len = sizeof(struct sctp_shutdown_event); 2328 1.1 rjs m_notify->m_next = NULL; 2329 1.1 rjs 2330 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro); 2331 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 2332 1.1 rjs to->sa_family == AF_INET) { 2333 1.1 rjs const struct sockaddr_in *sin; 2334 1.1 rjs 2335 1.1 rjs sin = satocsin(to); 2336 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6); 2337 1.1 rjs to = (struct sockaddr *)&sin6; 2338 1.1 rjs } 2339 1.1 rjs /* check and strip embedded scope junk */ 2340 1.1 rjs to = (const struct sockaddr *)sctp_recover_scope((const struct sockaddr_in6 *)to, 2341 1.1 rjs &lsa6); 2342 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) { 2343 1.1 rjs sctp_m_freem(m_notify); 2344 1.1 rjs return; 2345 1.1 rjs } 2346 1.1 rjs /* append to socket */ 2347 1.1 rjs SCTP_TCB_UNLOCK(stcb); 2348 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep); 2349 1.1 rjs SCTP_TCB_LOCK(stcb); 2350 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to, 2351 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) { 2352 1.1 rjs /* not enough room */ 2353 1.1 rjs sctp_m_freem(m_notify); 2354 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2355 1.1 rjs return; 2356 1.1 rjs } 2357 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 2358 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){ 2359 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) { 2360 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2361 1.1 rjs } 2362 1.1 rjs } else { 2363 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2364 1.1 rjs } 2365 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2366 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 2367 1.1 rjs } 2368 1.1 rjs 2369 1.1 rjs static void 2370 1.1 rjs sctp_notify_stream_reset(struct sctp_tcb *stcb, 2371 1.1 rjs int number_entries, uint16_t *list, int flag) 2372 1.1 rjs { 2373 1.1 rjs struct mbuf *m_notify; 2374 1.1 rjs struct sctp_stream_reset_event *strreset; 2375 1.1 rjs struct sockaddr_in6 sin6, lsa6; 2376 1.1 rjs const struct sockaddr *to; 2377 1.1 rjs int len; 2378 1.1 rjs 2379 1.1 rjs if (!(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT)) 2380 1.1 rjs /* event not enabled */ 2381 1.1 rjs return; 2382 1.1 rjs 2383 1.1 rjs MGETHDR(m_notify, M_DONTWAIT, MT_DATA); 2384 1.1 rjs if (m_notify == NULL) 2385 1.1 rjs /* no space left */ 2386 1.1 rjs return; 2387 1.1 rjs m_notify->m_len = 0; 2388 1.1 rjs len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t)); 2389 1.1 rjs if (len > M_TRAILINGSPACE(m_notify)) { 2390 1.1 rjs MCLGET(m_notify, M_WAIT); 2391 1.1 rjs } 2392 1.1 rjs if (m_notify == NULL) 2393 1.1 rjs /* no clusters */ 2394 1.1 rjs return; 2395 1.1 rjs 2396 1.1 rjs if (len > M_TRAILINGSPACE(m_notify)) { 2397 1.1 rjs /* never enough room */ 2398 1.1 rjs m_freem(m_notify); 2399 1.1 rjs return; 2400 1.1 rjs } 2401 1.1 rjs strreset = mtod(m_notify, struct sctp_stream_reset_event *); 2402 1.1 rjs strreset->strreset_type = SCTP_STREAM_RESET_EVENT; 2403 1.1 rjs if (number_entries == 0) { 2404 1.1 rjs strreset->strreset_flags = flag | SCTP_STRRESET_ALL_STREAMS; 2405 1.1 rjs } else { 2406 1.1 rjs strreset->strreset_flags = flag | SCTP_STRRESET_STREAM_LIST; 2407 1.1 rjs } 2408 1.1 rjs strreset->strreset_length = len; 2409 1.1 rjs strreset->strreset_assoc_id = sctp_get_associd(stcb); 2410 1.1 rjs if (number_entries) { 2411 1.1 rjs int i; 2412 1.1 rjs for (i=0; i<number_entries; i++) { 2413 1.1 rjs strreset->strreset_list[i] = list[i]; 2414 1.1 rjs } 2415 1.1 rjs } 2416 1.1 rjs m_notify->m_flags |= M_EOR | M_NOTIFICATION; 2417 1.1 rjs m_notify->m_pkthdr.len = len; 2418 1.9 ozaki m_reset_rcvif(m_notify); 2419 1.1 rjs m_notify->m_len = len; 2420 1.1 rjs m_notify->m_next = NULL; 2421 1.1 rjs if (sctp_sbspace(&stcb->sctp_socket->so_rcv) < m_notify->m_len) { 2422 1.1 rjs /* no space */ 2423 1.1 rjs sctp_m_freem(m_notify); 2424 1.1 rjs return; 2425 1.1 rjs } 2426 1.1 rjs to = rtcache_getdst(&stcb->asoc.primary_destination->ro); 2427 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) && 2428 1.1 rjs to->sa_family == AF_INET) { 2429 1.1 rjs const struct sockaddr_in *sin; 2430 1.1 rjs 2431 1.1 rjs sin = satocsin(to); 2432 1.2 rtr in6_sin_2_v4mapsin6(sin, &sin6); 2433 1.1 rjs to = (struct sockaddr *)&sin6; 2434 1.1 rjs } 2435 1.1 rjs /* check and strip embedded scope junk */ 2436 1.1 rjs to = (const struct sockaddr *) sctp_recover_scope((const struct sockaddr_in6 *)to, 2437 1.1 rjs &lsa6); 2438 1.1 rjs /* append to socket */ 2439 1.1 rjs SCTP_TCB_UNLOCK(stcb); 2440 1.1 rjs SCTP_INP_WLOCK(stcb->sctp_ep); 2441 1.1 rjs SCTP_TCB_LOCK(stcb); 2442 1.1 rjs if (!sbappendaddr_nocheck(&stcb->sctp_socket->so_rcv, to, 2443 1.1 rjs m_notify, NULL, stcb->asoc.my_vtag, stcb->sctp_ep)) { 2444 1.1 rjs /* not enough room */ 2445 1.1 rjs sctp_m_freem(m_notify); 2446 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2447 1.1 rjs return; 2448 1.1 rjs } 2449 1.1 rjs if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0) && 2450 1.1 rjs ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)){ 2451 1.1 rjs if (sctp_add_to_socket_q(stcb->sctp_ep, stcb)) { 2452 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2453 1.1 rjs } 2454 1.1 rjs } else { 2455 1.1 rjs stcb->asoc.my_rwnd_control_len += sizeof(struct mbuf); 2456 1.1 rjs } 2457 1.1 rjs SCTP_INP_WUNLOCK(stcb->sctp_ep); 2458 1.1 rjs sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); 2459 1.1 rjs } 2460 1.1 rjs 2461 1.1 rjs 2462 1.1 rjs void 2463 1.1 rjs sctp_ulp_notify(u_int32_t notification, struct sctp_tcb *stcb, 2464 1.1 rjs u_int32_t error, void *data) 2465 1.1 rjs { 2466 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 2467 1.1 rjs /* No notifications up when we are in a no socket state */ 2468 1.1 rjs return; 2469 1.1 rjs } 2470 1.1 rjs if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) { 2471 1.1 rjs /* Can't send up to a closed socket any notifications */ 2472 1.1 rjs return; 2473 1.1 rjs } 2474 1.1 rjs switch (notification) { 2475 1.1 rjs case SCTP_NOTIFY_ASSOC_UP: 2476 1.1 rjs sctp_notify_assoc_change(SCTP_COMM_UP, stcb, error); 2477 1.1 rjs break; 2478 1.1 rjs case SCTP_NOTIFY_ASSOC_DOWN: 2479 1.1 rjs sctp_notify_assoc_change(SCTP_SHUTDOWN_COMP, stcb, error); 2480 1.1 rjs break; 2481 1.1 rjs case SCTP_NOTIFY_INTERFACE_DOWN: 2482 1.1 rjs { 2483 1.1 rjs struct sctp_nets *net; 2484 1.1 rjs net = (struct sctp_nets *)data; 2485 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_UNREACHABLE, 2486 1.1 rjs rtcache_getdst(&net->ro), error); 2487 1.1 rjs break; 2488 1.1 rjs } 2489 1.1 rjs case SCTP_NOTIFY_INTERFACE_UP: 2490 1.1 rjs { 2491 1.1 rjs struct sctp_nets *net; 2492 1.1 rjs net = (struct sctp_nets *)data; 2493 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_AVAILABLE, 2494 1.1 rjs rtcache_getdst(&net->ro), error); 2495 1.1 rjs break; 2496 1.1 rjs } 2497 1.1 rjs case SCTP_NOTIFY_INTERFACE_CONFIRMED: 2498 1.1 rjs { 2499 1.1 rjs struct sctp_nets *net; 2500 1.1 rjs net = (struct sctp_nets *)data; 2501 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_CONFIRMED, 2502 1.1 rjs rtcache_getdst(&net->ro), error); 2503 1.1 rjs break; 2504 1.1 rjs } 2505 1.1 rjs case SCTP_NOTIFY_DG_FAIL: 2506 1.1 rjs sctp_notify_send_failed(stcb, error, 2507 1.1 rjs (struct sctp_tmit_chunk *)data); 2508 1.1 rjs break; 2509 1.1 rjs case SCTP_NOTIFY_ADAPTION_INDICATION: 2510 1.1 rjs /* Here the error is the adaption indication */ 2511 1.1 rjs sctp_notify_adaption_layer(stcb, error); 2512 1.1 rjs break; 2513 1.1 rjs case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION: 2514 1.1 rjs sctp_notify_partial_delivery_indication(stcb, error); 2515 1.1 rjs break; 2516 1.1 rjs case SCTP_NOTIFY_STRDATA_ERR: 2517 1.1 rjs break; 2518 1.1 rjs case SCTP_NOTIFY_ASSOC_ABORTED: 2519 1.1 rjs sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error); 2520 1.1 rjs break; 2521 1.1 rjs case SCTP_NOTIFY_PEER_OPENED_STREAM: 2522 1.1 rjs break; 2523 1.1 rjs case SCTP_NOTIFY_STREAM_OPENED_OK: 2524 1.1 rjs break; 2525 1.1 rjs case SCTP_NOTIFY_ASSOC_RESTART: 2526 1.1 rjs sctp_notify_assoc_change(SCTP_RESTART, stcb, error); 2527 1.1 rjs break; 2528 1.1 rjs case SCTP_NOTIFY_HB_RESP: 2529 1.1 rjs break; 2530 1.1 rjs case SCTP_NOTIFY_STR_RESET_SEND: 2531 1.1 rjs sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_OUTBOUND_STR); 2532 1.1 rjs break; 2533 1.1 rjs case SCTP_NOTIFY_STR_RESET_RECV: 2534 1.1 rjs sctp_notify_stream_reset(stcb, error, ((uint16_t *)data), SCTP_STRRESET_INBOUND_STR); 2535 1.1 rjs break; 2536 1.1 rjs case SCTP_NOTIFY_ASCONF_ADD_IP: 2537 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_ADDED, data, 2538 1.1 rjs error); 2539 1.1 rjs break; 2540 1.1 rjs case SCTP_NOTIFY_ASCONF_DELETE_IP: 2541 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data, 2542 1.1 rjs error); 2543 1.1 rjs break; 2544 1.1 rjs case SCTP_NOTIFY_ASCONF_SET_PRIMARY: 2545 1.1 rjs sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data, 2546 1.1 rjs error); 2547 1.1 rjs break; 2548 1.1 rjs case SCTP_NOTIFY_ASCONF_SUCCESS: 2549 1.1 rjs break; 2550 1.1 rjs case SCTP_NOTIFY_ASCONF_FAILED: 2551 1.1 rjs break; 2552 1.1 rjs case SCTP_NOTIFY_PEER_SHUTDOWN: 2553 1.1 rjs sctp_notify_shutdown_event(stcb); 2554 1.1 rjs break; 2555 1.1 rjs default: 2556 1.1 rjs #ifdef SCTP_DEBUG 2557 1.1 rjs if (sctp_debug_on & SCTP_DEBUG_UTIL1) { 2558 1.1 rjs printf("NOTIFY: unknown notification %xh (%u)\n", 2559 1.1 rjs notification, notification); 2560 1.1 rjs } 2561 1.1 rjs #endif /* SCTP_DEBUG */ 2562 1.1 rjs break; 2563 1.1 rjs } /* end switch */ 2564 1.1 rjs } 2565 1.1 rjs 2566 1.1 rjs void 2567 1.1 rjs sctp_report_all_outbound(struct sctp_tcb *stcb) 2568 1.1 rjs { 2569 1.1 rjs struct sctp_association *asoc; 2570 1.1 rjs struct sctp_stream_out *outs; 2571 1.1 rjs struct sctp_tmit_chunk *chk; 2572 1.1 rjs 2573 1.1 rjs asoc = &stcb->asoc; 2574 1.1 rjs 2575 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 2576 1.1 rjs return; 2577 1.1 rjs } 2578 1.1 rjs /* now through all the gunk freeing chunks */ 2579 1.1 rjs TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) { 2580 1.1 rjs /* now clean up any chunks here */ 2581 1.1 rjs chk = TAILQ_FIRST(&outs->outqueue); 2582 1.1 rjs while (chk) { 2583 1.1 rjs stcb->asoc.stream_queue_cnt--; 2584 1.1 rjs TAILQ_REMOVE(&outs->outqueue, chk, sctp_next); 2585 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, 2586 1.1 rjs SCTP_NOTIFY_DATAGRAM_UNSENT, chk); 2587 1.20 rin sctp_m_freem(chk->data); 2588 1.20 rin chk->data = NULL; 2589 1.1 rjs if (chk->whoTo) 2590 1.1 rjs sctp_free_remote_addr(chk->whoTo); 2591 1.1 rjs chk->whoTo = NULL; 2592 1.1 rjs chk->asoc = NULL; 2593 1.1 rjs /* Free the chunk */ 2594 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk); 2595 1.1 rjs sctppcbinfo.ipi_count_chunk--; 2596 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) { 2597 1.1 rjs panic("Chunk count is negative"); 2598 1.1 rjs } 2599 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++; 2600 1.1 rjs chk = TAILQ_FIRST(&outs->outqueue); 2601 1.1 rjs } 2602 1.1 rjs } 2603 1.1 rjs /* pending send queue SHOULD be empty */ 2604 1.1 rjs if (!TAILQ_EMPTY(&asoc->send_queue)) { 2605 1.1 rjs chk = TAILQ_FIRST(&asoc->send_queue); 2606 1.1 rjs while (chk) { 2607 1.1 rjs TAILQ_REMOVE(&asoc->send_queue, chk, sctp_next); 2608 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, SCTP_NOTIFY_DATAGRAM_UNSENT, chk); 2609 1.20 rin sctp_m_freem(chk->data); 2610 1.20 rin chk->data = NULL; 2611 1.1 rjs if (chk->whoTo) 2612 1.1 rjs sctp_free_remote_addr(chk->whoTo); 2613 1.1 rjs chk->whoTo = NULL; 2614 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk); 2615 1.1 rjs sctppcbinfo.ipi_count_chunk--; 2616 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) { 2617 1.1 rjs panic("Chunk count is negative"); 2618 1.1 rjs } 2619 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++; 2620 1.1 rjs chk = TAILQ_FIRST(&asoc->send_queue); 2621 1.1 rjs } 2622 1.1 rjs } 2623 1.1 rjs /* sent queue SHOULD be empty */ 2624 1.1 rjs if (!TAILQ_EMPTY(&asoc->sent_queue)) { 2625 1.1 rjs chk = TAILQ_FIRST(&asoc->sent_queue); 2626 1.1 rjs while (chk) { 2627 1.1 rjs TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next); 2628 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, 2629 1.1 rjs SCTP_NOTIFY_DATAGRAM_SENT, chk); 2630 1.20 rin sctp_m_freem(chk->data); 2631 1.20 rin chk->data = NULL; 2632 1.1 rjs if (chk->whoTo) 2633 1.1 rjs sctp_free_remote_addr(chk->whoTo); 2634 1.1 rjs chk->whoTo = NULL; 2635 1.1 rjs SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, chk); 2636 1.1 rjs sctppcbinfo.ipi_count_chunk--; 2637 1.1 rjs if ((int)sctppcbinfo.ipi_count_chunk < 0) { 2638 1.1 rjs panic("Chunk count is negative"); 2639 1.1 rjs } 2640 1.1 rjs sctppcbinfo.ipi_gencnt_chunk++; 2641 1.1 rjs chk = TAILQ_FIRST(&asoc->sent_queue); 2642 1.1 rjs } 2643 1.1 rjs } 2644 1.1 rjs } 2645 1.1 rjs 2646 1.1 rjs void 2647 1.1 rjs sctp_abort_notification(struct sctp_tcb *stcb, int error) 2648 1.1 rjs { 2649 1.1 rjs 2650 1.1 rjs if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 2651 1.1 rjs return; 2652 1.1 rjs } 2653 1.1 rjs /* Tell them we lost the asoc */ 2654 1.1 rjs sctp_report_all_outbound(stcb); 2655 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_ASSOC_ABORTED, stcb, error, NULL); 2656 1.1 rjs } 2657 1.1 rjs 2658 1.1 rjs void 2659 1.1 rjs sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 2660 1.1 rjs struct mbuf *m, int iphlen, struct sctphdr *sh, struct mbuf *op_err) 2661 1.1 rjs { 2662 1.1 rjs u_int32_t vtag; 2663 1.1 rjs 2664 1.1 rjs vtag = 0; 2665 1.1 rjs if (stcb != NULL) { 2666 1.1 rjs /* We have a TCB to abort, send notification too */ 2667 1.1 rjs vtag = stcb->asoc.peer_vtag; 2668 1.1 rjs sctp_abort_notification(stcb, 0); 2669 1.1 rjs } 2670 1.1 rjs sctp_send_abort(m, iphlen, sh, vtag, op_err); 2671 1.1 rjs if (stcb != NULL) { 2672 1.1 rjs /* Ok, now lets free it */ 2673 1.1 rjs sctp_free_assoc(inp, stcb); 2674 1.1 rjs } else { 2675 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 2676 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) { 2677 1.1 rjs sctp_inpcb_free(inp, 1); 2678 1.1 rjs } 2679 1.1 rjs } 2680 1.1 rjs } 2681 1.1 rjs } 2682 1.1 rjs 2683 1.1 rjs void 2684 1.1 rjs sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 2685 1.1 rjs int error, struct mbuf *op_err) 2686 1.1 rjs { 2687 1.1 rjs 2688 1.1 rjs if (stcb == NULL) { 2689 1.1 rjs /* Got to have a TCB */ 2690 1.1 rjs if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { 2691 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) { 2692 1.1 rjs sctp_inpcb_free(inp, 1); 2693 1.1 rjs } 2694 1.1 rjs } 2695 1.1 rjs return; 2696 1.1 rjs } 2697 1.1 rjs /* notify the ulp */ 2698 1.1 rjs if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) 2699 1.1 rjs sctp_abort_notification(stcb, error); 2700 1.1 rjs /* notify the peer */ 2701 1.1 rjs sctp_send_abort_tcb(stcb, op_err); 2702 1.1 rjs /* now free the asoc */ 2703 1.1 rjs sctp_free_assoc(inp, stcb); 2704 1.1 rjs } 2705 1.1 rjs 2706 1.1 rjs void 2707 1.1 rjs sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh, 2708 1.1 rjs struct sctp_inpcb *inp, struct mbuf *op_err) 2709 1.1 rjs { 2710 1.1 rjs struct sctp_chunkhdr *ch, chunk_buf; 2711 1.1 rjs unsigned int chk_length; 2712 1.1 rjs 2713 1.1 rjs /* Generate a TO address for future reference */ 2714 1.1 rjs if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) { 2715 1.1 rjs if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) { 2716 1.1 rjs sctp_inpcb_free(inp, 1); 2717 1.1 rjs } 2718 1.1 rjs } 2719 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 2720 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf); 2721 1.1 rjs while (ch != NULL) { 2722 1.1 rjs chk_length = ntohs(ch->chunk_length); 2723 1.1 rjs if (chk_length < sizeof(*ch)) { 2724 1.1 rjs /* break to abort land */ 2725 1.1 rjs break; 2726 1.1 rjs } 2727 1.1 rjs switch (ch->chunk_type) { 2728 1.1 rjs case SCTP_PACKET_DROPPED: 2729 1.1 rjs /* we don't respond to pkt-dropped */ 2730 1.1 rjs return; 2731 1.1 rjs case SCTP_ABORT_ASSOCIATION: 2732 1.1 rjs /* we don't respond with an ABORT to an ABORT */ 2733 1.1 rjs return; 2734 1.1 rjs case SCTP_SHUTDOWN_COMPLETE: 2735 1.1 rjs /* 2736 1.1 rjs * we ignore it since we are not waiting for it 2737 1.1 rjs * and peer is gone 2738 1.1 rjs */ 2739 1.1 rjs return; 2740 1.1 rjs case SCTP_SHUTDOWN_ACK: 2741 1.1 rjs sctp_send_shutdown_complete2(m, iphlen, sh); 2742 1.1 rjs return; 2743 1.1 rjs default: 2744 1.1 rjs break; 2745 1.1 rjs } 2746 1.1 rjs offset += SCTP_SIZE32(chk_length); 2747 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 2748 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf); 2749 1.1 rjs } 2750 1.1 rjs sctp_send_abort(m, iphlen, sh, 0, op_err); 2751 1.1 rjs } 2752 1.1 rjs 2753 1.1 rjs /* 2754 1.1 rjs * check the inbound datagram to make sure there is not an abort 2755 1.1 rjs * inside it, if there is return 1, else return 0. 2756 1.1 rjs */ 2757 1.1 rjs int 2758 1.1 rjs sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, int *vtagfill) 2759 1.1 rjs { 2760 1.1 rjs struct sctp_chunkhdr *ch; 2761 1.1 rjs struct sctp_init_chunk *init_chk, chunk_buf; 2762 1.1 rjs int offset; 2763 1.1 rjs unsigned int chk_length; 2764 1.1 rjs 2765 1.1 rjs offset = iphlen + sizeof(struct sctphdr); 2766 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, sizeof(*ch), 2767 1.1 rjs (u_int8_t *)&chunk_buf); 2768 1.1 rjs while (ch != NULL) { 2769 1.1 rjs chk_length = ntohs(ch->chunk_length); 2770 1.1 rjs if (chk_length < sizeof(*ch)) { 2771 1.1 rjs /* packet is probably corrupt */ 2772 1.1 rjs break; 2773 1.1 rjs } 2774 1.1 rjs /* we seem to be ok, is it an abort? */ 2775 1.1 rjs if (ch->chunk_type == SCTP_ABORT_ASSOCIATION) { 2776 1.1 rjs /* yep, tell them */ 2777 1.1 rjs return (1); 2778 1.1 rjs } 2779 1.1 rjs if (ch->chunk_type == SCTP_INITIATION) { 2780 1.1 rjs /* need to update the Vtag */ 2781 1.1 rjs init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m, 2782 1.1 rjs offset, sizeof(*init_chk), (u_int8_t *)&chunk_buf); 2783 1.1 rjs if (init_chk != NULL) { 2784 1.1 rjs *vtagfill = ntohl(init_chk->init.initiate_tag); 2785 1.1 rjs } 2786 1.1 rjs } 2787 1.1 rjs /* Nope, move to the next chunk */ 2788 1.1 rjs offset += SCTP_SIZE32(chk_length); 2789 1.1 rjs ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset, 2790 1.1 rjs sizeof(*ch), (u_int8_t *)&chunk_buf); 2791 1.1 rjs } 2792 1.1 rjs return (0); 2793 1.1 rjs } 2794 1.1 rjs 2795 1.1 rjs /* 2796 1.1 rjs * currently (2/02), ifa_addr embeds scope_id's and don't 2797 1.1 rjs * have sin6_scope_id set (i.e. it's 0) 2798 1.1 rjs * so, create this function to compare link local scopes 2799 1.1 rjs */ 2800 1.1 rjs uint32_t 2801 1.8 rjs sctp_is_same_scope(const struct sockaddr_in6 *addr1, const struct sockaddr_in6 *addr2) 2802 1.1 rjs { 2803 1.1 rjs struct sockaddr_in6 a, b; 2804 1.1 rjs 2805 1.1 rjs /* save copies */ 2806 1.1 rjs a = *addr1; 2807 1.1 rjs b = *addr2; 2808 1.1 rjs 2809 1.1 rjs if (a.sin6_scope_id == 0) 2810 1.1 rjs if (sa6_recoverscope(&a)) { 2811 1.1 rjs /* can't get scope, so can't match */ 2812 1.1 rjs return (0); 2813 1.1 rjs } 2814 1.1 rjs if (b.sin6_scope_id == 0) 2815 1.1 rjs if (sa6_recoverscope(&b)) { 2816 1.1 rjs /* can't get scope, so can't match */ 2817 1.1 rjs return (0); 2818 1.1 rjs } 2819 1.1 rjs if (a.sin6_scope_id != b.sin6_scope_id) 2820 1.1 rjs return (0); 2821 1.1 rjs 2822 1.1 rjs return (1); 2823 1.1 rjs } 2824 1.1 rjs 2825 1.1 rjs /* 2826 1.1 rjs * returns a sockaddr_in6 with embedded scope recovered and removed 2827 1.1 rjs */ 2828 1.1 rjs const struct sockaddr_in6 * 2829 1.1 rjs sctp_recover_scope(const struct sockaddr_in6 *addr, struct sockaddr_in6 *store) 2830 1.1 rjs { 2831 1.1 rjs const struct sockaddr_in6 *newaddr; 2832 1.1 rjs 2833 1.1 rjs newaddr = addr; 2834 1.1 rjs /* check and strip embedded scope junk */ 2835 1.1 rjs if (addr->sin6_family == AF_INET6) { 2836 1.1 rjs if (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr)) { 2837 1.1 rjs if (addr->sin6_scope_id == 0) { 2838 1.1 rjs *store = *addr; 2839 1.1 rjs if (sa6_recoverscope(store) == 0) { 2840 1.1 rjs /* use the recovered scope */ 2841 1.1 rjs newaddr = store; 2842 1.1 rjs } 2843 1.1 rjs /* else, return the original "to" addr */ 2844 1.1 rjs } 2845 1.1 rjs } 2846 1.1 rjs } 2847 1.1 rjs return (newaddr); 2848 1.1 rjs } 2849 1.1 rjs 2850 1.1 rjs /* 2851 1.1 rjs * are the two addresses the same? currently a "scopeless" check 2852 1.1 rjs * returns: 1 if same, 0 if not 2853 1.1 rjs */ 2854 1.1 rjs int 2855 1.1 rjs sctp_cmpaddr(const struct sockaddr *sa1, const struct sockaddr *sa2) 2856 1.1 rjs { 2857 1.1 rjs 2858 1.1 rjs /* must be valid */ 2859 1.1 rjs if (sa1 == NULL || sa2 == NULL) 2860 1.1 rjs return (0); 2861 1.1 rjs 2862 1.1 rjs /* must be the same family */ 2863 1.1 rjs if (sa1->sa_family != sa2->sa_family) 2864 1.1 rjs return (0); 2865 1.1 rjs 2866 1.1 rjs if (sa1->sa_family == AF_INET6) { 2867 1.1 rjs /* IPv6 addresses */ 2868 1.1 rjs const struct sockaddr_in6 *sin6_1, *sin6_2; 2869 1.1 rjs 2870 1.1 rjs sin6_1 = (const struct sockaddr_in6 *)sa1; 2871 1.1 rjs sin6_2 = (const struct sockaddr_in6 *)sa2; 2872 1.1 rjs return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr, 2873 1.1 rjs &sin6_2->sin6_addr)); 2874 1.1 rjs } else if (sa1->sa_family == AF_INET) { 2875 1.1 rjs /* IPv4 addresses */ 2876 1.1 rjs const struct sockaddr_in *sin_1, *sin_2; 2877 1.1 rjs 2878 1.1 rjs sin_1 = (const struct sockaddr_in *)sa1; 2879 1.1 rjs sin_2 = (const struct sockaddr_in *)sa2; 2880 1.1 rjs return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr); 2881 1.1 rjs } else { 2882 1.1 rjs /* we don't do these... */ 2883 1.1 rjs return (0); 2884 1.1 rjs } 2885 1.1 rjs } 2886 1.1 rjs 2887 1.1 rjs void 2888 1.1 rjs sctp_print_address(const struct sockaddr *sa) 2889 1.1 rjs { 2890 1.11 ryo char ip6buf[INET6_ADDRSTRLEN]; 2891 1.1 rjs 2892 1.1 rjs if (sa->sa_family == AF_INET6) { 2893 1.1 rjs const struct sockaddr_in6 *sin6; 2894 1.1 rjs sin6 = (const struct sockaddr_in6 *)sa; 2895 1.1 rjs printf("IPv6 address: %s:%d scope:%u\n", 2896 1.12 christos IN6_PRINT(ip6buf, &sin6->sin6_addr), ntohs(sin6->sin6_port), 2897 1.1 rjs sin6->sin6_scope_id); 2898 1.1 rjs } else if (sa->sa_family == AF_INET) { 2899 1.1 rjs const struct sockaddr_in *sin; 2900 1.1 rjs sin = (const struct sockaddr_in *)sa; 2901 1.1 rjs printf("IPv4 address: %s:%d\n", inet_ntoa(sin->sin_addr), 2902 1.1 rjs ntohs(sin->sin_port)); 2903 1.1 rjs } else { 2904 1.1 rjs printf("?\n"); 2905 1.1 rjs } 2906 1.1 rjs } 2907 1.1 rjs 2908 1.1 rjs void 2909 1.1 rjs sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh) 2910 1.1 rjs { 2911 1.1 rjs if (iph->ip_v == IPVERSION) { 2912 1.1 rjs struct sockaddr_in lsa, fsa; 2913 1.1 rjs 2914 1.1 rjs memset(&lsa, 0, sizeof(lsa)); 2915 1.1 rjs lsa.sin_len = sizeof(lsa); 2916 1.1 rjs lsa.sin_family = AF_INET; 2917 1.1 rjs lsa.sin_addr = iph->ip_src; 2918 1.1 rjs lsa.sin_port = sh->src_port; 2919 1.1 rjs memset(&fsa, 0, sizeof(fsa)); 2920 1.1 rjs fsa.sin_len = sizeof(fsa); 2921 1.1 rjs fsa.sin_family = AF_INET; 2922 1.1 rjs fsa.sin_addr = iph->ip_dst; 2923 1.1 rjs fsa.sin_port = sh->dest_port; 2924 1.1 rjs printf("src: "); 2925 1.1 rjs sctp_print_address((struct sockaddr *)&lsa); 2926 1.1 rjs printf("dest: "); 2927 1.1 rjs sctp_print_address((struct sockaddr *)&fsa); 2928 1.1 rjs } else if (iph->ip_v == (IPV6_VERSION >> 4)) { 2929 1.1 rjs struct ip6_hdr *ip6; 2930 1.1 rjs struct sockaddr_in6 lsa6, fsa6; 2931 1.1 rjs 2932 1.1 rjs ip6 = (struct ip6_hdr *)iph; 2933 1.1 rjs memset(&lsa6, 0, sizeof(lsa6)); 2934 1.1 rjs lsa6.sin6_len = sizeof(lsa6); 2935 1.1 rjs lsa6.sin6_family = AF_INET6; 2936 1.1 rjs lsa6.sin6_addr = ip6->ip6_src; 2937 1.1 rjs lsa6.sin6_port = sh->src_port; 2938 1.1 rjs memset(&fsa6, 0, sizeof(fsa6)); 2939 1.1 rjs fsa6.sin6_len = sizeof(fsa6); 2940 1.1 rjs fsa6.sin6_family = AF_INET6; 2941 1.1 rjs fsa6.sin6_addr = ip6->ip6_dst; 2942 1.1 rjs fsa6.sin6_port = sh->dest_port; 2943 1.1 rjs printf("src: "); 2944 1.1 rjs sctp_print_address((struct sockaddr *)&lsa6); 2945 1.1 rjs printf("dest: "); 2946 1.1 rjs sctp_print_address((struct sockaddr *)&fsa6); 2947 1.1 rjs } 2948 1.1 rjs } 2949 1.1 rjs 2950 1.1 rjs #if defined(__FreeBSD__) || defined(__APPLE__) 2951 1.1 rjs 2952 1.1 rjs /* cloned from uipc_socket.c */ 2953 1.1 rjs 2954 1.1 rjs #define SCTP_SBLINKRECORD(sb, m0) do { \ 2955 1.1 rjs if ((sb)->sb_lastrecord != NULL) \ 2956 1.1 rjs (sb)->sb_lastrecord->m_nextpkt = (m0); \ 2957 1.1 rjs else \ 2958 1.1 rjs (sb)->sb_mb = (m0); \ 2959 1.1 rjs (sb)->sb_lastrecord = (m0); \ 2960 1.1 rjs } while (/*CONSTCOND*/0) 2961 1.1 rjs #endif 2962 1.1 rjs 2963 1.1 rjs 2964 1.1 rjs int 2965 1.1 rjs sbappendaddr_nocheck(struct sockbuf *sb, const struct sockaddr *asa, 2966 1.1 rjs struct mbuf *m0, struct mbuf *control, 2967 1.1 rjs u_int32_t tag, struct sctp_inpcb *inp) 2968 1.1 rjs { 2969 1.1 rjs #ifdef __NetBSD__ 2970 1.1 rjs struct mbuf *m, *n; 2971 1.1 rjs 2972 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0) 2973 1.1 rjs panic("sbappendaddr_nocheck"); 2974 1.1 rjs 2975 1.1 rjs m0->m_pkthdr.csum_data = (int)tag; 2976 1.1 rjs 2977 1.1 rjs for (n = control; n; n = n->m_next) { 2978 1.1 rjs if (n->m_next == 0) /* keep pointer to last control buf */ 2979 1.1 rjs break; 2980 1.1 rjs } 2981 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) || 2982 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) { 2983 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME); 2984 1.1 rjs if (m == 0) 2985 1.1 rjs return (0); 2986 1.1 rjs 2987 1.1 rjs m->m_len = asa->sa_len; 2988 1.1 rjs memcpy(mtod(m, void *), (const void *)asa, asa->sa_len); 2989 1.1 rjs } else { 2990 1.1 rjs m = NULL; 2991 1.1 rjs } 2992 1.1 rjs if (n) { 2993 1.1 rjs n->m_next = m0; /* concatenate data to control */ 2994 1.1 rjs }else { 2995 1.1 rjs control = m0; 2996 1.1 rjs } 2997 1.1 rjs if (m) 2998 1.1 rjs m->m_next = control; 2999 1.1 rjs else 3000 1.1 rjs m = control; 3001 1.1 rjs m->m_pkthdr.csum_data = tag; 3002 1.1 rjs 3003 1.1 rjs for (n = m; n; n = n->m_next) 3004 1.1 rjs sballoc(sb, n); 3005 1.1 rjs if ((n = sb->sb_mb) != NULL) { 3006 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) { 3007 1.1 rjs inp->sb_last_mpkt = NULL; 3008 1.1 rjs } 3009 1.1 rjs if (inp->sb_last_mpkt) 3010 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m; 3011 1.1 rjs else { 3012 1.1 rjs while (n->m_nextpkt) { 3013 1.1 rjs n = n->m_nextpkt; 3014 1.1 rjs } 3015 1.1 rjs n->m_nextpkt = m; 3016 1.1 rjs } 3017 1.1 rjs inp->sb_last_mpkt = m; 3018 1.1 rjs } else { 3019 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m; 3020 1.1 rjs inp->sctp_vtag_first = tag; 3021 1.1 rjs } 3022 1.1 rjs return (1); 3023 1.1 rjs #endif 3024 1.1 rjs #if defined(__FreeBSD__) || defined(__APPLE__) 3025 1.1 rjs struct mbuf *m, *n, *nlast; 3026 1.1 rjs int cnt=0; 3027 1.1 rjs 3028 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0) 3029 1.1 rjs panic("sbappendaddr_nocheck"); 3030 1.1 rjs 3031 1.1 rjs for (n = control; n; n = n->m_next) { 3032 1.1 rjs if (n->m_next == 0) /* get pointer to last control buf */ 3033 1.1 rjs break; 3034 1.1 rjs } 3035 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) || 3036 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) { 3037 1.1 rjs if (asa->sa_len > MHLEN) 3038 1.1 rjs return (0); 3039 1.1 rjs try_again: 3040 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME); 3041 1.1 rjs if (m == 0) 3042 1.1 rjs return (0); 3043 1.1 rjs m->m_len = 0; 3044 1.1 rjs /* safety */ 3045 1.1 rjs if (m == m0) { 3046 1.1 rjs printf("Duplicate mbuf allocated %p in and mget returned %p?\n", 3047 1.1 rjs m0, m); 3048 1.1 rjs if (cnt) { 3049 1.1 rjs panic("more than once"); 3050 1.1 rjs } 3051 1.1 rjs cnt++; 3052 1.1 rjs goto try_again; 3053 1.1 rjs } 3054 1.1 rjs m->m_len = asa->sa_len; 3055 1.1 rjs bcopy((void *)asa, mtod(m, void *), asa->sa_len); 3056 1.1 rjs } 3057 1.1 rjs else { 3058 1.1 rjs m = NULL; 3059 1.1 rjs } 3060 1.1 rjs if (n) 3061 1.1 rjs n->m_next = m0; /* concatenate data to control */ 3062 1.1 rjs else 3063 1.1 rjs control = m0; 3064 1.1 rjs if (m) 3065 1.1 rjs m->m_next = control; 3066 1.1 rjs else 3067 1.1 rjs m = control; 3068 1.1 rjs m->m_pkthdr.csum_data = (int)tag; 3069 1.1 rjs 3070 1.1 rjs for (n = m; n; n = n->m_next) 3071 1.1 rjs sballoc(sb, n); 3072 1.1 rjs nlast = n; 3073 1.1 rjs if (sb->sb_mb == NULL) { 3074 1.1 rjs inp->sctp_vtag_first = tag; 3075 1.1 rjs } 3076 1.1 rjs 3077 1.1 rjs #ifdef __FREEBSD__ 3078 1.1 rjs if (sb->sb_mb == NULL) 3079 1.1 rjs inp->sctp_vtag_first = tag; 3080 1.1 rjs SCTP_SBLINKRECORD(sb, m); 3081 1.1 rjs sb->sb_mbtail = nlast; 3082 1.1 rjs #else 3083 1.1 rjs if ((n = sb->sb_mb) != NULL) { 3084 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) { 3085 1.1 rjs inp->sb_last_mpkt = NULL; 3086 1.1 rjs } 3087 1.1 rjs if (inp->sb_last_mpkt) 3088 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m; 3089 1.1 rjs else { 3090 1.1 rjs while (n->m_nextpkt) { 3091 1.1 rjs n = n->m_nextpkt; 3092 1.1 rjs } 3093 1.1 rjs n->m_nextpkt = m; 3094 1.1 rjs } 3095 1.1 rjs inp->sb_last_mpkt = m; 3096 1.1 rjs } else { 3097 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m; 3098 1.1 rjs inp->sctp_vtag_first = tag; 3099 1.1 rjs } 3100 1.1 rjs #endif 3101 1.1 rjs return (1); 3102 1.1 rjs #endif 3103 1.1 rjs #ifdef __OpenBSD__ 3104 1.1 rjs struct mbuf *m, *n; 3105 1.1 rjs 3106 1.1 rjs if (m0 && (m0->m_flags & M_PKTHDR) == 0) 3107 1.1 rjs panic("sbappendaddr_nocheck"); 3108 1.1 rjs m0->m_pkthdr.csum = (int)tag; 3109 1.1 rjs for (n = control; n; n = n->m_next) { 3110 1.1 rjs if (n->m_next == 0) /* keep pointer to last control buf */ 3111 1.1 rjs break; 3112 1.1 rjs } 3113 1.1 rjs if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) == 0) || 3114 1.1 rjs ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)== 0)) { 3115 1.1 rjs if (asa->sa_len > MHLEN) 3116 1.1 rjs return (0); 3117 1.1 rjs MGETHDR(m, M_DONTWAIT, MT_SONAME); 3118 1.1 rjs if (m == 0) 3119 1.1 rjs return (0); 3120 1.1 rjs m->m_len = asa->sa_len; 3121 1.1 rjs bcopy((void *)asa, mtod(m, void *), asa->sa_len); 3122 1.1 rjs } else { 3123 1.1 rjs m = NULL; 3124 1.1 rjs } 3125 1.1 rjs if (n) 3126 1.1 rjs n->m_next = m0; /* concatenate data to control */ 3127 1.1 rjs else 3128 1.1 rjs control = m0; 3129 1.1 rjs 3130 1.1 rjs m->m_pkthdr.csum = (int)tag; 3131 1.1 rjs m->m_next = control; 3132 1.1 rjs for (n = m; n; n = n->m_next) 3133 1.1 rjs sballoc(sb, n); 3134 1.1 rjs if ((n = sb->sb_mb) != NULL) { 3135 1.1 rjs if ((n->m_nextpkt != inp->sb_last_mpkt) && (n->m_nextpkt == NULL)) { 3136 1.1 rjs inp->sb_last_mpkt = NULL; 3137 1.1 rjs } 3138 1.1 rjs if (inp->sb_last_mpkt) 3139 1.1 rjs inp->sb_last_mpkt->m_nextpkt = m; 3140 1.1 rjs else { 3141 1.1 rjs while (n->m_nextpkt) { 3142 1.1 rjs n = n->m_nextpkt; 3143 1.1 rjs } 3144 1.1 rjs n->m_nextpkt = m; 3145 1.1 rjs } 3146 1.1 rjs inp->sb_last_mpkt = m; 3147 1.1 rjs } else { 3148 1.1 rjs inp->sb_last_mpkt = sb->sb_mb = m; 3149 1.1 rjs inp->sctp_vtag_first = tag; 3150 1.1 rjs } 3151 1.1 rjs return (1); 3152 1.1 rjs #endif 3153 1.1 rjs } 3154 1.1 rjs 3155 1.1 rjs /*************HOLD THIS COMMENT FOR PATCH FILE OF 3156 1.1 rjs *************ALTERNATE ROUTING CODE 3157 1.1 rjs */ 3158 1.1 rjs 3159 1.1 rjs /*************HOLD THIS COMMENT FOR END OF PATCH FILE OF 3160 1.1 rjs *************ALTERNATE ROUTING CODE 3161 1.1 rjs */ 3162 1.1 rjs 3163 1.1 rjs struct mbuf * 3164 1.1 rjs sctp_generate_invmanparam(int err) 3165 1.1 rjs { 3166 1.1 rjs /* Return a MBUF with a invalid mandatory parameter */ 3167 1.1 rjs struct mbuf *m; 3168 1.1 rjs 3169 1.1 rjs MGET(m, M_DONTWAIT, MT_DATA); 3170 1.1 rjs if (m) { 3171 1.1 rjs struct sctp_paramhdr *ph; 3172 1.1 rjs m->m_len = sizeof(struct sctp_paramhdr); 3173 1.1 rjs ph = mtod(m, struct sctp_paramhdr *); 3174 1.1 rjs ph->param_length = htons(sizeof(struct sctp_paramhdr)); 3175 1.1 rjs ph->param_type = htons(err); 3176 1.1 rjs } 3177 1.1 rjs return (m); 3178 1.1 rjs } 3179 1.1 rjs 3180 1.1 rjs static int 3181 1.1 rjs sctp_should_be_moved(struct mbuf *this, struct sctp_association *asoc) 3182 1.1 rjs { 3183 1.1 rjs struct mbuf *m; 3184 1.1 rjs /* 3185 1.1 rjs * given a mbuf chain, look through it finding 3186 1.1 rjs * the M_PKTHDR and return 1 if it belongs to 3187 1.1 rjs * the association given. We tell this by 3188 1.1 rjs * a kludge where we stuff the my_vtag of the asoc 3189 1.1 rjs * into the m->m_pkthdr.csum_data/csum field. 3190 1.1 rjs */ 3191 1.1 rjs m = this; 3192 1.1 rjs while (m) { 3193 1.1 rjs if (m->m_flags & M_PKTHDR) { 3194 1.1 rjs /* check it */ 3195 1.1 rjs #if defined(__OpenBSD__) 3196 1.1 rjs if ((u_int32_t)m->m_pkthdr.csum == asoc->my_vtag) 3197 1.1 rjs #else 3198 1.1 rjs if ((u_int32_t)m->m_pkthdr.csum_data == asoc->my_vtag) 3199 1.1 rjs #endif 3200 1.1 rjs { 3201 1.1 rjs /* Yep */ 3202 1.1 rjs return (1); 3203 1.1 rjs } 3204 1.1 rjs } 3205 1.1 rjs m = m->m_next; 3206 1.1 rjs } 3207 1.1 rjs return (0); 3208 1.1 rjs } 3209 1.1 rjs 3210 1.1 rjs u_int32_t 3211 1.1 rjs sctp_get_first_vtag_from_sb(struct socket *so) 3212 1.1 rjs { 3213 1.1 rjs struct mbuf *this, *at; 3214 1.1 rjs u_int32_t retval; 3215 1.1 rjs 3216 1.1 rjs retval = 0; 3217 1.1 rjs if (so->so_rcv.sb_mb) { 3218 1.1 rjs /* grubbing time */ 3219 1.1 rjs this = so->so_rcv.sb_mb; 3220 1.1 rjs while (this) { 3221 1.1 rjs at = this; 3222 1.1 rjs /* get to the m_pkthdr */ 3223 1.1 rjs while (at) { 3224 1.1 rjs if (at->m_flags & M_PKTHDR) 3225 1.1 rjs break; 3226 1.1 rjs else { 3227 1.1 rjs at = at->m_next; 3228 1.1 rjs } 3229 1.1 rjs } 3230 1.1 rjs /* now do we have a m_pkthdr */ 3231 1.1 rjs if (at && (at->m_flags & M_PKTHDR)) { 3232 1.1 rjs /* check it */ 3233 1.1 rjs #if defined(__OpenBSD__) 3234 1.1 rjs if ((u_int32_t)at->m_pkthdr.csum != 0) 3235 1.1 rjs #else 3236 1.1 rjs if ((u_int32_t)at->m_pkthdr.csum_data != 0) 3237 1.1 rjs #endif 3238 1.1 rjs { 3239 1.1 rjs /* its the one */ 3240 1.1 rjs #if defined(__OpenBSD__) 3241 1.1 rjs retval = (u_int32_t)at->m_pkthdr.csum; 3242 1.1 rjs #else 3243 1.1 rjs retval = 3244 1.1 rjs (u_int32_t)at->m_pkthdr.csum_data; 3245 1.1 rjs #endif 3246 1.1 rjs break; 3247 1.1 rjs } 3248 1.1 rjs } 3249 1.1 rjs this = this->m_nextpkt; 3250 1.1 rjs } 3251 1.1 rjs 3252 1.1 rjs } 3253 1.1 rjs return (retval); 3254 1.1 rjs 3255 1.1 rjs } 3256 1.1 rjs void 3257 1.1 rjs sctp_grub_through_socket_buffer(struct sctp_inpcb *inp, struct socket *old, 3258 1.1 rjs struct socket *new, struct sctp_tcb *stcb) 3259 1.1 rjs { 3260 1.1 rjs struct mbuf **put, **take, *next, *this; 3261 1.1 rjs struct sockbuf *old_sb, *new_sb; 3262 1.1 rjs struct sctp_association *asoc; 3263 1.1 rjs int moved_top = 0; 3264 1.1 rjs 3265 1.1 rjs asoc = &stcb->asoc; 3266 1.1 rjs old_sb = &old->so_rcv; 3267 1.1 rjs new_sb = &new->so_rcv; 3268 1.1 rjs if (old_sb->sb_mb == NULL) { 3269 1.1 rjs /* Nothing to move */ 3270 1.1 rjs return; 3271 1.1 rjs } 3272 1.1 rjs 3273 1.1 rjs if (inp->sctp_vtag_first == asoc->my_vtag) { 3274 1.1 rjs /* First one must be moved */ 3275 1.1 rjs struct mbuf *mm; 3276 1.1 rjs for (mm = old_sb->sb_mb; mm; mm = mm->m_next) { 3277 1.1 rjs /* 3278 1.1 rjs * Go down the chain and fix 3279 1.1 rjs * the space allocation of the 3280 1.1 rjs * two sockets. 3281 1.1 rjs */ 3282 1.1 rjs sbfree(old_sb, mm); 3283 1.1 rjs sballoc(new_sb, mm); 3284 1.1 rjs } 3285 1.1 rjs new_sb->sb_mb = old_sb->sb_mb; 3286 1.1 rjs old_sb->sb_mb = new_sb->sb_mb->m_nextpkt; 3287 1.1 rjs new_sb->sb_mb->m_nextpkt = NULL; 3288 1.1 rjs put = &new_sb->sb_mb->m_nextpkt; 3289 1.1 rjs moved_top = 1; 3290 1.1 rjs } else { 3291 1.1 rjs put = &new_sb->sb_mb; 3292 1.1 rjs } 3293 1.1 rjs 3294 1.1 rjs take = &old_sb->sb_mb; 3295 1.1 rjs next = old_sb->sb_mb; 3296 1.1 rjs while (next) { 3297 1.1 rjs this = next; 3298 1.19 andvar /* position for next one */ 3299 1.1 rjs next = this->m_nextpkt; 3300 1.1 rjs /* check the tag of this packet */ 3301 1.1 rjs if (sctp_should_be_moved(this, asoc)) { 3302 1.1 rjs /* yes this needs to be moved */ 3303 1.1 rjs struct mbuf *mm; 3304 1.1 rjs *take = this->m_nextpkt; 3305 1.1 rjs this->m_nextpkt = NULL; 3306 1.1 rjs *put = this; 3307 1.1 rjs for (mm = this; mm; mm = mm->m_next) { 3308 1.1 rjs /* 3309 1.1 rjs * Go down the chain and fix 3310 1.1 rjs * the space allocation of the 3311 1.1 rjs * two sockets. 3312 1.1 rjs */ 3313 1.1 rjs sbfree(old_sb, mm); 3314 1.1 rjs sballoc(new_sb, mm); 3315 1.1 rjs } 3316 1.1 rjs put = &this->m_nextpkt; 3317 1.1 rjs 3318 1.1 rjs } else { 3319 1.1 rjs /* no advance our take point. */ 3320 1.1 rjs take = &this->m_nextpkt; 3321 1.1 rjs } 3322 1.1 rjs } 3323 1.1 rjs if (moved_top) { 3324 1.1 rjs /* 3325 1.19 andvar * Ok so now we must re-position vtag_first to 3326 1.1 rjs * match the new first one since we moved the 3327 1.1 rjs * mbuf at the top. 3328 1.1 rjs */ 3329 1.1 rjs inp->sctp_vtag_first = sctp_get_first_vtag_from_sb(old); 3330 1.1 rjs } 3331 1.1 rjs } 3332 1.1 rjs 3333 1.1 rjs void 3334 1.1 rjs sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc, 3335 1.1 rjs struct sctp_tmit_chunk *tp1) 3336 1.1 rjs { 3337 1.1 rjs if (tp1->data == NULL) { 3338 1.1 rjs return; 3339 1.1 rjs } 3340 1.1 rjs #ifdef SCTP_MBCNT_LOGGING 3341 1.1 rjs sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE, 3342 1.1 rjs asoc->total_output_queue_size, 3343 1.1 rjs tp1->book_size, 3344 1.1 rjs asoc->total_output_mbuf_queue_size, 3345 1.1 rjs tp1->mbcnt); 3346 1.1 rjs #endif 3347 1.1 rjs if (asoc->total_output_queue_size >= tp1->book_size) { 3348 1.1 rjs asoc->total_output_queue_size -= tp1->book_size; 3349 1.1 rjs } else { 3350 1.1 rjs asoc->total_output_queue_size = 0; 3351 1.1 rjs } 3352 1.1 rjs 3353 1.1 rjs /* Now free the mbuf */ 3354 1.1 rjs if (asoc->total_output_mbuf_queue_size >= tp1->mbcnt) { 3355 1.1 rjs asoc->total_output_mbuf_queue_size -= tp1->mbcnt; 3356 1.1 rjs } else { 3357 1.1 rjs asoc->total_output_mbuf_queue_size = 0; 3358 1.1 rjs } 3359 1.1 rjs if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 3360 1.1 rjs (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 3361 1.1 rjs if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { 3362 1.1 rjs stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size; 3363 1.1 rjs } else { 3364 1.1 rjs stcb->sctp_socket->so_snd.sb_cc = 0; 3365 1.1 rjs 3366 1.1 rjs } 3367 1.1 rjs if (stcb->sctp_socket->so_snd.sb_mbcnt >= tp1->mbcnt) { 3368 1.1 rjs stcb->sctp_socket->so_snd.sb_mbcnt -= tp1->mbcnt; 3369 1.1 rjs } else { 3370 1.1 rjs stcb->sctp_socket->so_snd.sb_mbcnt = 0; 3371 1.1 rjs } 3372 1.1 rjs } 3373 1.1 rjs } 3374 1.1 rjs 3375 1.1 rjs int 3376 1.1 rjs sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, 3377 1.1 rjs int reason, struct sctpchunk_listhead *queue) 3378 1.1 rjs { 3379 1.1 rjs int ret_sz = 0; 3380 1.1 rjs int notdone; 3381 1.1 rjs uint8_t foundeom = 0; 3382 1.1 rjs 3383 1.1 rjs do { 3384 1.1 rjs ret_sz += tp1->book_size; 3385 1.1 rjs tp1->sent = SCTP_FORWARD_TSN_SKIP; 3386 1.1 rjs if (tp1->data) { 3387 1.1 rjs sctp_free_bufspace(stcb, &stcb->asoc, tp1); 3388 1.1 rjs sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1); 3389 1.1 rjs sctp_m_freem(tp1->data); 3390 1.1 rjs tp1->data = NULL; 3391 1.1 rjs sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket); 3392 1.1 rjs } 3393 1.1 rjs if (tp1->flags & SCTP_PR_SCTP_BUFFER) { 3394 1.1 rjs stcb->asoc.sent_queue_cnt_removeable--; 3395 1.1 rjs } 3396 1.1 rjs if (queue == &stcb->asoc.send_queue) { 3397 1.1 rjs TAILQ_REMOVE(&stcb->asoc.send_queue, tp1, sctp_next); 3398 1.1 rjs /* on to the sent queue */ 3399 1.1 rjs TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, tp1, 3400 1.1 rjs sctp_next); 3401 1.1 rjs stcb->asoc.sent_queue_cnt++; 3402 1.1 rjs } 3403 1.1 rjs if ((tp1->rec.data.rcv_flags & SCTP_DATA_NOT_FRAG) == 3404 1.1 rjs SCTP_DATA_NOT_FRAG) { 3405 1.1 rjs /* not frag'ed we ae done */ 3406 1.1 rjs notdone = 0; 3407 1.1 rjs foundeom = 1; 3408 1.1 rjs } else if (tp1->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { 3409 1.1 rjs /* end of frag, we are done */ 3410 1.1 rjs notdone = 0; 3411 1.1 rjs foundeom = 1; 3412 1.1 rjs } else { 3413 1.1 rjs /* Its a begin or middle piece, we must mark all of it */ 3414 1.1 rjs notdone = 1; 3415 1.1 rjs tp1 = TAILQ_NEXT(tp1, sctp_next); 3416 1.1 rjs } 3417 1.1 rjs } while (tp1 && notdone); 3418 1.1 rjs if ((foundeom == 0) && (queue == &stcb->asoc.sent_queue)) { 3419 1.1 rjs /* 3420 1.1 rjs * The multi-part message was scattered 3421 1.1 rjs * across the send and sent queue. 3422 1.1 rjs */ 3423 1.1 rjs tp1 = TAILQ_FIRST(&stcb->asoc.send_queue); 3424 1.1 rjs /* 3425 1.1 rjs * recurse throught the send_queue too, starting at the 3426 1.1 rjs * beginning. 3427 1.1 rjs */ 3428 1.1 rjs if (tp1) { 3429 1.1 rjs ret_sz += sctp_release_pr_sctp_chunk(stcb, tp1, reason, 3430 1.1 rjs &stcb->asoc.send_queue); 3431 1.1 rjs } else { 3432 1.1 rjs printf("hmm, nothing on the send queue and no EOM?\n"); 3433 1.1 rjs } 3434 1.1 rjs } 3435 1.1 rjs return (ret_sz); 3436 1.1 rjs } 3437 1.1 rjs 3438 1.1 rjs /* 3439 1.1 rjs * checks to see if the given address, sa, is one that is currently 3440 1.1 rjs * known by the kernel 3441 1.1 rjs * note: can't distinguish the same address on multiple interfaces and 3442 1.1 rjs * doesn't handle multiple addresses with different zone/scope id's 3443 1.1 rjs * note: ifa_ifwithaddr() compares the entire sockaddr struct 3444 1.1 rjs */ 3445 1.1 rjs struct ifaddr * 3446 1.1 rjs sctp_find_ifa_by_addr(struct sockaddr *sa) 3447 1.1 rjs { 3448 1.1 rjs struct ifnet *ifn; 3449 1.1 rjs struct ifaddr *ifa; 3450 1.7 ozaki int s; 3451 1.1 rjs 3452 1.1 rjs /* go through all our known interfaces */ 3453 1.7 ozaki s = pserialize_read_enter(); 3454 1.7 ozaki IFNET_READER_FOREACH(ifn) { 3455 1.1 rjs /* go through each interface addresses */ 3456 1.10 ozaki IFADDR_READER_FOREACH(ifa, ifn) { 3457 1.1 rjs /* correct family? */ 3458 1.1 rjs if (ifa->ifa_addr->sa_family != sa->sa_family) 3459 1.1 rjs continue; 3460 1.1 rjs 3461 1.1 rjs #ifdef INET6 3462 1.1 rjs if (ifa->ifa_addr->sa_family == AF_INET6) { 3463 1.1 rjs /* IPv6 address */ 3464 1.1 rjs struct sockaddr_in6 *sin1, *sin2, sin6_tmp; 3465 1.1 rjs sin1 = (struct sockaddr_in6 *)ifa->ifa_addr; 3466 1.1 rjs if (IN6_IS_SCOPE_LINKLOCAL(&sin1->sin6_addr)) { 3467 1.1 rjs /* create a copy and clear scope */ 3468 1.1 rjs memcpy(&sin6_tmp, sin1, 3469 1.1 rjs sizeof(struct sockaddr_in6)); 3470 1.1 rjs sin1 = &sin6_tmp; 3471 1.1 rjs in6_clearscope(&sin1->sin6_addr); 3472 1.1 rjs } 3473 1.1 rjs sin2 = (struct sockaddr_in6 *)sa; 3474 1.1 rjs if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, 3475 1.1 rjs sizeof(struct in6_addr)) == 0) { 3476 1.1 rjs /* found it */ 3477 1.7 ozaki pserialize_read_exit(s); 3478 1.1 rjs return (ifa); 3479 1.1 rjs } 3480 1.1 rjs } else 3481 1.1 rjs #endif 3482 1.1 rjs if (ifa->ifa_addr->sa_family == AF_INET) { 3483 1.1 rjs /* IPv4 address */ 3484 1.1 rjs struct sockaddr_in *sin1, *sin2; 3485 1.1 rjs sin1 = (struct sockaddr_in *)ifa->ifa_addr; 3486 1.1 rjs sin2 = (struct sockaddr_in *)sa; 3487 1.1 rjs if (sin1->sin_addr.s_addr == 3488 1.1 rjs sin2->sin_addr.s_addr) { 3489 1.1 rjs /* found it */ 3490 1.7 ozaki pserialize_read_exit(s); 3491 1.1 rjs return (ifa); 3492 1.1 rjs } 3493 1.1 rjs } 3494 1.1 rjs /* else, not AF_INET or AF_INET6, so skip */ 3495 1.1 rjs } /* end foreach ifa */ 3496 1.1 rjs } /* end foreach ifn */ 3497 1.7 ozaki pserialize_read_exit(s); 3498 1.7 ozaki 3499 1.1 rjs /* not found! */ 3500 1.1 rjs return (NULL); 3501 1.1 rjs } 3502 1.1 rjs 3503 1.1 rjs 3504 1.1 rjs #ifdef __APPLE__ 3505 1.1 rjs /* 3506 1.1 rjs * here we hack in a fix for Apple's m_copym for the case where the first mbuf 3507 1.1 rjs * in the chain is a M_PKTHDR and the length is zero 3508 1.1 rjs */ 3509 1.1 rjs static void 3510 1.1 rjs sctp_pkthdr_fix(struct mbuf *m) 3511 1.1 rjs { 3512 1.1 rjs struct mbuf *m_nxt; 3513 1.1 rjs 3514 1.1 rjs if ((m->m_flags & M_PKTHDR) == 0) { 3515 1.1 rjs /* not a PKTHDR */ 3516 1.1 rjs return; 3517 1.1 rjs } 3518 1.1 rjs 3519 1.1 rjs if (m->m_len != 0) { 3520 1.1 rjs /* not a zero length PKTHDR mbuf */ 3521 1.1 rjs return; 3522 1.1 rjs } 3523 1.1 rjs 3524 1.1 rjs /* let's move in a word into the first mbuf... yes, ugly! */ 3525 1.1 rjs m_nxt = m->m_next; 3526 1.1 rjs if (m_nxt == NULL) { 3527 1.1 rjs /* umm... not a very useful mbuf chain... */ 3528 1.1 rjs return; 3529 1.1 rjs } 3530 1.1 rjs if ((size_t)m_nxt->m_len > sizeof(long)) { 3531 1.1 rjs /* move over a long */ 3532 1.1 rjs bcopy(mtod(m_nxt, void *), mtod(m, void *), sizeof(long)); 3533 1.1 rjs /* update mbuf data pointers and lengths */ 3534 1.1 rjs m->m_len += sizeof(long); 3535 1.1 rjs m_nxt->m_data += sizeof(long); 3536 1.1 rjs m_nxt->m_len -= sizeof(long); 3537 1.1 rjs } 3538 1.1 rjs } 3539 1.1 rjs 3540 1.1 rjs inline struct mbuf * 3541 1.1 rjs sctp_m_copym(struct mbuf *m, int off, int len, int wait) 3542 1.1 rjs { 3543 1.1 rjs sctp_pkthdr_fix(m); 3544 1.1 rjs return (m_copym(m, off, len, wait)); 3545 1.1 rjs } 3546 1.1 rjs #endif /* __APPLE__ */ 3547