Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 1 | /* $Id$ */ |
| 2 | /* |
| 3 | * Copyright (C) 2003-2005 Benny Prijono <benny@prijono.org> |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 18 | */ |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 19 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 20 | #include "server.h" |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 21 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 22 | #define THIS_FILE "server.c" |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 23 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 24 | struct pj_stun_server |
Benny Prijono | c5ee091 | 2007-03-01 00:08:27 +0000 | [diff] [blame] | 25 | { |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 26 | pj_stun_server_info si; |
Benny Prijono | c5ee091 | 2007-03-01 00:08:27 +0000 | [diff] [blame] | 27 | |
Benny Prijono | c5ee091 | 2007-03-01 00:08:27 +0000 | [diff] [blame] | 28 | pj_pool_t *pool; |
Benny Prijono | c5ee091 | 2007-03-01 00:08:27 +0000 | [diff] [blame] | 29 | |
| 30 | pj_bool_t thread_quit_flag; |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 31 | pj_thread_t **threads; |
Benny Prijono | e631558 | 2007-03-08 18:58:04 +0000 | [diff] [blame] | 32 | |
| 33 | unsigned usage_cnt; |
| 34 | pj_stun_usage *usage[32]; |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 35 | }; |
Benny Prijono | c5ee091 | 2007-03-01 00:08:27 +0000 | [diff] [blame] | 36 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 37 | PJ_DEF(pj_status_t) pj_stun_perror( const char *sender, |
| 38 | const char *title, |
| 39 | pj_status_t status) |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 40 | { |
| 41 | char errmsg[PJ_ERR_MSG_SIZE]; |
| 42 | pj_strerror(status, errmsg, sizeof(errmsg)); |
| 43 | |
| 44 | PJ_LOG(3,(sender, "%s: %s", title, errmsg)); |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 45 | return status; |
| 46 | } |
| 47 | |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 48 | static int worker_thread(void *p) |
| 49 | { |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 50 | pj_stun_server *srv = (pj_stun_server*)p; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 51 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 52 | while (!srv->thread_quit_flag) { |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 53 | pj_time_val timeout = { 0, 50 }; |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 54 | pj_timer_heap_poll(srv->si.timer_heap, NULL); |
| 55 | pj_ioqueue_poll(srv->si.ioqueue, &timeout); |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | return 0; |
| 59 | } |
| 60 | |
| 61 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 62 | PJ_DEF(pj_status_t) pj_stun_server_create(pj_pool_factory *pf, |
| 63 | unsigned thread_cnt, |
| 64 | pj_stun_server **p_srv) |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 65 | { |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 66 | pj_pool_t *pool; |
| 67 | pj_stun_server *srv; |
| 68 | unsigned i; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 69 | pj_status_t status; |
| 70 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 71 | pool = pj_pool_create(pf, "server%p", 4000, 4000, NULL); |
| 72 | |
| 73 | srv = PJ_POOL_ZALLOC_T(pool, pj_stun_server); |
| 74 | srv->pool = pool; |
| 75 | srv->si.pf = pf; |
| 76 | |
| 77 | status = pj_ioqueue_create(srv->pool, PJ_IOQUEUE_MAX_HANDLES, |
| 78 | &srv->si.ioqueue); |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 79 | if (status != PJ_SUCCESS) |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 80 | goto on_error; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 81 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 82 | status = pj_timer_heap_create(srv->pool, 1024, &srv->si.timer_heap); |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 83 | if (status != PJ_SUCCESS) |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 84 | goto on_error; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 85 | |
Benny Prijono | 48a4927 | 2007-03-21 09:31:01 +0000 | [diff] [blame] | 86 | pj_stun_config_init(&srv->si.stun_cfg, srv->si.pf, 0, srv->si.ioqueue, |
| 87 | srv->si.timer_heap); |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 88 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 89 | srv->si.thread_cnt = thread_cnt; |
| 90 | srv->threads = pj_pool_calloc(pool, thread_cnt, sizeof(pj_thread_t*)); |
| 91 | for (i=0; i<thread_cnt; ++i) { |
| 92 | status = pj_thread_create(pool, "worker%p", &worker_thread, |
| 93 | srv, 0, 0, &srv->threads[i]); |
| 94 | if (status != PJ_SUCCESS) |
| 95 | goto on_error; |
| 96 | } |
Benny Prijono | c5ee091 | 2007-03-01 00:08:27 +0000 | [diff] [blame] | 97 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 98 | *p_srv = srv; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 99 | return PJ_SUCCESS; |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 100 | |
| 101 | on_error: |
| 102 | pj_stun_server_destroy(srv); |
| 103 | return status; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 107 | PJ_DEF(pj_stun_server_info*) pj_stun_server_get_info(pj_stun_server *srv) |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 108 | { |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 109 | return &srv->si; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | |
Benny Prijono | e631558 | 2007-03-08 18:58:04 +0000 | [diff] [blame] | 113 | pj_status_t pj_stun_server_register_usage(pj_stun_server *srv, |
| 114 | pj_stun_usage *usage) |
| 115 | { |
| 116 | unsigned i; |
| 117 | |
| 118 | for (i=0; i<PJ_ARRAY_SIZE(srv->usage); ++i) { |
| 119 | if (srv->usage[i] == usage) |
| 120 | return PJ_SUCCESS; |
| 121 | } |
| 122 | |
| 123 | for (i=0; i<PJ_ARRAY_SIZE(srv->usage); ++i) { |
| 124 | if (srv->usage[i] == NULL) |
| 125 | break; |
| 126 | } |
| 127 | |
| 128 | if (i == PJ_ARRAY_SIZE(srv->usage)) |
| 129 | return PJ_ETOOMANY; |
| 130 | |
| 131 | srv->usage[i] = usage; |
| 132 | ++srv->usage_cnt; |
| 133 | |
| 134 | return PJ_SUCCESS; |
| 135 | } |
| 136 | |
| 137 | pj_status_t pj_stun_server_unregister_usage(pj_stun_server *srv, |
| 138 | pj_stun_usage *usage) |
| 139 | { |
| 140 | unsigned i; |
| 141 | |
| 142 | for (i=0; i<PJ_ARRAY_SIZE(srv->usage); ++i) { |
| 143 | if (srv->usage[i] == usage) |
| 144 | break; |
| 145 | } |
| 146 | |
| 147 | if (i != PJ_ARRAY_SIZE(srv->usage)) { |
| 148 | srv->usage[i] = NULL; |
| 149 | --srv->usage_cnt; |
| 150 | return PJ_SUCCESS; |
| 151 | } |
| 152 | |
| 153 | return PJ_ENOTFOUND; |
| 154 | } |
| 155 | |
| 156 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 157 | PJ_DEF(pj_status_t) pj_stun_server_destroy(pj_stun_server *srv) |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 158 | { |
| 159 | unsigned i; |
| 160 | |
Benny Prijono | e631558 | 2007-03-08 18:58:04 +0000 | [diff] [blame] | 161 | for (i=0; i<PJ_ARRAY_SIZE(srv->usage); ++i) { |
| 162 | if (!srv->usage[i]) |
| 163 | continue; |
| 164 | |
| 165 | pj_stun_usage_destroy(srv->usage[i]); |
| 166 | pj_stun_server_unregister_usage(srv, srv->usage[i]); |
| 167 | } |
| 168 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 169 | srv->thread_quit_flag = PJ_TRUE; |
| 170 | for (i=0; i<srv->si.thread_cnt; ++i) { |
| 171 | pj_thread_join(srv->threads[i]); |
| 172 | srv->threads[i] = NULL; |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 173 | } |
| 174 | |
Benny Prijono | 7cd1622 | 2007-03-05 00:58:24 +0000 | [diff] [blame] | 175 | pj_timer_heap_destroy(srv->si.timer_heap); |
| 176 | pj_ioqueue_destroy(srv->si.ioqueue); |
| 177 | pj_pool_release(srv->pool); |
Benny Prijono | 14c2b86 | 2007-02-21 00:40:05 +0000 | [diff] [blame] | 178 | |
| 179 | return PJ_SUCCESS; |
| 180 | } |
| 181 | |
| 182 | |