diff options
Diffstat (limited to 'sys/netinet/sctp_usrreq.c')
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 140 |
1 files changed, 13 insertions, 127 deletions
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index c60f4e9..673e13e 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -32,44 +32,8 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); - - -#include "opt_ipsec.h" -#include "opt_inet6.h" -#include "opt_inet.h" - -#include "opt_sctp.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/domain.h> -#include <sys/priv.h> -#include <sys/proc.h> -#include <sys/protosw.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/sysctl.h> -#include <sys/syslog.h> -#include <net/if.h> -#include <net/if_types.h> -#include <net/if_var.h> -#include <net/route.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/ip6.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> -#include <netinet6/ip6_var.h> -#include <netinet6/in6_var.h> -#include <netinet6/scope6_var.h> -#include <netinet/ip_icmp.h> -#include <netinet/icmp_var.h> #include <netinet/sctp_os.h> +#include <sys/proc.h> #include <netinet/sctp_pcb.h> #include <netinet/sctp_header.h> #include <netinet/sctp_var.h> @@ -83,21 +47,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/sctp_timer.h> #include <netinet/sctp_auth.h> -#ifdef IPSEC -#include <netinet6/ipsec.h> -#include <netkey/key.h> -#endif /* IPSEC */ - - - - -#ifndef in6pcb -#define in6pcb inpcb -#endif -#ifndef sotoin6pcb -#define sotoin6pcb sotoinpcb -#endif - /* @@ -436,8 +385,6 @@ sctp_ctlinput(cmd, sa, vip) { struct ip *ip = vip; struct sctphdr *sh; - int s; - if (sa->sa_family != AF_INET || ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) { @@ -469,7 +416,6 @@ sctp_ctlinput(cmd, sa, vip) * 'from' holds our local endpoint address. Thus we reverse * the to and the from in the lookup. */ - s = splnet(); stcb = sctp_findassociation_addr_sa((struct sockaddr *)&from, (struct sockaddr *)&to, &inp, &net, 1); @@ -497,7 +443,6 @@ sctp_ctlinput(cmd, sa, vip) SCTP_INP_WUNLOCK(inp); } } - splx(s); } return; } @@ -956,14 +901,12 @@ static void sctp_abort(struct socket *so) { struct sctp_inpcb *inp; - int s; uint32_t flags; inp = (struct sctp_inpcb *)so->so_pcb; if (inp == 0) return; - s = splnet(); sctp_must_try_again: flags = inp->sctp_flags; #ifdef SCTP_LOG_CLOSING @@ -999,7 +942,6 @@ sctp_must_try_again: goto sctp_must_try_again; } } - splx(s); return; } @@ -1008,26 +950,22 @@ sctp_attach(struct socket *so, int proto, struct thread *p) { struct sctp_inpcb *inp; struct inpcb *ip_inp; - int s, error; + int error; #ifdef IPSEC uint32_t flags; #endif - s = splnet(); inp = (struct sctp_inpcb *)so->so_pcb; if (inp != 0) { - splx(s); return EINVAL; } error = soreserve(so, sctp_sendspace, sctp_recvspace); if (error) { - splx(s); return error; } error = sctp_inpcb_alloc(so); if (error) { - splx(s); return error; } inp = (struct sctp_inpcb *)so->so_pcb; @@ -1056,7 +994,6 @@ sctp_attach(struct socket *so, int proto, struct thread *p) } #endif /* IPSEC */ SCTP_INP_WUNLOCK(inp); - splx(s); return 0; } @@ -1064,7 +1001,7 @@ static int sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p) { struct sctp_inpcb *inp; - int s, error; + int error; #ifdef INET6 if (addr && addr->sa_family != AF_INET) @@ -1076,9 +1013,7 @@ sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p) if (inp == 0) return EINVAL; - s = splnet(); error = sctp_inpcb_bind(so, addr, p); - splx(s); return error; } @@ -1237,19 +1172,15 @@ static int sctp_disconnect(struct socket *so) { struct sctp_inpcb *inp; - int s; - s = splnet(); inp = (struct sctp_inpcb *)so->so_pcb; if (inp == NULL) { - splx(s); return (ENOTCONN); } SCTP_INP_RLOCK(inp); if (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { if (LIST_EMPTY(&inp->sctp_asoc_list)) { /* No connection */ - splx(s); SCTP_INP_RUNLOCK(inp); return (0); } else { @@ -1258,7 +1189,6 @@ sctp_disconnect(struct socket *so) stcb = LIST_FIRST(&inp->sctp_asoc_list); if (stcb == NULL) { - splx(s); SCTP_INP_RUNLOCK(inp); return (EINVAL); } @@ -1301,7 +1231,6 @@ sctp_disconnect(struct socket *so) } sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3); /* No unlock tcb assoc is gone */ - splx(s); return (0); } if (TAILQ_EMPTY(&asoc->send_queue) && @@ -1391,20 +1320,17 @@ sctp_disconnect(struct socket *so) } SCTP_INP_RUNLOCK(inp); sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5); - splx(s); return (0); } } SCTP_TCB_UNLOCK(stcb); SCTP_INP_RUNLOCK(inp); - splx(s); return (0); } /* not reached */ } else { /* UDP model does not support this */ SCTP_INP_RUNLOCK(inp); - splx(s); return EOPNOTSUPP; } } @@ -1413,12 +1339,9 @@ int sctp_shutdown(struct socket *so) { struct sctp_inpcb *inp; - int s; - s = splnet(); inp = (struct sctp_inpcb *)so->so_pcb; if (inp == 0) { - splx(s); return EINVAL; } SCTP_INP_RLOCK(inp); @@ -1427,7 +1350,6 @@ sctp_shutdown(struct socket *so) /* Restore the flags that the soshutdown took away. */ so->so_rcv.sb_state &= ~SBS_CANTRCVMORE; /* This proc will wakeup for read and do nothing (I hope) */ - splx(s); SCTP_INP_RUNLOCK(inp); return (EOPNOTSUPP); } @@ -1448,7 +1370,6 @@ sctp_shutdown(struct socket *so) * made after an abort or something. Nothing to do * now. */ - splx(s); return (0); } SCTP_TCB_LOCK(stcb); @@ -1532,7 +1453,6 @@ sctp_shutdown(struct socket *so) } skip_unlock: SCTP_INP_RUNLOCK(inp); - splx(s); return 0; } @@ -1804,8 +1724,6 @@ sctp_do_connect_x(struct socket *so, int delay ) { - int s = splnet(); - int error = 0; int creat_lock_on = 0; struct sctp_tcb *stcb = NULL; @@ -1821,11 +1739,9 @@ sctp_do_connect_x(struct socket *so, if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { /* We are already connected AND the TCP model */ - splx(s); return (EADDRINUSE); } if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) { - splx(s); return (EINVAL); } if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { @@ -1834,7 +1750,6 @@ sctp_do_connect_x(struct socket *so, SCTP_INP_RUNLOCK(inp); } if (stcb) { - splx(s); return (EALREADY); } @@ -1889,7 +1804,6 @@ sctp_do_connect_x(struct socket *so, #ifdef INET6 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) && (num_v6 > 0)) { - splx(s); error = EINVAL; goto out_now; } @@ -1975,7 +1889,6 @@ out_now: if (creat_lock_on) SCTP_ASOC_CREATE_UNLOCK(inp); SCTP_INP_DECR_REF(inp); - splx(s); return error; } @@ -3250,8 +3163,9 @@ sctp_optsset(struct socket *so, struct thread *p ) { - int error, *mopt, set_opt, s; + int error, *mopt, set_opt; struct mbuf *m; + struct sctp_tcb *stcb = NULL; struct sctp_inpcb *inp; @@ -3760,10 +3674,8 @@ sctp_optsset(struct socket *so, send_out, (stcb->asoc.str_reset_seq_in - 3), send_in, send_tsn); - s = splnet(); sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ); SCTP_TCB_UNLOCK(stcb); - splx(s); } break; @@ -4570,12 +4482,10 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt) { struct mbuf *m = NULL; struct sctp_inpcb *inp; - int s, error; + int error; inp = (struct sctp_inpcb *)so->so_pcb; - s = splnet(); if (inp == 0) { - splx(s); /* I made the same as TCP since we are not setup? */ return (ECONNRESET); } @@ -4587,7 +4497,6 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt) else #endif /* INET6 */ error = ip_ctloutput(so, sopt); - splx(s); return (error); } if (sopt->sopt_valsize) { @@ -4598,7 +4507,6 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt) } if (m == NULL) { sctp_m_freem(m); - splx(s); return (ENOBUFS); } if (sopt->sopt_valsize > M_TRAILINGSPACE(m)) { @@ -4627,7 +4535,6 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt) sctp_m_freem(m); } out: - splx(s); return (error); } @@ -4635,8 +4542,6 @@ out: static int sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) { - int s = splnet(); - int error = 0; int create_lock_on = 0; struct sctp_inpcb *inp; @@ -4644,7 +4549,6 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) inp = (struct sctp_inpcb *)so->so_pcb; if (inp == 0) { - splx(s); /* I made the same as TCP since we are not setup? */ return (ECONNRESET); } @@ -4710,7 +4614,6 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p) stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0); if (stcb == NULL) { /* Gak! no memory */ - splx(s); return (error); } if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { @@ -4732,7 +4635,6 @@ out_now: if (stcb) SCTP_TCB_UNLOCK(stcb); SCTP_INP_DECR_REF(inp); - splx(s); return error; } @@ -4747,14 +4649,12 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) * sys/kern/uipc_socket.c module to reverse this but this MUST be in * place if the socket API for SCTP is to work properly. */ - int s = splnet(); int error = 0; struct sctp_inpcb *inp; inp = (struct sctp_inpcb *)so->so_pcb; if (inp == 0) { - splx(s); /* I made the same as TCP since we are not setup? */ return (ECONNRESET); } @@ -4771,7 +4671,6 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { /* We are already connected AND the TCP model */ - splx(s); SCTP_INP_RUNLOCK(inp); SOCK_UNLOCK(so); return (EADDRINUSE); @@ -4782,7 +4681,6 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) if ((error = sctp_inpcb_bind(so, NULL, p))) { /* bind error, probably perm */ SOCK_UNLOCK(so); - splx(s); return (error); } } else { @@ -4800,7 +4698,6 @@ sctp_listen(struct socket *so, int backlog, struct thread *p) so->so_options &= ~SO_ACCEPTCONN; } SOCK_UNLOCK(so); - splx(s); return (error); } @@ -4809,8 +4706,6 @@ static int sctp_defered_wakeup_cnt = 0; int sctp_accept(struct socket *so, struct sockaddr **addr) { - int s = splnet(); - struct sctp_tcb *stcb; struct sctp_inpcb *inp; union sctp_sockstore store; @@ -4821,7 +4716,6 @@ sctp_accept(struct socket *so, struct sockaddr **addr) inp = (struct sctp_inpcb *)so->so_pcb; if (inp == 0) { - splx(s); return (ECONNRESET); } SCTP_INP_RLOCK(inp); @@ -4829,13 +4723,11 @@ sctp_accept(struct socket *so, struct sockaddr **addr) return (ENOTSUP); } if (so->so_state & SS_ISDISCONNECTED) { - splx(s); SCTP_INP_RUNLOCK(inp); return (ECONNABORTED); } stcb = LIST_FIRST(&inp->sctp_asoc_list); if (stcb == NULL) { - splx(s); SCTP_INP_RUNLOCK(inp); return (ECONNRESET); } @@ -4869,18 +4761,22 @@ sctp_accept(struct socket *so, struct sockaddr **addr) } /* Wake any delayed sleep action */ if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) { + SCTP_INP_WLOCK(inp); inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE; if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) { inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; + SCTP_INP_WUNLOCK(inp); SOCKBUF_LOCK(&inp->sctp_socket->so_snd); if (sowriteable(inp->sctp_socket)) { sowwakeup_locked(inp->sctp_socket); } else { SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd); } + SCTP_INP_WLOCK(inp); } if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) { inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; + SCTP_INP_WUNLOCK(inp); SOCKBUF_LOCK(&inp->sctp_socket->so_rcv); if (soreadable(inp->sctp_socket)) { sctp_defered_wakeup_cnt++; @@ -4888,9 +4784,10 @@ sctp_accept(struct socket *so, struct sockaddr **addr) } else { SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv); } + SCTP_INP_WLOCK(inp); } + SCTP_INP_WUNLOCK(inp); } - splx(s); return (0); } @@ -4899,7 +4796,6 @@ sctp_ingetaddr(struct socket *so, struct sockaddr **addr) { struct sockaddr_in *sin; - int s; struct sctp_inpcb *inp; /* @@ -4908,10 +4804,8 @@ sctp_ingetaddr(struct socket *so, struct sockaddr **addr) SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); sin->sin_family = AF_INET; sin->sin_len = sizeof(*sin); - s = splnet(); inp = (struct sctp_inpcb *)so->so_pcb; if (!inp) { - splx(s); SCTP_FREE_SONAME(sin); return ECONNRESET; } @@ -4972,14 +4866,12 @@ sctp_ingetaddr(struct socket *so, struct sockaddr **addr) } } if (!fnd) { - splx(s); SCTP_FREE_SONAME(sin); SCTP_INP_RUNLOCK(inp); return ENOENT; } } SCTP_INP_RUNLOCK(inp); - splx(s); (*addr) = (struct sockaddr *)sin; return (0); } @@ -4989,7 +4881,7 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr) { struct sockaddr_in *sin = (struct sockaddr_in *)*addr; - int s, fnd; + int fnd; struct sockaddr_in *sin_a; struct sctp_inpcb *inp; struct sctp_tcb *stcb; @@ -5003,8 +4895,6 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr) /* UDP type and listeners will drop out here */ return (ENOTCONN); } - s = splnet(); - SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin); sin->sin_family = AF_INET; sin->sin_len = sizeof(*sin); @@ -5012,7 +4902,6 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr) /* We must recapture incase we blocked */ inp = (struct sctp_inpcb *)so->so_pcb; if (!inp) { - splx(s); SCTP_FREE_SONAME(sin); return ECONNRESET; } @@ -5022,7 +4911,6 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr) SCTP_TCB_LOCK(stcb); SCTP_INP_RUNLOCK(inp); if (stcb == NULL) { - splx(s); SCTP_FREE_SONAME(sin); return ECONNRESET; } @@ -5039,11 +4927,9 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr) SCTP_TCB_UNLOCK(stcb); if (!fnd) { /* No IPv4 address */ - splx(s); SCTP_FREE_SONAME(sin); return ENOENT; } - splx(s); (*addr) = (struct sockaddr *)sin; return (0); } |