1
0
mirror of https://github.com/coturn/coturn.git synced 2025-11-04 00:41:02 +01:00
coturn/src/server/ns_turn_allocation.h
2014-05-07 07:26:17 +00:00

237 lines
6.7 KiB
C

/*
* Copyright (C) 2011, 2012, 2013 Citrix Systems
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __TURN_TURN_A_LIB__
#define __TURN_TURN_A_LIB__
#include "ns_turn_utils.h"
#include "ns_turn_msg.h"
#include "ns_turn_ioalib.h"
#include "ns_turn_maps.h"
#ifdef __cplusplus
extern "C" {
#endif
///////// Defines //////////
#define TCP_PEER_CONN_TIMEOUT (30)
#define TCP_CONN_BIND_TIMEOUT (30)
///////// types ////////////
enum _UR_STATE {
UR_STATE_UNKNOWN=0,
UR_STATE_READY,
UR_STATE_DONE
};
typedef enum _UR_STATE UR_STATE;
////////////// Network session ////////////////
typedef struct
{
UR_STATE state;
ioa_socket_handle s;
int known_mtu;
} ts_ur_session;
static inline void clear_ts_ur_session_data(ts_ur_session* cdi)
{
if (cdi)
IOA_CLOSE_SOCKET(cdi->s);
}
////////// RFC 6062 TCP connection ////////
#define MAX_UNSENT_BUFFER_SIZE (0x10)
enum _TC_STATE {
TC_STATE_UNKNOWN=0,
TC_STATE_CLIENT_TO_PEER_CONNECTING,
TC_STATE_PEER_CONNECTING,
TC_STATE_PEER_CONNECTED,
TC_STATE_READY,
TC_STATE_FAILED
};
typedef enum _TC_STATE TC_STATE;
typedef u32bits tcp_connection_id;
typedef struct {
size_t sz;
ioa_network_buffer_handle *bufs;
} unsent_buffer;
struct _tcp_connection
{
TC_STATE state;
tcp_connection_id id;
ioa_addr peer_addr;
ioa_socket_handle client_s;
ioa_socket_handle peer_s;
ioa_timer_handle peer_conn_timeout;
ioa_timer_handle conn_bind_timeout;
stun_tid tid;
void *owner; //a
int done;
unsent_buffer ub_to_client;
};
typedef struct _tcp_connection_list {
size_t sz;
tcp_connection **elems;
} tcp_connection_list;
////////////////////////////////
#define TURN_PERMISSION_HASHTABLE_SIZE (0x8)
#define TURN_PERMISSION_ARRAY_SIZE (0x3)
struct _allocation;
typedef struct _ch_info {
u16bits chnum;
int allocated;
u16bits port;
ioa_addr peer_addr;
turn_time_t expiration_time;
ioa_timer_handle lifetime_ev;
void *owner; //perm
TURN_CHANNEL_HANDLER_KERNEL kernel_channel;
} ch_info;
///////////// "channel" map /////////////////////
#define CH_MAP_HASH_SIZE (0x8)
#define CH_MAP_ARRAY_SIZE (0x3)
typedef struct _chn_map_array {
ch_info main_chns[CH_MAP_ARRAY_SIZE];
size_t extra_sz;
ch_info **extra_chns;
} ch_map_array;
typedef struct _ch_map {
ch_map_array table[CH_MAP_HASH_SIZE];
} ch_map;
ch_info *ch_map_get(ch_map* map, u16bits chnum, int new_chn);
void ch_map_clean(ch_map* map);
////////////////////////////
typedef struct _turn_permission_info {
int allocated;
lm_map chns;
ioa_addr addr;
turn_time_t expiration_time;
ioa_timer_handle lifetime_ev;
void* owner; //a
} turn_permission_info;
typedef struct _turn_permission_slot {
turn_permission_info info;
} turn_permission_slot;
typedef struct _turn_permission_array {
turn_permission_slot main_slots[TURN_PERMISSION_ARRAY_SIZE];
size_t extra_sz;
turn_permission_slot **extra_slots;
} turn_permission_array;
typedef struct _turn_permission_hashtable {
turn_permission_array table[TURN_PERMISSION_HASHTABLE_SIZE];
} turn_permission_hashtable;
//////////////// ALLOCATION //////////////////////
typedef struct _allocation {
int is_valid;
stun_tid tid;
turn_time_t expiration_time;
ioa_timer_handle lifetime_ev;
turn_permission_hashtable addr_to_perm;
ts_ur_session relay_session;
ch_map chns; /* chnum-to-ch_info* */
void *owner; //ss
ur_map *tcp_connections; //global (per turn server) reference
tcp_connection_list tcs; //local reference
} allocation;
//////////// CHANNELS ////////////////////
u16bits get_turn_channel_number(turn_permission_info* tinfo, ioa_addr *addr);
ch_info *get_turn_channel(turn_permission_info* tinfo, ioa_addr *addr);
void turn_channel_delete(ch_info* chn);
/////////// ALLOCATION ////////////
void init_allocation(void *owner, allocation* a, ur_map *tcp_connections);
void clear_allocation(allocation *a);
void turn_permission_clean(turn_permission_info* tinfo);
void set_allocation_lifetime_ev(allocation *a, turn_time_t exp_time, ioa_timer_handle ev);
int is_allocation_valid(const allocation* a);
void set_allocation_valid(allocation* a, int value);
turn_permission_info* allocation_get_permission(allocation* a, const ioa_addr *addr);
turn_permission_hashtable* allocation_get_turn_permission_hashtable(allocation *a);
turn_permission_info* allocation_add_permission(allocation *a, const ioa_addr* addr);
ch_info* allocation_get_new_ch_info(allocation* a, u16bits chnum, ioa_addr* peer_addr);
ch_info* allocation_get_ch_info(allocation* a, u16bits chnum);
ch_info* allocation_get_ch_info_by_peer_addr(allocation* a, ioa_addr* peer_addr);
ts_ur_session *get_relay_session(allocation *a);
ioa_socket_handle get_relay_socket(allocation *a);
tcp_connection *get_and_clean_tcp_connection_by_id(ur_map *map, tcp_connection_id id);
tcp_connection *get_tcp_connection_by_peer(allocation *a, ioa_addr *peer_addr);
int can_accept_tcp_connection_from_peer(allocation *a, ioa_addr *peer_addr, int server_relay);
tcp_connection *create_tcp_connection(u08bits server_id, allocation *a, stun_tid *tid, ioa_addr *peer_addr, int *err_code);
void delete_tcp_connection(tcp_connection *tc);
void clear_unsent_buffer(unsent_buffer *ub);
void add_unsent_buffer(unsent_buffer *ub, ioa_network_buffer_handle nbh);
ioa_network_buffer_handle top_unsent_buffer(unsent_buffer *ub);
void pop_unsent_buffer(unsent_buffer *ub);
///////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif //__TURN_TURN_A_LIB__