summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/sctp_pcb.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/sctp_pcb.c')
-rw-r--r--freebsd/sys/netinet/sctp_pcb.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/freebsd/sys/netinet/sctp_pcb.c b/freebsd/sys/netinet/sctp_pcb.c
index 782e5f1d..45342dc3 100644
--- a/freebsd/sys/netinet/sctp_pcb.c
+++ b/freebsd/sys/netinet/sctp_pcb.c
@@ -2847,7 +2847,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
struct sockaddr_in *sin;
/* IPV6_V6ONLY socket? */
- if (SCTP_IPV6_V6ONLY(ip_inp)) {
+ if (SCTP_IPV6_V6ONLY(inp)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
return (EINVAL);
}
@@ -3648,10 +3648,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
#ifdef INET6
if (ip_pcb->inp_vflag & INP_IPV6) {
- struct in6pcb *in6p;
-
- in6p = (struct in6pcb *)inp;
- ip6_freepcbopts(in6p->in6p_outputopts);
+ ip6_freepcbopts(ip_pcb->in6p_outputopts);
}
#endif /* INET6 */
ip_pcb->inp_vflag = 0;
@@ -4161,11 +4158,9 @@ sctp_aloc_a_assoc_id(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
struct sctpasochead *head;
struct sctp_tcb *lstcb;
- SCTP_INP_WLOCK(inp);
try_again:
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
/* TSNH */
- SCTP_INP_WUNLOCK(inp);
return (0);
}
/*
@@ -4184,8 +4179,7 @@ try_again:
head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
LIST_INSERT_HEAD(head, stcb, sctp_tcbasocidhash);
stcb->asoc.in_asocid_hash = 1;
- SCTP_INP_WUNLOCK(inp);
- return id;
+ return (id);
}
/*
@@ -4197,8 +4191,8 @@ struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
int *error, uint32_t override_tag, uint32_t vrf_id,
uint16_t o_streams, uint16_t port,
- struct thread *p
-)
+ struct thread *p,
+ int initialize_auth_params)
{
/* note the p argument is only valid in unbound sockets */
@@ -4348,7 +4342,6 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
memset(stcb, 0, sizeof(*stcb));
asoc = &stcb->asoc;
- asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb);
SCTP_TCB_LOCK_INIT(stcb);
SCTP_TCB_SEND_LOCK_INIT(stcb);
stcb->rport = rport;
@@ -4359,7 +4352,6 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
/* failed */
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
- LIST_REMOVE(stcb, sctp_tcbasocidhash);
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
SCTP_DECR_ASOC_COUNT();
*error = err;
@@ -4372,7 +4364,6 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
/* inpcb freed while alloc going on */
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
- LIST_REMOVE(stcb, sctp_tcbasocidhash);
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
SCTP_INP_WUNLOCK(inp);
SCTP_INP_INFO_WUNLOCK();
@@ -4383,6 +4374,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
}
SCTP_TCB_LOCK(stcb);
+ asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb);
/* now that my_vtag is set, add it to the hash */
head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
/* put it in the bucket in the vtag hash of assoc's for the system */
@@ -4430,6 +4422,9 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
inp->sctp_hashmark)];
LIST_INSERT_HEAD(head, stcb, sctp_tcbhash);
}
+ if (initialize_auth_params == SCTP_INITIALIZE_AUTH_PARAMS) {
+ sctp_initialize_auth_params(inp, stcb);
+ }
SCTP_INP_WUNLOCK(inp);
SCTPDBG(SCTP_DEBUG_PCB1, "Association %p now allocated\n", (void *)stcb);
return (stcb);
@@ -4918,12 +4913,11 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED;
if (so) {
SOCKBUF_LOCK(&so->so_rcv);
- if (so->so_rcv.sb_cc == 0) {
- so->so_state &= ~(SS_ISCONNECTING |
- SS_ISDISCONNECTING |
- SS_ISCONFIRMING |
- SS_ISCONNECTED);
- }
+ so->so_state &= ~(SS_ISCONNECTING |
+ SS_ISDISCONNECTING |
+ SS_ISCONFIRMING |
+ SS_ISCONNECTED);
+ so->so_state |= SS_ISDISCONNECTED;
socantrcvmore_locked(so);
socantsendmore(so);
sctp_sowwakeup(inp, so);
@@ -4991,6 +4985,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
* in case.
*/
/* anything on the wheel needs to be removed */
+ SCTP_TCB_SEND_LOCK(stcb);
for (i = 0; i < asoc->streamoutcnt; i++) {
struct sctp_stream_out *outs;
@@ -4999,7 +4994,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) {
atomic_subtract_int(&asoc->stream_queue_cnt, 1);
TAILQ_REMOVE(&outs->outqueue, sp, next);
- stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, 0);
+ stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, 1);
sctp_free_spbufspace(stcb, asoc, sp);
if (sp->data) {
if (so) {
@@ -5021,6 +5016,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
}
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
/* sa_ignore FREED_MEMORY */
TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
@@ -5779,7 +5775,7 @@ sctp_startup_mcore_threads(void)
#endif
void
-sctp_pcb_init()
+sctp_pcb_init(void)
{
/*
* SCTP initialization for the PCB structures should be called by