/* $Id$ */ /* * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) * Copyright (C) 2003-2008 Benny Prijono * * 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 */ #ifndef __PJ_TURN_SRV_TURN_H__ #define __PJ_TURN_SRV_TURN_H__ #include #include typedef struct pj_turn_relay_res pj_turn_relay_res; typedef struct pj_turn_listener pj_turn_listener; typedef struct pj_turn_transport pj_turn_transport; typedef struct pj_turn_permission pj_turn_permission; typedef struct pj_turn_allocation pj_turn_allocation; typedef struct pj_turn_srv pj_turn_srv; typedef struct pj_turn_pkt pj_turn_pkt; #define PJ_TURN_INVALID_LIS_ID ((unsigned)-1) /** * Get transport type name string. */ PJ_DECL(const char*) pj_turn_tp_type_name(int tp_type); /** * This structure describes TURN relay resource. An allocation allocates * one relay resource, and optionally it may reserve another resource. */ struct pj_turn_relay_res { /** Hash table key */ struct { /** Transport type. */ int tp_type; /** Transport/relay address */ pj_sockaddr addr; } hkey; /** Allocation who requested or reserved this resource. */ pj_turn_allocation *allocation; /** Username used in credential */ pj_str_t user; /** Realm used in credential. */ pj_str_t realm; /** Lifetime, in seconds. */ unsigned lifetime; /** Relay/allocation expiration time */ pj_time_val expiry; /** Timeout timer entry */ pj_timer_entry timer; /** Transport. */ struct { /** Transport/relay socket */ pj_sock_t sock; /** Transport/relay ioqueue */ pj_ioqueue_key_t *key; /** Read operation key. */ pj_ioqueue_op_key_t read_key; /** The incoming packet buffer */ char rx_pkt[PJ_TURN_MAX_PKT_LEN]; /** Source address of the packet. */ pj_sockaddr src_addr; /** Source address length */ int src_addr_len; /** The outgoing packet buffer. This must be 3wbit aligned. */ char tx_pkt[PJ_TURN_MAX_PKT_LEN+4]; } tp; }; /****************************************************************************/ /* * TURN Allocation API */ /** * This structure describes key to lookup TURN allocations in the * allocation hash table. */ typedef struct pj_turn_allocation_key { int tp_type; /**< Transport type. */ pj_sockaddr clt_addr; /**< Client's address. */ } pj_turn_allocation_key; /** * This structure describes TURN pj_turn_allocation session. */ struct pj_turn_allocation { /** Hash table key to identify client. */ pj_turn_allocation_key hkey; /** Pool for this allocation. */ pj_pool_t *pool; /** Object name for logging identification */ char *obj_name; /** Client info (IP address and port) */ char info[80]; /** Mutex */ pj_lock_t *lock; /** Server instance. */ pj_turn_srv *server; /** Transport to send/receive packets to/from client. */ pj_turn_transport *transport; /** The relay resource for this allocation. */ pj_turn_relay_res relay; /** Relay resource reserved by this allocation, if any */ pj_turn_relay_res *resv; /** Requested bandwidth */ unsigned bandwidth; /** STUN session for this client */ pj_stun_session *sess; /** Credential for this STUN session. */ pj_stun_auth_cred cred; /** Peer hash table (keyed by peer address) */ pj_hash_table_t *peer_table; /** Channel hash table (keyed by channel number) */ pj_hash_table_t *ch_table; }; /** * This structure describes the hash table key to lookup TURN * permission. */ typedef struct pj_turn_permission_key { /** Peer address. */ pj_sockaddr peer_addr; } pj_turn_permission_key; /** * This structure describes TURN pj_turn_permission or channel. */ struct pj_turn_permission { /** Hash table key */ pj_turn_permission_key hkey; /** TURN allocation that owns this permission/channel */ pj_turn_allocation *allocation; /** Optional channel number, or PJ_TURN_INVALID_CHANNEL if channel number * is not requested for this permission. */ pj_uint16_t channel; /** Permission expiration time. */ pj_time_val expiry; }; /** * Create new allocation. */ PJ_DECL(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport, const pj_sockaddr_t *src_addr, unsigned src_addr_len, const pj_stun_rx_data *rdata, pj_stun_session *srv_sess, pj_turn_allocation **p_alloc); /** * Destroy allocation. */ PJ_DECL(void) pj_turn_allocation_destroy(pj_turn_allocation *alloc); /** * Handle incoming packet from client. */ PJ_DECL(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc, pj_turn_pkt *pkt); /** * Handle transport closure. */ PJ_DECL(void) pj_turn_allocation_on_transport_closed(pj_turn_allocation *alloc, pj_turn_transport *tp); /****************************************************************************/ /* * TURN Listener API */ /** * This structure describes TURN listener socket. A TURN listener socket * listens for incoming connections from clients. */ struct pj_turn_listener { /** Object name/identification */ char *obj_name; /** Slightly longer info about this listener */ char info[80]; /** TURN server instance. */ pj_turn_srv *server; /** Listener index in the server */ unsigned id; /** Pool for this listener. */ pj_pool_t *pool; /** Transport type. */ int tp_type; /** Bound address of this listener. */ pj_sockaddr addr; /** Socket. */ pj_sock_t sock; /** Flags. */ unsigned flags; /** Destroy handler */ pj_status_t (*destroy)(pj_turn_listener*); }; /** * This structure describes TURN transport socket which is used to send and * receive packets towards client. */ struct pj_turn_transport { /** Object name/identification */ char *obj_name; /** Slightly longer info about this listener */ char *info; /** Listener instance */ pj_turn_listener *listener; /** Sendto handler */ pj_status_t (*sendto)(pj_turn_transport *tp, const void *packet, pj_size_t size, unsigned flag, const pj_sockaddr_t *addr, int addr_len); /** Addref handler */ void (*add_ref)(pj_turn_transport *tp, pj_turn_allocation *alloc); /** Decref handler */ void (*dec_ref)(pj_turn_transport *tp, pj_turn_allocation *alloc); }; /** * An incoming packet. */ struct pj_turn_pkt { /** Pool for this packet */ pj_pool_t *pool; /** Transport where the packet was received. */ pj_turn_transport *transport; /** Packet buffer (must be 32bit aligned). */ pj_uint8_t pkt[PJ_TURN_MAX_PKT_LEN]; /** Size of the packet */ pj_size_t len; /** Arrival time. */ pj_time_val rx_time; /** Source transport type and source address. */ pj_turn_allocation_key src; /** Source address length. */ int src_addr_len; }; /** * Create a UDP listener on the specified port. */ PJ_DECL(pj_status_t) pj_turn_listener_create_udp(pj_turn_srv *srv, int af, const pj_str_t *bound_addr, unsigned port, unsigned concurrency_cnt, unsigned flags, pj_turn_listener **p_lis); /** * Create a TCP listener on the specified port. */ PJ_DECL(pj_status_t) pj_turn_listener_create_tcp(pj_turn_srv *srv, int af, const pj_str_t *bound_addr, unsigned port, unsigned concurrency_cnt, unsigned flags, pj_turn_listener **p_lis); /** * Destroy listener. */ PJ_DECL(pj_status_t) pj_turn_listener_destroy(pj_turn_listener *listener); /** * Add a reference to a transport. */ PJ_DECL(void) pj_turn_transport_add_ref(pj_turn_transport *transport, pj_turn_allocation *alloc); /** * Decrement transport reference counter. */ PJ_DECL(void) pj_turn_transport_dec_ref(pj_turn_transport *transport, pj_turn_allocation *alloc); /****************************************************************************/ /* * TURN Server API */ /** * This structure describes TURN pj_turn_srv instance. */ struct pj_turn_srv { /** Object name */ char *obj_name; /** Core settings */ struct { /** Pool factory */ pj_pool_factory *pf; /** Pool for this server instance. */ pj_pool_t *pool; /** Global Ioqueue */ pj_ioqueue_t *ioqueue; /** Mutex */ pj_lock_t *lock; /** Global timer heap instance. */ pj_timer_heap_t *timer_heap; /** Number of listeners */ unsigned lis_cnt; /** Array of listeners. */ pj_turn_listener **listener; /** STUN session to handle initial Allocate request. */ pj_stun_session *stun_sess; /** Number of worker threads. */ unsigned thread_cnt; /** Array of worker threads. */ pj_thread_t **thread; /** Thread quit signal */ pj_bool_t quit; /** STUN config. */ pj_stun_config stun_cfg; /** STUN auth credential. */ pj_stun_auth_cred cred; /** Thread local ID for storing credential */ long tls_key, tls_data; } core; /** Hash tables */ struct { /** Allocations hash table, indexed by transport type and * client address. */ pj_hash_table_t *alloc; /** Relay resource hash table, indexed by transport type and * relay address. */ pj_hash_table_t *res; } tables; /** Ports settings */ struct { /** Minimum UDP port number. */ pj_uint16_t min_udp; /** Maximum UDP port number. */ pj_uint16_t max_udp; /** Next UDP port number. */ pj_uint16_t next_udp; /** Minimum TCP port number. */ pj_uint16_t min_tcp; /** Maximum TCP port number. */ pj_uint16_t max_tcp; /** Next TCP port number. */ pj_uint16_t next_tcp; } ports; }; /** * Create server. */ PJ_DECL(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf, pj_turn_srv **p_srv); /** * Destroy server. */ PJ_DECL(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv); /** * Add listener. */ PJ_DECL(pj_status_t) pj_turn_srv_add_listener(pj_turn_srv *srv, pj_turn_listener *lis); /** * Register an allocation. */ PJ_DECL(pj_status_t) pj_turn_srv_register_allocation(pj_turn_srv *srv, pj_turn_allocation *alloc); /** * Unregister an allocation. */ PJ_DECL(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv, pj_turn_allocation *alloc); /** * This callback is called by UDP listener on incoming packet. */ PJ_DECL(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv, pj_turn_pkt *pkt); #endif /* __PJ_TURN_SRV_TURN_H__ */