mirror of
				https://github.com/coturn/coturn.git
				synced 2025-11-04 00:41:02 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			237 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			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__
 |