Skip to content

Commit fa6616c

Browse files
committed
Close #2197: Support TURN extensions for TCP allocations (RFC 6062).
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5987 74dad513-b988-da41-8d7b-12977e46ad98
1 parent 2a8a1ff commit fa6616c

File tree

7 files changed

+803
-34
lines changed

7 files changed

+803
-34
lines changed

pjnath/include/pjnath/config.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@
220220
# define PJ_TURN_KEEP_ALIVE_SEC 15
221221
#endif
222222

223+
/**
224+
* Maximum number of TCP data connection to peer(s) that a TURN client can
225+
* open/accept for each TURN allocation (or TURN control connection).
226+
*/
227+
#ifndef PJ_TURN_MAX_TCP_CONN_CNT
228+
# define PJ_TURN_MAX_TCP_CONN_CNT 8
229+
#endif
223230

224231
/* **************************************************************************
225232
* ICE CONFIGURATION

pjnath/include/pjnath/stun_msg.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,21 @@ enum pj_stun_method_e
9292
*/
9393
PJ_STUN_CHANNEL_BIND_METHOD = 9,
9494

95+
/**
96+
* STUN/TURN Connect as defined by RFC 6062
97+
*/
98+
PJ_STUN_CONNECT_METHOD = 10,
99+
100+
/**
101+
* STUN/TURN ConnectionBind as defined by RFC 6062
102+
*/
103+
PJ_STUN_CONNECTION_BIND_METHOD = 11,
104+
105+
/**
106+
* STUN/TURN ConnectionAttempt as defined by RFC 6062
107+
*/
108+
PJ_STUN_CONNECTION_ATTEMPT_METHOD = 12,
109+
95110
/**
96111
* All known methods.
97112
*/
@@ -291,7 +306,18 @@ typedef enum pj_stun_msg_type
291306
/**
292307
* Error response to STUN ChannelBind request.
293308
*/
294-
PJ_STUN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119
309+
PJ_STUN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119,
310+
311+
312+
/**
313+
* STUN/TURN ConnectBind Request
314+
*/
315+
PJ_STUN_CONNECTION_BIND_REQUEST = 0x000b,
316+
317+
/**
318+
* TURN ConnectionAttempt indication
319+
*/
320+
PJ_STUN_CONNECTION_ATTEMPT_INDICATION = 0x001c,
295321

296322
} pj_stun_msg_type;
297323

@@ -333,6 +359,7 @@ typedef enum pj_stun_attr_type
333359
PJ_STUN_ATTR_XOR_REFLECTED_FROM = 0x0023,/**< XOR-REFLECTED-FROM */
334360
PJ_STUN_ATTR_PRIORITY = 0x0024,/**< PRIORITY */
335361
PJ_STUN_ATTR_USE_CANDIDATE = 0x0025,/**< USE-CANDIDATE */
362+
PJ_STUN_ATTR_CONNECTION_ID = 0x002a,/**< CONNECTION-ID */
336363
PJ_STUN_ATTR_ICMP = 0x0030,/**< ICMP (TURN) */
337364

338365
PJ_STUN_ATTR_END_MANDATORY_ATTR,

pjnath/include/pjnath/turn_session.h

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,43 @@ typedef struct pj_turn_session_cb
298298
pj_turn_state_t old_state,
299299
pj_turn_state_t new_state);
300300

301+
/**
302+
* Notification when TURN client received a ConnectionAttempt Indication
303+
* from the TURN server, which indicates that peer initiates a TCP
304+
* connection to allocated slot in the TURN server. Application must
305+
* implement this callback if it uses RFC 6062 (TURN TCP allocations).
306+
*
307+
* After receiving this callback, application should establish a new TCP
308+
* connection to the TURN server and send ConnectionBind request (using
309+
* pj_turn_session_connection_bind()). After the connection binding
310+
* succeeds, this new connection will become a data only connection.
311+
*
312+
* @param sess The TURN session.
313+
* @param conn_id The connection ID assigned by TURN server.
314+
* @param peer_addr Peer address that tried to connect to the TURN server.
315+
* @param addr_len Length of the peer address.
316+
*/
317+
void (*on_connection_attempt)(pj_turn_session *sess,
318+
pj_uint32_t conn_id,
319+
const pj_sockaddr_t *peer_addr,
320+
unsigned addr_len);
321+
322+
/**
323+
* Notification for ConnectionBind request sent using
324+
* pj_turn_session_connection_bind().
325+
*
326+
* @param sess The TURN session.
327+
* @param status The status code.
328+
* @param conn_id The connection ID.
329+
* @param peer_addr Peer address.
330+
* @param addr_len Length of the peer address.
331+
*/
332+
void (*on_connection_bind_status)(pj_turn_session *sess,
333+
pj_status_t status,
334+
pj_uint32_t conn_id,
335+
const pj_sockaddr_t *peer_addr,
336+
unsigned addr_len);
337+
301338
} pj_turn_session_cb;
302339

303340

@@ -339,6 +376,13 @@ typedef struct pj_turn_alloc_param
339376
*/
340377
int af;
341378

379+
/**
380+
* Type of connection to from TURN server to peer. Supported values are
381+
* PJ_TURN_TP_UDP (RFC 5766) and PJ_TURN_TP_TCP (RFC 6062)
382+
*
383+
* Default is PJ_TURN_TP_UDP.
384+
*/
385+
pj_turn_tp_type peer_conn_type;
342386

343387
} pj_turn_alloc_param;
344388

@@ -386,6 +430,40 @@ typedef struct pj_turn_session_info
386430
} pj_turn_session_info;
387431

388432

433+
/**
434+
* Parameters for function pj_turn_session_on_rx_pkt2().
435+
*/
436+
typedef struct pj_turn_session_on_rx_pkt_param
437+
{
438+
/**
439+
* The packet as received from the TURN server. This should contain
440+
* either STUN encapsulated message or a ChannelData packet.
441+
*/
442+
void *pkt;
443+
444+
/**
445+
* The length of the packet.
446+
*/
447+
pj_size_t pkt_len;
448+
449+
/**
450+
* The number of parsed or processed data from the packet.
451+
*/
452+
pj_size_t parsed_len;
453+
454+
/**
455+
* Source address where the packet is received from.
456+
*/
457+
const pj_sockaddr_t *src_addr;
458+
459+
/**
460+
* Length of the source address.
461+
*/
462+
unsigned src_addr_len;
463+
464+
} pj_turn_session_on_rx_pkt_param;
465+
466+
389467
/**
390468
* Initialize pj_turn_alloc_param with the default values.
391469
*
@@ -741,6 +819,56 @@ PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,
741819
pj_size_t pkt_len,
742820
pj_size_t *parsed_len);
743821

822+
/**
823+
* Notify TURN client session upon receiving a packet from server. Since
824+
* the TURN session is transport independent, it does not read packet from
825+
* any sockets, and rather relies on application giving it packets that
826+
* are received from the TURN server. The session then processes this packet
827+
* and decides whether it is part of TURN protocol exchange or if it is a
828+
* data to be reported back to user, which in this case it will call the
829+
* \a on_rx_data() callback.
830+
*
831+
* This function is variant of pj_turn_session_on_rx_pkt() with additional
832+
* parameters such as source address. Source address will allow STUN/TURN
833+
* session to resend the request (e.g: with updated authentication) to the
834+
* provided source address which may be different to the initial connection,
835+
* for example in RFC 6062 scenario that there can be some data connection
836+
* and a control connection.
837+
*
838+
* @param sess The TURN client session.
839+
* @param prm The function parameters, e.g: packet, source address.
840+
*
841+
* @return The function may return non-PJ_SUCCESS if it receives
842+
* non-STUN and non-ChannelData packet, or if the
843+
* \a on_rx_data() returns non-PJ_SUCCESS;
844+
*/
845+
PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt2(
846+
pj_turn_session *sess,
847+
pj_turn_session_on_rx_pkt_param *prm);
848+
849+
/**
850+
* Initiate connection binding to the specified peer using ConnectionBind
851+
* request. Application must call this function when it uses RFC 6062
852+
* (TURN TCP allocations) to establish a data connection with peer after
853+
* opening/accepting connection to/from peer. The connection binding status
854+
* will be notified via on_connection_bind_status callback.
855+
*
856+
* @param sess The TURN session.
857+
* @param pool The memory pool.
858+
* @param conn_id The connection ID assigned by TURN server.
859+
* @param peer_addr Peer address.
860+
* @param addr_len Length of the peer address.
861+
*
862+
* @return PJ_SUCCESS if the operation has been successfully
863+
* issued, or the appropriate error code. Note that
864+
* the operation itself will complete asynchronously.
865+
*/
866+
PJ_DECL(pj_status_t) pj_turn_session_connection_bind(
867+
pj_turn_session *sess,
868+
pj_pool_t *pool,
869+
pj_uint32_t conn_id,
870+
const pj_sockaddr_t *peer_addr,
871+
unsigned addr_len);
744872

745873
/**
746874
* @}

pjnath/include/pjnath/turn_sock.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,49 @@ typedef struct pj_turn_sock_cb
9898
pj_turn_state_t old_state,
9999
pj_turn_state_t new_state);
100100

101+
/**
102+
* Notification when TURN client received a ConnectionAttempt Indication
103+
* from the TURN server, which indicates that peer initiates a TCP
104+
* connection to allocated slot in the TURN server. Application should
105+
* implement this callback if it uses RFC 6062 (TURN TCP allocations),
106+
* otherwise TURN client will automatically accept it.
107+
*
108+
* If application accepts the peer connection attempt (i.e: by returning
109+
* PJ_SUCCESS or not implementing this callback), the TURN socket will
110+
* initiate a new connection to the TURN server and send ConnectionBind
111+
* request, and eventually will notify application via
112+
* on_connection_status callback, if implemented.
113+
*
114+
* @param turn_sock The TURN client transport.
115+
* @param conn_id The connection ID assigned by TURN server.
116+
* @param peer_addr Peer address that tried to connect to the
117+
* TURN server.
118+
* @param addr_len Length of the peer address.
119+
*
120+
* @return The callback must return PJ_SUCCESS to accept
121+
* the connection attempt.
122+
*/
123+
pj_status_t (*on_connection_attempt)(pj_turn_sock *turn_sock,
124+
pj_uint32_t conn_id,
125+
const pj_sockaddr_t *peer_addr,
126+
unsigned addr_len);
127+
128+
/**
129+
* Notification for initiated TCP data connection to peer (RFC 6062),
130+
* for example after peer connection attempt is accepted.
131+
*
132+
* @param turn_sock The TURN client transport.
133+
* @param status The status code.
134+
* @param conn_id The connection ID.
135+
* @param peer_addr Peer address.
136+
* @param addr_len Length of the peer address.
137+
*/
138+
void (*on_connection_status)(pj_turn_sock *turn_sock,
139+
pj_status_t status,
140+
pj_uint32_t conn_id,
141+
const pj_sockaddr_t *peer_addr,
142+
unsigned addr_len);
143+
101144
} pj_turn_sock_cb;
102145

103146

pjnath/src/pjnath/stun_msg.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ static const char *stun_method_names[PJ_STUN_METHOD_MAX] =
4545
"Data", /* 7 */
4646
"CreatePermission", /* 8 */
4747
"ChannelBind", /* 9 */
48+
"Connect", /* 10 */
49+
"ConnectionBind", /* 11 */
50+
"ConnectionAttempt", /* 12 */
4851
};
4952

5053
static struct
@@ -476,11 +479,11 @@ static struct attr_desc mandatory_attr_desc[] =
476479
NULL
477480
},
478481
{
479-
/* ID 0x002a is not assigned */
480-
NULL,
481-
NULL,
482-
NULL,
483-
NULL
482+
/* PJ_STUN_ATTR_CONNECTION_ID, */
483+
"CONNECTION-ID",
484+
&decode_uint_attr,
485+
&encode_uint_attr,
486+
&clone_uint_attr
484487
},
485488
{
486489
/* ID 0x002b is not assigned */

0 commit comments

Comments
 (0)