/* Destructor */ static void stun_sock_destructor(void *obj) { pj_stun_sock *stun_sock = (pj_stun_sock*)obj; if (stun_sock->q) { pj_dns_srv_cancel_query(stun_sock->q, PJ_FALSE); stun_sock->q = NULL; } /* if (stun_sock->stun_sess) { pj_stun_session_destroy(stun_sock->stun_sess); stun_sock->stun_sess = NULL; } */ if (stun_sock->pool) { pj_pool_t *pool = stun_sock->pool; stun_sock->pool = NULL; pj_pool_release(pool); } TRACE_(("", "STUN sock %p destroyed", stun_sock)); }
/* Destroy */ PJ_DEF(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *stun_sock) { if (stun_sock->q) { pj_dns_srv_cancel_query(stun_sock->q, PJ_FALSE); stun_sock->q = NULL; } /* Destroy the active socket first just in case we'll get * stray callback. */ if (stun_sock->active_sock != NULL) { pj_activesock_close(stun_sock->active_sock); stun_sock->active_sock = NULL; stun_sock->sock_fd = PJ_INVALID_SOCKET; } else if (stun_sock->sock_fd != PJ_INVALID_SOCKET) { pj_sock_close(stun_sock->sock_fd); stun_sock->sock_fd = PJ_INVALID_SOCKET; } if (stun_sock->ka_timer.id != 0) { pj_timer_heap_cancel(stun_sock->stun_cfg.timer_heap, &stun_sock->ka_timer); stun_sock->ka_timer.id = 0; } if (stun_sock->stun_sess) { pj_stun_session_destroy(stun_sock->stun_sess); stun_sock->stun_sess = NULL; } if (stun_sock->pool) { pj_pool_t *pool = stun_sock->pool; stun_sock->pool = NULL; pj_pool_release(pool); } return PJ_SUCCESS; }
/* * Notify application and shutdown the TCP session. */ static void sess_shutdown(pj_tcp_session *sess, pj_status_t status) { pj_bool_t can_destroy = PJ_TRUE; PJ_LOG(4,(sess->obj_name, "Request to shutdown in state %s, cause:%d", state_names[sess->state], status)); if (sess->last_status == PJ_SUCCESS && status != PJ_SUCCESS) sess->last_status = status; switch (sess->state) { case PJ_TCP_STATE_NULL: break; case PJ_TCP_STATE_RESOLVING: if (sess->dns_async != NULL) { pj_dns_srv_cancel_query(sess->dns_async, PJ_FALSE); sess->dns_async = NULL; } break; case PJ_TCP_STATE_RESOLVED: break; case PJ_TCP_STATE_CONNECTING: /* We need to wait until connection complete */ sess->pending_destroy = PJ_TRUE; can_destroy = PJ_FALSE; break; case PJ_TCP_STATE_READY: /* Send REFRESH with LIFETIME=0 */ #if 0 can_destroy = PJ_FALSE; send_refresh(sess, 0); #endif break; case PJ_TCP_STATE_DISCONNECTING: can_destroy = PJ_FALSE; /* This may recursively call this function again with * state==PJ_TCP_STATE_DISCONNECTING. */ #if 0 send_refresh(sess, 0); #endif break; case PJ_TCP_STATE_DISCONNECTED: case PJ_TCP_STATE_DESTROYING: break; } if (can_destroy) { /* Schedule destroy */ pj_time_val delay = {0, 0}; pj_tcp_session_set_state(sess, PJ_TCP_STATE_DESTROYING); if (sess->timer.id != TIMER_NONE) { pj_timer_heap_cancel(sess->timer_heap, &sess->timer); sess->timer.id = TIMER_NONE; } sess->timer.id = TIMER_DESTROY; pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay); } }