blob: ae9cc59088f6c013ceef1dde3f6b570a6dfc0c78 [file] [log] [blame]
Benny Prijonod1e862f2008-02-21 15:54:27 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2007 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 Prijono708725a2008-03-09 12:55:00 +000019#ifndef __PJ_TURN_SRV_TURN_H__
20#define __PJ_TURN_SRV_TURN_H__
Benny Prijonod1e862f2008-02-21 15:54:27 +000021
22#include <pjlib.h>
23#include <pjnath.h>
24
Benny Prijono879ad1a2008-04-09 09:38:12 +000025typedef struct pj_turn_relay_res pj_turn_relay_res;
Benny Prijono708725a2008-03-09 12:55:00 +000026typedef struct pj_turn_listener pj_turn_listener;
Benny Prijono879ad1a2008-04-09 09:38:12 +000027typedef struct pj_turn_transport pj_turn_transport;
28typedef struct pj_turn_permission pj_turn_permission;
29typedef struct pj_turn_allocation pj_turn_allocation;
Benny Prijono708725a2008-03-09 12:55:00 +000030typedef struct pj_turn_srv pj_turn_srv;
31typedef struct pj_turn_pkt pj_turn_pkt;
Benny Prijonod1e862f2008-02-21 15:54:27 +000032
33
Benny Prijono708725a2008-03-09 12:55:00 +000034#define PJ_TURN_INVALID_LIS_ID ((unsigned)-1)
Benny Prijonod1e862f2008-02-21 15:54:27 +000035
Benny Prijonob05aafc2008-03-08 00:54:04 +000036/**
37 * Get transport type name string.
38 */
Benny Prijono708725a2008-03-09 12:55:00 +000039PJ_DECL(const char*) pj_turn_tp_type_name(int tp_type);
Benny Prijonod1e862f2008-02-21 15:54:27 +000040
41/**
42 * This structure describes TURN relay resource. An allocation allocates
43 * one relay resource, and optionally it may reserve another resource.
44 */
Benny Prijono708725a2008-03-09 12:55:00 +000045struct pj_turn_relay_res
Benny Prijonod1e862f2008-02-21 15:54:27 +000046{
47 /** Hash table key */
48 struct {
49 /** Transport type. */
50 int tp_type;
51
52 /** Transport/relay address */
53 pj_sockaddr addr;
Benny Prijonob05aafc2008-03-08 00:54:04 +000054 } hkey;
Benny Prijonod1e862f2008-02-21 15:54:27 +000055
56 /** Allocation who requested or reserved this resource. */
Benny Prijono708725a2008-03-09 12:55:00 +000057 pj_turn_allocation *allocation;
Benny Prijonod1e862f2008-02-21 15:54:27 +000058
Benny Prijonod1e862f2008-02-21 15:54:27 +000059 /** Username used in credential */
60 pj_str_t user;
61
62 /** Realm used in credential. */
63 pj_str_t realm;
64
Benny Prijonob05aafc2008-03-08 00:54:04 +000065 /** Lifetime, in seconds. */
66 unsigned lifetime;
67
68 /** Relay/allocation expiration time */
69 pj_time_val expiry;
70
71 /** Timeout timer entry */
72 pj_timer_entry timer;
73
74 /** Transport. */
75 struct {
76 /** Transport/relay socket */
77 pj_sock_t sock;
78
79 /** Transport/relay ioqueue */
80 pj_ioqueue_key_t *key;
81
82 /** Read operation key. */
83 pj_ioqueue_op_key_t read_key;
84
85 /** The incoming packet buffer */
Benny Prijono708725a2008-03-09 12:55:00 +000086 char rx_pkt[PJ_TURN_MAX_PKT_LEN];
Benny Prijonob05aafc2008-03-08 00:54:04 +000087
88 /** Source address of the packet. */
89 pj_sockaddr src_addr;
90
91 /** Source address length */
92 int src_addr_len;
93
94 /** The outgoing packet buffer. This must be 3wbit aligned. */
Benny Prijono708725a2008-03-09 12:55:00 +000095 char tx_pkt[PJ_TURN_MAX_PKT_LEN+4];
Benny Prijonob05aafc2008-03-08 00:54:04 +000096 } tp;
Benny Prijonod1e862f2008-02-21 15:54:27 +000097};
98
99
100/****************************************************************************/
101/*
102 * TURN Allocation API
103 */
104
105/**
106 * This structure describes key to lookup TURN allocations in the
107 * allocation hash table.
108 */
Benny Prijono708725a2008-03-09 12:55:00 +0000109typedef struct pj_turn_allocation_key
Benny Prijonod1e862f2008-02-21 15:54:27 +0000110{
111 int tp_type; /**< Transport type. */
112 pj_sockaddr clt_addr; /**< Client's address. */
Benny Prijono708725a2008-03-09 12:55:00 +0000113} pj_turn_allocation_key;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000114
115
116/**
Benny Prijono708725a2008-03-09 12:55:00 +0000117 * This structure describes TURN pj_turn_allocation session.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000118 */
Benny Prijono708725a2008-03-09 12:55:00 +0000119struct pj_turn_allocation
Benny Prijonod1e862f2008-02-21 15:54:27 +0000120{
121 /** Hash table key to identify client. */
Benny Prijono708725a2008-03-09 12:55:00 +0000122 pj_turn_allocation_key hkey;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000123
124 /** Pool for this allocation. */
125 pj_pool_t *pool;
126
Benny Prijonob05aafc2008-03-08 00:54:04 +0000127 /** Object name for logging identification */
128 char *obj_name;
129
130 /** Client info (IP address and port) */
131 char info[80];
132
Benny Prijonod1e862f2008-02-21 15:54:27 +0000133 /** Mutex */
134 pj_lock_t *lock;
135
Benny Prijono879ad1a2008-04-09 09:38:12 +0000136 /** Server instance. */
137 pj_turn_srv *server;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000138
Benny Prijono879ad1a2008-04-09 09:38:12 +0000139 /** Transport to send/receive packets to/from client. */
140 pj_turn_transport *transport;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000141
142 /** The relay resource for this allocation. */
Benny Prijono708725a2008-03-09 12:55:00 +0000143 pj_turn_relay_res relay;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000144
145 /** Relay resource reserved by this allocation, if any */
Benny Prijono708725a2008-03-09 12:55:00 +0000146 pj_turn_relay_res *resv;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000147
Benny Prijonob05aafc2008-03-08 00:54:04 +0000148 /** Requested bandwidth */
149 unsigned bandwidth;
150
151 /** STUN session for this client */
152 pj_stun_session *sess;
153
Benny Prijono708725a2008-03-09 12:55:00 +0000154 /** Credential for this STUN session. */
155 pj_stun_auth_cred cred;
156
Benny Prijonob05aafc2008-03-08 00:54:04 +0000157 /** Peer hash table (keyed by peer address) */
158 pj_hash_table_t *peer_table;
159
160 /** Channel hash table (keyed by channel number) */
161 pj_hash_table_t *ch_table;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000162};
163
164
165/**
Benny Prijonob05aafc2008-03-08 00:54:04 +0000166 * This structure describes the hash table key to lookup TURN
167 * permission.
168 */
Benny Prijono708725a2008-03-09 12:55:00 +0000169typedef struct pj_turn_permission_key
Benny Prijonob05aafc2008-03-08 00:54:04 +0000170{
171 /** Peer address. */
172 pj_sockaddr peer_addr;
173
Benny Prijono708725a2008-03-09 12:55:00 +0000174} pj_turn_permission_key;
Benny Prijonob05aafc2008-03-08 00:54:04 +0000175
176
177/**
Benny Prijono708725a2008-03-09 12:55:00 +0000178 * This structure describes TURN pj_turn_permission or channel.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000179 */
Benny Prijono708725a2008-03-09 12:55:00 +0000180struct pj_turn_permission
Benny Prijonod1e862f2008-02-21 15:54:27 +0000181{
182 /** Hash table key */
Benny Prijono708725a2008-03-09 12:55:00 +0000183 pj_turn_permission_key hkey;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000184
Benny Prijonod1e862f2008-02-21 15:54:27 +0000185 /** TURN allocation that owns this permission/channel */
Benny Prijono708725a2008-03-09 12:55:00 +0000186 pj_turn_allocation *allocation;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000187
Benny Prijono708725a2008-03-09 12:55:00 +0000188 /** Optional channel number, or PJ_TURN_INVALID_CHANNEL if channel number
Benny Prijono9e6d60a2008-03-20 16:32:06 +0000189 * is not requested for this permission.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000190 */
191 pj_uint16_t channel;
192
Benny Prijonob05aafc2008-03-08 00:54:04 +0000193 /** Permission expiration time. */
194 pj_time_val expiry;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000195};
196
197/**
Benny Prijonob05aafc2008-03-08 00:54:04 +0000198 * Create new allocation.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000199 */
Benny Prijono879ad1a2008-04-09 09:38:12 +0000200PJ_DECL(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,
201 const pj_sockaddr_t *src_addr,
202 unsigned src_addr_len,
203 const pj_stun_rx_data *rdata,
204 pj_stun_session *srv_sess,
205 pj_turn_allocation **p_alloc);
Benny Prijonob05aafc2008-03-08 00:54:04 +0000206/**
207 * Destroy allocation.
208 */
Benny Prijono708725a2008-03-09 12:55:00 +0000209PJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000210
Benny Prijonob05aafc2008-03-08 00:54:04 +0000211
212/**
213 * Handle incoming packet from client.
214 */
Benny Prijono708725a2008-03-09 12:55:00 +0000215PJ_DECL(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
Benny Prijono879ad1a2008-04-09 09:38:12 +0000216 pj_turn_pkt *pkt);
217
218/**
219 * Handle transport closure.
220 */
221PJ_DECL(void) pj_turn_allocation_on_transport_closed(pj_turn_allocation *alloc,
222 pj_turn_transport *tp);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000223
224/****************************************************************************/
225/*
226 * TURN Listener API
227 */
228
229/**
230 * This structure describes TURN listener socket. A TURN listener socket
231 * listens for incoming connections from clients.
232 */
Benny Prijono708725a2008-03-09 12:55:00 +0000233struct pj_turn_listener
Benny Prijonod1e862f2008-02-21 15:54:27 +0000234{
Benny Prijono708725a2008-03-09 12:55:00 +0000235 /** Object name/identification */
236 char *obj_name;
237
238 /** Slightly longer info about this listener */
239 char info[80];
240
Benny Prijonod1e862f2008-02-21 15:54:27 +0000241 /** TURN server instance. */
Benny Prijono708725a2008-03-09 12:55:00 +0000242 pj_turn_srv *server;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000243
244 /** Listener index in the server */
245 unsigned id;
246
247 /** Pool for this listener. */
248 pj_pool_t *pool;
249
250 /** Transport type. */
251 int tp_type;
252
253 /** Bound address of this listener. */
254 pj_sockaddr addr;
255
256 /** Socket. */
257 pj_sock_t sock;
258
259 /** Flags. */
260 unsigned flags;
261
Benny Prijono879ad1a2008-04-09 09:38:12 +0000262 /** Destroy handler */
263 pj_status_t (*destroy)(pj_turn_listener*);
264};
265
266
267/**
268 * This structure describes TURN transport socket which is used to send and
269 * receive packets towards client.
270 */
271struct pj_turn_transport
272{
273 /** Object name/identification */
274 char *obj_name;
275
276 /** Slightly longer info about this listener */
277 char *info;
278
279 /** Listener instance */
280 pj_turn_listener *listener;
281
Benny Prijonod1e862f2008-02-21 15:54:27 +0000282 /** Sendto handler */
Benny Prijono879ad1a2008-04-09 09:38:12 +0000283 pj_status_t (*sendto)(pj_turn_transport *tp,
Benny Prijonod1e862f2008-02-21 15:54:27 +0000284 const void *packet,
285 pj_size_t size,
286 unsigned flag,
287 const pj_sockaddr_t *addr,
288 int addr_len);
289
Benny Prijono879ad1a2008-04-09 09:38:12 +0000290 /** Addref handler */
291 void (*add_ref)(pj_turn_transport *tp,
292 pj_turn_allocation *alloc);
293
294 /** Decref handler */
295 void (*dec_ref)(pj_turn_transport *tp,
296 pj_turn_allocation *alloc);
297
Benny Prijonod1e862f2008-02-21 15:54:27 +0000298};
299
300
301/**
302 * An incoming packet.
303 */
Benny Prijono708725a2008-03-09 12:55:00 +0000304struct pj_turn_pkt
Benny Prijonod1e862f2008-02-21 15:54:27 +0000305{
306 /** Pool for this packet */
307 pj_pool_t *pool;
308
Benny Prijono879ad1a2008-04-09 09:38:12 +0000309 /** Transport where the packet was received. */
310 pj_turn_transport *transport;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000311
Benny Prijonob05aafc2008-03-08 00:54:04 +0000312 /** Packet buffer (must be 32bit aligned). */
Benny Prijono708725a2008-03-09 12:55:00 +0000313 pj_uint8_t pkt[PJ_TURN_MAX_PKT_LEN];
Benny Prijonod1e862f2008-02-21 15:54:27 +0000314
315 /** Size of the packet */
316 pj_size_t len;
317
318 /** Arrival time. */
319 pj_time_val rx_time;
320
321 /** Source transport type and source address. */
Benny Prijono708725a2008-03-09 12:55:00 +0000322 pj_turn_allocation_key src;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000323
324 /** Source address length. */
325 int src_addr_len;
326};
327
328
329/**
Benny Prijono879ad1a2008-04-09 09:38:12 +0000330 * Create a UDP listener on the specified port.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000331 */
Benny Prijono708725a2008-03-09 12:55:00 +0000332PJ_DECL(pj_status_t) pj_turn_listener_create_udp(pj_turn_srv *srv,
Benny Prijono879ad1a2008-04-09 09:38:12 +0000333 int af,
334 const pj_str_t *bound_addr,
335 unsigned port,
336 unsigned concurrency_cnt,
337 unsigned flags,
338 pj_turn_listener **p_lis);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000339
340/**
Benny Prijono879ad1a2008-04-09 09:38:12 +0000341 * Create a TCP listener on the specified port.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000342 */
Benny Prijono879ad1a2008-04-09 09:38:12 +0000343PJ_DECL(pj_status_t) pj_turn_listener_create_tcp(pj_turn_srv *srv,
344 int af,
345 const pj_str_t *bound_addr,
346 unsigned port,
347 unsigned concurrency_cnt,
348 unsigned flags,
349 pj_turn_listener **p_lis);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000350
351/**
352 * Destroy listener.
353 */
Benny Prijono708725a2008-03-09 12:55:00 +0000354PJ_DECL(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000355
356
Benny Prijono879ad1a2008-04-09 09:38:12 +0000357/**
358 * Add a reference to a transport.
359 */
360PJ_DECL(void) pj_turn_transport_add_ref(pj_turn_transport *transport,
361 pj_turn_allocation *alloc);
362
363
364/**
365 * Decrement transport reference counter.
366 */
367PJ_DECL(void) pj_turn_transport_dec_ref(pj_turn_transport *transport,
368 pj_turn_allocation *alloc);
369
370
371
Benny Prijonod1e862f2008-02-21 15:54:27 +0000372/****************************************************************************/
373/*
374 * TURN Server API
375 */
376/**
Benny Prijono708725a2008-03-09 12:55:00 +0000377 * This structure describes TURN pj_turn_srv instance.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000378 */
Benny Prijono708725a2008-03-09 12:55:00 +0000379struct pj_turn_srv
Benny Prijonod1e862f2008-02-21 15:54:27 +0000380{
Benny Prijono708725a2008-03-09 12:55:00 +0000381 /** Object name */
382 char *obj_name;
383
Benny Prijonod1e862f2008-02-21 15:54:27 +0000384 /** Core settings */
385 struct {
Benny Prijonod1e862f2008-02-21 15:54:27 +0000386 /** Pool factory */
387 pj_pool_factory *pf;
388
389 /** Pool for this server instance. */
390 pj_pool_t *pool;
391
392 /** Global Ioqueue */
393 pj_ioqueue_t *ioqueue;
394
395 /** Mutex */
396 pj_lock_t *lock;
397
398 /** Global timer heap instance. */
399 pj_timer_heap_t *timer_heap;
400
401 /** Number of listeners */
402 unsigned lis_cnt;
403
404 /** Array of listeners. */
Benny Prijono708725a2008-03-09 12:55:00 +0000405 pj_turn_listener **listener;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000406
Benny Prijono879ad1a2008-04-09 09:38:12 +0000407 /** STUN session to handle initial Allocate request. */
408 pj_stun_session *stun_sess;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000409
410 /** Number of worker threads. */
411 unsigned thread_cnt;
412
413 /** Array of worker threads. */
414 pj_thread_t **thread;
415
Benny Prijono708725a2008-03-09 12:55:00 +0000416 /** Thread quit signal */
417 pj_bool_t quit;
418
Benny Prijonod1e862f2008-02-21 15:54:27 +0000419 /** STUN config. */
420 pj_stun_config stun_cfg;
421
Benny Prijono708725a2008-03-09 12:55:00 +0000422 /** STUN auth credential. */
423 pj_stun_auth_cred cred;
424
425 /** Thread local ID for storing credential */
426 long tls_key, tls_data;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000427
428 } core;
429
430
431 /** Hash tables */
432 struct {
433 /** Allocations hash table, indexed by transport type and
434 * client address.
435 */
436 pj_hash_table_t *alloc;
437
438 /** Relay resource hash table, indexed by transport type and
439 * relay address.
440 */
441 pj_hash_table_t *res;
442
Benny Prijonod1e862f2008-02-21 15:54:27 +0000443 } tables;
444
445 /** Ports settings */
446 struct {
447 /** Minimum UDP port number. */
448 pj_uint16_t min_udp;
449
450 /** Maximum UDP port number. */
451 pj_uint16_t max_udp;
452
453 /** Next UDP port number. */
454 pj_uint16_t next_udp;
455
456
457 /** Minimum TCP port number. */
458 pj_uint16_t min_tcp;
459
460 /** Maximum TCP port number. */
461 pj_uint16_t max_tcp;
462
463 /** Next TCP port number. */
464 pj_uint16_t next_tcp;
465
466 } ports;
467};
468
469
470/**
471 * Create server.
472 */
Benny Prijono708725a2008-03-09 12:55:00 +0000473PJ_DECL(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
474 pj_turn_srv **p_srv);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000475
476/**
477 * Destroy server.
478 */
Benny Prijono708725a2008-03-09 12:55:00 +0000479PJ_DECL(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000480
481/**
482 * Add listener.
483 */
Benny Prijono708725a2008-03-09 12:55:00 +0000484PJ_DECL(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv,
485 pj_turn_listener *lis);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000486
487/**
Benny Prijonob05aafc2008-03-08 00:54:04 +0000488 * Register an allocation.
489 */
Benny Prijono708725a2008-03-09 12:55:00 +0000490PJ_DECL(pj_status_t) pj_turn_srv_register_allocation(pj_turn_srv *srv,
491 pj_turn_allocation *alloc);
Benny Prijonob05aafc2008-03-08 00:54:04 +0000492
493/**
494 * Unregister an allocation.
495 */
Benny Prijono708725a2008-03-09 12:55:00 +0000496PJ_DECL(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv,
497 pj_turn_allocation *alloc);
Benny Prijonob05aafc2008-03-08 00:54:04 +0000498
499/**
Benny Prijonod1e862f2008-02-21 15:54:27 +0000500 * This callback is called by UDP listener on incoming packet.
501 */
Benny Prijono708725a2008-03-09 12:55:00 +0000502PJ_DECL(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
Benny Prijono879ad1a2008-04-09 09:38:12 +0000503 pj_turn_pkt *pkt);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000504
505
Benny Prijono708725a2008-03-09 12:55:00 +0000506#endif /* __PJ_TURN_SRV_TURN_H__ */
Benny Prijonod1e862f2008-02-21 15:54:27 +0000507