release sctp_inpcb unbind the port */
| 3292 | |
| 3293 | /* release sctp_inpcb unbind the port */ |
| 3294 | void |
| 3295 | sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) |
| 3296 | { |
| 3297 | /* |
| 3298 | * Here we free a endpoint. We must find it (if it is in the Hash |
| 3299 | * table) and remove it from there. Then we must also find it in the |
| 3300 | * overall list and remove it from there. After all removals are |
| 3301 | * complete then any timer has to be stopped. Then start the actual |
| 3302 | * freeing. a) Any local lists. b) Any associations. c) The hash of |
| 3303 | * all associations. d) finally the ep itself. |
| 3304 | */ |
| 3305 | struct sctp_tcb *asoc, *nasoc; |
| 3306 | struct sctp_laddr *laddr, *nladdr; |
| 3307 | struct inpcb *ip_pcb; |
| 3308 | struct socket *so; |
| 3309 | int being_refed = 0; |
| 3310 | struct sctp_queued_to_read *sq, *nsq; |
| 3311 | int cnt; |
| 3312 | sctp_sharedkey_t *shared_key, *nshared_key; |
| 3313 | |
| 3314 | #ifdef SCTP_LOG_CLOSING |
| 3315 | sctp_log_closing(inp, NULL, 0); |
| 3316 | #endif |
| 3317 | SCTP_ITERATOR_LOCK(); |
| 3318 | /* mark any iterators on the list or being processed */ |
| 3319 | sctp_iterator_inp_being_freed(inp); |
| 3320 | SCTP_ITERATOR_UNLOCK(); |
| 3321 | so = inp->sctp_socket; |
| 3322 | if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { |
| 3323 | /* been here before.. eeks.. get out of here */ |
| 3324 | SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate); |
| 3325 | #ifdef SCTP_LOG_CLOSING |
| 3326 | sctp_log_closing(inp, NULL, 1); |
| 3327 | #endif |
| 3328 | return; |
| 3329 | } |
| 3330 | SCTP_ASOC_CREATE_LOCK(inp); |
| 3331 | SCTP_INP_INFO_WLOCK(); |
| 3332 | |
| 3333 | SCTP_INP_WLOCK(inp); |
| 3334 | if (from == SCTP_CALLED_AFTER_CMPSET_OFCLOSE) { |
| 3335 | inp->sctp_flags &= ~SCTP_PCB_FLAGS_CLOSE_IP; |
| 3336 | /* socket is gone, so no more wakeups allowed */ |
| 3337 | inp->sctp_flags |= SCTP_PCB_FLAGS_DONT_WAKE; |
| 3338 | inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT; |
| 3339 | inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT; |
| 3340 | } |
| 3341 | /* First time through we have the socket lock, after that no more. */ |
| 3342 | sctp_timer_stop(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL, |
| 3343 | SCTP_FROM_SCTP_PCB + SCTP_LOC_1); |
| 3344 | |
| 3345 | if (inp->control) { |
| 3346 | sctp_m_freem(inp->control); |
| 3347 | inp->control = NULL; |
| 3348 | } |
| 3349 | if (inp->pkt) { |
| 3350 | sctp_m_freem(inp->pkt); |
| 3351 | inp->pkt = NULL; |
no test coverage detected