Tristan Matthews | 0a329cc | 2013-07-17 13:20:14 -0400 | [diff] [blame] | 1 | /* $Id: main.c 3553 2011-05-05 06:14:19Z nanang $ */ |
| 2 | /* |
| 3 | * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) |
| 4 | * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; either version 2 of the License, or |
| 9 | * (at your option) any later version. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ |
| 20 | #include "turn.h" |
| 21 | #include "auth.h" |
| 22 | |
| 23 | #define REALM "pjsip.org" |
| 24 | //#define TURN_PORT PJ_STUN_TURN_PORT |
| 25 | #define TURN_PORT 34780 |
| 26 | #define LOG_LEVEL 4 |
| 27 | |
| 28 | |
| 29 | static pj_caching_pool g_cp; |
| 30 | |
| 31 | int err(const char *title, pj_status_t status) |
| 32 | { |
| 33 | char errmsg[PJ_ERR_MSG_SIZE]; |
| 34 | pj_strerror(status, errmsg, sizeof(errmsg)); |
| 35 | |
| 36 | printf("%s: %s\n", title, errmsg); |
| 37 | return 1; |
| 38 | } |
| 39 | |
| 40 | static void dump_status(pj_turn_srv *srv) |
| 41 | { |
| 42 | char addr[80]; |
| 43 | pj_hash_iterator_t itbuf, *it; |
| 44 | pj_time_val now; |
| 45 | unsigned i; |
| 46 | |
| 47 | for (i=0; i<srv->core.lis_cnt; ++i) { |
| 48 | pj_turn_listener *lis = srv->core.listener[i]; |
| 49 | printf("Server address : %s\n", lis->info); |
| 50 | } |
| 51 | |
| 52 | printf("Worker threads : %d\n", srv->core.thread_cnt); |
| 53 | printf("Total mem usage: %u.%03uMB\n", (unsigned)(g_cp.used_size / 1000000), |
| 54 | (unsigned)((g_cp.used_size % 1000000)/1000)); |
| 55 | printf("UDP port range : %u %u %u (next/min/max)\n", srv->ports.next_udp, |
| 56 | srv->ports.min_udp, srv->ports.max_udp); |
| 57 | printf("TCP port range : %u %u %u (next/min/max)\n", srv->ports.next_tcp, |
| 58 | srv->ports.min_tcp, srv->ports.max_tcp); |
| 59 | printf("Clients # : %u\n", pj_hash_count(srv->tables.alloc)); |
| 60 | |
| 61 | puts(""); |
| 62 | |
| 63 | if (pj_hash_count(srv->tables.alloc)==0) { |
| 64 | return; |
| 65 | } |
| 66 | |
| 67 | puts("# Client addr. Alloc addr. Username Lftm Expy #prm #chl"); |
| 68 | puts("------------------------------------------------------------------------------"); |
| 69 | |
| 70 | pj_gettimeofday(&now); |
| 71 | |
| 72 | it = pj_hash_first(srv->tables.alloc, &itbuf); |
| 73 | i=1; |
| 74 | while (it) { |
| 75 | pj_turn_allocation *alloc = (pj_turn_allocation*) |
| 76 | pj_hash_this(srv->tables.alloc, it); |
| 77 | printf("%-3d %-22s %-22s %-8.*s %-4d %-4ld %-4d %-4d\n", |
| 78 | i, |
| 79 | alloc->info, |
| 80 | pj_sockaddr_print(&alloc->relay.hkey.addr, addr, sizeof(addr), 3), |
| 81 | (int)alloc->cred.data.static_cred.username.slen, |
| 82 | alloc->cred.data.static_cred.username.ptr, |
| 83 | alloc->relay.lifetime, |
| 84 | alloc->relay.expiry.sec - now.sec, |
| 85 | pj_hash_count(alloc->peer_table), |
| 86 | pj_hash_count(alloc->ch_table)); |
| 87 | |
| 88 | it = pj_hash_next(srv->tables.alloc, it); |
| 89 | ++i; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | static void menu(void) |
| 94 | { |
| 95 | puts(""); |
| 96 | puts("Menu:"); |
| 97 | puts(" d Dump status"); |
| 98 | puts(" q Quit"); |
| 99 | printf(">> "); |
| 100 | } |
| 101 | |
| 102 | static void console_main(pj_turn_srv *srv) |
| 103 | { |
| 104 | pj_bool_t quit = PJ_FALSE; |
| 105 | |
| 106 | while (!quit) { |
| 107 | char line[10]; |
| 108 | |
| 109 | menu(); |
| 110 | |
| 111 | if (fgets(line, sizeof(line), stdin) == NULL) |
| 112 | break; |
| 113 | |
| 114 | switch (line[0]) { |
| 115 | case 'd': |
| 116 | dump_status(srv); |
| 117 | break; |
| 118 | case 'q': |
| 119 | quit = PJ_TRUE; |
| 120 | break; |
| 121 | } |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | int main() |
| 126 | { |
| 127 | pj_turn_srv *srv; |
| 128 | pj_turn_listener *listener; |
| 129 | pj_status_t status; |
| 130 | |
| 131 | status = pj_init(); |
| 132 | if (status != PJ_SUCCESS) |
| 133 | return err("pj_init() error", status); |
| 134 | |
| 135 | pjlib_util_init(); |
| 136 | pjnath_init(); |
| 137 | |
| 138 | pj_caching_pool_init(&g_cp, NULL, 0); |
| 139 | |
| 140 | pj_turn_auth_init(REALM); |
| 141 | |
| 142 | status = pj_turn_srv_create(&g_cp.factory, &srv); |
| 143 | if (status != PJ_SUCCESS) |
| 144 | return err("Error creating server", status); |
| 145 | |
| 146 | status = pj_turn_listener_create_udp(srv, pj_AF_INET(), NULL, |
| 147 | TURN_PORT, 1, 0, &listener); |
| 148 | if (status != PJ_SUCCESS) |
| 149 | return err("Error creating UDP listener", status); |
| 150 | |
| 151 | #if PJ_HAS_TCP |
| 152 | status = pj_turn_listener_create_tcp(srv, pj_AF_INET(), NULL, |
| 153 | TURN_PORT, 1, 0, &listener); |
| 154 | if (status != PJ_SUCCESS) |
| 155 | return err("Error creating listener", status); |
| 156 | #endif |
| 157 | |
| 158 | status = pj_turn_srv_add_listener(srv, listener); |
| 159 | if (status != PJ_SUCCESS) |
| 160 | return err("Error adding listener", status); |
| 161 | |
| 162 | puts("Server is running"); |
| 163 | |
| 164 | pj_log_set_level(LOG_LEVEL); |
| 165 | |
| 166 | console_main(srv); |
| 167 | |
| 168 | pj_turn_srv_destroy(srv); |
| 169 | pj_caching_pool_destroy(&g_cp); |
| 170 | pj_shutdown(); |
| 171 | |
| 172 | return 0; |
| 173 | } |
| 174 | |