blob: d48a34cdc06b607cbdca20d6ae581411023e4e02 [file] [log] [blame]
Benny Prijonod1e862f2008-02-21 15:54:27 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijonod1e862f2008-02-21 15:54:27 +00005 *
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 */
Benny Prijono708725a2008-03-09 12:55:00 +000020#ifndef __PJ_TURN_SRV_TURN_H__
21#define __PJ_TURN_SRV_TURN_H__
Benny Prijonod1e862f2008-02-21 15:54:27 +000022
23#include <pjlib.h>
24#include <pjnath.h>
25
Benny Prijono879ad1a2008-04-09 09:38:12 +000026typedef struct pj_turn_relay_res pj_turn_relay_res;
Benny Prijono708725a2008-03-09 12:55:00 +000027typedef struct pj_turn_listener pj_turn_listener;
Benny Prijono879ad1a2008-04-09 09:38:12 +000028typedef struct pj_turn_transport pj_turn_transport;
29typedef struct pj_turn_permission pj_turn_permission;
30typedef struct pj_turn_allocation pj_turn_allocation;
Benny Prijono708725a2008-03-09 12:55:00 +000031typedef struct pj_turn_srv pj_turn_srv;
32typedef struct pj_turn_pkt pj_turn_pkt;
Benny Prijonod1e862f2008-02-21 15:54:27 +000033
34
Benny Prijono708725a2008-03-09 12:55:00 +000035#define PJ_TURN_INVALID_LIS_ID ((unsigned)-1)
Benny Prijonod1e862f2008-02-21 15:54:27 +000036
Benny Prijonob05aafc2008-03-08 00:54:04 +000037/**
38 * Get transport type name string.
39 */
Benny Prijono708725a2008-03-09 12:55:00 +000040PJ_DECL(const char*) pj_turn_tp_type_name(int tp_type);
Benny Prijonod1e862f2008-02-21 15:54:27 +000041
42/**
43 * This structure describes TURN relay resource. An allocation allocates
44 * one relay resource, and optionally it may reserve another resource.
45 */
Benny Prijono708725a2008-03-09 12:55:00 +000046struct pj_turn_relay_res
Benny Prijonod1e862f2008-02-21 15:54:27 +000047{
48 /** Hash table key */
49 struct {
50 /** Transport type. */
51 int tp_type;
52
53 /** Transport/relay address */
54 pj_sockaddr addr;
Benny Prijonob05aafc2008-03-08 00:54:04 +000055 } hkey;
Benny Prijonod1e862f2008-02-21 15:54:27 +000056
57 /** Allocation who requested or reserved this resource. */
Benny Prijono708725a2008-03-09 12:55:00 +000058 pj_turn_allocation *allocation;
Benny Prijonod1e862f2008-02-21 15:54:27 +000059
Benny Prijonod1e862f2008-02-21 15:54:27 +000060 /** Username used in credential */
61 pj_str_t user;
62
63 /** Realm used in credential. */
64 pj_str_t realm;
65
Benny Prijonob05aafc2008-03-08 00:54:04 +000066 /** Lifetime, in seconds. */
67 unsigned lifetime;
68
69 /** Relay/allocation expiration time */
70 pj_time_val expiry;
71
72 /** Timeout timer entry */
73 pj_timer_entry timer;
74
75 /** Transport. */
76 struct {
77 /** Transport/relay socket */
78 pj_sock_t sock;
79
80 /** Transport/relay ioqueue */
81 pj_ioqueue_key_t *key;
82
83 /** Read operation key. */
84 pj_ioqueue_op_key_t read_key;
85
86 /** The incoming packet buffer */
Benny Prijono708725a2008-03-09 12:55:00 +000087 char rx_pkt[PJ_TURN_MAX_PKT_LEN];
Benny Prijonob05aafc2008-03-08 00:54:04 +000088
89 /** Source address of the packet. */
90 pj_sockaddr src_addr;
91
92 /** Source address length */
93 int src_addr_len;
94
95 /** The outgoing packet buffer. This must be 3wbit aligned. */
Benny Prijono708725a2008-03-09 12:55:00 +000096 char tx_pkt[PJ_TURN_MAX_PKT_LEN+4];
Benny Prijonob05aafc2008-03-08 00:54:04 +000097 } tp;
Benny Prijonod1e862f2008-02-21 15:54:27 +000098};
99
100
101/****************************************************************************/
102/*
103 * TURN Allocation API
104 */
105
106/**
107 * This structure describes key to lookup TURN allocations in the
108 * allocation hash table.
109 */
Benny Prijono708725a2008-03-09 12:55:00 +0000110typedef struct pj_turn_allocation_key
Benny Prijonod1e862f2008-02-21 15:54:27 +0000111{
112 int tp_type; /**< Transport type. */
113 pj_sockaddr clt_addr; /**< Client's address. */
Benny Prijono708725a2008-03-09 12:55:00 +0000114} pj_turn_allocation_key;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000115
116
117/**
Benny Prijono708725a2008-03-09 12:55:00 +0000118 * This structure describes TURN pj_turn_allocation session.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000119 */
Benny Prijono708725a2008-03-09 12:55:00 +0000120struct pj_turn_allocation
Benny Prijonod1e862f2008-02-21 15:54:27 +0000121{
122 /** Hash table key to identify client. */
Benny Prijono708725a2008-03-09 12:55:00 +0000123 pj_turn_allocation_key hkey;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000124
125 /** Pool for this allocation. */
126 pj_pool_t *pool;
127
Benny Prijonob05aafc2008-03-08 00:54:04 +0000128 /** Object name for logging identification */
129 char *obj_name;
130
131 /** Client info (IP address and port) */
132 char info[80];
133
Benny Prijonod1e862f2008-02-21 15:54:27 +0000134 /** Mutex */
135 pj_lock_t *lock;
136
Benny Prijono879ad1a2008-04-09 09:38:12 +0000137 /** Server instance. */
138 pj_turn_srv *server;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000139
Benny Prijono879ad1a2008-04-09 09:38:12 +0000140 /** Transport to send/receive packets to/from client. */
141 pj_turn_transport *transport;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000142
143 /** The relay resource for this allocation. */
Benny Prijono708725a2008-03-09 12:55:00 +0000144 pj_turn_relay_res relay;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000145
146 /** Relay resource reserved by this allocation, if any */
Benny Prijono708725a2008-03-09 12:55:00 +0000147 pj_turn_relay_res *resv;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000148
Benny Prijonob05aafc2008-03-08 00:54:04 +0000149 /** Requested bandwidth */
150 unsigned bandwidth;
151
152 /** STUN session for this client */
153 pj_stun_session *sess;
154
Benny Prijono708725a2008-03-09 12:55:00 +0000155 /** Credential for this STUN session. */
156 pj_stun_auth_cred cred;
157
Benny Prijonob05aafc2008-03-08 00:54:04 +0000158 /** Peer hash table (keyed by peer address) */
159 pj_hash_table_t *peer_table;
160
161 /** Channel hash table (keyed by channel number) */
162 pj_hash_table_t *ch_table;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000163};
164
165
166/**
Benny Prijonob05aafc2008-03-08 00:54:04 +0000167 * This structure describes the hash table key to lookup TURN
168 * permission.
169 */
Benny Prijono708725a2008-03-09 12:55:00 +0000170typedef struct pj_turn_permission_key
Benny Prijonob05aafc2008-03-08 00:54:04 +0000171{
172 /** Peer address. */
173 pj_sockaddr peer_addr;
174
Benny Prijono708725a2008-03-09 12:55:00 +0000175} pj_turn_permission_key;
Benny Prijonob05aafc2008-03-08 00:54:04 +0000176
177
178/**
Benny Prijono708725a2008-03-09 12:55:00 +0000179 * This structure describes TURN pj_turn_permission or channel.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000180 */
Benny Prijono708725a2008-03-09 12:55:00 +0000181struct pj_turn_permission
Benny Prijonod1e862f2008-02-21 15:54:27 +0000182{
183 /** Hash table key */
Benny Prijono708725a2008-03-09 12:55:00 +0000184 pj_turn_permission_key hkey;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000185
Benny Prijonod1e862f2008-02-21 15:54:27 +0000186 /** TURN allocation that owns this permission/channel */
Benny Prijono708725a2008-03-09 12:55:00 +0000187 pj_turn_allocation *allocation;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000188
Benny Prijono708725a2008-03-09 12:55:00 +0000189 /** Optional channel number, or PJ_TURN_INVALID_CHANNEL if channel number
Benny Prijono9e6d60a2008-03-20 16:32:06 +0000190 * is not requested for this permission.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000191 */
192 pj_uint16_t channel;
193
Benny Prijonob05aafc2008-03-08 00:54:04 +0000194 /** Permission expiration time. */
195 pj_time_val expiry;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000196};
197
198/**
Benny Prijonob05aafc2008-03-08 00:54:04 +0000199 * Create new allocation.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000200 */
Benny Prijono879ad1a2008-04-09 09:38:12 +0000201PJ_DECL(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,
202 const pj_sockaddr_t *src_addr,
203 unsigned src_addr_len,
204 const pj_stun_rx_data *rdata,
205 pj_stun_session *srv_sess,
206 pj_turn_allocation **p_alloc);
Benny Prijonob05aafc2008-03-08 00:54:04 +0000207/**
208 * Destroy allocation.
209 */
Benny Prijono708725a2008-03-09 12:55:00 +0000210PJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000211
Benny Prijonob05aafc2008-03-08 00:54:04 +0000212
213/**
214 * Handle incoming packet from client.
215 */
Benny Prijono708725a2008-03-09 12:55:00 +0000216PJ_DECL(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
Benny Prijono879ad1a2008-04-09 09:38:12 +0000217 pj_turn_pkt *pkt);
218
219/**
220 * Handle transport closure.
221 */
222PJ_DECL(void) pj_turn_allocation_on_transport_closed(pj_turn_allocation *alloc,
223 pj_turn_transport *tp);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000224
225/****************************************************************************/
226/*
227 * TURN Listener API
228 */
229
230/**
231 * This structure describes TURN listener socket. A TURN listener socket
232 * listens for incoming connections from clients.
233 */
Benny Prijono708725a2008-03-09 12:55:00 +0000234struct pj_turn_listener
Benny Prijonod1e862f2008-02-21 15:54:27 +0000235{
Benny Prijono708725a2008-03-09 12:55:00 +0000236 /** Object name/identification */
237 char *obj_name;
238
239 /** Slightly longer info about this listener */
240 char info[80];
241
Benny Prijonod1e862f2008-02-21 15:54:27 +0000242 /** TURN server instance. */
Benny Prijono708725a2008-03-09 12:55:00 +0000243 pj_turn_srv *server;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000244
245 /** Listener index in the server */
246 unsigned id;
247
248 /** Pool for this listener. */
249 pj_pool_t *pool;
250
251 /** Transport type. */
252 int tp_type;
253
254 /** Bound address of this listener. */
255 pj_sockaddr addr;
256
257 /** Socket. */
258 pj_sock_t sock;
259
260 /** Flags. */
261 unsigned flags;
262
Benny Prijono879ad1a2008-04-09 09:38:12 +0000263 /** Destroy handler */
264 pj_status_t (*destroy)(pj_turn_listener*);
265};
266
267
268/**
269 * This structure describes TURN transport socket which is used to send and
270 * receive packets towards client.
271 */
272struct pj_turn_transport
273{
274 /** Object name/identification */
275 char *obj_name;
276
277 /** Slightly longer info about this listener */
278 char *info;
279
280 /** Listener instance */
281 pj_turn_listener *listener;
282
Benny Prijonod1e862f2008-02-21 15:54:27 +0000283 /** Sendto handler */
Benny Prijono879ad1a2008-04-09 09:38:12 +0000284 pj_status_t (*sendto)(pj_turn_transport *tp,
Benny Prijonod1e862f2008-02-21 15:54:27 +0000285 const void *packet,
286 pj_size_t size,
287 unsigned flag,
288 const pj_sockaddr_t *addr,
289 int addr_len);
290
Benny Prijono879ad1a2008-04-09 09:38:12 +0000291 /** Addref handler */
292 void (*add_ref)(pj_turn_transport *tp,
293 pj_turn_allocation *alloc);
294
295 /** Decref handler */
296 void (*dec_ref)(pj_turn_transport *tp,
297 pj_turn_allocation *alloc);
298
Benny Prijonod1e862f2008-02-21 15:54:27 +0000299};
300
301
302/**
303 * An incoming packet.
304 */
Benny Prijono708725a2008-03-09 12:55:00 +0000305struct pj_turn_pkt
Benny Prijonod1e862f2008-02-21 15:54:27 +0000306{
307 /** Pool for this packet */
308 pj_pool_t *pool;
309
Benny Prijono879ad1a2008-04-09 09:38:12 +0000310 /** Transport where the packet was received. */
311 pj_turn_transport *transport;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000312
Benny Prijonob05aafc2008-03-08 00:54:04 +0000313 /** Packet buffer (must be 32bit aligned). */
Benny Prijono708725a2008-03-09 12:55:00 +0000314 pj_uint8_t pkt[PJ_TURN_MAX_PKT_LEN];
Benny Prijonod1e862f2008-02-21 15:54:27 +0000315
316 /** Size of the packet */
317 pj_size_t len;
318
319 /** Arrival time. */
320 pj_time_val rx_time;
321
322 /** Source transport type and source address. */
Benny Prijono708725a2008-03-09 12:55:00 +0000323 pj_turn_allocation_key src;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000324
325 /** Source address length. */
326 int src_addr_len;
327};
328
329
330/**
Benny Prijono879ad1a2008-04-09 09:38:12 +0000331 * Create a UDP listener on the specified port.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000332 */
Benny Prijono708725a2008-03-09 12:55:00 +0000333PJ_DECL(pj_status_t) pj_turn_listener_create_udp(pj_turn_srv *srv,
Benny Prijono879ad1a2008-04-09 09:38:12 +0000334 int af,
335 const pj_str_t *bound_addr,
336 unsigned port,
337 unsigned concurrency_cnt,
338 unsigned flags,
339 pj_turn_listener **p_lis);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000340
341/**
Benny Prijono879ad1a2008-04-09 09:38:12 +0000342 * Create a TCP listener on the specified port.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000343 */
Benny Prijono879ad1a2008-04-09 09:38:12 +0000344PJ_DECL(pj_status_t) pj_turn_listener_create_tcp(pj_turn_srv *srv,
345 int af,
346 const pj_str_t *bound_addr,
347 unsigned port,
348 unsigned concurrency_cnt,
349 unsigned flags,
350 pj_turn_listener **p_lis);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000351
352/**
353 * Destroy listener.
354 */
Benny Prijono708725a2008-03-09 12:55:00 +0000355PJ_DECL(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000356
357
Benny Prijono879ad1a2008-04-09 09:38:12 +0000358/**
359 * Add a reference to a transport.
360 */
361PJ_DECL(void) pj_turn_transport_add_ref(pj_turn_transport *transport,
362 pj_turn_allocation *alloc);
363
364
365/**
366 * Decrement transport reference counter.
367 */
368PJ_DECL(void) pj_turn_transport_dec_ref(pj_turn_transport *transport,
369 pj_turn_allocation *alloc);
370
371
372
Benny Prijonod1e862f2008-02-21 15:54:27 +0000373/****************************************************************************/
374/*
375 * TURN Server API
376 */
377/**
Benny Prijono708725a2008-03-09 12:55:00 +0000378 * This structure describes TURN pj_turn_srv instance.
Benny Prijonod1e862f2008-02-21 15:54:27 +0000379 */
Benny Prijono708725a2008-03-09 12:55:00 +0000380struct pj_turn_srv
Benny Prijonod1e862f2008-02-21 15:54:27 +0000381{
Benny Prijono708725a2008-03-09 12:55:00 +0000382 /** Object name */
383 char *obj_name;
384
Benny Prijonod1e862f2008-02-21 15:54:27 +0000385 /** Core settings */
386 struct {
Benny Prijonod1e862f2008-02-21 15:54:27 +0000387 /** Pool factory */
388 pj_pool_factory *pf;
389
390 /** Pool for this server instance. */
391 pj_pool_t *pool;
392
393 /** Global Ioqueue */
394 pj_ioqueue_t *ioqueue;
395
396 /** Mutex */
397 pj_lock_t *lock;
398
399 /** Global timer heap instance. */
400 pj_timer_heap_t *timer_heap;
401
402 /** Number of listeners */
403 unsigned lis_cnt;
404
405 /** Array of listeners. */
Benny Prijono708725a2008-03-09 12:55:00 +0000406 pj_turn_listener **listener;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000407
Benny Prijono879ad1a2008-04-09 09:38:12 +0000408 /** STUN session to handle initial Allocate request. */
409 pj_stun_session *stun_sess;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000410
411 /** Number of worker threads. */
412 unsigned thread_cnt;
413
414 /** Array of worker threads. */
415 pj_thread_t **thread;
416
Benny Prijono708725a2008-03-09 12:55:00 +0000417 /** Thread quit signal */
418 pj_bool_t quit;
419
Benny Prijonod1e862f2008-02-21 15:54:27 +0000420 /** STUN config. */
421 pj_stun_config stun_cfg;
422
Benny Prijono708725a2008-03-09 12:55:00 +0000423 /** STUN auth credential. */
424 pj_stun_auth_cred cred;
425
426 /** Thread local ID for storing credential */
427 long tls_key, tls_data;
Benny Prijonod1e862f2008-02-21 15:54:27 +0000428
429 } core;
430
431
432 /** Hash tables */
433 struct {
434 /** Allocations hash table, indexed by transport type and
435 * client address.
436 */
437 pj_hash_table_t *alloc;
438
439 /** Relay resource hash table, indexed by transport type and
440 * relay address.
441 */
442 pj_hash_table_t *res;
443
Benny Prijonod1e862f2008-02-21 15:54:27 +0000444 } tables;
445
446 /** Ports settings */
447 struct {
448 /** Minimum UDP port number. */
449 pj_uint16_t min_udp;
450
451 /** Maximum UDP port number. */
452 pj_uint16_t max_udp;
453
454 /** Next UDP port number. */
455 pj_uint16_t next_udp;
456
457
458 /** Minimum TCP port number. */
459 pj_uint16_t min_tcp;
460
461 /** Maximum TCP port number. */
462 pj_uint16_t max_tcp;
463
464 /** Next TCP port number. */
465 pj_uint16_t next_tcp;
466
467 } ports;
468};
469
470
471/**
472 * Create server.
473 */
Benny Prijono708725a2008-03-09 12:55:00 +0000474PJ_DECL(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
475 pj_turn_srv **p_srv);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000476
477/**
478 * Destroy server.
479 */
Benny Prijono708725a2008-03-09 12:55:00 +0000480PJ_DECL(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000481
482/**
483 * Add listener.
484 */
Benny Prijono708725a2008-03-09 12:55:00 +0000485PJ_DECL(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv,
486 pj_turn_listener *lis);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000487
488/**
Benny Prijonob05aafc2008-03-08 00:54:04 +0000489 * Register an allocation.
490 */
Benny Prijono708725a2008-03-09 12:55:00 +0000491PJ_DECL(pj_status_t) pj_turn_srv_register_allocation(pj_turn_srv *srv,
492 pj_turn_allocation *alloc);
Benny Prijonob05aafc2008-03-08 00:54:04 +0000493
494/**
495 * Unregister an allocation.
496 */
Benny Prijono708725a2008-03-09 12:55:00 +0000497PJ_DECL(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv,
498 pj_turn_allocation *alloc);
Benny Prijonob05aafc2008-03-08 00:54:04 +0000499
500/**
Benny Prijonod1e862f2008-02-21 15:54:27 +0000501 * This callback is called by UDP listener on incoming packet.
502 */
Benny Prijono708725a2008-03-09 12:55:00 +0000503PJ_DECL(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
Benny Prijono879ad1a2008-04-09 09:38:12 +0000504 pj_turn_pkt *pkt);
Benny Prijonod1e862f2008-02-21 15:54:27 +0000505
506
Benny Prijono708725a2008-03-09 12:55:00 +0000507#endif /* __PJ_TURN_SRV_TURN_H__ */
Benny Prijonod1e862f2008-02-21 15:54:27 +0000508