/* Initiate shutdown sequence for this allocation and start destroy timer. * Once allocation is marked as shutting down, any packets will be * rejected/discarded */ static void alloc_shutdown(pj_turn_allocation *alloc) { pj_time_val destroy_delay = DESTROY_DELAY; /* Work with existing schedule */ if (alloc->relay.timer.id == TIMER_ID_TIMEOUT) { /* Cancel existing shutdown timer */ pj_timer_heap_cancel(alloc->server->core.timer_heap, &alloc->relay.timer); alloc->relay.timer.id = TIMER_ID_NONE; } else if (alloc->relay.timer.id == TIMER_ID_DESTROY) { /* We've been scheduled to be destroyed, ignore this * shutdown request. */ return; } pj_assert(alloc->relay.timer.id == TIMER_ID_NONE); /* Shutdown relay socket */ destroy_relay(&alloc->relay); /* Don't unregister from hash table because we still need to * handle REFRESH retransmission. */ /* Schedule destroy timer */ alloc->relay.timer.id = TIMER_ID_DESTROY; pj_timer_heap_schedule(alloc->server->core.timer_heap, &alloc->relay.timer, &destroy_delay); }
/* * Really destroy allocation. */ static void destroy_allocation(pj_turn_allocation *alloc) { pj_pool_t *pool; /* Unregister this allocation */ pj_turn_srv_unregister_allocation(alloc->server, alloc); /* Destroy relay */ destroy_relay(&alloc->relay); /* Must lock only after destroying relay otherwise deadlock */ if (alloc->lock) { pj_lock_acquire(alloc->lock); } /* Unreference transport */ if (alloc->transport) { pj_turn_transport_dec_ref(alloc->transport, alloc); alloc->transport = NULL; } /* Destroy STUN session */ if (alloc->sess) { pj_stun_session_destroy(alloc->sess); alloc->sess = NULL; } /* Destroy lock */ if (alloc->lock) { pj_lock_release(alloc->lock); pj_lock_destroy(alloc->lock); alloc->lock = NULL; } /* Destroy pool */ pool = alloc->pool; if (pool) { alloc->pool = NULL; pj_pool_release(pool); } }
static void console_main(void) { while (!g.quit) { char input[32]; struct peer *peer; pj_status_t status; menu(); if (fgets(input, sizeof(input), stdin) == NULL) break; switch (input[0]) { case 'a': create_relay(); break; case 'd': pj_pool_factory_dump(&g.cp.factory, PJ_TRUE); break; case 's': if (g.relay == NULL) { puts("Error: no relay"); continue; } if (input[1]!='s') peer = &g.peer[0]; else peer = &g.peer[1]; strcpy(input, "Hello from client"); status = pj_turn_sock_sendto(g.relay, (const pj_uint8_t*)input, strlen(input)+1, &peer->mapped_addr, pj_sockaddr_get_len(&peer->mapped_addr)); if (status != PJ_SUCCESS) my_perror("turn_udp_sendto() failed", status); break; case 'b': if (g.relay == NULL) { puts("Error: no relay"); continue; } if (input[1]!='b') peer = &g.peer[0]; else peer = &g.peer[1]; status = pj_turn_sock_bind_channel(g.relay, &peer->mapped_addr, pj_sockaddr_get_len(&peer->mapped_addr)); if (status != PJ_SUCCESS) my_perror("turn_udp_bind_channel() failed", status); break; case 'p': if (g.relay == NULL) { puts("Error: no relay"); continue; } if (input[1]!='p') peer = &g.peer[0]; else peer = &g.peer[1]; status = pj_turn_sock_set_perm(g.relay, 1, &peer->mapped_addr, 1); if (status != PJ_SUCCESS) my_perror("pj_turn_sock_set_perm() failed", status); break; case 'x': if (g.relay == NULL) { puts("Error: no relay"); continue; } destroy_relay(); break; case '0': case '1': if (g.relay == NULL) { puts("No relay"); break; } peer = &g.peer[input[0]-'0']; sprintf(input, "Hello from peer%d", input[0]-'0'); pj_stun_sock_sendto(peer->stun_sock, NULL, input, strlen(input)+1, 0, &g.relay_addr, pj_sockaddr_get_len(&g.relay_addr)); break; case 'q': g.quit = PJ_TRUE; break; } } }