| /* $Id$ */ |
| /* |
| * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
| * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| #include "turn.h" |
| #include "auth.h" |
| |
| #define REALM "pjsip.org" |
| //#define TURN_PORT PJ_STUN_TURN_PORT |
| #define TURN_PORT 34780 |
| #define LOG_LEVEL 4 |
| |
| |
| static pj_caching_pool g_cp; |
| |
| int err(const char *title, pj_status_t status) |
| { |
| char errmsg[PJ_ERR_MSG_SIZE]; |
| pj_strerror(status, errmsg, sizeof(errmsg)); |
| |
| printf("%s: %s\n", title, errmsg); |
| return 1; |
| } |
| |
| static void dump_status(pj_turn_srv *srv) |
| { |
| char addr[80]; |
| pj_hash_iterator_t itbuf, *it; |
| pj_time_val now; |
| unsigned i; |
| |
| for (i=0; i<srv->core.lis_cnt; ++i) { |
| pj_turn_listener *lis = srv->core.listener[i]; |
| printf("Server address : %s\n", lis->info); |
| } |
| |
| printf("Worker threads : %d\n", srv->core.thread_cnt); |
| printf("Total mem usage: %u.%03uMB\n", (unsigned)(g_cp.used_size / 1000000), |
| (unsigned)((g_cp.used_size % 1000000)/1000)); |
| printf("UDP port range : %u %u %u (next/min/max)\n", srv->ports.next_udp, |
| srv->ports.min_udp, srv->ports.max_udp); |
| printf("TCP port range : %u %u %u (next/min/max)\n", srv->ports.next_tcp, |
| srv->ports.min_tcp, srv->ports.max_tcp); |
| printf("Clients # : %u\n", pj_hash_count(srv->tables.alloc)); |
| |
| puts(""); |
| |
| if (pj_hash_count(srv->tables.alloc)==0) { |
| return; |
| } |
| |
| puts("# Client addr. Alloc addr. Username Lftm Expy #prm #chl"); |
| puts("------------------------------------------------------------------------------"); |
| |
| pj_gettimeofday(&now); |
| |
| it = pj_hash_first(srv->tables.alloc, &itbuf); |
| i=1; |
| while (it) { |
| pj_turn_allocation *alloc = (pj_turn_allocation*) |
| pj_hash_this(srv->tables.alloc, it); |
| printf("%-3d %-22s %-22s %-8.*s %-4d %-4ld %-4d %-4d\n", |
| i, |
| alloc->info, |
| pj_sockaddr_print(&alloc->relay.hkey.addr, addr, sizeof(addr), 3), |
| (int)alloc->cred.data.static_cred.username.slen, |
| alloc->cred.data.static_cred.username.ptr, |
| alloc->relay.lifetime, |
| alloc->relay.expiry.sec - now.sec, |
| pj_hash_count(alloc->peer_table), |
| pj_hash_count(alloc->ch_table)); |
| |
| it = pj_hash_next(srv->tables.alloc, it); |
| ++i; |
| } |
| } |
| |
| static void menu(void) |
| { |
| puts(""); |
| puts("Menu:"); |
| puts(" d Dump status"); |
| puts(" q Quit"); |
| printf(">> "); |
| } |
| |
| static void console_main(pj_turn_srv *srv) |
| { |
| pj_bool_t quit = PJ_FALSE; |
| |
| while (!quit) { |
| char line[10]; |
| |
| menu(); |
| |
| if (fgets(line, sizeof(line), stdin) == NULL) |
| break; |
| |
| switch (line[0]) { |
| case 'd': |
| dump_status(srv); |
| break; |
| case 'q': |
| quit = PJ_TRUE; |
| break; |
| } |
| } |
| } |
| |
| int main() |
| { |
| pj_turn_srv *srv; |
| pj_turn_listener *listener; |
| pj_status_t status; |
| |
| status = pj_init(); |
| if (status != PJ_SUCCESS) |
| return err("pj_init() error", status); |
| |
| pjlib_util_init(); |
| pjnath_init(); |
| |
| pj_caching_pool_init(&g_cp, NULL, 0); |
| |
| pj_turn_auth_init(REALM); |
| |
| status = pj_turn_srv_create(&g_cp.factory, &srv); |
| if (status != PJ_SUCCESS) |
| return err("Error creating server", status); |
| |
| status = pj_turn_listener_create_udp(srv, pj_AF_INET(), NULL, |
| TURN_PORT, 1, 0, &listener); |
| if (status != PJ_SUCCESS) |
| return err("Error creating UDP listener", status); |
| |
| #if PJ_HAS_TCP |
| status = pj_turn_listener_create_tcp(srv, pj_AF_INET(), NULL, |
| TURN_PORT, 1, 0, &listener); |
| if (status != PJ_SUCCESS) |
| return err("Error creating listener", status); |
| #endif |
| |
| status = pj_turn_srv_add_listener(srv, listener); |
| if (status != PJ_SUCCESS) |
| return err("Error adding listener", status); |
| |
| puts("Server is running"); |
| |
| pj_log_set_level(LOG_LEVEL); |
| |
| console_main(srv); |
| |
| pj_turn_srv_destroy(srv); |
| pj_caching_pool_destroy(&g_cp); |
| pj_shutdown(); |
| |
| return 0; |
| } |
| |