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