diff options
Diffstat (limited to 'sys/netinet/sctp_pcb.c')
-rw-r--r-- | sys/netinet/sctp_pcb.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index cccd8c50..5115460 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -2296,7 +2296,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) if (inp->sctp_asocidhash == NULL) { SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); SCTP_INP_INFO_WUNLOCK(); - return error; + return (ENOBUFS); } #ifdef IPSEC { @@ -3107,29 +3107,13 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) #ifdef SCTP_LOG_CLOSING sctp_log_closing(inp, NULL, 0); #endif - SCTP_ITERATOR_LOCK(); - - so = inp->sctp_socket; - if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { - /* been here before.. eeks.. get out of here */ - SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate); - SCTP_ITERATOR_UNLOCK(); -#ifdef SCTP_LOG_CLOSING - sctp_log_closing(inp, NULL, 1); -#endif - return; - } - SCTP_ASOC_CREATE_LOCK(inp); - SCTP_INP_INFO_WLOCK(); - - SCTP_INP_WLOCK(inp); - /* First time through we have the socket lock, after that no more. */ if (from == SCTP_CALLED_AFTER_CMPSET_OFCLOSE) { /* * Once we are in we can remove the flag from = 1 is only * passed from the actual closing routines that are called * via the sockets layer. */ + SCTP_ITERATOR_LOCK(); inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP; /* socket is gone, so no more wakeups allowed */ inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE; @@ -3138,7 +3122,22 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) /* mark any iterators on the list or being processed */ sctp_iterator_inp_being_freed(inp); + SCTP_ITERATOR_UNLOCK(); + } + so = inp->sctp_socket; + if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { + /* been here before.. eeks.. get out of here */ + SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate); +#ifdef SCTP_LOG_CLOSING + sctp_log_closing(inp, NULL, 1); +#endif + return; } + SCTP_ASOC_CREATE_LOCK(inp); + SCTP_INP_INFO_WLOCK(); + + SCTP_INP_WLOCK(inp); + /* First time through we have the socket lock, after that no more. */ sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL, SCTP_FROM_SCTP_PCB + SCTP_LOC_1); @@ -3338,7 +3337,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) SCTP_INP_WUNLOCK(inp); SCTP_ASOC_CREATE_UNLOCK(inp); SCTP_INP_INFO_WUNLOCK(); - SCTP_ITERATOR_UNLOCK(); #ifdef SCTP_LOG_CLOSING sctp_log_closing(inp, NULL, 2); #endif @@ -3416,7 +3414,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) SCTP_INP_WUNLOCK(inp); SCTP_ASOC_CREATE_UNLOCK(inp); SCTP_INP_INFO_WUNLOCK(); - SCTP_ITERATOR_UNLOCK(); #ifdef SCTP_LOG_CLOSING sctp_log_closing(inp, NULL, 3); #endif @@ -3428,7 +3425,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) SCTP_INP_WUNLOCK(inp); SCTP_ASOC_CREATE_UNLOCK(inp); SCTP_INP_INFO_WUNLOCK(); - SCTP_ITERATOR_UNLOCK(); #ifdef SCTP_LOG_CLOSING sctp_log_closing(inp, NULL, 4); #endif @@ -3550,7 +3546,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) SCTP_INP_READ_DESTROY(inp); SCTP_ASOC_CREATE_LOCK_DESTROY(inp); SCTP_INP_INFO_WUNLOCK(); - SCTP_ITERATOR_UNLOCK(); SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); SCTP_DECR_EP_COUNT(); } |