summaryrefslogtreecommitdiff
path: root/pjlib-util/include/pjlib-util/stun_session.h
blob: fa18dc3adc66ddb1b9528eb73ce2664fbdd5a79c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/* $Id$ */
/* 
 * Copyright (C) 2003-2005 Benny Prijono <benny@prijono.org>
 *
 * 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 __PJLIB_UTIL_STUN_SESSION_H__
#define __PJLIB_UTIL_STUN_SESSION_H__

#include <pjlib-util/stun_msg.h>
#include <pjlib-util/stun_auth.h>
#include <pjlib-util/stun_endpoint.h>
#include <pjlib-util/stun_transaction.h>
#include <pj/list.h>
#include <pj/timer.h>

PJ_BEGIN_DECL


/* **************************************************************************/
/**
 * @defgroup PJLIB_UTIL_STUN_SESSION STUN Client/Server Session
 * @brief STUN client and server session
 * @ingroup PJLIB_UTIL_STUN
 * @{
 */


/** Forward declaration for pj_stun_tx_data */
typedef struct pj_stun_tx_data pj_stun_tx_data;

/** Forward declaration for pj_stun_session */
typedef struct pj_stun_session pj_stun_session;


/**
 * This is the callback to be registered to pj_stun_session, to send
 * outgoing message and to receive various notifications from the STUN
 * session.
 */
typedef struct pj_stun_session_cb
{
    /**
     * Callback to be called by the STUN session to send outgoing message.
     *
     * @param sess	    The STUN session.
     * @param pkt	    Packet to be sent.
     * @param pkt_size	    Size of the packet to be sent.
     * @param dst_addr	    The destination address.
     * @param addr_len	    Length of destination address.
     *
     * @return		    The callback should return the status of the
     *			    packet sending.
     */
    pj_status_t (*on_send_msg)(pj_stun_session *sess,
			       const void *pkt,
			       pj_size_t pkt_size,
			       const pj_sockaddr_t *dst_addr,
			       unsigned addr_len);

    /** 
     * Callback to be called on incoming STUN request message. In the 
     * callback processing, application MUST create a response by calling
     * pj_stun_session_create_response() function and send the response
     * with pj_stun_session_send_msg() function, before returning from
     * the callback.
     *
     * @param sess	    The STUN session.
     * @param pkt	    Pointer to the original STUN packet.
     * @param pkt_len	    Length of the STUN packet.
     * @param msg	    The parsed STUN request.
     * @param src_addr	    Source address of the packet.
     * @param src_addr_len  Length of the source address.
     *
     * @return		    The return value of this callback will be
     *			    returned back to pj_stun_session_on_rx_pkt()
     *			    function.
     */
    pj_status_t (*on_rx_request)(pj_stun_session *sess,
				 const pj_uint8_t *pkt,
				 unsigned pkt_len,
				 const pj_stun_msg *msg,
				 const pj_sockaddr_t *src_addr,
				 unsigned src_addr_len);

    /**
     * Callback to be called when response is received or the transaction 
     * has timed out.
     *
     * @param sess	    The STUN session.
     * @param status	    Status of the request. If the value if not
     *			    PJ_SUCCESS, the transaction has timed-out
     *			    or other error has occurred, and the response
     *			    argument may be NULL.
     * @param request	    The original STUN request.
     * @param response	    The response message, on successful transaction.
     */
    void (*on_request_complete)(pj_stun_session *sess,
			        pj_status_t status,
			        pj_stun_tx_data *tdata,
			        const pj_stun_msg *response);


    /**
     * Type of callback to be called on incoming STUN indication.
     */
    pj_status_t (*on_rx_indication)(pj_stun_session *sess,
				    const pj_uint8_t *pkt,
				    unsigned pkt_len,
				    const pj_stun_msg *msg,
				    const pj_sockaddr_t *src_addr,
				    unsigned src_addr_len);

} pj_stun_session_cb;


/**
 * This structure describe the outgoing STUN transmit data to carry the
 * message to be sent.
 */
struct pj_stun_tx_data
{
    PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data);

    pj_pool_t		*pool;		/**< Pool.			    */
    pj_stun_session	*sess;		/**< The STUN session.		    */
    pj_stun_msg		*msg;		/**< The STUN message.		    */

    pj_stun_client_tsx	*client_tsx;	/**< Client STUN transaction.	    */
    pj_uint32_t		 msg_magic;	/**< Message magic.		    */
    pj_uint8_t		 msg_key[12];	/**< Message/transaction key.	    */

    void		*pkt;		/**< The STUN packet.		    */
    unsigned		 max_len;	/**< Length of packet buffer.	    */
    unsigned		 pkt_size;	/**< The actual length of STUN pkt. */

    unsigned		 addr_len;	/**< Length of destination address. */
    const pj_sockaddr_t	*dst_addr;	/**< Destination address.	    */

    pj_timer_entry	 res_timer;	/**< Response cache timer.	    */
};


/**
 * Create a STUN session.
 *
 * @param endpt		The STUN endpoint, to be used to register timers etc.
 * @param name		Optional name to be associated with this instance. The
 *			name will be used for example for logging purpose.
 * @param cb		Session callback.
 * @param fingerprint	Enable message fingerprint for outgoing messages.
 * @param p_sess	Pointer to receive STUN session instance.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_endpoint *endpt,
					    const char *name,
					    const pj_stun_session_cb *cb,
					    pj_bool_t fingerprint,
					    pj_stun_session **p_sess);

/**
 * Destroy the STUN session.
 *
 * @param sess	    The STUN session instance.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess);

/**
 * Associated an arbitrary data with this STUN session. The user data may
 * be retrieved later with pj_stun_session_get_user_data() function.
 *
 * @param sess	    The STUN session instance.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_set_user_data(pj_stun_session *sess,
						   void *user_data);

/**
 * Retrieve the user data previously associated to this STUN session with
 * pj_stun_session_set_user_data().
 *
 * @param sess	    The STUN session instance.
 *
 * @return	    The user data associated with this STUN session.
 */
PJ_DECL(void*) pj_stun_session_get_user_data(pj_stun_session *sess);

/**
 * Set server name to be included in all response.
 *
 * @param sess	    The STUN session instance.
 * @param srv_name  Server name string.
 *
 * @return	    The user data associated with this STUN session.
 */
PJ_DECL(pj_status_t) pj_stun_session_set_server_name(pj_stun_session *sess,
						     const pj_str_t *srv_name);

/**
 * Set credential to be used by this session. Once credential is set, all
 * outgoing messages will include MESSAGE-INTEGRITY, and all incoming
 * message will be authenticated against this credential.
 *
 * To disable authentication after it has been set, call this function
 * again with NULL as the argument.
 *
 * @param sess	    The STUN session instance.
 * @param cred	    The credential to be used by this session. If NULL
 *		    is specified, authentication will be disabled.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(void) pj_stun_session_set_credential(pj_stun_session *sess,
					     const pj_stun_auth_cred *cred);

/**
 * Create a STUN request message. After the message has been successfully
 * created, application can send the message by calling 
 * pj_stun_session_send_msg().
 *
 * @param sess	    The STUN session instance.
 * @param msg_type  The STUN request message type, from pj_stun_method_e or
 *		    from pj_stun_msg_type.
 * @param p_tdata   Pointer to receive STUN transmit data instance containing
 *		    the request.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_create_req(pj_stun_session *sess,
						int msg_type,
						pj_stun_tx_data **p_tdata);

/**
 * Create a STUN Indication message. After the message  has been successfully
 * created, application can send the message by calling 
 * pj_stun_session_send_msg().
 *
 * @param sess	    The STUN session instance.
 * @param msg_type  The STUN request message type, from pj_stun_method_e or
 *		    from pj_stun_msg_type. This function will add the
 *		    indication bit as necessary.
 * @param p_tdata   Pointer to receive STUN transmit data instance containing
 *		    the message.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_create_ind(pj_stun_session *sess,
						int msg_type,
					        pj_stun_tx_data **p_tdata);

/**
 * Create a STUN response message. After the message has been 
 * successfully created, application can send the message by calling 
 * pj_stun_session_send_msg().
 *
 * @param sess	    The STUN session instance.
 * @param req	    The STUN request where the response is to be created.
 * @param err_code  Error code to be set in the response, if error response
 *		    is to be created, according to pj_stun_status enumeration.
 *		    This argument MUST be zero if successful response is
 *		    to be created.
 * @param err_msg   Optional pointer for the error message string, when
 *		    creating error response. If the value is NULL and the
 *		    \a err_code is non-zero, then default error message will
 *		    be used.
 * @param p_tdata   Pointer to receive the response message created.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_create_response(pj_stun_session *sess,
						     const pj_stun_msg *req,
						     unsigned err_code,
						     const pj_str_t *err_msg,
						     pj_stun_tx_data **p_tdata);


/**
 * Send STUN message to the specified destination. This function will encode
 * the pj_stun_msg instance to a packet buffer, and add credential or
 * fingerprint if necessary. If the message is a request, the session will
 * also create and manage a STUN client transaction to be used to manage the
 * retransmission of the request. After the message has been encoded and
 * transaction is setup, the \a on_send_msg() callback of pj_stun_session_cb
 * (which is registered when the STUN session is created) will be called
 * to actually send the message to the wire.
 *
 * @param sess	    The STUN session instance.
 * @param cache_res If PJ_TRUE then response will be cached.
 * @param dst_addr  The destination socket address.
 * @param addr_len  Length of destination address.
 * @param tdata	    The STUN transmit data containing the STUN message to
 *		    be sent.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess,
					      pj_bool_t cache_res,
					      const pj_sockaddr_t *dst_addr,
					      unsigned addr_len,
					      pj_stun_tx_data *tdata);

/**
 * Application must call this function to notify the STUN session about
 * the arrival of STUN packet. The STUN packet MUST have been checked
 * first with #pj_stun_msg_check() to verify that this is indeed a valid
 * STUN packet.
 *
 * The STUN session will decode the packet into pj_stun_msg, and process
 * the message accordingly. If the message is a response, it will search
 * through the outstanding STUN client transactions for a matching
 * transaction ID and hand over the response to the transaction.
 *
 * On successful message processing, application will be notified about
 * the message via one of the pj_stun_session_cb callback.
 *
 * @param sess	     The STUN session instance.
 * @param packet     The packet containing STUN message.
 * @param pkt_size   Size of the packet.
 * @param options    Options, from #pj_stun_decode_options.
 * @param parsed_len Optional pointer to receive the size of the parsed
 *		     STUN message (useful if packet is received via a
 *		     stream oriented protocol).
 *
 * @return	     PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
					       const void *packet,
					       pj_size_t pkt_size,
					       unsigned options,
					       unsigned *parsed_len,
					       const pj_sockaddr_t *src_addr,
					       unsigned src_addr_len);

/**
 * Destroy the transmit data. Call this function only when tdata has been
 * created but application doesn't want to send the message (perhaps
 * because of other error).
 *
 * @param sess	    The STUN session.
 * @param tdata	    The transmit data.
 *
 * @return	    PJ_SUCCESS on success, or the appropriate error code.
 */
PJ_DECL(void) pj_stun_msg_destroy_tdata(pj_stun_session *sess,
					pj_stun_tx_data *tdata);


/**
 * @}
 */


PJ_END_DECL

#endif	/* __PJLIB_UTIL_STUN_SESSION_H__ */