sctp_usrreq.c revision 1.1 1 /* $KAME: sctp_usrreq.c,v 1.50 2005/06/16 20:45:29 jinmei Exp $ */
2 /* $NetBSD: sctp_usrreq.c,v 1.1 2015/10/13 21:28:35 rjs Exp $ */
3
4 /*
5 * Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Cisco Systems, Inc.
19 * 4. Neither the name of the project nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY CISCO SYSTEMS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL CISCO SYSTEMS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: sctp_usrreq.c,v 1.1 2015/10/13 21:28:35 rjs Exp $");
37
38 #ifdef _KERNEL_OPT
39 #include "opt_inet.h"
40 #include "opt_sctp.h"
41 #endif /* _KERNEL_OPT */
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/mbuf.h>
48 #include <sys/domain.h>
49 #include <sys/proc.h>
50 #include <sys/protosw.h>
51 #include <sys/socket.h>
52 #include <sys/socketvar.h>
53 #include <sys/sysctl.h>
54 #include <sys/syslog.h>
55 #include <net/if.h>
56 #include <net/if_types.h>
57 #include <net/route.h>
58 #include <netinet/in.h>
59 #include <netinet/in_systm.h>
60 #include <netinet/ip.h>
61 #include <netinet/ip6.h>
62 #include <netinet/in_pcb.h>
63 #include <netinet/in_var.h>
64 #include <netinet/ip_var.h>
65 #include <netinet6/ip6_var.h>
66 #include <netinet6/in6_var.h>
67 #include <netinet6/scope6_var.h>
68
69 #include <netinet/ip_icmp.h>
70 #include <netinet/icmp_var.h>
71 #include <netinet/sctp_pcb.h>
72 #include <netinet/sctp_header.h>
73 #include <netinet/sctp_var.h>
74 #include <netinet/sctp_output.h>
75 #include <netinet/sctp_uio.h>
76 #include <netinet/sctp_asconf.h>
77 #include <netinet/sctputil.h>
78 #include <netinet/sctp_indata.h>
79 #include <netinet/sctp_asconf.h>
80 #ifdef IPSEC
81 #include <netinet6/ipsec.h>
82 #include <netkey/key.h>
83 #endif /* IPSEC */
84
85 #include <net/net_osdep.h>
86
87 #if defined(HAVE_NRL_INPCB) || defined(__FreeBSD__)
88 #ifndef in6pcb
89 #define in6pcb inpcb
90 #endif
91 #ifndef sotoin6pcb
92 #define sotoin6pcb sotoinpcb
93 #endif
94 #endif
95
96 #ifdef SCTP_DEBUG
97 extern u_int32_t sctp_debug_on;
98 #endif /* SCTP_DEBUG */
99
100 /*
101 * sysctl tunable variables
102 */
103 int sctp_auto_asconf = SCTP_DEFAULT_AUTO_ASCONF;
104 int sctp_max_burst_default = SCTP_DEF_MAX_BURST;
105 int sctp_peer_chunk_oh = sizeof(struct mbuf);
106 int sctp_strict_init = 1;
107 int sctp_no_csum_on_loopback = 1;
108 unsigned int sctp_max_chunks_on_queue = SCTP_ASOC_MAX_CHUNKS_ON_QUEUE;
109 int sctp_sendspace = (128 * 1024);
110 int sctp_recvspace = 128 * (1024 +
111 #ifdef INET6
112 sizeof(struct sockaddr_in6)
113 #else
114 sizeof(struct sockaddr_in)
115 #endif
116 );
117 int sctp_strict_sacks = 0;
118 int sctp_ecn = 1;
119 int sctp_ecn_nonce = 0;
120
121 unsigned int sctp_delayed_sack_time_default = SCTP_RECV_MSEC;
122 unsigned int sctp_heartbeat_interval_default = SCTP_HB_DEFAULT_MSEC;
123 unsigned int sctp_pmtu_raise_time_default = SCTP_DEF_PMTU_RAISE_SEC;
124 unsigned int sctp_shutdown_guard_time_default = SCTP_DEF_MAX_SHUTDOWN_SEC;
125 unsigned int sctp_secret_lifetime_default = SCTP_DEFAULT_SECRET_LIFE_SEC;
126 unsigned int sctp_rto_max_default = SCTP_RTO_UPPER_BOUND;
127 unsigned int sctp_rto_min_default = SCTP_RTO_LOWER_BOUND;
128 unsigned int sctp_rto_initial_default = SCTP_RTO_INITIAL;
129 unsigned int sctp_init_rto_max_default = SCTP_RTO_UPPER_BOUND;
130 unsigned int sctp_valid_cookie_life_default = SCTP_DEFAULT_COOKIE_LIFE;
131 unsigned int sctp_init_rtx_max_default = SCTP_DEF_MAX_INIT;
132 unsigned int sctp_assoc_rtx_max_default = SCTP_DEF_MAX_SEND;
133 unsigned int sctp_path_rtx_max_default = SCTP_DEF_MAX_SEND/2;
134 unsigned int sctp_nr_outgoing_streams_default = SCTP_OSTREAM_INITIAL;
135
136 void
137 sctp_init(void)
138 {
139 /* Init the SCTP pcb in sctp_pcb.c */
140 u_long sb_max_adj;
141
142 sctp_pcb_init();
143
144 if (nmbclusters > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE)
145 sctp_max_chunks_on_queue = nmbclusters;
146 /*
147 * Allow a user to take no more than 1/2 the number of clusters
148 * or the SB_MAX whichever is smaller for the send window.
149 */
150 sb_max_adj = (u_long)((u_quad_t)(SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES));
151 sctp_sendspace = min((min(SB_MAX, sb_max_adj)),
152 ((nmbclusters/2) * SCTP_DEFAULT_MAXSEGMENT));
153 /*
154 * Now for the recv window, should we take the same amount?
155 * or should I do 1/2 the SB_MAX instead in the SB_MAX min above.
156 * For now I will just copy.
157 */
158 sctp_recvspace = sctp_sendspace;
159 }
160
161 #ifdef INET6
162 void
163 ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip)
164 {
165 memset(ip6, 0, sizeof(*ip6));
166
167 ip6->ip6_vfc = IPV6_VERSION;
168 ip6->ip6_plen = ip->ip_len;
169 ip6->ip6_nxt = ip->ip_p;
170 ip6->ip6_hlim = ip->ip_ttl;
171 ip6->ip6_src.s6_addr32[2] = ip6->ip6_dst.s6_addr32[2] =
172 IPV6_ADDR_INT32_SMP;
173 ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr;
174 ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr;
175 }
176 #endif /* INET6 */
177
178 static void
179 sctp_split_chunks(struct sctp_association *asoc,
180 struct sctp_stream_out *strm,
181 struct sctp_tmit_chunk *chk)
182 {
183 struct sctp_tmit_chunk *new_chk;
184
185 /* First we need a chunk */
186 new_chk = (struct sctp_tmit_chunk *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_chunk);
187 if (new_chk == NULL) {
188 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
189 return;
190 }
191 sctppcbinfo.ipi_count_chunk++;
192 sctppcbinfo.ipi_gencnt_chunk++;
193 /* Copy it all */
194 *new_chk = *chk;
195 /* split the data */
196 new_chk->data = m_split(chk->data, (chk->send_size>>1), M_DONTWAIT);
197 if (new_chk->data == NULL) {
198 /* Can't split */
199 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
200 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_chunk, new_chk);
201 sctppcbinfo.ipi_count_chunk--;
202 if ((int)sctppcbinfo.ipi_count_chunk < 0) {
203 panic("Chunk count is negative");
204 }
205 sctppcbinfo.ipi_gencnt_chunk++;
206 return;
207
208 }
209 /* Data is now split adjust sizes */
210 chk->send_size >>= 1;
211 new_chk->send_size >>= 1;
212
213 chk->book_size >>= 1;
214 new_chk->book_size >>= 1;
215
216 /* now adjust the marks */
217 chk->rec.data.rcv_flags |= SCTP_DATA_FIRST_FRAG;
218 chk->rec.data.rcv_flags &= ~SCTP_DATA_LAST_FRAG;
219
220 new_chk->rec.data.rcv_flags &= ~SCTP_DATA_FIRST_FRAG;
221 new_chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
222
223 /* Increase ref count if dest is set */
224 if (chk->whoTo) {
225 new_chk->whoTo->ref_count++;
226 }
227 /* now drop it on the end of the list*/
228 asoc->stream_queue_cnt++;
229 TAILQ_INSERT_AFTER(&strm->outqueue, chk, new_chk, sctp_next);
230 }
231
232 static void
233 sctp_notify_mbuf(struct sctp_inpcb *inp,
234 struct sctp_tcb *stcb,
235 struct sctp_nets *net,
236 struct ip *ip,
237 struct sctphdr *sh)
238
239 {
240 struct icmp *icmph;
241 int totsz;
242 uint16_t nxtsz;
243
244 /* protection */
245 if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
246 (ip == NULL) || (sh == NULL)) {
247 if (stcb != NULL) {
248 SCTP_TCB_UNLOCK(stcb);
249 }
250 return;
251 }
252 /* First job is to verify the vtag matches what I would send */
253 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
254 SCTP_TCB_UNLOCK(stcb);
255 return;
256 }
257 icmph = (struct icmp *)((vaddr_t)ip - (sizeof(struct icmp) -
258 sizeof(struct ip)));
259 if (icmph->icmp_type != ICMP_UNREACH) {
260 /* We only care about unreachable */
261 SCTP_TCB_UNLOCK(stcb);
262 return;
263 }
264 if (icmph->icmp_code != ICMP_UNREACH_NEEDFRAG) {
265 /* not a unreachable message due to frag. */
266 SCTP_TCB_UNLOCK(stcb);
267 return;
268 }
269 totsz = ip->ip_len;
270 nxtsz = ntohs(icmph->icmp_seq);
271 if (nxtsz == 0) {
272 /*
273 * old type router that does not tell us what the next size
274 * mtu is. Rats we will have to guess (in a educated fashion
275 * of course)
276 */
277 nxtsz = find_next_best_mtu(totsz);
278 }
279
280 /* Stop any PMTU timer */
281 sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL);
282
283 /* Adjust destination size limit */
284 if (net->mtu > nxtsz) {
285 net->mtu = nxtsz;
286 }
287 /* now what about the ep? */
288 if (stcb->asoc.smallest_mtu > nxtsz) {
289 struct sctp_tmit_chunk *chk, *nchk;
290 struct sctp_stream_out *strm;
291 /* Adjust that too */
292 stcb->asoc.smallest_mtu = nxtsz;
293 /* now off to subtract IP_DF flag if needed */
294
295 TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) {
296 if ((chk->send_size+IP_HDR_SIZE) > nxtsz) {
297 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
298 }
299 }
300 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
301 if ((chk->send_size+IP_HDR_SIZE) > nxtsz) {
302 /*
303 * For this guy we also mark for immediate
304 * resend since we sent to big of chunk
305 */
306 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
307 if (chk->sent != SCTP_DATAGRAM_RESEND) {
308 stcb->asoc.sent_queue_retran_cnt++;
309 }
310 chk->sent = SCTP_DATAGRAM_RESEND;
311 chk->rec.data.doing_fast_retransmit = 0;
312
313 /* Clear any time so NO RTT is being done */
314 chk->do_rtt = 0;
315 sctp_total_flight_decrease(stcb, chk);
316 if (net->flight_size >= chk->book_size) {
317 net->flight_size -= chk->book_size;
318 } else {
319 net->flight_size = 0;
320 }
321 }
322 }
323 TAILQ_FOREACH(strm, &stcb->asoc.out_wheel, next_spoke) {
324 chk = TAILQ_FIRST(&strm->outqueue);
325 while (chk) {
326 nchk = TAILQ_NEXT(chk, sctp_next);
327 if ((chk->send_size+SCTP_MED_OVERHEAD) > nxtsz) {
328 sctp_split_chunks(&stcb->asoc, strm, chk);
329 }
330 chk = nchk;
331 }
332 }
333 }
334 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL);
335 SCTP_TCB_UNLOCK(stcb);
336 }
337
338
339 void
340 sctp_notify(struct sctp_inpcb *inp,
341 int errno,
342 struct sctphdr *sh,
343 struct sockaddr *to,
344 struct sctp_tcb *stcb,
345 struct sctp_nets *net)
346 {
347 /* protection */
348 if ((inp == NULL) || (stcb == NULL) || (net == NULL) ||
349 (sh == NULL) || (to == NULL)) {
350 #ifdef SCTP_DEBUG
351 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
352 printf("sctp-notify, bad call\n");
353 }
354 #endif /* SCTP_DEBUG */
355 return;
356 }
357 /* First job is to verify the vtag matches what I would send */
358 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) {
359 return;
360 }
361
362 /* FIX ME FIX ME PROTOPT i.e. no SCTP should ALWAYS be an ABORT */
363
364 if ((errno == EHOSTUNREACH) || /* Host is not reachable */
365 (errno == EHOSTDOWN) || /* Host is down */
366 (errno == ECONNREFUSED) || /* Host refused the connection, (not an abort?) */
367 (errno == ENOPROTOOPT) /* SCTP is not present on host */
368 ) {
369 /*
370 * Hmm reachablity problems we must examine closely.
371 * If its not reachable, we may have lost a network.
372 * Or if there is NO protocol at the other end named SCTP.
373 * well we consider it a OOTB abort.
374 */
375 if ((errno == EHOSTUNREACH) || (errno == EHOSTDOWN)) {
376 if (net->dest_state & SCTP_ADDR_REACHABLE) {
377 /* Ok that destination is NOT reachable */
378 net->dest_state &= ~SCTP_ADDR_REACHABLE;
379 net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
380 net->error_count = net->failure_threshold + 1;
381 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
382 stcb, SCTP_FAILED_THRESHOLD,
383 (void *)net);
384 }
385 if (stcb) {
386 SCTP_TCB_UNLOCK(stcb);
387 }
388 } else {
389 /*
390 * Here the peer is either playing tricks on us,
391 * including an address that belongs to someone who
392 * does not support SCTP OR was a userland
393 * implementation that shutdown and now is dead. In
394 * either case treat it like a OOTB abort with no TCB
395 */
396 sctp_abort_notification(stcb, SCTP_PEER_FAULTY);
397 sctp_free_assoc(inp, stcb);
398 /* no need to unlock here, since the TCB is gone */
399 }
400 } else {
401 /* Send all others to the app */
402 if (inp->sctp_socket) {
403 inp->sctp_socket->so_error = errno;
404 sctp_sowwakeup(inp, inp->sctp_socket);
405 }
406 if (stcb) {
407 SCTP_TCB_UNLOCK(stcb);
408 }
409 }
410 }
411
412 void *
413 sctp_ctlinput(int cmd, const struct sockaddr *sa, void *vip)
414 {
415 struct ip *ip = vip;
416 struct sctphdr *sh;
417 int s;
418
419 if (sa->sa_family != AF_INET ||
420 ((const struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
421 return (NULL);
422 }
423
424 if (PRC_IS_REDIRECT(cmd)) {
425 ip = 0;
426 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
427 return (NULL);
428 }
429 if (ip) {
430 struct sctp_inpcb *inp;
431 struct sctp_tcb *stcb;
432 struct sctp_nets *net;
433 struct sockaddr_in to, from;
434
435 sh = (struct sctphdr *)((vaddr_t)ip + (ip->ip_hl << 2));
436 memset(&to, 0, sizeof(to));
437 memset(&from, 0, sizeof(from));
438 from.sin_family = to.sin_family = AF_INET;
439 from.sin_len = to.sin_len = sizeof(to);
440 from.sin_port = sh->src_port;
441 from.sin_addr = ip->ip_src;
442 to.sin_port = sh->dest_port;
443 to.sin_addr = ip->ip_dst;
444
445 /*
446 * 'to' holds the dest of the packet that failed to be sent.
447 * 'from' holds our local endpoint address.
448 * Thus we reverse the to and the from in the lookup.
449 */
450 s = splsoftnet();
451 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&from,
452 (struct sockaddr *)&to,
453 &inp, &net, 1);
454 if (stcb != NULL && inp && (inp->sctp_socket != NULL)) {
455 if (cmd != PRC_MSGSIZE) {
456 int cm;
457 if (cmd == PRC_HOSTDEAD) {
458 cm = EHOSTUNREACH;
459 } else {
460 cm = inetctlerrmap[cmd];
461 }
462 sctp_notify(inp, cm, sh,
463 (struct sockaddr *)&to, stcb,
464 net);
465 } else {
466 /* handle possible ICMP size messages */
467 sctp_notify_mbuf(inp, stcb, net, ip, sh);
468 }
469 } else {
470 #if defined(__FreeBSD__) && __FreeBSD_version < 500000
471 /* XXX must be fixed for 5.x and higher, leave for 4.x */
472 if (PRC_IS_REDIRECT(cmd) && inp) {
473 in_rtchange((struct inpcb *)inp,
474 inetctlerrmap[cmd]);
475 }
476 #endif
477 if ((stcb == NULL) && (inp != NULL)) {
478 /* reduce ref-count */
479 SCTP_INP_WLOCK(inp);
480 SCTP_INP_DECR_REF(inp);
481 SCTP_INP_WUNLOCK(inp);
482 }
483
484 }
485 splx(s);
486 }
487 return (NULL);
488 }
489
490 static int
491 sctp_abort(struct socket *so)
492 {
493 struct sctp_inpcb *inp;
494
495 inp = (struct sctp_inpcb *)so->so_pcb;
496 if (inp == 0)
497 return EINVAL; /* ??? possible? panic instead? */
498
499 sctp_inpcb_free(inp, 1);
500 return 0;
501 }
502
503 static int
504 sctp_attach(struct socket *so, int proto)
505 {
506 struct sctp_inpcb *inp;
507 #ifdef IPSEC
508 struct inpcb *ip_inp;
509 #endif
510 int error;
511
512 sosetlock(so);
513 inp = (struct sctp_inpcb *)so->so_pcb;
514 if (inp != 0) {
515 return EINVAL;
516 }
517 error = soreserve(so, sctp_sendspace, sctp_recvspace);
518 if (error) {
519 return error;
520 }
521 error = sctp_inpcb_alloc(so);
522 if (error) {
523 return error;
524 }
525 inp = (struct sctp_inpcb *)so->so_pcb;
526 SCTP_INP_WLOCK(inp);
527
528 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */
529 #ifdef IPSEC
530 ip_inp = &inp->ip_inp.inp;
531 #endif
532 inp->inp_vflag |= INP_IPV4;
533 inp->inp_ip_ttl = ip_defttl;
534
535 #ifdef IPSEC
536 error = ipsec_init_pcbpolicy(so, &ip_inp->inp_sp);
537 if (error != 0) {
538 sctp_inpcb_free(inp, 1);
539 return error;
540 }
541 #endif /*IPSEC*/
542 SCTP_INP_WUNLOCK(inp);
543 so->so_send = sctp_sosend;
544 return 0;
545 }
546
547 static int
548 sctp_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
549 {
550 struct sctp_inpcb *inp;
551 int error;
552
553 KASSERT(solocked(so));
554
555 #ifdef INET6
556 if (nam && nam->sa_family != AF_INET)
557 /* must be a v4 address! */
558 return EINVAL;
559 #endif /* INET6 */
560
561 inp = (struct sctp_inpcb *)so->so_pcb;
562 if (inp == 0)
563 return EINVAL;
564
565 error = sctp_inpcb_bind(so, nam, l);
566 return error;
567 }
568
569
570 static int
571 sctp_detach(struct socket *so)
572 {
573 struct sctp_inpcb *inp;
574 inp = (struct sctp_inpcb *)so->so_pcb;
575 if (inp == 0)
576 return EINVAL;
577
578 if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
579 (so->so_rcv.sb_cc > 0)) {
580 sctp_inpcb_free(inp, 1);
581 } else {
582 sctp_inpcb_free(inp, 0);
583 }
584 return 0;
585 }
586
587 static int
588 sctp_recvoob(struct socket *so, struct mbuf *m, int flags)
589 {
590 KASSERT(solocked(so));
591
592 return EOPNOTSUPP;
593 }
594
595 int
596 sctp_send(struct socket *so, struct mbuf *m, struct sockaddr *addr,
597 struct mbuf *control, struct lwp *l)
598 {
599 struct sctp_inpcb *inp;
600 int error;
601 inp = (struct sctp_inpcb *)so->so_pcb;
602 if (inp == 0) {
603 if (control) {
604 sctp_m_freem(control);
605 control = NULL;
606 }
607 sctp_m_freem(m);
608 return EINVAL;
609 }
610 /* Got to have an to address if we are NOT a connected socket */
611 if ((addr == NULL) &&
612 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
613 (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))
614 ) {
615 goto connected_type;
616 } else if (addr == NULL) {
617 error = EDESTADDRREQ;
618 sctp_m_freem(m);
619 if (control) {
620 sctp_m_freem(control);
621 control = NULL;
622 }
623 return (error);
624 }
625 #ifdef INET6
626 if (addr->sa_family != AF_INET) {
627 /* must be a v4 address! */
628 sctp_m_freem(m);
629 if (control) {
630 sctp_m_freem(control);
631 control = NULL;
632 }
633 error = EDESTADDRREQ;
634 return EINVAL;
635 }
636 #endif /* INET6 */
637 connected_type:
638 /* now what about control */
639 if (control) {
640 if (inp->control) {
641 printf("huh? control set?\n");
642 sctp_m_freem(inp->control);
643 inp->control = NULL;
644 }
645 inp->control = control;
646 }
647 /* add it in possibly */
648 if ((inp->pkt) && (inp->pkt->m_flags & M_PKTHDR)) {
649 struct mbuf *x;
650 int c_len;
651
652 c_len = 0;
653 /* How big is it */
654 for (x=m;x;x = x->m_next) {
655 c_len += x->m_len;
656 }
657 inp->pkt->m_pkthdr.len += c_len;
658 }
659 /* Place the data */
660 if (inp->pkt) {
661 inp->pkt_last->m_next = m;
662 inp->pkt_last = m;
663 } else {
664 inp->pkt_last = inp->pkt = m;
665 }
666 if ((so->so_state & SS_MORETOCOME) == 0) {
667 /*
668 * note with the current version this code will only be used
669 * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for
670 * re-defining sosend to use the sctp_sosend. One can
671 * optionally switch back to this code (by changing back the
672 * definitions) but this is not advisable.
673 */
674 int ret;
675 ret = sctp_output(inp, inp->pkt, addr, inp->control, l, 0);
676 inp->pkt = NULL;
677 inp->control = NULL;
678 return (ret);
679 } else {
680 return (0);
681 }
682 }
683
684 static int
685 sctp_disconnect(struct socket *so)
686 {
687 struct sctp_inpcb *inp;
688
689 inp = (struct sctp_inpcb *)so->so_pcb;
690 if (inp == NULL) {
691 return (ENOTCONN);
692 }
693 SCTP_INP_RLOCK(inp);
694 if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
695 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
696 /* No connection */
697 SCTP_INP_RUNLOCK(inp);
698 return (0);
699 } else {
700 int some_on_streamwheel = 0;
701 struct sctp_association *asoc;
702 struct sctp_tcb *stcb;
703
704 stcb = LIST_FIRST(&inp->sctp_asoc_list);
705 if (stcb == NULL) {
706 SCTP_INP_RUNLOCK(inp);
707 return (EINVAL);
708 }
709 asoc = &stcb->asoc;
710 SCTP_TCB_LOCK(stcb);
711 if (((so->so_options & SO_LINGER) &&
712 (so->so_linger == 0)) ||
713 (so->so_rcv.sb_cc > 0)) {
714 if (SCTP_GET_STATE(asoc) !=
715 SCTP_STATE_COOKIE_WAIT) {
716 /* Left with Data unread */
717 struct mbuf *err;
718 err = NULL;
719 MGET(err, M_DONTWAIT, MT_DATA);
720 if (err) {
721 /* Fill in the user initiated abort */
722 struct sctp_paramhdr *ph;
723 ph = mtod(err, struct sctp_paramhdr *);
724 err->m_len = sizeof(struct sctp_paramhdr);
725 ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
726 ph->param_length = htons(err->m_len);
727 }
728 sctp_send_abort_tcb(stcb, err);
729 }
730 SCTP_INP_RUNLOCK(inp);
731 sctp_free_assoc(inp, stcb);
732 /* No unlock tcb assoc is gone */
733 return (0);
734 }
735 if (!TAILQ_EMPTY(&asoc->out_wheel)) {
736 /* Check to see if some data queued */
737 struct sctp_stream_out *outs;
738 TAILQ_FOREACH(outs, &asoc->out_wheel,
739 next_spoke) {
740 if (!TAILQ_EMPTY(&outs->outqueue)) {
741 some_on_streamwheel = 1;
742 break;
743 }
744 }
745 }
746
747 if (TAILQ_EMPTY(&asoc->send_queue) &&
748 TAILQ_EMPTY(&asoc->sent_queue) &&
749 (some_on_streamwheel == 0)) {
750 /* there is nothing queued to send, so done */
751 if ((SCTP_GET_STATE(asoc) !=
752 SCTP_STATE_SHUTDOWN_SENT) &&
753 (SCTP_GET_STATE(asoc) !=
754 SCTP_STATE_SHUTDOWN_ACK_SENT)) {
755 /* only send SHUTDOWN 1st time thru */
756 #ifdef SCTP_DEBUG
757 if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
758 printf("%s:%d sends a shutdown\n",
759 __FILE__,
760 __LINE__
761 );
762 }
763 #endif
764 sctp_send_shutdown(stcb,
765 stcb->asoc.primary_destination);
766 sctp_chunk_output(stcb->sctp_ep, stcb, 1);
767 asoc->state = SCTP_STATE_SHUTDOWN_SENT;
768 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
769 stcb->sctp_ep, stcb,
770 asoc->primary_destination);
771 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
772 stcb->sctp_ep, stcb,
773 asoc->primary_destination);
774 }
775 } else {
776 /*
777 * we still got (or just got) data to send,
778 * so set SHUTDOWN_PENDING
779 */
780 /*
781 * XXX sockets draft says that MSG_EOF should
782 * be sent with no data.
783 * currently, we will allow user data to be
784 * sent first and move to SHUTDOWN-PENDING
785 */
786 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
787 }
788 SCTP_TCB_UNLOCK(stcb);
789 SCTP_INP_RUNLOCK(inp);
790 return (0);
791 }
792 /* not reached */
793 } else {
794 /* UDP model does not support this */
795 SCTP_INP_RUNLOCK(inp);
796 return EOPNOTSUPP;
797 }
798 }
799
800 int
801 sctp_shutdown(struct socket *so)
802 {
803 struct sctp_inpcb *inp;
804
805 inp = (struct sctp_inpcb *)so->so_pcb;
806 if (inp == 0) {
807 return EINVAL;
808 }
809 SCTP_INP_RLOCK(inp);
810 /* For UDP model this is a invalid call */
811 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
812 /* Restore the flags that the soshutdown took away. */
813 so->so_state &= ~SS_CANTRCVMORE;
814 /* This proc will wakeup for read and do nothing (I hope) */
815 SCTP_INP_RUNLOCK(inp);
816 return (EOPNOTSUPP);
817 }
818 /*
819 * Ok if we reach here its the TCP model and it is either a SHUT_WR
820 * or SHUT_RDWR. This means we put the shutdown flag against it.
821 */
822 {
823 int some_on_streamwheel = 0;
824 struct sctp_tcb *stcb;
825 struct sctp_association *asoc;
826 socantsendmore(so);
827
828 stcb = LIST_FIRST(&inp->sctp_asoc_list);
829 if (stcb == NULL) {
830 /*
831 * Ok we hit the case that the shutdown call was made
832 * after an abort or something. Nothing to do now.
833 */
834 return (0);
835 }
836 SCTP_TCB_LOCK(stcb);
837 asoc = &stcb->asoc;
838
839 if (!TAILQ_EMPTY(&asoc->out_wheel)) {
840 /* Check to see if some data queued */
841 struct sctp_stream_out *outs;
842 TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) {
843 if (!TAILQ_EMPTY(&outs->outqueue)) {
844 some_on_streamwheel = 1;
845 break;
846 }
847 }
848 }
849 if (TAILQ_EMPTY(&asoc->send_queue) &&
850 TAILQ_EMPTY(&asoc->sent_queue) &&
851 (some_on_streamwheel == 0)) {
852 /* there is nothing queued to send, so I'm done... */
853 if (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) {
854 /* only send SHUTDOWN the first time through */
855 #ifdef SCTP_DEBUG
856 if (sctp_debug_on & SCTP_DEBUG_OUTPUT4) {
857 printf("%s:%d sends a shutdown\n",
858 __FILE__,
859 __LINE__
860 );
861 }
862 #endif
863 sctp_send_shutdown(stcb,
864 stcb->asoc.primary_destination);
865 sctp_chunk_output(stcb->sctp_ep, stcb, 1);
866 asoc->state = SCTP_STATE_SHUTDOWN_SENT;
867 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
868 stcb->sctp_ep, stcb,
869 asoc->primary_destination);
870 sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
871 stcb->sctp_ep, stcb,
872 asoc->primary_destination);
873 }
874 } else {
875 /*
876 * we still got (or just got) data to send, so
877 * set SHUTDOWN_PENDING
878 */
879 asoc->state |= SCTP_STATE_SHUTDOWN_PENDING;
880 }
881 SCTP_TCB_UNLOCK(stcb);
882 }
883 SCTP_INP_RUNLOCK(inp);
884 return 0;
885 }
886
887 /*
888 * copies a "user" presentable address and removes embedded scope, etc.
889 * returns 0 on success, 1 on error
890 */
891 static uint32_t
892 sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa)
893 {
894 struct sockaddr_in6 lsa6;
895
896 sctp_recover_scope((struct sockaddr_in6 *)sa, &lsa6);
897 memcpy(ss, sa, sa->sa_len);
898 return (0);
899 }
900
901
902 static int
903 sctp_fill_up_addresses(struct sctp_inpcb *inp,
904 struct sctp_tcb *stcb,
905 int limit,
906 struct sockaddr_storage *sas)
907 {
908 struct ifnet *ifn;
909 struct ifaddr *ifa;
910 int loopback_scope, ipv4_local_scope, local_scope, site_scope, actual;
911 int ipv4_addr_legal, ipv6_addr_legal;
912 actual = 0;
913 if (limit <= 0)
914 return (actual);
915
916 if (stcb) {
917 /* Turn on all the appropriate scope */
918 loopback_scope = stcb->asoc.loopback_scope;
919 ipv4_local_scope = stcb->asoc.ipv4_local_scope;
920 local_scope = stcb->asoc.local_scope;
921 site_scope = stcb->asoc.site_scope;
922 } else {
923 /* Turn on ALL scope, since we look at the EP */
924 loopback_scope = ipv4_local_scope = local_scope =
925 site_scope = 1;
926 }
927 ipv4_addr_legal = ipv6_addr_legal = 0;
928 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
929 ipv6_addr_legal = 1;
930 if (
931 #if defined(__OpenBSD__)
932 (0) /* we always do dual bind */
933 #elif defined (__NetBSD__)
934 (((struct in6pcb *)inp)->in6p_flags & IN6P_IPV6_V6ONLY)
935 #else
936 (((struct in6pcb *)inp)->inp_flags & IN6P_IPV6_V6ONLY)
937 #endif
938 == 0) {
939 ipv4_addr_legal = 1;
940 }
941 } else {
942 ipv4_addr_legal = 1;
943 }
944
945 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
946 TAILQ_FOREACH(ifn, &ifnet_list, if_list) {
947 if ((loopback_scope == 0) &&
948 (ifn->if_type == IFT_LOOP)) {
949 /* Skip loopback if loopback_scope not set */
950 continue;
951 }
952 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
953 if (stcb) {
954 /*
955 * For the BOUND-ALL case, the list
956 * associated with a TCB is Always
957 * considered a reverse list.. i.e.
958 * it lists addresses that are NOT
959 * part of the association. If this
960 * is one of those we must skip it.
961 */
962 if (sctp_is_addr_restricted(stcb,
963 ifa->ifa_addr)) {
964 continue;
965 }
966 }
967 if ((ifa->ifa_addr->sa_family == AF_INET) &&
968 (ipv4_addr_legal)) {
969 struct sockaddr_in *sin;
970 sin = (struct sockaddr_in *)ifa->ifa_addr;
971 if (sin->sin_addr.s_addr == 0) {
972 /* we skip unspecifed addresses */
973 continue;
974 }
975 if ((ipv4_local_scope == 0) &&
976 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
977 continue;
978 }
979 if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) {
980 in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas);
981 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
982 sas = (struct sockaddr_storage *)((vaddr_t)sas + sizeof(struct sockaddr_in6));
983 actual += sizeof(sizeof(struct sockaddr_in6));
984 } else {
985 memcpy(sas, sin, sizeof(*sin));
986 ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
987 sas = (struct sockaddr_storage *)((vaddr_t)sas + sizeof(*sin));
988 actual += sizeof(*sin);
989 }
990 if (actual >= limit) {
991 return (actual);
992 }
993 } else if ((ifa->ifa_addr->sa_family == AF_INET6) &&
994 (ipv6_addr_legal)) {
995 struct sockaddr_in6 *sin6;
996 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
997 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
998 /*
999 * we skip unspecified
1000 * addresses
1001 */
1002 continue;
1003 }
1004 if ((site_scope == 0) &&
1005 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
1006 continue;
1007 }
1008 memcpy(sas, sin6, sizeof(*sin6));
1009 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1010 sas = (struct sockaddr_storage *)((vaddr_t)sas + sizeof(*sin6));
1011 actual += sizeof(*sin6);
1012 if (actual >= limit) {
1013 return (actual);
1014 }
1015 }
1016 }
1017 }
1018 } else {
1019 struct sctp_laddr *laddr;
1020 /*
1021 * If we have a TCB and we do NOT support ASCONF (it's
1022 * turned off or otherwise) then the list is always the
1023 * true list of addresses (the else case below). Otherwise
1024 * the list on the association is a list of addresses that
1025 * are NOT part of the association.
1026 */
1027 if (inp->sctp_flags & SCTP_PCB_FLAGS_DO_ASCONF) {
1028 /* The list is a NEGATIVE list */
1029 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1030 if (stcb) {
1031 if (sctp_is_addr_restricted(stcb, laddr->ifa->ifa_addr)) {
1032 continue;
1033 }
1034 }
1035 if (sctp_fill_user_address(sas, laddr->ifa->ifa_addr))
1036 continue;
1037
1038 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1039 sas = (struct sockaddr_storage *)((vaddr_t)sas +
1040 laddr->ifa->ifa_addr->sa_len);
1041 actual += laddr->ifa->ifa_addr->sa_len;
1042 if (actual >= limit) {
1043 return (actual);
1044 }
1045 }
1046 } else {
1047 /* The list is a positive list if present */
1048 if (stcb) {
1049 /* Must use the specific association list */
1050 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list,
1051 sctp_nxt_addr) {
1052 if (sctp_fill_user_address(sas,
1053 laddr->ifa->ifa_addr))
1054 continue;
1055 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1056 sas = (struct sockaddr_storage *)((vaddr_t)sas +
1057 laddr->ifa->ifa_addr->sa_len);
1058 actual += laddr->ifa->ifa_addr->sa_len;
1059 if (actual >= limit) {
1060 return (actual);
1061 }
1062 }
1063 } else {
1064 /* No endpoint so use the endpoints individual list */
1065 LIST_FOREACH(laddr, &inp->sctp_addr_list,
1066 sctp_nxt_addr) {
1067 if (sctp_fill_user_address(sas,
1068 laddr->ifa->ifa_addr))
1069 continue;
1070 ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
1071 sas = (struct sockaddr_storage *)((vaddr_t)sas +
1072 laddr->ifa->ifa_addr->sa_len);
1073 actual += laddr->ifa->ifa_addr->sa_len;
1074 if (actual >= limit) {
1075 return (actual);
1076 }
1077 }
1078 }
1079 }
1080 }
1081 return (actual);
1082 }
1083
1084 static int
1085 sctp_count_max_addresses(struct sctp_inpcb *inp)
1086 {
1087 int cnt = 0;
1088 /*
1089 * In both sub-set bound an bound_all cases we return the MAXIMUM
1090 * number of addresses that you COULD get. In reality the sub-set
1091 * bound may have an exclusion list for a given TCB OR in the
1092 * bound-all case a TCB may NOT include the loopback or other
1093 * addresses as well.
1094 */
1095 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1096 struct ifnet *ifn;
1097 struct ifaddr *ifa;
1098
1099 TAILQ_FOREACH(ifn, &ifnet_list, if_list) {
1100 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) {
1101 /* Count them if they are the right type */
1102 if (ifa->ifa_addr->sa_family == AF_INET) {
1103 if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1104 cnt += sizeof(struct sockaddr_in6);
1105 else
1106 cnt += sizeof(struct sockaddr_in);
1107
1108 } else if (ifa->ifa_addr->sa_family == AF_INET6)
1109 cnt += sizeof(struct sockaddr_in6);
1110 }
1111 }
1112 } else {
1113 struct sctp_laddr *laddr;
1114 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
1115 if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
1116 if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
1117 cnt += sizeof(struct sockaddr_in6);
1118 else
1119 cnt += sizeof(struct sockaddr_in);
1120
1121 } else if (laddr->ifa->ifa_addr->sa_family == AF_INET6)
1122 cnt += sizeof(struct sockaddr_in6);
1123 }
1124 }
1125 return (cnt);
1126 }
1127
1128 static int
1129 sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, struct mbuf *m,
1130 struct lwp *l, int delay)
1131 {
1132 int error = 0;
1133 struct sctp_tcb *stcb = NULL;
1134 struct sockaddr *sa;
1135 int num_v6=0, num_v4=0, *totaddrp, totaddr, i, incr, at;
1136 #ifdef SCTP_DEBUG
1137 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
1138 printf("Connectx called\n");
1139 }
1140 #endif /* SCTP_DEBUG */
1141
1142 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
1143 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
1144 /* We are already connected AND the TCP model */
1145 return (EADDRINUSE);
1146 }
1147 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1148 SCTP_INP_RLOCK(inp);
1149 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1150 SCTP_INP_RUNLOCK(inp);
1151 }
1152 if (stcb) {
1153 return (EALREADY);
1154
1155 }
1156 SCTP_ASOC_CREATE_LOCK(inp);
1157 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
1158 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
1159 SCTP_ASOC_CREATE_UNLOCK(inp);
1160 return (EFAULT);
1161 }
1162
1163 totaddrp = mtod(m, int *);
1164 totaddr = *totaddrp;
1165 sa = (struct sockaddr *)(totaddrp + 1);
1166 at = incr = 0;
1167 /* account and validate addresses */
1168 SCTP_INP_WLOCK(inp);
1169 SCTP_INP_INCR_REF(inp);
1170 SCTP_INP_WUNLOCK(inp);
1171 for (i = 0; i < totaddr; i++) {
1172 if (sa->sa_family == AF_INET) {
1173 num_v4++;
1174 incr = sizeof(struct sockaddr_in);
1175 } else if (sa->sa_family == AF_INET6) {
1176 struct sockaddr_in6 *sin6;
1177 sin6 = (struct sockaddr_in6 *)sa;
1178 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1179 /* Must be non-mapped for connectx */
1180 SCTP_ASOC_CREATE_UNLOCK(inp);
1181 return EINVAL;
1182 }
1183 num_v6++;
1184 incr = sizeof(struct sockaddr_in6);
1185 } else {
1186 totaddr = i;
1187 break;
1188 }
1189 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
1190 if (stcb != NULL) {
1191 /* Already have or am bring up an association */
1192 SCTP_ASOC_CREATE_UNLOCK(inp);
1193 SCTP_TCB_UNLOCK(stcb);
1194 return (EALREADY);
1195 }
1196 if ((at + incr) > m->m_len) {
1197 totaddr = i;
1198 break;
1199 }
1200 sa = (struct sockaddr *)((vaddr_t)sa + incr);
1201 }
1202 sa = (struct sockaddr *)(totaddrp + 1);
1203 SCTP_INP_WLOCK(inp);
1204 SCTP_INP_DECR_REF(inp);
1205 SCTP_INP_WUNLOCK(inp);
1206 #ifdef INET6
1207 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
1208 (num_v6 > 0)) {
1209 SCTP_INP_WUNLOCK(inp);
1210 SCTP_ASOC_CREATE_UNLOCK(inp);
1211 return (EINVAL);
1212 }
1213 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
1214 (num_v4 > 0)) {
1215 struct in6pcb *inp6;
1216 inp6 = (struct in6pcb *)inp;
1217 if (inp6->in6p_flags & IN6P_IPV6_V6ONLY) {
1218 /*
1219 * if IPV6_V6ONLY flag, ignore connections
1220 * destined to a v4 addr or v4-mapped addr
1221 */
1222 SCTP_INP_WUNLOCK(inp);
1223 SCTP_ASOC_CREATE_UNLOCK(inp);
1224 return EINVAL;
1225 }
1226 }
1227 #endif /* INET6 */
1228 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
1229 SCTP_PCB_FLAGS_UNBOUND) {
1230 /* Bind a ephemeral port */
1231 SCTP_INP_WUNLOCK(inp);
1232 error = sctp_inpcb_bind(so, NULL, l);
1233 if (error) {
1234 SCTP_ASOC_CREATE_UNLOCK(inp);
1235 return (error);
1236 }
1237 } else {
1238 SCTP_INP_WUNLOCK(inp);
1239 }
1240 /* We are GOOD to go */
1241 stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0);
1242 if (stcb == NULL) {
1243 /* Gak! no memory */
1244 SCTP_ASOC_CREATE_UNLOCK(inp);
1245 return (error);
1246 }
1247 /* move to second address */
1248 if (sa->sa_family == AF_INET)
1249 sa = (struct sockaddr *)((vaddr_t)sa + sizeof(struct sockaddr_in));
1250 else
1251 sa = (struct sockaddr *)((vaddr_t)sa + sizeof(struct sockaddr_in6));
1252
1253 for (i = 1; i < totaddr; i++) {
1254 if (sa->sa_family == AF_INET) {
1255 incr = sizeof(struct sockaddr_in);
1256 if (sctp_add_remote_addr(stcb, sa, 0, 8)) {
1257 /* assoc gone no un-lock */
1258 sctp_free_assoc(inp, stcb);
1259 SCTP_ASOC_CREATE_UNLOCK(inp);
1260 return (ENOBUFS);
1261 }
1262
1263 } else if (sa->sa_family == AF_INET6) {
1264 incr = sizeof(struct sockaddr_in6);
1265 if (sctp_add_remote_addr(stcb, sa, 0, 8)) {
1266 /* assoc gone no un-lock */
1267 sctp_free_assoc(inp, stcb);
1268 SCTP_ASOC_CREATE_UNLOCK(inp);
1269 return (ENOBUFS);
1270 }
1271 }
1272 sa = (struct sockaddr *)((vaddr_t)sa + incr);
1273 }
1274 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
1275 if (delay) {
1276 /* doing delayed connection */
1277 stcb->asoc.delayed_connection = 1;
1278 sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
1279 } else {
1280 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
1281 sctp_send_initiate(inp, stcb);
1282 }
1283 SCTP_TCB_UNLOCK(stcb);
1284 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
1285 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
1286 /* Set the connected flag so we can queue data */
1287 soisconnecting(so);
1288 }
1289 SCTP_ASOC_CREATE_UNLOCK(inp);
1290 return error;
1291 }
1292
1293
1294 static int
1295 sctp_optsget(struct socket *so, struct sockopt *sopt)
1296 {
1297 struct sctp_inpcb *inp;
1298 int error, optval=0;
1299 int *ovp;
1300 struct sctp_tcb *stcb = NULL;
1301
1302 inp = (struct sctp_inpcb *)so->so_pcb;
1303 if (inp == 0)
1304 return EINVAL;
1305 error = 0;
1306
1307 #ifdef SCTP_DEBUG
1308 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1309 printf("optsget opt:%x sz:%zu\n", sopt->sopt_name,
1310 sopt->sopt_size);
1311 }
1312 #endif /* SCTP_DEBUG */
1313
1314 switch (sopt->sopt_name) {
1315 case SCTP_NODELAY:
1316 case SCTP_AUTOCLOSE:
1317 case SCTP_AUTO_ASCONF:
1318 case SCTP_DISABLE_FRAGMENTS:
1319 case SCTP_I_WANT_MAPPED_V4_ADDR:
1320 #ifdef SCTP_DEBUG
1321 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1322 printf("other stuff\n");
1323 }
1324 #endif /* SCTP_DEBUG */
1325 SCTP_INP_RLOCK(inp);
1326 switch (sopt->sopt_name) {
1327 case SCTP_DISABLE_FRAGMENTS:
1328 optval = inp->sctp_flags & SCTP_PCB_FLAGS_NO_FRAGMENT;
1329 break;
1330 case SCTP_I_WANT_MAPPED_V4_ADDR:
1331 optval = inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
1332 break;
1333 case SCTP_AUTO_ASCONF:
1334 optval = inp->sctp_flags & SCTP_PCB_FLAGS_AUTO_ASCONF;
1335 break;
1336 case SCTP_NODELAY:
1337 optval = inp->sctp_flags & SCTP_PCB_FLAGS_NODELAY;
1338 break;
1339 case SCTP_AUTOCLOSE:
1340 if ((inp->sctp_flags & SCTP_PCB_FLAGS_AUTOCLOSE) ==
1341 SCTP_PCB_FLAGS_AUTOCLOSE)
1342 optval = inp->sctp_ep.auto_close_time;
1343 else
1344 optval = 0;
1345 break;
1346
1347 default:
1348 error = ENOPROTOOPT;
1349 } /* end switch (sopt->sopt_name) */
1350 if (sopt->sopt_name != SCTP_AUTOCLOSE) {
1351 /* make it an "on/off" value */
1352 optval = (optval != 0);
1353 }
1354 if (sopt->sopt_size < sizeof(int)) {
1355 error = EINVAL;
1356 }
1357 SCTP_INP_RUNLOCK(inp);
1358 if (error == 0) {
1359 /* return the option value */
1360 ovp = sopt->sopt_data;
1361 *ovp = optval;
1362 sopt->sopt_size = sizeof(optval);
1363 }
1364 break;
1365 case SCTP_GET_ASOC_ID_LIST:
1366 {
1367 struct sctp_assoc_ids *ids;
1368 int cnt, at;
1369 u_int16_t orig;
1370
1371 if (sopt->sopt_size < sizeof(struct sctp_assoc_ids)) {
1372 error = EINVAL;
1373 break;
1374 }
1375 ids = sopt->sopt_data;
1376 cnt = 0;
1377 SCTP_INP_RLOCK(inp);
1378 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1379 if (stcb == NULL) {
1380 none_out_now:
1381 ids->asls_numb_present = 0;
1382 ids->asls_more_to_get = 0;
1383 SCTP_INP_RUNLOCK(inp);
1384 break;
1385 }
1386 orig = ids->asls_assoc_start;
1387 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1388 while( orig ) {
1389 stcb = LIST_NEXT(stcb , sctp_tcblist);
1390 orig--;
1391 cnt--;
1392 }
1393 if ( stcb == NULL)
1394 goto none_out_now;
1395
1396 at = 0;
1397 ids->asls_numb_present = 0;
1398 ids->asls_more_to_get = 1;
1399 while(at < MAX_ASOC_IDS_RET) {
1400 ids->asls_assoc_id[at] = sctp_get_associd(stcb);
1401 at++;
1402 ids->asls_numb_present++;
1403 stcb = LIST_NEXT(stcb , sctp_tcblist);
1404 if (stcb == NULL) {
1405 ids->asls_more_to_get = 0;
1406 break;
1407 }
1408 }
1409 SCTP_INP_RUNLOCK(inp);
1410 }
1411 break;
1412 case SCTP_GET_NONCE_VALUES:
1413 {
1414 struct sctp_get_nonce_values *gnv;
1415 if (sopt->sopt_size < sizeof(struct sctp_get_nonce_values)) {
1416 error = EINVAL;
1417 break;
1418 }
1419 gnv = sopt->sopt_data;
1420 stcb = sctp_findassociation_ep_asocid(inp, gnv->gn_assoc_id);
1421 if (stcb == NULL) {
1422 error = ENOTCONN;
1423 } else {
1424 gnv->gn_peers_tag = stcb->asoc.peer_vtag;
1425 gnv->gn_local_tag = stcb->asoc.my_vtag;
1426 SCTP_TCB_UNLOCK(stcb);
1427 }
1428
1429 }
1430 break;
1431 case SCTP_PEER_PUBLIC_KEY:
1432 case SCTP_MY_PUBLIC_KEY:
1433 case SCTP_SET_AUTH_CHUNKS:
1434 case SCTP_SET_AUTH_SECRET:
1435 /* not supported yet and until we refine the draft */
1436 error = EOPNOTSUPP;
1437 break;
1438
1439 case SCTP_DELAYED_ACK_TIME:
1440 {
1441 int32_t *tm;
1442 if (sopt->sopt_size < sizeof(int32_t)) {
1443 error = EINVAL;
1444 break;
1445 }
1446 tm = sopt->sopt_data;
1447
1448 *tm = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
1449 }
1450 break;
1451
1452 case SCTP_GET_SNDBUF_USE:
1453 if (sopt->sopt_size < sizeof(struct sctp_sockstat)) {
1454 error = EINVAL;
1455 } else {
1456 struct sctp_sockstat *ss;
1457 struct sctp_association *asoc;
1458 ss = sopt->sopt_data;
1459 stcb = sctp_findassociation_ep_asocid(inp, ss->ss_assoc_id);
1460 if (stcb == NULL) {
1461 error = ENOTCONN;
1462 } else {
1463 asoc = &stcb->asoc;
1464 ss->ss_total_sndbuf = (u_int32_t)asoc->total_output_queue_size;
1465 ss->ss_total_mbuf_sndbuf = (u_int32_t)asoc->total_output_mbuf_queue_size;
1466 ss->ss_total_recv_buf = (u_int32_t)(asoc->size_on_delivery_queue +
1467 asoc->size_on_reasm_queue +
1468 asoc->size_on_all_streams);
1469 SCTP_TCB_UNLOCK(stcb);
1470 error = 0;
1471 sopt->sopt_size = sizeof(struct sctp_sockstat);
1472 }
1473 }
1474 break;
1475 case SCTP_MAXBURST:
1476 {
1477 u_int8_t *burst;
1478 burst = sopt->sopt_data;
1479 SCTP_INP_RLOCK(inp);
1480 *burst = inp->sctp_ep.max_burst;
1481 SCTP_INP_RUNLOCK(inp);
1482 sopt->sopt_size = sizeof(u_int8_t);
1483 }
1484 break;
1485 case SCTP_MAXSEG:
1486 {
1487 u_int32_t *segsize;
1488 sctp_assoc_t *assoc_id;
1489 int ovh;
1490
1491 if (sopt->sopt_size < sizeof(u_int32_t)) {
1492 error = EINVAL;
1493 break;
1494 }
1495 if (sopt->sopt_size < sizeof(sctp_assoc_t)) {
1496 error = EINVAL;
1497 break;
1498 }
1499 assoc_id = sopt->sopt_data;
1500 segsize = sopt->sopt_data;
1501 sopt->sopt_size = sizeof(u_int32_t);
1502
1503 if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
1504 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) ||
1505 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
1506 SCTP_INP_RLOCK(inp);
1507 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1508 if (stcb) {
1509 SCTP_TCB_LOCK(stcb);
1510 SCTP_INP_RUNLOCK(inp);
1511 *segsize = sctp_get_frag_point(stcb, &stcb->asoc);
1512 SCTP_TCB_UNLOCK(stcb);
1513 } else {
1514 SCTP_INP_RUNLOCK(inp);
1515 goto skipit;
1516 }
1517 } else {
1518 stcb = sctp_findassociation_ep_asocid(inp, *assoc_id);
1519 if (stcb) {
1520 *segsize = sctp_get_frag_point(stcb, &stcb->asoc);
1521 SCTP_TCB_UNLOCK(stcb);
1522 break;
1523 }
1524 skipit:
1525 /* default is to get the max, if I
1526 * can't calculate from an existing association.
1527 */
1528 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
1529 ovh = SCTP_MED_OVERHEAD;
1530 } else {
1531 ovh = SCTP_MED_V4_OVERHEAD;
1532 }
1533 *segsize = inp->sctp_frag_point - ovh;
1534 }
1535 }
1536 break;
1537
1538 case SCTP_SET_DEBUG_LEVEL:
1539 #ifdef SCTP_DEBUG
1540 {
1541 u_int32_t *level;
1542 if (sopt->sopt_size < sizeof(u_int32_t)) {
1543 error = EINVAL;
1544 break;
1545 }
1546 level = sopt->sopt_data;
1547 error = 0;
1548 *level = sctp_debug_on;
1549 sopt->sopt_size = sizeof(u_int32_t);
1550 printf("Returning DEBUG LEVEL %x is set\n",
1551 (u_int)sctp_debug_on);
1552 }
1553 #else /* SCTP_DEBUG */
1554 error = EOPNOTSUPP;
1555 #endif
1556 break;
1557 case SCTP_GET_STAT_LOG:
1558 #ifdef SCTP_STAT_LOGGING
1559 error = sctp_fill_stat_log(m);
1560 #else /* SCTP_DEBUG */
1561 error = EOPNOTSUPP;
1562 #endif
1563 break;
1564 case SCTP_GET_PEGS:
1565 {
1566 u_int32_t *pt;
1567 if (sopt->sopt_size < sizeof(sctp_pegs)) {
1568 error = EINVAL;
1569 break;
1570 }
1571 pt = sopt->sopt_data;
1572 memcpy(pt, sctp_pegs, sizeof(sctp_pegs));
1573 sopt->sopt_size = sizeof(sctp_pegs);
1574 }
1575 break;
1576 case SCTP_EVENTS:
1577 {
1578 struct sctp_event_subscribe *events;
1579 #ifdef SCTP_DEBUG
1580 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1581 printf("get events\n");
1582 }
1583 #endif /* SCTP_DEBUG */
1584 if (sopt->sopt_size < sizeof(struct sctp_event_subscribe)) {
1585 #ifdef SCTP_DEBUG
1586 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1587 printf("sopt->sopt_size is %d not %d\n",
1588 (int)sopt->sopt_size,
1589 (int)sizeof(struct sctp_event_subscribe));
1590 }
1591 #endif /* SCTP_DEBUG */
1592 error = EINVAL;
1593 break;
1594 }
1595 events = sopt->sopt_data;
1596 memset(events, 0, sopt->sopt_size);
1597 SCTP_INP_RLOCK(inp);
1598 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVDATAIOEVNT)
1599 events->sctp_data_io_event = 1;
1600
1601 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVASSOCEVNT)
1602 events->sctp_association_event = 1;
1603
1604 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVPADDREVNT)
1605 events->sctp_address_event = 1;
1606
1607 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVSENDFAILEVNT)
1608 events->sctp_send_failure_event = 1;
1609
1610 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVPEERERR)
1611 events->sctp_peer_error_event = 1;
1612
1613 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)
1614 events->sctp_shutdown_event = 1;
1615
1616 if (inp->sctp_flags & SCTP_PCB_FLAGS_PDAPIEVNT)
1617 events->sctp_partial_delivery_event = 1;
1618
1619 if (inp->sctp_flags & SCTP_PCB_FLAGS_ADAPTIONEVNT)
1620 events->sctp_adaption_layer_event = 1;
1621
1622 if (inp->sctp_flags & SCTP_PCB_FLAGS_STREAM_RESETEVNT)
1623 events->sctp_stream_reset_events = 1;
1624 SCTP_INP_RUNLOCK(inp);
1625 sopt->sopt_size = sizeof(struct sctp_event_subscribe);
1626
1627 }
1628 break;
1629
1630 case SCTP_ADAPTION_LAYER:
1631 if (sopt->sopt_size < sizeof(int)) {
1632 error = EINVAL;
1633 break;
1634 }
1635 #ifdef SCTP_DEBUG
1636 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1637 printf("getadaption ind\n");
1638 }
1639 #endif /* SCTP_DEBUG */
1640 SCTP_INP_RLOCK(inp);
1641 ovp = sopt->sopt_data;
1642 *ovp = inp->sctp_ep.adaption_layer_indicator;
1643 SCTP_INP_RUNLOCK(inp);
1644 sopt->sopt_size = sizeof(int);
1645 break;
1646 case SCTP_SET_INITIAL_DBG_SEQ:
1647 if (sopt->sopt_size < sizeof(int)) {
1648 error = EINVAL;
1649 break;
1650 }
1651 #ifdef SCTP_DEBUG
1652 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1653 printf("get initial dbg seq\n");
1654 }
1655 #endif /* SCTP_DEBUG */
1656 SCTP_INP_RLOCK(inp);
1657 ovp = sopt->sopt_data;
1658 *ovp = inp->sctp_ep.initial_sequence_debug;
1659 SCTP_INP_RUNLOCK(inp);
1660 sopt->sopt_size = sizeof(int);
1661 break;
1662 case SCTP_GET_LOCAL_ADDR_SIZE:
1663 if (sopt->sopt_size < sizeof(int)) {
1664 error = EINVAL;
1665 break;
1666 }
1667 #ifdef SCTP_DEBUG
1668 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1669 printf("get local sizes\n");
1670 }
1671 #endif /* SCTP_DEBUG */
1672 SCTP_INP_RLOCK(inp);
1673 ovp = sopt->sopt_data;
1674 *ovp = sctp_count_max_addresses(inp);
1675 SCTP_INP_RUNLOCK(inp);
1676 sopt->sopt_size = sizeof(int);
1677 break;
1678 case SCTP_GET_REMOTE_ADDR_SIZE:
1679 {
1680 sctp_assoc_t *assoc_id;
1681 u_int32_t *val, sz;
1682 struct sctp_nets *net;
1683 #ifdef SCTP_DEBUG
1684 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1685 printf("get remote size\n");
1686 }
1687 #endif /* SCTP_DEBUG */
1688 if (sopt->sopt_size < sizeof(sctp_assoc_t)) {
1689 #ifdef SCTP_DEBUG
1690 printf("sopt->sopt_size:%zu not %zu\n",
1691 sopt->sopt_size, sizeof(sctp_assoc_t));
1692 #endif /* SCTP_DEBUG */
1693 error = EINVAL;
1694 break;
1695 }
1696 stcb = NULL;
1697 val = sopt->sopt_data;
1698 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1699 SCTP_INP_RLOCK(inp);
1700 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1701 if (stcb) {
1702 SCTP_TCB_LOCK(stcb);
1703 }
1704 SCTP_INP_RUNLOCK(inp);
1705 }
1706 if (stcb == NULL) {
1707 assoc_id = sopt->sopt_data;
1708 stcb = sctp_findassociation_ep_asocid(inp, *assoc_id);
1709 }
1710
1711 if (stcb == NULL) {
1712 error = EINVAL;
1713 break;
1714 }
1715 *val = 0;
1716 sz = 0;
1717 /* Count the sizes */
1718 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1719 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
1720 (rtcache_getdst(&net->ro)->sa_family == AF_INET6)) {
1721 sz += sizeof(struct sockaddr_in6);
1722 } else if (rtcache_getdst(&net->ro)->sa_family == AF_INET) {
1723 sz += sizeof(struct sockaddr_in);
1724 } else {
1725 /* huh */
1726 break;
1727 }
1728 }
1729 SCTP_TCB_UNLOCK(stcb);
1730 *val = sz;
1731 sopt->sopt_size = sizeof(u_int32_t);
1732 }
1733 break;
1734 case SCTP_GET_PEER_ADDRESSES:
1735 /*
1736 * Get the address information, an array
1737 * is passed in to fill up we pack it.
1738 */
1739 {
1740 int cpsz, left;
1741 struct sockaddr_storage *sas;
1742 struct sctp_nets *net;
1743 struct sctp_getaddresses *saddr;
1744 #ifdef SCTP_DEBUG
1745 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1746 printf("get peer addresses\n");
1747 }
1748 #endif /* SCTP_DEBUG */
1749 if (sopt->sopt_size < sizeof(struct sctp_getaddresses)) {
1750 error = EINVAL;
1751 break;
1752 }
1753 left = sopt->sopt_size - sizeof(struct sctp_getaddresses);
1754 saddr = sopt->sopt_data;
1755 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1756 SCTP_INP_RLOCK(inp);
1757 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1758 if (stcb) {
1759 SCTP_TCB_LOCK(stcb);
1760 }
1761 SCTP_INP_RUNLOCK(inp);
1762 } else
1763 stcb = sctp_findassociation_ep_asocid(inp,
1764 saddr->sget_assoc_id);
1765 if (stcb == NULL) {
1766 error = ENOENT;
1767 break;
1768 }
1769 sopt->sopt_size = sizeof(struct sctp_getaddresses);
1770 sas = (struct sockaddr_storage *)&saddr->addr[0];
1771
1772 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1773 sa_family_t family;
1774
1775 family = rtcache_getdst(&net->ro)->sa_family;
1776 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
1777 (family == AF_INET6)) {
1778 cpsz = sizeof(struct sockaddr_in6);
1779 } else if (family == AF_INET) {
1780 cpsz = sizeof(struct sockaddr_in);
1781 } else {
1782 /* huh */
1783 break;
1784 }
1785 if (left < cpsz) {
1786 /* not enough room. */
1787 #ifdef SCTP_DEBUG
1788 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1789 printf("Out of room\n");
1790 }
1791 #endif /* SCTP_DEBUG */
1792 break;
1793 }
1794 if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
1795 (family == AF_INET)) {
1796 /* Must map the address */
1797 in6_sin_2_v4mapsin6((const struct sockaddr_in *) rtcache_getdst(&net->ro),
1798 (struct sockaddr_in6 *)sas);
1799 } else {
1800 memcpy(sas, rtcache_getdst(&net->ro), cpsz);
1801 }
1802 ((struct sockaddr_in *)sas)->sin_port = stcb->rport;
1803
1804 sas = (struct sockaddr_storage *)((vaddr_t)sas + cpsz);
1805 left -= cpsz;
1806 sopt->sopt_size += cpsz;
1807 #ifdef SCTP_DEBUG
1808 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1809 printf("left now:%d mlen:%zu\n",
1810 left, sopt->sopt_size);
1811 }
1812 #endif /* SCTP_DEBUG */
1813 }
1814 SCTP_TCB_UNLOCK(stcb);
1815 }
1816 #ifdef SCTP_DEBUG
1817 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1818 printf("All done\n");
1819 }
1820 #endif /* SCTP_DEBUG */
1821 break;
1822 case SCTP_GET_LOCAL_ADDRESSES:
1823 {
1824 int limit, actual;
1825 struct sockaddr_storage *sas;
1826 struct sctp_getaddresses *saddr;
1827 #ifdef SCTP_DEBUG
1828 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1829 printf("get local addresses\n");
1830 }
1831 #endif /* SCTP_DEBUG */
1832 if (sopt->sopt_size < sizeof(struct sctp_getaddresses)) {
1833 error = EINVAL;
1834 break;
1835 }
1836 saddr = sopt->sopt_data;
1837
1838 if (saddr->sget_assoc_id) {
1839 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1840 SCTP_INP_RLOCK(inp);
1841 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1842 if (stcb) {
1843 SCTP_TCB_LOCK(stcb);
1844 }
1845 SCTP_INP_RUNLOCK(inp);
1846 } else
1847 stcb = sctp_findassociation_ep_asocid(inp, saddr->sget_assoc_id);
1848
1849 } else {
1850 stcb = NULL;
1851 }
1852 /*
1853 * assure that the TCP model does not need a assoc id
1854 * once connected.
1855 */
1856 if ( (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) &&
1857 (stcb == NULL) ) {
1858 SCTP_INP_RLOCK(inp);
1859 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1860 if (stcb) {
1861 SCTP_TCB_LOCK(stcb);
1862 }
1863 SCTP_INP_RUNLOCK(inp);
1864 }
1865 sas = (struct sockaddr_storage *)&saddr->addr[0];
1866 limit = sopt->sopt_size - sizeof(sctp_assoc_t);
1867 actual = sctp_fill_up_addresses(inp, stcb, limit, sas);
1868 SCTP_TCB_UNLOCK(stcb);
1869 sopt->sopt_size = sizeof(struct sockaddr_storage) + actual;
1870 }
1871 break;
1872 case SCTP_PEER_ADDR_PARAMS:
1873 {
1874 struct sctp_paddrparams *paddrp;
1875 struct sctp_nets *net;
1876
1877 #ifdef SCTP_DEBUG
1878 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1879 printf("Getting peer_addr_params\n");
1880 }
1881 #endif /* SCTP_DEBUG */
1882 if (sopt->sopt_size < sizeof(struct sctp_paddrparams)) {
1883 #ifdef SCTP_DEBUG
1884 if (sctp_debug_on & SCTP_DEBUG_USRREQ2) {
1885 printf("Hmm m->m_len:%zu is to small\n",
1886 sopt->sopt_size);
1887 }
1888 #endif /* SCTP_DEBUG */
1889 error = EINVAL;
1890 break;
1891 }
1892 paddrp = sopt->sopt_data;
1893
1894 net = NULL;
1895 if (paddrp->spp_assoc_id) {
1896 #ifdef SCTP_DEBUG
1897 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1898 printf("In spp_assoc_id find type\n");
1899 }
1900 #endif /* SCTP_DEBUG */
1901 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1902 SCTP_INP_RLOCK(inp);
1903 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1904 if (stcb) {
1905 SCTP_TCB_LOCK(stcb);
1906 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
1907 }
1908 SCTP_INP_RLOCK(inp);
1909 } else {
1910 stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id);
1911 }
1912 if (stcb == NULL) {
1913 error = ENOENT;
1914 break;
1915 }
1916 }
1917 if ( (stcb == NULL) &&
1918 ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) ||
1919 (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) {
1920 /* Lookup via address */
1921 #ifdef SCTP_DEBUG
1922 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1923 printf("Ok we need to lookup a param\n");
1924 }
1925 #endif /* SCTP_DEBUG */
1926 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1927 SCTP_INP_RLOCK(inp);
1928 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1929 if (stcb) {
1930 SCTP_TCB_LOCK(stcb);
1931 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
1932 }
1933 SCTP_INP_RUNLOCK(inp);
1934 } else {
1935 SCTP_INP_WLOCK(inp);
1936 SCTP_INP_INCR_REF(inp);
1937 SCTP_INP_WUNLOCK(inp);
1938 stcb = sctp_findassociation_ep_addr(&inp,
1939 (struct sockaddr *)&paddrp->spp_address,
1940 &net, NULL, NULL);
1941 if (stcb == NULL) {
1942 SCTP_INP_WLOCK(inp);
1943 SCTP_INP_DECR_REF(inp);
1944 SCTP_INP_WUNLOCK(inp);
1945 }
1946 }
1947
1948 if (stcb == NULL) {
1949 error = ENOENT;
1950 break;
1951 }
1952 } else {
1953 /* Effects the Endpoint */
1954 #ifdef SCTP_DEBUG
1955 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1956 printf("User wants EP level info\n");
1957 }
1958 #endif /* SCTP_DEBUG */
1959 stcb = NULL;
1960 }
1961 if (stcb) {
1962 /* Applys to the specific association */
1963 #ifdef SCTP_DEBUG
1964 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1965 printf("In TCB side\n");
1966 }
1967 #endif /* SCTP_DEBUG */
1968 if (net) {
1969 paddrp->spp_pathmaxrxt = net->failure_threshold;
1970 } else {
1971 /* No destination so return default value */
1972 paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
1973 }
1974 paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
1975 paddrp->spp_assoc_id = sctp_get_associd(stcb);
1976 SCTP_TCB_UNLOCK(stcb);
1977 } else {
1978 /* Use endpoint defaults */
1979 SCTP_INP_RLOCK(inp);
1980 #ifdef SCTP_DEBUG
1981 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1982 printf("In EP levle info\n");
1983 }
1984 #endif /* SCTP_DEBUG */
1985 paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
1986 paddrp->spp_hbinterval = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT];
1987 paddrp->spp_assoc_id = (sctp_assoc_t)0;
1988 SCTP_INP_RUNLOCK(inp);
1989 }
1990 sopt->sopt_size = sizeof(struct sctp_paddrparams);
1991 }
1992 break;
1993 case SCTP_GET_PEER_ADDR_INFO:
1994 {
1995 struct sctp_paddrinfo *paddri;
1996 struct sctp_nets *net;
1997 #ifdef SCTP_DEBUG
1998 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
1999 printf("GetPEER ADDR_INFO\n");
2000 }
2001 #endif /* SCTP_DEBUG */
2002 if (sopt->sopt_size < sizeof(struct sctp_paddrinfo)) {
2003 error = EINVAL;
2004 break;
2005 }
2006 paddri = sopt->sopt_data;
2007 net = NULL;
2008 if ((((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET) ||
2009 (((struct sockaddr *)&paddri->spinfo_address)->sa_family == AF_INET6)) {
2010 /* Lookup via address */
2011 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2012 SCTP_INP_RLOCK(inp);
2013 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2014 if (stcb) {
2015 SCTP_TCB_LOCK(stcb);
2016 net = sctp_findnet(stcb,
2017 (struct sockaddr *)&paddri->spinfo_address);
2018 }
2019 SCTP_INP_RUNLOCK(inp);
2020 } else {
2021 SCTP_INP_WLOCK(inp);
2022 SCTP_INP_INCR_REF(inp);
2023 SCTP_INP_WUNLOCK(inp);
2024 stcb = sctp_findassociation_ep_addr(&inp,
2025 (struct sockaddr *)&paddri->spinfo_address,
2026 &net, NULL, NULL);
2027 if (stcb == NULL) {
2028 SCTP_INP_WLOCK(inp);
2029 SCTP_INP_DECR_REF(inp);
2030 SCTP_INP_WUNLOCK(inp);
2031 }
2032 }
2033
2034 } else {
2035 stcb = NULL;
2036 }
2037 if ((stcb == NULL) || (net == NULL)) {
2038 error = ENOENT;
2039 break;
2040 }
2041 sopt->sopt_size = sizeof(struct sctp_paddrinfo);
2042 paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK|SCTP_ADDR_NOHB);
2043 paddri->spinfo_cwnd = net->cwnd;
2044 paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1;
2045 paddri->spinfo_rto = net->RTO;
2046 paddri->spinfo_assoc_id = sctp_get_associd(stcb);
2047 SCTP_TCB_UNLOCK(stcb);
2048 }
2049 break;
2050 case SCTP_PCB_STATUS:
2051 {
2052 struct sctp_pcbinfo *spcb;
2053 #ifdef SCTP_DEBUG
2054 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2055 printf("PCB status\n");
2056 }
2057 #endif /* SCTP_DEBUG */
2058 if (sopt->sopt_size < sizeof(struct sctp_pcbinfo)) {
2059 error = EINVAL;
2060 break;
2061 }
2062 spcb = sopt->sopt_data;
2063 sctp_fill_pcbinfo(spcb);
2064 sopt->sopt_size = sizeof(struct sctp_pcbinfo);
2065 }
2066 break;
2067 case SCTP_STATUS:
2068 {
2069 struct sctp_nets *net;
2070 struct sctp_status *sstat;
2071 #ifdef SCTP_DEBUG
2072 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2073 printf("SCTP status\n");
2074 }
2075 #endif /* SCTP_DEBUG */
2076
2077 if (sopt->sopt_size < sizeof(struct sctp_status)) {
2078 error = EINVAL;
2079 break;
2080 }
2081 sstat = sopt->sopt_data;
2082
2083 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2084 SCTP_INP_RLOCK(inp);
2085 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2086 if (stcb) {
2087 SCTP_TCB_LOCK(stcb);
2088 }
2089 SCTP_INP_RUNLOCK(inp);
2090 } else
2091 stcb = sctp_findassociation_ep_asocid(inp, sstat->sstat_assoc_id);
2092
2093 if (stcb == NULL) {
2094 error = EINVAL;
2095 break;
2096 }
2097 /*
2098 * I think passing the state is fine since
2099 * sctp_constants.h will be available to the user
2100 * land.
2101 */
2102 sstat->sstat_state = stcb->asoc.state;
2103 sstat->sstat_rwnd = stcb->asoc.peers_rwnd;
2104 sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt;
2105 /*
2106 * We can't include chunks that have been passed
2107 * to the socket layer. Only things in queue.
2108 */
2109 sstat->sstat_penddata = (stcb->asoc.cnt_on_delivery_queue +
2110 stcb->asoc.cnt_on_reasm_queue +
2111 stcb->asoc.cnt_on_all_streams);
2112
2113
2114 sstat->sstat_instrms = stcb->asoc.streamincnt;
2115 sstat->sstat_outstrms = stcb->asoc.streamoutcnt;
2116 sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc);
2117 memcpy(&sstat->sstat_primary.spinfo_address,
2118 rtcache_getdst(&stcb->asoc.primary_destination->ro),
2119 (rtcache_getdst(&stcb->asoc.primary_destination->ro))->sa_len);
2120 net = stcb->asoc.primary_destination;
2121 ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
2122 /*
2123 * Again the user can get info from sctp_constants.h
2124 * for what the state of the network is.
2125 */
2126 sstat->sstat_primary.spinfo_state = net->dest_state & SCTP_REACHABLE_MASK;
2127 sstat->sstat_primary.spinfo_cwnd = net->cwnd;
2128 sstat->sstat_primary.spinfo_srtt = net->lastsa;
2129 sstat->sstat_primary.spinfo_rto = net->RTO;
2130 sstat->sstat_primary.spinfo_mtu = net->mtu;
2131 sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
2132 SCTP_TCB_UNLOCK(stcb);
2133 sopt->sopt_size = sizeof(*sstat);
2134 }
2135 break;
2136 case SCTP_RTOINFO:
2137 {
2138 struct sctp_rtoinfo *srto;
2139 #ifdef SCTP_DEBUG
2140 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2141 printf("RTO Info\n");
2142 }
2143 #endif /* SCTP_DEBUG */
2144 if (sopt->sopt_size < sizeof(struct sctp_rtoinfo)) {
2145 error = EINVAL;
2146 break;
2147 }
2148 srto = sopt->sopt_data;
2149 if (srto->srto_assoc_id == 0) {
2150 /* Endpoint only please */
2151 SCTP_INP_RLOCK(inp);
2152 srto->srto_initial = inp->sctp_ep.initial_rto;
2153 srto->srto_max = inp->sctp_ep.sctp_maxrto;
2154 srto->srto_min = inp->sctp_ep.sctp_minrto;
2155 SCTP_INP_RUNLOCK(inp);
2156 break;
2157 }
2158 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2159 SCTP_INP_RLOCK(inp);
2160 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2161 if (stcb) {
2162 SCTP_TCB_LOCK(stcb);
2163 }
2164 SCTP_INP_RUNLOCK(inp);
2165 } else
2166 stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id);
2167
2168 if (stcb == NULL) {
2169 error = EINVAL;
2170 break;
2171 }
2172 srto->srto_initial = stcb->asoc.initial_rto;
2173 srto->srto_max = stcb->asoc.maxrto;
2174 srto->srto_min = stcb->asoc.minrto;
2175 SCTP_TCB_UNLOCK(stcb);
2176 sopt->sopt_size = sizeof(*srto);
2177 }
2178 break;
2179 case SCTP_ASSOCINFO:
2180 {
2181 struct sctp_assocparams *sasoc;
2182 #ifdef SCTP_DEBUG
2183 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2184 printf("Associnfo\n");
2185 }
2186 #endif /* SCTP_DEBUG */
2187 if (sopt->sopt_size < sizeof(struct sctp_assocparams)) {
2188 error = EINVAL;
2189 break;
2190 }
2191 sasoc = sopt->sopt_data;
2192 stcb = NULL;
2193
2194 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2195 SCTP_INP_RLOCK(inp);
2196 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2197 if (stcb) {
2198 SCTP_TCB_LOCK(stcb);
2199 }
2200 SCTP_INP_RUNLOCK(inp);
2201 }
2202 if ((sasoc->sasoc_assoc_id) && (stcb == NULL)) {
2203 stcb = sctp_findassociation_ep_asocid(inp,
2204 sasoc->sasoc_assoc_id);
2205 if (stcb == NULL) {
2206 error = ENOENT;
2207 break;
2208 }
2209 } else {
2210 stcb = NULL;
2211 }
2212
2213 if (stcb) {
2214 sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
2215 sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
2216 sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
2217 sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd;
2218 sasoc->sasoc_cookie_life = stcb->asoc.cookie_life;
2219 SCTP_TCB_UNLOCK(stcb);
2220 } else {
2221 SCTP_INP_RLOCK(inp);
2222 sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
2223 sasoc->sasoc_number_peer_destinations = 0;
2224 sasoc->sasoc_peer_rwnd = 0;
2225 sasoc->sasoc_local_rwnd = sbspace(&inp->sctp_socket->so_rcv);
2226 sasoc->sasoc_cookie_life = inp->sctp_ep.def_cookie_life;
2227 SCTP_INP_RUNLOCK(inp);
2228 }
2229 sopt->sopt_size = sizeof(*sasoc);
2230 }
2231 break;
2232 case SCTP_DEFAULT_SEND_PARAM:
2233 {
2234 struct sctp_sndrcvinfo *s_info;
2235
2236 if (sopt->sopt_size != sizeof(struct sctp_sndrcvinfo)) {
2237 error = EINVAL;
2238 break;
2239 }
2240 s_info = sopt->sopt_data;
2241 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2242 SCTP_INP_RLOCK(inp);
2243 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2244 if (stcb) {
2245 SCTP_TCB_LOCK(stcb);
2246 }
2247 SCTP_INP_RUNLOCK(inp);
2248 } else
2249 stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id);
2250
2251 if (stcb == NULL) {
2252 error = ENOENT;
2253 break;
2254 }
2255 /* Copy it out */
2256 *s_info = stcb->asoc.def_send;
2257 SCTP_TCB_UNLOCK(stcb);
2258 sopt->sopt_size = sizeof(*s_info);
2259 }
2260 case SCTP_INITMSG:
2261 {
2262 struct sctp_initmsg *sinit;
2263 #ifdef SCTP_DEBUG
2264 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2265 printf("initmsg\n");
2266 }
2267 #endif /* SCTP_DEBUG */
2268 if (sopt->sopt_size < sizeof(struct sctp_initmsg)) {
2269 error = EINVAL;
2270 break;
2271 }
2272 sinit = sopt->sopt_data;
2273 SCTP_INP_RLOCK(inp);
2274 sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count;
2275 sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome;
2276 sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
2277 sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
2278 SCTP_INP_RUNLOCK(inp);
2279 sopt->sopt_size = sizeof(*sinit);
2280 }
2281 break;
2282 case SCTP_PRIMARY_ADDR:
2283 /* we allow a "get" operation on this */
2284 {
2285 struct sctp_setprim *ssp;
2286
2287 #ifdef SCTP_DEBUG
2288 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2289 printf("setprimary\n");
2290 }
2291 #endif /* SCTP_DEBUG */
2292 if (sopt->sopt_size < sizeof(struct sctp_setprim)) {
2293 error = EINVAL;
2294 break;
2295 }
2296 ssp = sopt->sopt_data;
2297 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2298 SCTP_INP_RLOCK(inp);
2299 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2300 if (stcb) {
2301 SCTP_TCB_LOCK(stcb);
2302 }
2303 SCTP_INP_RUNLOCK(inp);
2304 } else {
2305 stcb = sctp_findassociation_ep_asocid(inp, ssp->ssp_assoc_id);
2306 if (stcb == NULL) {
2307 /* one last shot, try it by the address in */
2308 struct sctp_nets *net;
2309
2310 SCTP_INP_WLOCK(inp);
2311 SCTP_INP_INCR_REF(inp);
2312 SCTP_INP_WUNLOCK(inp);
2313 stcb = sctp_findassociation_ep_addr(&inp,
2314 (struct sockaddr *)&ssp->ssp_addr,
2315 &net, NULL, NULL);
2316 if (stcb == NULL) {
2317 SCTP_INP_WLOCK(inp);
2318 SCTP_INP_DECR_REF(inp);
2319 SCTP_INP_WUNLOCK(inp);
2320 }
2321 }
2322 if (stcb == NULL) {
2323 error = EINVAL;
2324 break;
2325 }
2326 }
2327 /* simply copy out the sockaddr_storage... */
2328 memcpy(&ssp->ssp_addr,
2329 rtcache_getdst(&stcb->asoc.primary_destination->ro),
2330 (rtcache_getdst(&stcb->asoc.primary_destination->ro))->sa_len);
2331 SCTP_TCB_UNLOCK(stcb);
2332 sopt->sopt_size = sizeof(*ssp);
2333 }
2334 break;
2335 default:
2336 error = ENOPROTOOPT;
2337 sopt->sopt_size = 0;
2338 break;
2339 } /* end switch (sopt->sopt_name) */
2340 return (error);
2341 }
2342
2343 static int
2344 sctp_optsset(struct socket *so, struct sockopt *sopt)
2345 {
2346 int error, *mopt, set_opt;
2347 struct sctp_tcb *stcb = NULL;
2348 struct sctp_inpcb *inp;
2349
2350 if (sopt->sopt_data == NULL) {
2351 #ifdef SCTP_DEBUG
2352 if (sctp_debug_on & SCTP_DEBUG_USRREQ1) {
2353 printf("optsset:MP is NULL EINVAL\n");
2354 }
2355 #endif /* SCTP_DEBUG */
2356 return (EINVAL);
2357 }
2358 inp = (struct sctp_inpcb *)so->so_pcb;
2359 if (inp == 0)
2360 return EINVAL;
2361
2362 error = 0;
2363 switch (sopt->sopt_name) {
2364 case SCTP_NODELAY:
2365 case SCTP_AUTOCLOSE:
2366 case SCTP_AUTO_ASCONF:
2367 case SCTP_DISABLE_FRAGMENTS:
2368 case SCTP_I_WANT_MAPPED_V4_ADDR:
2369 /* copy in the option value */
2370 if (sopt->sopt_size < sizeof(int)) {
2371 error = EINVAL;
2372 break;
2373 }
2374 mopt = sopt->sopt_data;
2375 set_opt = 0;
2376 if (error)
2377 break;
2378 switch (sopt->sopt_name) {
2379 case SCTP_DISABLE_FRAGMENTS:
2380 set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT;
2381 break;
2382 case SCTP_AUTO_ASCONF:
2383 set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF;
2384 break;
2385
2386 case SCTP_I_WANT_MAPPED_V4_ADDR:
2387 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2388 set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
2389 } else {
2390 return (EINVAL);
2391 }
2392 break;
2393 case SCTP_NODELAY:
2394 set_opt = SCTP_PCB_FLAGS_NODELAY;
2395 break;
2396 case SCTP_AUTOCLOSE:
2397 set_opt = SCTP_PCB_FLAGS_AUTOCLOSE;
2398 /*
2399 * The value is in ticks.
2400 * Note this does not effect old associations, only
2401 * new ones.
2402 */
2403 inp->sctp_ep.auto_close_time = (*mopt * hz);
2404 break;
2405 }
2406 SCTP_INP_WLOCK(inp);
2407 if (*mopt != 0) {
2408 inp->sctp_flags |= set_opt;
2409 } else {
2410 inp->sctp_flags &= ~set_opt;
2411 }
2412 SCTP_INP_WUNLOCK(inp);
2413 break;
2414 case SCTP_MY_PUBLIC_KEY: /* set my public key */
2415 case SCTP_SET_AUTH_CHUNKS: /* set the authenticated chunks required */
2416 case SCTP_SET_AUTH_SECRET: /* set the actual secret for the endpoint */
2417 /* not supported yet and until we refine the draft */
2418 error = EOPNOTSUPP;
2419 break;
2420
2421 case SCTP_CLR_STAT_LOG:
2422 #ifdef SCTP_STAT_LOGGING
2423 sctp_clr_stat_log();
2424 #else
2425 error = EOPNOTSUPP;
2426 #endif
2427 break;
2428 case SCTP_DELAYED_ACK_TIME:
2429 {
2430 int32_t *tm;
2431 if (sopt->sopt_size < sizeof(int32_t)) {
2432 error = EINVAL;
2433 break;
2434 }
2435 tm = sopt->sopt_data;
2436
2437 if ((*tm < 10) || (*tm > 500)) {
2438 /* can't be smaller than 10ms */
2439 /* MUST NOT be larger than 500ms */
2440 error = EINVAL;
2441 break;
2442 }
2443 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(*tm);
2444 }
2445 break;
2446 case SCTP_RESET_STREAMS:
2447 {
2448 struct sctp_stream_reset *strrst;
2449 uint8_t two_way, not_peer;
2450
2451 if (sopt->sopt_size < sizeof(struct sctp_stream_reset)) {
2452 error = EINVAL;
2453 break;
2454 }
2455 strrst = sopt->sopt_data;
2456
2457 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2458 SCTP_INP_RLOCK(inp);
2459 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2460 if (stcb) {
2461 SCTP_TCB_LOCK(stcb);
2462 }
2463 SCTP_INP_RUNLOCK(inp);
2464 } else
2465 stcb = sctp_findassociation_ep_asocid(inp, strrst->strrst_assoc_id);
2466 if (stcb == NULL) {
2467 error = ENOENT;
2468 break;
2469 }
2470 if (stcb->asoc.peer_supports_strreset == 0) {
2471 /* Peer does not support it,
2472 * we return protocol not supported since
2473 * this is true for this feature and this
2474 * peer, not the socket request in general.
2475 */
2476 error = EPROTONOSUPPORT;
2477 SCTP_TCB_UNLOCK(stcb);
2478 break;
2479 }
2480
2481 /* Having re-thought this code I added as I write the I-D there
2482 * is NO need for it. The peer, if we are requesting a stream-reset
2483 * will send a request to us but will itself do what we do, take
2484 * and copy off the "reset information" we send and queue TSN's
2485 * larger than the send-next in our response message. Thus they
2486 * will handle it.
2487 */
2488 /* if (stcb->asoc.sending_seq != (stcb->asoc.last_acked_seq + 1)) {*/
2489 /* Must have all sending data ack'd before we
2490 * start this procedure. This is a bit restrictive
2491 * and we SHOULD work on changing this so ONLY the
2492 * streams being RESET get held up. So, a reset-all
2493 * would require this.. but a reset specific just
2494 * needs to be sure that the ones being reset have
2495 * nothing on the send_queue. For now we will
2496 * skip this more detailed method and do a course
2497 * way.. i.e. nothing pending ... for future FIX ME!
2498 */
2499 /* error = EBUSY;*/
2500 /* break;*/
2501 /* }*/
2502
2503 if (stcb->asoc.stream_reset_outstanding) {
2504 error = EALREADY;
2505 SCTP_TCB_UNLOCK(stcb);
2506 break;
2507 }
2508 if (strrst->strrst_flags == SCTP_RESET_LOCAL_RECV) {
2509 two_way = 0;
2510 not_peer = 0;
2511 } else if (strrst->strrst_flags == SCTP_RESET_LOCAL_SEND) {
2512 two_way = 1;
2513 not_peer = 1;
2514 } else if (strrst->strrst_flags == SCTP_RESET_BOTH) {
2515 two_way = 1;
2516 not_peer = 0;
2517 } else {
2518 error = EINVAL;
2519 SCTP_TCB_UNLOCK(stcb);
2520 break;
2521 }
2522 sctp_send_str_reset_req(stcb, strrst->strrst_num_streams,
2523 strrst->strrst_list, two_way, not_peer);
2524 sctp_chunk_output(inp, stcb, 12);
2525 SCTP_TCB_UNLOCK(stcb);
2526
2527 }
2528 break;
2529 case SCTP_RESET_PEGS:
2530 memset(sctp_pegs, 0, sizeof(sctp_pegs));
2531 error = 0;
2532 break;
2533 case SCTP_CONNECT_X:
2534 if (sopt->sopt_size < (sizeof(int) + sizeof(struct sockaddr_in))) {
2535 error = EINVAL;
2536 break;
2537 }
2538 error = sctp_do_connect_x(so, inp, sopt->sopt_data, curlwp, 0);
2539 break;
2540
2541 case SCTP_CONNECT_X_DELAYED:
2542 if (sopt->sopt_size < (sizeof(int) + sizeof(struct sockaddr_in))) {
2543 error = EINVAL;
2544 break;
2545 }
2546 error = sctp_do_connect_x(so, inp, sopt->sopt_data, curlwp, 1);
2547 break;
2548
2549 case SCTP_CONNECT_X_COMPLETE:
2550 {
2551 struct sockaddr *sa;
2552 struct sctp_nets *net;
2553 if (sopt->sopt_size < sizeof(struct sockaddr_in)) {
2554 error = EINVAL;
2555 break;
2556 }
2557 sa = sopt->sopt_data;
2558 /* find tcb */
2559 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2560 SCTP_INP_RLOCK(inp);
2561 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2562 if (stcb) {
2563 SCTP_TCB_LOCK(stcb);
2564 net = sctp_findnet(stcb, sa);
2565 }
2566 SCTP_INP_RUNLOCK(inp);
2567 } else {
2568 SCTP_INP_WLOCK(inp);
2569 SCTP_INP_INCR_REF(inp);
2570 SCTP_INP_WUNLOCK(inp);
2571 stcb = sctp_findassociation_ep_addr(&inp, sa, &net, NULL, NULL);
2572 if (stcb == NULL) {
2573 SCTP_INP_WLOCK(inp);
2574 SCTP_INP_DECR_REF(inp);
2575 SCTP_INP_WUNLOCK(inp);
2576 }
2577 }
2578
2579 if (stcb == NULL) {
2580 error = ENOENT;
2581 break;
2582 }
2583 if (stcb->asoc.delayed_connection == 1) {
2584 stcb->asoc.delayed_connection = 0;
2585 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
2586 sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
2587 sctp_send_initiate(inp, stcb);
2588 } else {
2589 /* already expired or did not use delayed connectx */
2590 error = EALREADY;
2591 }
2592 SCTP_TCB_UNLOCK(stcb);
2593 }
2594 break;
2595 case SCTP_MAXBURST:
2596 {
2597 u_int8_t *burst;
2598 SCTP_INP_WLOCK(inp);
2599 burst = sopt->sopt_data;
2600 if (*burst) {
2601 inp->sctp_ep.max_burst = *burst;
2602 }
2603 SCTP_INP_WUNLOCK(inp);
2604 }
2605 break;
2606 case SCTP_MAXSEG:
2607 {
2608 u_int32_t *segsize;
2609 int ovh;
2610 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2611 ovh = SCTP_MED_OVERHEAD;
2612 } else {
2613 ovh = SCTP_MED_V4_OVERHEAD;
2614 }
2615 segsize = sopt->sopt_data;
2616 if (*segsize < 1) {
2617 error = EINVAL;
2618 break;
2619 }
2620 SCTP_INP_WLOCK(inp);
2621 inp->sctp_frag_point = (*segsize+ovh);
2622 if (inp->sctp_frag_point < MHLEN) {
2623 inp->sctp_frag_point = MHLEN;
2624 }
2625 SCTP_INP_WUNLOCK(inp);
2626 }
2627 break;
2628 case SCTP_SET_DEBUG_LEVEL:
2629 #ifdef SCTP_DEBUG
2630 {
2631 u_int32_t *level;
2632 if (sopt->sopt_size < sizeof(u_int32_t)) {
2633 error = EINVAL;
2634 break;
2635 }
2636 level = sopt->sopt_data;
2637 error = 0;
2638 sctp_debug_on = (*level & (SCTP_DEBUG_ALL |
2639 SCTP_DEBUG_NOISY));
2640 printf("SETTING DEBUG LEVEL to %x\n",
2641 (u_int)sctp_debug_on);
2642
2643 }
2644 #else
2645 error = EOPNOTSUPP;
2646 #endif /* SCTP_DEBUG */
2647 break;
2648 case SCTP_EVENTS:
2649 {
2650 struct sctp_event_subscribe *events;
2651 if (sopt->sopt_size < sizeof(struct sctp_event_subscribe)) {
2652 error = EINVAL;
2653 break;
2654 }
2655 SCTP_INP_WLOCK(inp);
2656 events = sopt->sopt_data;
2657 if (events->sctp_data_io_event) {
2658 inp->sctp_flags |= SCTP_PCB_FLAGS_RECVDATAIOEVNT;
2659 } else {
2660 inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVDATAIOEVNT;
2661 }
2662
2663 if (events->sctp_association_event) {
2664 inp->sctp_flags |= SCTP_PCB_FLAGS_RECVASSOCEVNT;
2665 } else {
2666 inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVASSOCEVNT;
2667 }
2668
2669 if (events->sctp_address_event) {
2670 inp->sctp_flags |= SCTP_PCB_FLAGS_RECVPADDREVNT;
2671 } else {
2672 inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVPADDREVNT;
2673 }
2674
2675 if (events->sctp_send_failure_event) {
2676 inp->sctp_flags |= SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
2677 } else {
2678 inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
2679 }
2680
2681 if (events->sctp_peer_error_event) {
2682 inp->sctp_flags |= SCTP_PCB_FLAGS_RECVPEERERR;
2683 } else {
2684 inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVPEERERR;
2685 }
2686
2687 if (events->sctp_shutdown_event) {
2688 inp->sctp_flags |= SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
2689 } else {
2690 inp->sctp_flags &= ~SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
2691 }
2692
2693 if (events->sctp_partial_delivery_event) {
2694 inp->sctp_flags |= SCTP_PCB_FLAGS_PDAPIEVNT;
2695 } else {
2696 inp->sctp_flags &= ~SCTP_PCB_FLAGS_PDAPIEVNT;
2697 }
2698
2699 if (events->sctp_adaption_layer_event) {
2700 inp->sctp_flags |= SCTP_PCB_FLAGS_ADAPTIONEVNT;
2701 } else {
2702 inp->sctp_flags &= ~SCTP_PCB_FLAGS_ADAPTIONEVNT;
2703 }
2704
2705 if (events->sctp_stream_reset_events) {
2706 inp->sctp_flags |= SCTP_PCB_FLAGS_STREAM_RESETEVNT;
2707 } else {
2708 inp->sctp_flags &= ~SCTP_PCB_FLAGS_STREAM_RESETEVNT;
2709 }
2710 SCTP_INP_WUNLOCK(inp);
2711 }
2712 break;
2713
2714 case SCTP_ADAPTION_LAYER:
2715 {
2716 struct sctp_setadaption *adap_bits;
2717 if (sopt->sopt_size < sizeof(struct sctp_setadaption)) {
2718 error = EINVAL;
2719 break;
2720 }
2721 SCTP_INP_WLOCK(inp);
2722 adap_bits = sopt->sopt_data;
2723 inp->sctp_ep.adaption_layer_indicator = adap_bits->ssb_adaption_ind;
2724 SCTP_INP_WUNLOCK(inp);
2725 }
2726 break;
2727 case SCTP_SET_INITIAL_DBG_SEQ:
2728 {
2729 u_int32_t *vvv;
2730 if (sopt->sopt_size < sizeof(u_int32_t)) {
2731 error = EINVAL;
2732 break;
2733 }
2734 SCTP_INP_WLOCK(inp);
2735 vvv = sopt->sopt_data;
2736 inp->sctp_ep.initial_sequence_debug = *vvv;
2737 SCTP_INP_WUNLOCK(inp);
2738 }
2739 break;
2740 case SCTP_DEFAULT_SEND_PARAM:
2741 {
2742 struct sctp_sndrcvinfo *s_info;
2743
2744 if (sopt->sopt_size != sizeof(struct sctp_sndrcvinfo)) {
2745 error = EINVAL;
2746 break;
2747 }
2748 s_info = sopt->sopt_data;
2749
2750 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2751 SCTP_INP_RLOCK(inp);
2752 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2753 if (stcb) {
2754 SCTP_TCB_LOCK(stcb);
2755 }
2756 SCTP_INP_RUNLOCK(inp);
2757 } else
2758 stcb = sctp_findassociation_ep_asocid(inp, s_info->sinfo_assoc_id);
2759
2760 if (stcb == NULL) {
2761 error = ENOENT;
2762 break;
2763 }
2764 /* Validate things */
2765 if (s_info->sinfo_stream > stcb->asoc.streamoutcnt) {
2766 SCTP_TCB_UNLOCK(stcb);
2767 error = EINVAL;
2768 break;
2769 }
2770 /* Mask off the flags that are allowed */
2771 s_info->sinfo_flags = (s_info->sinfo_flags &
2772 (MSG_UNORDERED | MSG_ADDR_OVER |
2773 MSG_PR_SCTP_TTL | MSG_PR_SCTP_BUF));
2774 /* Copy it in */
2775 stcb->asoc.def_send = *s_info;
2776 SCTP_TCB_UNLOCK(stcb);
2777 }
2778 break;
2779 case SCTP_PEER_ADDR_PARAMS:
2780 {
2781 struct sctp_paddrparams *paddrp;
2782 struct sctp_nets *net;
2783 if (sopt->sopt_size < sizeof(struct sctp_paddrparams)) {
2784 error = EINVAL;
2785 break;
2786 }
2787 paddrp = sopt->sopt_data;
2788 net = NULL;
2789 if (paddrp->spp_assoc_id) {
2790 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2791 SCTP_INP_RLOCK(inp);
2792 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2793 if (stcb) {
2794 SCTP_TCB_LOCK(stcb);
2795 net = sctp_findnet(stcb, (struct sockaddr *)&paddrp->spp_address);
2796 }
2797 SCTP_INP_RUNLOCK(inp);
2798 } else
2799 stcb = sctp_findassociation_ep_asocid(inp, paddrp->spp_assoc_id);
2800 if (stcb == NULL) {
2801 error = ENOENT;
2802 break;
2803 }
2804
2805 }
2806 if ((stcb == NULL) &&
2807 ((((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET) ||
2808 (((struct sockaddr *)&paddrp->spp_address)->sa_family == AF_INET6))) {
2809 /* Lookup via address */
2810 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2811 SCTP_INP_RLOCK(inp);
2812 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2813 if (stcb) {
2814 SCTP_TCB_LOCK(stcb);
2815 net = sctp_findnet(stcb,
2816 (struct sockaddr *)&paddrp->spp_address);
2817 }
2818 SCTP_INP_RUNLOCK(inp);
2819 } else {
2820 SCTP_INP_WLOCK(inp);
2821 SCTP_INP_INCR_REF(inp);
2822 SCTP_INP_WUNLOCK(inp);
2823 stcb = sctp_findassociation_ep_addr(&inp,
2824 (struct sockaddr *)&paddrp->spp_address,
2825 &net, NULL, NULL);
2826 if (stcb == NULL) {
2827 SCTP_INP_WLOCK(inp);
2828 SCTP_INP_DECR_REF(inp);
2829 SCTP_INP_WUNLOCK(inp);
2830 }
2831 }
2832 } else {
2833 /* Effects the Endpoint */
2834 stcb = NULL;
2835 }
2836 if (stcb) {
2837 /* Applies to the specific association */
2838 if (paddrp->spp_pathmaxrxt) {
2839 if (net) {
2840 if (paddrp->spp_pathmaxrxt)
2841 net->failure_threshold = paddrp->spp_pathmaxrxt;
2842 } else {
2843 if (paddrp->spp_pathmaxrxt)
2844 stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
2845 }
2846 }
2847 if ((paddrp->spp_hbinterval != 0) && (paddrp->spp_hbinterval != 0xffffffff)) {
2848 /* Just a set */
2849 int old;
2850 if (net) {
2851 net->dest_state &= ~SCTP_ADDR_NOHB;
2852 } else {
2853 old = stcb->asoc.heart_beat_delay;
2854 stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
2855 if (old == 0) {
2856 /* Turn back on the timer */
2857 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
2858 }
2859 }
2860 } else if (paddrp->spp_hbinterval == 0xffffffff) {
2861 /* on demand HB */
2862 sctp_send_hb(stcb, 1, net);
2863 } else {
2864 if (net == NULL) {
2865 /* off on association */
2866 if (stcb->asoc.heart_beat_delay) {
2867 int cnt_of_unconf = 0;
2868 struct sctp_nets *lnet;
2869 TAILQ_FOREACH(lnet, &stcb->asoc.nets, sctp_next) {
2870 if (lnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
2871 cnt_of_unconf++;
2872 }
2873 }
2874 /* stop the timer ONLY if we have no unconfirmed addresses
2875 */
2876 if (cnt_of_unconf == 0)
2877 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
2878 }
2879 stcb->asoc.heart_beat_delay = 0;
2880 } else {
2881 net->dest_state |= SCTP_ADDR_NOHB;
2882 }
2883 }
2884 SCTP_TCB_UNLOCK(stcb);
2885 } else {
2886 /* Use endpoint defaults */
2887 SCTP_INP_WLOCK(inp);
2888 if (paddrp->spp_pathmaxrxt)
2889 inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
2890 if (paddrp->spp_hbinterval != SCTP_ISSUE_HB)
2891 inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = paddrp->spp_hbinterval;
2892 SCTP_INP_WUNLOCK(inp);
2893 }
2894 }
2895 break;
2896 case SCTP_RTOINFO:
2897 {
2898 struct sctp_rtoinfo *srto;
2899 if (sopt->sopt_size < sizeof(struct sctp_rtoinfo)) {
2900 error = EINVAL;
2901 break;
2902 }
2903 srto = sopt->sopt_data;
2904 if (srto->srto_assoc_id == 0) {
2905 SCTP_INP_WLOCK(inp);
2906 /* If we have a null asoc, its default for the endpoint */
2907 if (srto->srto_initial > 10)
2908 inp->sctp_ep.initial_rto = srto->srto_initial;
2909 if (srto->srto_max > 10)
2910 inp->sctp_ep.sctp_maxrto = srto->srto_max;
2911 if (srto->srto_min > 10)
2912 inp->sctp_ep.sctp_minrto = srto->srto_min;
2913 SCTP_INP_WUNLOCK(inp);
2914 break;
2915 }
2916 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2917 SCTP_INP_RLOCK(inp);
2918 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2919 if (stcb) {
2920 SCTP_TCB_LOCK(stcb);
2921 }
2922 SCTP_INP_RUNLOCK(inp);
2923 } else
2924 stcb = sctp_findassociation_ep_asocid(inp, srto->srto_assoc_id);
2925 if (stcb == NULL) {
2926 error = EINVAL;
2927 break;
2928 }
2929 /* Set in ms we hope :-) */
2930 if (srto->srto_initial > 10)
2931 stcb->asoc.initial_rto = srto->srto_initial;
2932 if (srto->srto_max > 10)
2933 stcb->asoc.maxrto = srto->srto_max;
2934 if (srto->srto_min > 10)
2935 stcb->asoc.minrto = srto->srto_min;
2936 SCTP_TCB_UNLOCK(stcb);
2937 }
2938 break;
2939 case SCTP_ASSOCINFO:
2940 {
2941 struct sctp_assocparams *sasoc;
2942
2943 if (sopt->sopt_size < sizeof(struct sctp_assocparams)) {
2944 error = EINVAL;
2945 break;
2946 }
2947 sasoc = sopt->sopt_data;
2948 if (sasoc->sasoc_assoc_id) {
2949 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
2950 SCTP_INP_RLOCK(inp);
2951 stcb = LIST_FIRST(&inp->sctp_asoc_list);
2952 if (stcb) {
2953 SCTP_TCB_LOCK(stcb);
2954 }
2955 SCTP_INP_RUNLOCK(inp);
2956 } else
2957 stcb = sctp_findassociation_ep_asocid(inp,
2958 sasoc->sasoc_assoc_id);
2959 if (stcb == NULL) {
2960 error = ENOENT;
2961 break;
2962 }
2963
2964 } else {
2965 stcb = NULL;
2966 }
2967 if (stcb) {
2968 if (sasoc->sasoc_asocmaxrxt)
2969 stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
2970 sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
2971 sasoc->sasoc_peer_rwnd = 0;
2972 sasoc->sasoc_local_rwnd = 0;
2973 if (stcb->asoc.cookie_life)
2974 stcb->asoc.cookie_life = sasoc->sasoc_cookie_life;
2975 SCTP_TCB_UNLOCK(stcb);
2976 } else {
2977 SCTP_INP_WLOCK(inp);
2978 if (sasoc->sasoc_asocmaxrxt)
2979 inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
2980 sasoc->sasoc_number_peer_destinations = 0;
2981 sasoc->sasoc_peer_rwnd = 0;
2982 sasoc->sasoc_local_rwnd = 0;
2983 if (sasoc->sasoc_cookie_life)
2984 inp->sctp_ep.def_cookie_life = sasoc->sasoc_cookie_life;
2985 SCTP_INP_WUNLOCK(inp);
2986 }
2987 }
2988 break;
2989 case SCTP_INITMSG:
2990 {
2991 struct sctp_initmsg *sinit;
2992
2993 if (sopt->sopt_size < sizeof(struct sctp_initmsg)) {
2994 error = EINVAL;
2995 break;
2996 }
2997 sinit = sopt->sopt_data;
2998 SCTP_INP_WLOCK(inp);
2999 if (sinit->sinit_num_ostreams)
3000 inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams;
3001
3002 if (sinit->sinit_max_instreams)
3003 inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams;
3004
3005 if (sinit->sinit_max_attempts)
3006 inp->sctp_ep.max_init_times = sinit->sinit_max_attempts;
3007
3008 if (sinit->sinit_max_init_timeo > 10)
3009 /* We must be at least a 100ms (we set in ticks) */
3010 inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo;
3011 SCTP_INP_WUNLOCK(inp);
3012 }
3013 break;
3014 case SCTP_PRIMARY_ADDR:
3015 {
3016 struct sctp_setprim *spa;
3017 struct sctp_nets *net, *lnet;
3018 if (sopt->sopt_size < sizeof(struct sctp_setprim)) {
3019 error = EINVAL;
3020 break;
3021 }
3022 spa = sopt->sopt_data;
3023
3024 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3025 SCTP_INP_RLOCK(inp);
3026 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3027 if (stcb) {
3028 SCTP_TCB_LOCK(stcb);
3029 } else {
3030 error = EINVAL;
3031 break;
3032 }
3033 SCTP_INP_RUNLOCK(inp);
3034 } else
3035 stcb = sctp_findassociation_ep_asocid(inp, spa->ssp_assoc_id);
3036 if (stcb == NULL) {
3037 /* One last shot */
3038 SCTP_INP_WLOCK(inp);
3039 SCTP_INP_INCR_REF(inp);
3040 SCTP_INP_WUNLOCK(inp);
3041 stcb = sctp_findassociation_ep_addr(&inp,
3042 (struct sockaddr *)&spa->ssp_addr,
3043 &net, NULL, NULL);
3044 if (stcb == NULL) {
3045 SCTP_INP_WLOCK(inp);
3046 SCTP_INP_DECR_REF(inp);
3047 SCTP_INP_WUNLOCK(inp);
3048 error = EINVAL;
3049 break;
3050 }
3051 } else {
3052 /* find the net, associd or connected lookup type */
3053 net = sctp_findnet(stcb, (struct sockaddr *)&spa->ssp_addr);
3054 if (net == NULL) {
3055 SCTP_TCB_UNLOCK(stcb);
3056 error = EINVAL;
3057 break;
3058 }
3059 }
3060 if ((net != stcb->asoc.primary_destination) &&
3061 (!(net->dest_state & SCTP_ADDR_UNCONFIRMED))) {
3062 /* Ok we need to set it */
3063 lnet = stcb->asoc.primary_destination;
3064 lnet->next_tsn_at_change = net->next_tsn_at_change = stcb->asoc.sending_seq;
3065 if (sctp_set_primary_addr(stcb,
3066 (struct sockaddr *)NULL,
3067 net) == 0) {
3068 if (net->dest_state & SCTP_ADDR_SWITCH_PRIMARY) {
3069 net->dest_state |= SCTP_ADDR_DOUBLE_SWITCH;
3070 }
3071 net->dest_state |= SCTP_ADDR_SWITCH_PRIMARY;
3072 }
3073 }
3074 SCTP_TCB_UNLOCK(stcb);
3075 }
3076 break;
3077
3078 case SCTP_SET_PEER_PRIMARY_ADDR:
3079 {
3080 struct sctp_setpeerprim *sspp;
3081 if (sopt->sopt_size < sizeof(struct sctp_setpeerprim)) {
3082 error = EINVAL;
3083 break;
3084 }
3085 sspp = sopt->sopt_data;
3086
3087 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3088 SCTP_INP_RLOCK(inp);
3089 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3090 if (stcb) {
3091 SCTP_TCB_UNLOCK(stcb);
3092 }
3093 SCTP_INP_RUNLOCK(inp);
3094 } else
3095 stcb = sctp_findassociation_ep_asocid(inp, sspp->sspp_assoc_id);
3096 if (stcb == NULL) {
3097 error = EINVAL;
3098 break;
3099 }
3100 if (sctp_set_primary_ip_address_sa(stcb, (struct sockaddr *)&sspp->sspp_addr) != 0) {
3101 error = EINVAL;
3102 }
3103 SCTP_TCB_UNLOCK(stcb);
3104 }
3105 break;
3106 case SCTP_BINDX_ADD_ADDR:
3107 {
3108 struct sctp_getaddresses *addrs;
3109 struct sockaddr *addr_touse;
3110 struct sockaddr_in sin;
3111 /* see if we're bound all already! */
3112 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3113 error = EINVAL;
3114 break;
3115 }
3116 if (sopt->sopt_size < sizeof(struct sctp_getaddresses)) {
3117 error = EINVAL;
3118 break;
3119 }
3120 addrs = sopt->sopt_data;
3121 addr_touse = addrs->addr;
3122 if (addrs->addr->sa_family == AF_INET6) {
3123 struct sockaddr_in6 *sin6;
3124 sin6 = (struct sockaddr_in6 *)addr_touse;
3125 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
3126 in6_sin6_2_sin(&sin, sin6);
3127 addr_touse = (struct sockaddr *)&sin;
3128 }
3129 }
3130 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
3131 error = sctp_inpcb_bind(so, addr_touse, curlwp);
3132 break;
3133 }
3134 /* No locks required here since bind and mgmt_ep_sa all
3135 * do their own locking. If we do something for the FIX:
3136 * below we may need to lock in that case.
3137 */
3138 if (addrs->sget_assoc_id == 0) {
3139 /* add the address */
3140 struct sctp_inpcb *lep;
3141 ((struct sockaddr_in *)addr_touse)->sin_port = inp->sctp_lport;
3142 lep = sctp_pcb_findep(addr_touse, 1, 0);
3143 if (lep != NULL) {
3144 /* We must decrement the refcount
3145 * since we have the ep already and
3146 * are binding. No remove going on
3147 * here.
3148 */
3149 SCTP_INP_WLOCK(inp);
3150 SCTP_INP_DECR_REF(inp);
3151 SCTP_INP_WUNLOCK(inp);
3152 }
3153 if (lep == inp) {
3154 /* already bound to it.. ok */
3155 break;
3156 } else if (lep == NULL) {
3157 ((struct sockaddr_in *)addr_touse)->sin_port = 0;
3158 error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
3159 SCTP_ADD_IP_ADDRESS);
3160 } else {
3161 error = EADDRNOTAVAIL;
3162 }
3163 if (error)
3164 break;
3165
3166 } else {
3167 /* FIX: decide whether we allow assoc based bindx */
3168 }
3169 }
3170 break;
3171 case SCTP_BINDX_REM_ADDR:
3172 {
3173 struct sctp_getaddresses *addrs;
3174 struct sockaddr *addr_touse;
3175 struct sockaddr_in sin;
3176 /* see if we're bound all already! */
3177 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3178 error = EINVAL;
3179 break;
3180 }
3181 if (sopt->sopt_size < sizeof(struct sctp_getaddresses)) {
3182 error = EINVAL;
3183 break;
3184 }
3185 addrs = sopt->sopt_data;
3186 addr_touse = addrs->addr;
3187 if (addrs->addr->sa_family == AF_INET6) {
3188 struct sockaddr_in6 *sin6;
3189 sin6 = (struct sockaddr_in6 *)addr_touse;
3190 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
3191 in6_sin6_2_sin(&sin, sin6);
3192 addr_touse = (struct sockaddr *)&sin;
3193 }
3194 }
3195 /* No lock required mgmt_ep_sa does its own locking. If
3196 * the FIX: below is ever changed we may need to
3197 * lock before calling association level binding.
3198 */
3199 if (addrs->sget_assoc_id == 0) {
3200 /* delete the address */
3201 sctp_addr_mgmt_ep_sa(inp, addr_touse,
3202 SCTP_DEL_IP_ADDRESS);
3203 } else {
3204 /* FIX: decide whether we allow assoc based bindx */
3205 }
3206 }
3207 break;
3208 default:
3209 error = ENOPROTOOPT;
3210 break;
3211 } /* end switch (opt) */
3212 return (error);
3213 }
3214
3215 int
3216 sctp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
3217 {
3218 int s, error = 0;
3219 struct inpcb *inp;
3220 #ifdef INET6
3221 struct in6pcb *in6p;
3222 #endif
3223 int family; /* family of the socket */
3224
3225 family = so->so_proto->pr_domain->dom_family;
3226
3227 s = splsoftnet();
3228 switch (family) {
3229 case PF_INET:
3230 inp = sotoinpcb(so);
3231 #ifdef INET6
3232 in6p = NULL;
3233 #endif
3234 break;
3235 #ifdef INET6
3236 case PF_INET6:
3237 inp = NULL;
3238 in6p = sotoin6pcb(so);
3239 break;
3240 #endif
3241 default:
3242 splx(s);
3243 return EAFNOSUPPORT;
3244 }
3245 #ifndef INET6
3246 if (inp == NULL)
3247 #else
3248 if (inp == NULL && in6p == NULL)
3249 #endif
3250 {
3251 splx(s);
3252 return (ECONNRESET);
3253 }
3254 if (sopt->sopt_level != IPPROTO_SCTP) {
3255 switch (family) {
3256 case PF_INET:
3257 error = ip_ctloutput(op, so, sopt);
3258 break;
3259 #ifdef INET6
3260 case PF_INET6:
3261 error = ip6_ctloutput(op, so, sopt);
3262 break;
3263 #endif
3264 }
3265 splx(s);
3266 return (error);
3267 }
3268 /* Ok if we reach here it is a SCTP option we hope */
3269 if (op == PRCO_SETOPT) {
3270 error = sctp_optsset(so, sopt);
3271 } else if (op == PRCO_GETOPT) {
3272 error = sctp_optsget(so, sopt);
3273 } else {
3274 error = EINVAL;
3275 }
3276 splx(s);
3277 return (error);
3278 }
3279
3280 static int
3281 sctp_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
3282 {
3283 int error = 0;
3284 struct sctp_inpcb *inp;
3285 struct sctp_tcb *stcb;
3286
3287 KASSERT(solocked(so));
3288 #ifdef SCTP_DEBUG
3289 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
3290 printf("Connect called in SCTP to ");
3291 sctp_print_address(nam);
3292 printf("Port %d\n", ntohs(((struct sockaddr_in *)nam)->sin_port));
3293 }
3294 #endif /* SCTP_DEBUG */
3295 inp = (struct sctp_inpcb *)so->so_pcb;
3296 if (inp == 0) {
3297 /* I made the same as TCP since we are not setup? */
3298 return (ECONNRESET);
3299 }
3300 SCTP_ASOC_CREATE_LOCK(inp);
3301 #ifdef SCTP_DEBUG
3302 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
3303 printf("After ASOC lock\n");
3304 }
3305 #endif /* SCTP_DEBUG */
3306 SCTP_INP_WLOCK(inp);
3307 #ifdef SCTP_DEBUG
3308 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
3309 printf("After INP_WLOCK lock\n");
3310 }
3311 #endif /* SCTP_DEBUG */
3312 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
3313 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
3314 /* Should I really unlock ? */
3315 SCTP_INP_WUNLOCK(inp);
3316 SCTP_ASOC_CREATE_UNLOCK(inp);
3317 return (EFAULT);
3318 }
3319 #ifdef INET6
3320 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
3321 (nam->sa_family == AF_INET6)) {
3322 SCTP_INP_WUNLOCK(inp);
3323 SCTP_ASOC_CREATE_UNLOCK(inp);
3324 return (EINVAL);
3325 }
3326 #endif /* INET6 */
3327 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
3328 SCTP_PCB_FLAGS_UNBOUND) {
3329 /* Bind a ephemeral port */
3330 SCTP_INP_WUNLOCK(inp);
3331 error = sctp_inpcb_bind(so, NULL, l);
3332 if (error) {
3333 SCTP_ASOC_CREATE_UNLOCK(inp);
3334 return (error);
3335 }
3336 SCTP_INP_WLOCK(inp);
3337 }
3338 #ifdef SCTP_DEBUG
3339 if (sctp_debug_on & SCTP_DEBUG_PCB1) {
3340 printf("After bind\n");
3341 }
3342 #endif /* SCTP_DEBUG */
3343 /* Now do we connect? */
3344 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
3345 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
3346 /* We are already connected AND the TCP model */
3347 SCTP_INP_WUNLOCK(inp);
3348 SCTP_ASOC_CREATE_UNLOCK(inp);
3349 return (EADDRINUSE);
3350 }
3351 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3352 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3353 if (stcb) {
3354 SCTP_TCB_UNLOCK(stcb);
3355 }
3356 SCTP_INP_WUNLOCK(inp);
3357 } else {
3358 SCTP_INP_INCR_REF(inp);
3359 SCTP_INP_WUNLOCK(inp);
3360 stcb = sctp_findassociation_ep_addr(&inp, nam, NULL, NULL, NULL);
3361 if (stcb == NULL) {
3362 SCTP_INP_WLOCK(inp);
3363 SCTP_INP_DECR_REF(inp);
3364 SCTP_INP_WUNLOCK(inp);
3365 }
3366 }
3367 if (stcb != NULL) {
3368 /* Already have or am bring up an association */
3369 SCTP_ASOC_CREATE_UNLOCK(inp);
3370 SCTP_TCB_UNLOCK(stcb);
3371 return (EALREADY);
3372 }
3373 /* We are GOOD to go */
3374 stcb = sctp_aloc_assoc(inp, nam, 1, &error, 0);
3375 if (stcb == NULL) {
3376 /* Gak! no memory */
3377 return (error);
3378 }
3379 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
3380 stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
3381 /* Set the connected flag so we can queue data */
3382 soisconnecting(so);
3383 }
3384 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
3385 SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
3386 sctp_send_initiate(inp, stcb);
3387 SCTP_ASOC_CREATE_UNLOCK(inp);
3388 SCTP_TCB_UNLOCK(stcb);
3389 return error;
3390 }
3391
3392 static int
3393 sctp_connect2(struct socket *so, struct socket *so2)
3394 {
3395 KASSERT(solocked(so));
3396
3397 return EOPNOTSUPP;
3398 }
3399
3400 int
3401 sctp_rcvd(struct socket *so, int flags, struct lwp *l)
3402 {
3403 struct sctp_socket_q_list *sq=NULL;
3404 /*
3405 * The user has received some data, we may be able to stuff more
3406 * up the socket. And we need to possibly update the rwnd.
3407 */
3408 struct sctp_inpcb *inp;
3409 struct sctp_tcb *stcb=NULL;
3410
3411 inp = (struct sctp_inpcb *)so->so_pcb;
3412 #ifdef SCTP_DEBUG
3413 if (sctp_debug_on & SCTP_DEBUG_USRREQ2)
3414 printf("Read for so:%p inp:%p Flags:%x\n",
3415 so, inp, flags);
3416 #endif
3417
3418 if (inp == 0) {
3419 /* I made the same as TCP since we are not setup? */
3420 #ifdef SCTP_DEBUG
3421 if (sctp_debug_on & SCTP_DEBUG_USRREQ2)
3422 printf("Nope, connection reset\n");
3423 #endif
3424 return (ECONNRESET);
3425 }
3426 /*
3427 * Grab the first one on the list. It will re-insert itself if
3428 * it runs out of room
3429 */
3430 SCTP_INP_WLOCK(inp);
3431 if ((flags & MSG_EOR) && ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0)
3432 && ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
3433 /* Ok the other part of our grubby tracking
3434 * stuff for our horrible layer violation that
3435 * the tsvwg thinks is ok for sctp_peeloff.. gak!
3436 * We must update the next vtag pending on the
3437 * socket buffer (if any).
3438 */
3439 inp->sctp_vtag_first = sctp_get_first_vtag_from_sb(so);
3440 sq = TAILQ_FIRST(&inp->sctp_queue_list);
3441 if (sq) {
3442 stcb = sq->tcb;
3443 } else {
3444 stcb = NULL;
3445 }
3446 } else {
3447 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3448 }
3449 if (stcb) {
3450 SCTP_TCB_LOCK(stcb);
3451 }
3452 if (stcb) {
3453 long incr;
3454 /* all code in normal stcb path assumes
3455 * that you have a tcb_lock only. Thus
3456 * we must release the inp write lock.
3457 */
3458 if (flags & MSG_EOR) {
3459 if (((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0)
3460 && ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
3461 stcb = sctp_remove_from_socket_q(inp);
3462 }
3463 #ifdef SCTP_DEBUG
3464 if (sctp_debug_on & SCTP_DEBUG_USRREQ2)
3465 printf("remove from socket queue for inp:%p tcbret:%p\n",
3466 inp, stcb);
3467 #endif
3468
3469 stcb->asoc.my_rwnd_control_len = sctp_sbspace_sub(stcb->asoc.my_rwnd_control_len,
3470 sizeof(struct mbuf));
3471 if (inp->sctp_flags & SCTP_PCB_FLAGS_RECVDATAIOEVNT) {
3472 stcb->asoc.my_rwnd_control_len = sctp_sbspace_sub(stcb->asoc.my_rwnd_control_len,
3473 CMSG_LEN(sizeof(struct sctp_sndrcvinfo)));
3474 }
3475 }
3476 if ((TAILQ_EMPTY(&stcb->asoc.delivery_queue) == 0) ||
3477 (TAILQ_EMPTY(&stcb->asoc.reasmqueue) == 0)) {
3478 /* Deliver if there is something to be delivered */
3479 sctp_service_queues(stcb, &stcb->asoc, 1);
3480 }
3481 sctp_set_rwnd(stcb, &stcb->asoc);
3482 /* if we increase by 1 or more MTU's (smallest MTUs of all
3483 * nets) we send a window update sack
3484 */
3485 incr = stcb->asoc.my_rwnd - stcb->asoc.my_last_reported_rwnd;
3486 if (incr < 0) {
3487 incr = 0;
3488 }
3489 if (((uint32_t)incr >= (stcb->asoc.smallest_mtu * SCTP_SEG_TO_RWND_UPD)) ||
3490 ((((uint32_t)incr)*SCTP_SCALE_OF_RWND_TO_UPD) >= so->so_rcv.sb_hiwat)) {
3491 if (callout_pending(&stcb->asoc.dack_timer.timer)) {
3492 /* If the timer is up, stop it */
3493 sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
3494 stcb->sctp_ep, stcb, NULL);
3495 }
3496 /* Send the sack, with the new rwnd */
3497 sctp_send_sack(stcb);
3498 /* Now do the output */
3499 sctp_chunk_output(inp, stcb, 10);
3500 }
3501 } else {
3502 if ((( sq ) && (flags & MSG_EOR) && ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0))
3503 && ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
3504 stcb = sctp_remove_from_socket_q(inp);
3505 }
3506 }
3507 if ((so->so_rcv.sb_mb == NULL) &&
3508 (TAILQ_EMPTY(&inp->sctp_queue_list) == 0)) {
3509 int sq_cnt=0;
3510 #ifdef SCTP_DEBUG
3511 if (sctp_debug_on & SCTP_DEBUG_USRREQ2)
3512 printf("Something off, inp:%p so->so_rcv->sb_mb is empty and sockq is not.. cleaning\n",
3513 inp);
3514 #endif
3515 if (((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) == 0)
3516 && ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
3517 int done_yet;
3518 done_yet = TAILQ_EMPTY(&inp->sctp_queue_list);
3519 while (!done_yet) {
3520 sq_cnt++;
3521 (void)sctp_remove_from_socket_q(inp);
3522 done_yet = TAILQ_EMPTY(&inp->sctp_queue_list);
3523 }
3524 }
3525 #ifdef SCTP_DEBUG
3526 if (sctp_debug_on & SCTP_DEBUG_USRREQ2)
3527 printf("Cleaned up %d sockq's\n", sq_cnt);
3528 #endif
3529 }
3530 if (stcb) {
3531 SCTP_TCB_UNLOCK(stcb);
3532 }
3533 SCTP_INP_WUNLOCK(inp);
3534 return (0);
3535 }
3536
3537 int
3538 sctp_listen(struct socket *so, struct lwp *l)
3539 {
3540 /*
3541 * Note this module depends on the protocol processing being
3542 * called AFTER any socket level flags and backlog are applied
3543 * to the socket. The traditional way that the socket flags are
3544 * applied is AFTER protocol processing. We have made a change
3545 * to the sys/kern/uipc_socket.c module to reverse this but this
3546 * MUST be in place if the socket API for SCTP is to work properly.
3547 */
3548 int error = 0;
3549 struct sctp_inpcb *inp;
3550
3551 inp = (struct sctp_inpcb *)so->so_pcb;
3552 if (inp == 0) {
3553 /* I made the same as TCP since we are not setup? */
3554 return (ECONNRESET);
3555 }
3556 SCTP_INP_RLOCK(inp);
3557 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
3558 (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
3559 /* We are already connected AND the TCP model */
3560 SCTP_INP_RUNLOCK(inp);
3561 return (EADDRINUSE);
3562 }
3563 if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
3564 /* We must do a bind. */
3565 SCTP_INP_RUNLOCK(inp);
3566 if ((error = sctp_inpcb_bind(so, NULL, l))) {
3567 /* bind error, probably perm */
3568 return (error);
3569 }
3570 } else {
3571 SCTP_INP_RUNLOCK(inp);
3572 }
3573 SCTP_INP_WLOCK(inp);
3574 if (inp->sctp_socket->so_qlimit) {
3575 if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
3576 /*
3577 * For the UDP model we must TURN OFF the ACCEPT
3578 * flags since we do NOT allow the accept() call.
3579 * The TCP model (when present) will do accept which
3580 * then prohibits connect().
3581 */
3582 inp->sctp_socket->so_options &= ~SO_ACCEPTCONN;
3583 }
3584 inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
3585 } else {
3586 if (inp->sctp_flags & SCTP_PCB_FLAGS_ACCEPTING) {
3587 /*
3588 * Turning off the listen flags if the backlog is
3589 * set to 0 (i.e. qlimit is 0).
3590 */
3591 inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING;
3592 }
3593 inp->sctp_socket->so_options &= ~SO_ACCEPTCONN;
3594 }
3595 SCTP_INP_WUNLOCK(inp);
3596 return (error);
3597 }
3598
3599 int
3600 sctp_accept(struct socket *so, struct sockaddr *nam)
3601 {
3602 struct sctp_tcb *stcb;
3603 const struct sockaddr *prim;
3604 struct sctp_inpcb *inp;
3605 int error;
3606
3607 if (nam == NULL) {
3608 return EINVAL;
3609 }
3610 inp = (struct sctp_inpcb *)so->so_pcb;
3611
3612 if (inp == 0) {
3613 return ECONNRESET;
3614 }
3615 SCTP_INP_RLOCK(inp);
3616 if (so->so_state & SS_ISDISCONNECTED) {
3617 SCTP_INP_RUNLOCK(inp);
3618 return ECONNABORTED;
3619 }
3620 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3621 if (stcb == NULL) {
3622 SCTP_INP_RUNLOCK(inp);
3623 return ECONNRESET;
3624 }
3625 SCTP_TCB_LOCK(stcb);
3626 SCTP_INP_RUNLOCK(inp);
3627 prim = (const struct sockaddr *)rtcache_getdst(&stcb->asoc.primary_destination->ro);
3628 if (prim->sa_family == AF_INET) {
3629 struct sockaddr_in *sin;
3630
3631 sin = (struct sockaddr_in *)nam;
3632 memset((void *)sin, 0, sizeof (*sin));
3633
3634 sin->sin_family = AF_INET;
3635 sin->sin_len = sizeof(*sin);
3636 sin->sin_port = ((const struct sockaddr_in *)prim)->sin_port;
3637 sin->sin_addr = ((const struct sockaddr_in *)prim)->sin_addr;
3638 } else {
3639 struct sockaddr_in6 *sin6;
3640
3641 sin6 = (struct sockaddr_in6 *)nam;
3642 memset((void *)sin6, 0, sizeof (*sin6));
3643 sin6->sin6_family = AF_INET6;
3644 sin6->sin6_len = sizeof(*sin6);
3645 sin6->sin6_port = ((const struct sockaddr_in6 *)prim)->sin6_port;
3646
3647 sin6->sin6_addr = ((const struct sockaddr_in6 *)prim)->sin6_addr;
3648 if ((error = sa6_recoverscope(sin6)) != 0)
3649 return error;
3650
3651 }
3652 /* Wake any delayed sleep action */
3653 SCTP_TCB_UNLOCK(stcb);
3654 SCTP_INP_WLOCK(inp);
3655 if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
3656 inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE;
3657 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) {
3658 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
3659 if (sowritable(inp->sctp_socket))
3660 sowwakeup(inp->sctp_socket);
3661 }
3662 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) {
3663 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
3664 if (soreadable(inp->sctp_socket))
3665 sorwakeup(inp->sctp_socket);
3666 }
3667
3668 }
3669 SCTP_INP_WUNLOCK(inp);
3670 return 0;
3671 }
3672
3673 static int
3674 sctp_stat(struct socket *so, struct stat *ub)
3675 {
3676 return 0;
3677 }
3678
3679 int
3680 sctp_sockaddr(struct socket *so, struct sockaddr *nam)
3681 {
3682 struct sockaddr_in *sin = (struct sockaddr_in *)nam;
3683 struct sctp_inpcb *inp;
3684
3685 memset(sin, 0, sizeof(*sin));
3686 sin->sin_family = AF_INET;
3687 sin->sin_len = sizeof(*sin);
3688 inp = (struct sctp_inpcb *)so->so_pcb;
3689 if (!inp) {
3690 return ECONNRESET;
3691 }
3692 SCTP_INP_RLOCK(inp);
3693 sin->sin_port = inp->sctp_lport;
3694 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3695 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
3696 struct sctp_tcb *stcb;
3697 const struct sockaddr_in *sin_a;
3698 struct sctp_nets *net;
3699 int fnd;
3700
3701 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3702 if (stcb == NULL) {
3703 goto notConn;
3704 }
3705 fnd = 0;
3706 sin_a = NULL;
3707 SCTP_TCB_LOCK(stcb);
3708 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3709 sin_a = (const struct sockaddr_in *)rtcache_getdst(&net->ro);
3710 if (sin_a->sin_family == AF_INET) {
3711 fnd = 1;
3712 break;
3713 }
3714 }
3715 if ((!fnd) || (sin_a == NULL)) {
3716 /* punt */
3717 SCTP_TCB_UNLOCK(stcb);
3718 goto notConn;
3719 }
3720 sin->sin_addr = sctp_ipv4_source_address_selection(inp,
3721 stcb, (struct route *)&net->ro, net, 0);
3722 SCTP_TCB_UNLOCK(stcb);
3723 } else {
3724 /* For the bound all case you get back 0 */
3725 notConn:
3726 sin->sin_addr.s_addr = 0;
3727 }
3728
3729 } else {
3730 /* Take the first IPv4 address in the list */
3731 struct sctp_laddr *laddr;
3732 int fnd = 0;
3733 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
3734 if (laddr->ifa->ifa_addr->sa_family == AF_INET) {
3735 struct sockaddr_in *sin_a;
3736 sin_a = (struct sockaddr_in *)laddr->ifa->ifa_addr;
3737 sin->sin_addr = sin_a->sin_addr;
3738 fnd = 1;
3739 break;
3740 }
3741 }
3742 if (!fnd) {
3743 SCTP_INP_RUNLOCK(inp);
3744 return ENOENT;
3745 }
3746 }
3747 SCTP_INP_RUNLOCK(inp);
3748 return (0);
3749 }
3750
3751 int
3752 sctp_peeraddr(struct socket *so, struct sockaddr *nam)
3753 {
3754 struct sockaddr_in *sin = (struct sockaddr_in *)nam;
3755 int fnd;
3756 const struct sockaddr_in *sin_a;
3757 struct sctp_inpcb *inp;
3758 struct sctp_tcb *stcb;
3759 struct sctp_nets *net;
3760
3761 /* Do the malloc first in case it blocks. */
3762 inp = (struct sctp_inpcb *)so->so_pcb;
3763 if ((inp == NULL) ||
3764 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
3765 /* UDP type and listeners will drop out here */
3766 return (ENOTCONN);
3767 }
3768
3769 memset(sin, 0, sizeof(*sin));
3770 sin->sin_family = AF_INET;
3771 sin->sin_len = sizeof(*sin);
3772
3773 /* We must recapture incase we blocked */
3774 inp = (struct sctp_inpcb *)so->so_pcb;
3775 if (!inp) {
3776 return ECONNRESET;
3777 }
3778 SCTP_INP_RLOCK(inp);
3779 stcb = LIST_FIRST(&inp->sctp_asoc_list);
3780 if (stcb) {
3781 SCTP_TCB_LOCK(stcb);
3782 }
3783 SCTP_INP_RUNLOCK(inp);
3784 if (stcb == NULL) {
3785 return ECONNRESET;
3786 }
3787 fnd = 0;
3788 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
3789 sin_a = (const struct sockaddr_in *)rtcache_getdst(&net->ro);
3790 if (sin_a->sin_family == AF_INET) {
3791 fnd = 1;
3792 sin->sin_port = stcb->rport;
3793 sin->sin_addr = sin_a->sin_addr;
3794 break;
3795 }
3796 }
3797 SCTP_TCB_UNLOCK(stcb);
3798 if (!fnd) {
3799 /* No IPv4 address */
3800 return ENOENT;
3801 }
3802 return (0);
3803 }
3804
3805 static int
3806 sctp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
3807 {
3808 KASSERT(solocked(so));
3809
3810 if (m)
3811 m_freem(m);
3812 if (control)
3813 m_freem(control);
3814
3815 return EOPNOTSUPP;
3816 }
3817
3818 static int
3819 sctp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
3820 {
3821 int error = 0;
3822 int family;
3823
3824 family = so->so_proto->pr_domain->dom_family;
3825 switch (family) {
3826 #ifdef INET
3827 case PF_INET:
3828 error = in_control(so, cmd, nam, ifp);
3829 break;
3830 #endif
3831 #ifdef INET6
3832 case PF_INET6:
3833 error = in6_control(so, cmd, nam, ifp);
3834 break;
3835 #endif
3836 default:
3837 error = EAFNOSUPPORT;
3838 }
3839 return (error);
3840 }
3841
3842 static int
3843 sctp_purgeif(struct socket *so, struct ifnet *ifp)
3844 {
3845 struct ifaddr *ifa;
3846 IFADDR_FOREACH(ifa, ifp) {
3847 if (ifa->ifa_addr->sa_family == PF_INET) {
3848 sctp_delete_ip_address(ifa);
3849 }
3850 }
3851
3852 mutex_enter(softnet_lock);
3853 in_purgeif(ifp);
3854 mutex_exit(softnet_lock);
3855
3856 return 0;
3857 }
3858
3859 /*
3860 * Sysctl for sctp variables.
3861 */
3862 SYSCTL_SETUP(sysctl_net_inet_sctp_setup, "sysctl net.inet.sctp subtree setup")
3863 {
3864
3865 sysctl_createv(clog, 0, NULL, NULL,
3866 CTLFLAG_PERMANENT,
3867 CTLTYPE_NODE, "net", NULL,
3868 NULL, 0, NULL, 0,
3869 CTL_NET, CTL_EOL);
3870 sysctl_createv(clog, 0, NULL, NULL,
3871 CTLFLAG_PERMANENT,
3872 CTLTYPE_NODE, "inet", NULL,
3873 NULL, 0, NULL, 0,
3874 CTL_NET, PF_INET, CTL_EOL);
3875 sysctl_createv(clog, 0, NULL, NULL,
3876 CTLFLAG_PERMANENT,
3877 CTLTYPE_NODE, "sctp",
3878 SYSCTL_DESCR("sctp related settings"),
3879 NULL, 0, NULL, 0,
3880 CTL_NET, PF_INET, IPPROTO_SCTP, CTL_EOL);
3881
3882 sysctl_createv(clog, 0, NULL, NULL,
3883 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3884 CTLTYPE_INT, "maxdgram",
3885 SYSCTL_DESCR("Maximum outgoing SCTP buffer size"),
3886 NULL, 0, &sctp_sendspace, 0,
3887 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_MAXDGRAM,
3888 CTL_EOL);
3889
3890 sysctl_createv(clog, 0, NULL, NULL,
3891 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3892 CTLTYPE_INT, "recvspace",
3893 SYSCTL_DESCR("Maximum incoming SCTP buffer size"),
3894 NULL, 0, &sctp_recvspace, 0,
3895 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_RECVSPACE,
3896 CTL_EOL);
3897
3898 sysctl_createv(clog, 0, NULL, NULL,
3899 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3900 CTLTYPE_INT, "autoasconf",
3901 SYSCTL_DESCR("Enable SCTP Auto-ASCONF"),
3902 NULL, 0, &sctp_auto_asconf, 0,
3903 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_AUTOASCONF,
3904 CTL_EOL);
3905
3906 sysctl_createv(clog, 0, NULL, NULL,
3907 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3908 CTLTYPE_INT, "ecn_enable",
3909 SYSCTL_DESCR("Enable SCTP ECN"),
3910 NULL, 0, &sctp_ecn, 0,
3911 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_ECN_ENABLE,
3912 CTL_EOL);
3913
3914 sysctl_createv(clog, 0, NULL, NULL,
3915 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3916 CTLTYPE_INT, "ecn_nonce",
3917 SYSCTL_DESCR("Enable SCTP ECN Nonce"),
3918 NULL, 0, &sctp_ecn_nonce, 0,
3919 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_ECN_NONCE,
3920 CTL_EOL);
3921
3922 sysctl_createv(clog, 0, NULL, NULL,
3923 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3924 CTLTYPE_INT, "strict_sack",
3925 SYSCTL_DESCR("Enable SCTP Strict SACK checking"),
3926 NULL, 0, &sctp_strict_sacks, 0,
3927 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_STRICT_SACK,
3928 CTL_EOL);
3929
3930 sysctl_createv(clog, 0, NULL, NULL,
3931 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3932 CTLTYPE_INT, "loopback_nocsum",
3933 SYSCTL_DESCR("Enable NO Csum on packets sent on loopback"),
3934 NULL, 0, &sctp_no_csum_on_loopback, 0,
3935 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_NOCSUM_LO,
3936 CTL_EOL);
3937
3938 sysctl_createv(clog, 0, NULL, NULL,
3939 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3940 CTLTYPE_INT, "strict_init",
3941 SYSCTL_DESCR("Enable strict INIT/INIT-ACK singleton enforcement"),
3942 NULL, 0, &sctp_strict_init, 0,
3943 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_STRICT_INIT,
3944 CTL_EOL);
3945
3946 sysctl_createv(clog, 0, NULL, NULL,
3947 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3948 CTLTYPE_INT, "peer_chkoh",
3949 SYSCTL_DESCR("Amount to debit peers rwnd per chunk sent"),
3950 NULL, 0, &sctp_peer_chunk_oh, 0,
3951 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_PEER_CHK_OH,
3952 CTL_EOL);
3953
3954 sysctl_createv(clog, 0, NULL, NULL,
3955 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3956 CTLTYPE_INT, "maxburst",
3957 SYSCTL_DESCR("Default max burst for sctp endpoints"),
3958 NULL, 0, &sctp_max_burst_default, 0,
3959 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_MAXBURST,
3960 CTL_EOL);
3961
3962 sysctl_createv(clog, 0, NULL, NULL,
3963 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3964 CTLTYPE_INT, "maxchunks",
3965 SYSCTL_DESCR("Default max chunks on queue per asoc"),
3966 NULL, 0, &sctp_max_chunks_on_queue, 0,
3967 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_MAXCHUNKONQ,
3968 CTL_EOL);
3969 #ifdef SCTP_DEBUG
3970 sysctl_createv(clog, 0, NULL, NULL,
3971 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
3972 CTLTYPE_INT, "debug",
3973 SYSCTL_DESCR("Configure debug output"),
3974 NULL, 0, &sctp_debug_on, 0,
3975 CTL_NET, PF_INET, IPPROTO_SCTP, SCTPCTL_DEBUG,
3976 CTL_EOL);
3977 #endif
3978 }
3979
3980 PR_WRAP_USRREQS(sctp)
3981 #define sctp_attach sctp_attach_wrapper
3982 #define sctp_detach sctp_detach_wrapper
3983 #define sctp_accept sctp_accept_wrapper
3984 #define sctp_bind sctp_bind_wrapper
3985 #define sctp_listen sctp_listen_wrapper
3986 #define sctp_connect sctp_connect_wrapper
3987 #define sctp_connect2 sctp_connect2_wrapper
3988 #define sctp_disconnect sctp_disconnect_wrapper
3989 #define sctp_shutdown sctp_shutdown_wrapper
3990 #define sctp_abort sctp_abort_wrapper
3991 #define sctp_ioctl sctp_ioctl_wrapper
3992 #define sctp_stat sctp_stat_wrapper
3993 #define sctp_peeraddr sctp_peeraddr_wrapper
3994 #define sctp_sockaddr sctp_sockaddr_wrapper
3995 #define sctp_rcvd sctp_rcvd_wrapper
3996 #define sctp_recvoob sctp_recvoob_wrapper
3997 #define sctp_send sctp_send_wrapper
3998 #define sctp_sendoob sctp_sendoob_wrapper
3999 #define sctp_purgeif sctp_purgeif_wrapper
4000
4001 const struct pr_usrreqs sctp_usrreqs = {
4002 .pr_attach = sctp_attach,
4003 .pr_detach = sctp_detach,
4004 .pr_accept = sctp_accept,
4005 .pr_bind = sctp_bind,
4006 .pr_listen = sctp_listen,
4007 .pr_connect = sctp_connect,
4008 .pr_connect2 = sctp_connect2,
4009 .pr_disconnect = sctp_disconnect,
4010 .pr_shutdown = sctp_shutdown,
4011 .pr_abort = sctp_abort,
4012 .pr_ioctl = sctp_ioctl,
4013 .pr_stat = sctp_stat,
4014 .pr_peeraddr = sctp_peeraddr,
4015 .pr_sockaddr = sctp_sockaddr,
4016 .pr_rcvd = sctp_rcvd,
4017 .pr_recvoob = sctp_recvoob,
4018 .pr_send = sctp_send,
4019 .pr_sendoob = sctp_sendoob,
4020 .pr_purgeif = sctp_purgeif,
4021 };
4022