stun.h 9.8 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3
/*
 * This file is part of the Sofia-SIP package
 *
4
 * Copyright (C) 2005-2006 Nokia Corporation.
Pekka Pessi's avatar
Pekka Pessi committed
5 6 7
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
8
 * This library is free software; you can redistribute it and/or
Pekka Pessi's avatar
Pekka Pessi committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

Pekka Pessi's avatar
Pekka Pessi committed
25 26
#ifndef STUN_H
/** Defined when <sofia-sip/stun.h> has been included. */
Pekka Pessi's avatar
Pekka Pessi committed
27
#define STUN_H
28

Pekka Pessi's avatar
Pekka Pessi committed
29
/**@file sofia-sip/stun.h STUN module public interface
Pekka Pessi's avatar
Pekka Pessi committed
30
 *
31
 * @author Martti Mela <Martti.Mela@nokia.com>
32
 * @author Tat Chan <Tat.Chan@nokia.com>
Pekka Pessi's avatar
Pekka Pessi committed
33
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
34
 * @author Kai Vehmanen <kai.vehmanen@nokia.com>
Pekka Pessi's avatar
Pekka Pessi committed
35 36
 */

37
#ifndef SU_WAIT_H
38
#include <sofia-sip/su_wait.h>
39 40
#endif
#ifndef SU_TAG_H
41
#include <sofia-sip/su_tag.h>
42
#endif
43
#include "sofia-sip/stun_common.h"
Pekka Pessi's avatar
Pekka Pessi committed
44

45
#include <sofia-sip/su_localinfo.h>
46

47 48
SOFIA_BEGIN_DECLS

49 50 51 52
typedef struct stun_handle_s     stun_handle_t;
typedef struct stun_request_s    stun_request_t;
typedef struct stun_discovery_s  stun_discovery_t;
typedef struct stun_dns_lookup_s stun_dns_lookup_t;
Pekka Pessi's avatar
Pekka Pessi committed
53

Pekka Pessi's avatar
Pekka Pessi committed
54 55
typedef struct stun_mini_s     stun_mini_t;

56 57 58 59 60 61
#ifndef STUN_MAGIC_T 
#define STUN_MAGIC_T            struct stun_magic_t
#endif
/** STUN server context */
typedef STUN_MAGIC_T stun_magic_t;

62 63 64 65 66 67
#ifndef STUN_DISCOVERY_MAGIC_T 
#define STUN_DISCOVERY_MAGIC_T            struct stun_discovery_magic_t
#endif
/** STUN discovery_ context */
typedef STUN_DISCOVERY_MAGIC_T stun_discovery_magic_t;

68 69
/** Name and version of STUN software */
SOFIAPUBVAR char const stun_version[];
Pekka Pessi's avatar
Pekka Pessi committed
70

71 72
/**
 * STUN Action types. These define the current discovery process.
73
 * Defined as a bitmap.
74 75
 */
typedef enum stun_action_s {
76 77 78 79
  stun_action_no_action = 1,
  stun_action_tls_query = 2,
  stun_action_binding_request = 4,
  stun_action_keepalive = 8,
80 81
  stun_action_test_nattype = 16,
  stun_action_test_lifetime = 32,
82 83
} stun_action_t;

84 85 86 87 88 89 90 91 92 93 94
/**
 * NAT types
 *
 * XXX: should be extended to distinguish between filtering and
 *      mapping allocation behaviour (see IETF BEHAVE documents)
 *
 * Note: the NAT type detection algorithm can fail in 
 *       case where the NAT behaves in a nondeterministic 
 *       fashion.
 **/
typedef enum stun_nattype_e {
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
  stun_nat_unknown = 0, 
      
  /* no NAT between client and STUN server */
  stun_open_internet,     

  /* UDP communication blocked by FW */
  stun_udp_blocked,       

  /* No NAT, but a FW element is performing address and port
   * restricted filtering. */
  stun_sym_udp_fw,        

  /* Endpoint independent filtering (endpoint independent mapping) 
   * RFC3489 full cone NAT. */
  stun_nat_full_cone,     

  /* Address restricted filtering (endpoint independent mapping),
   * RFC3489 restricted cone NAT. */
  stun_nat_res_cone,      

  /* Address and port restricted filtering (endpoint 
   * independent mapping), RFC3489 port restricted cone */
  stun_nat_port_res_cone, 

  /* Endpoint independent filtering, endpoint dependent mapping. */
  stun_nat_ei_filt_ad_map, 

  /* Address dependent filtering, endpoint dependent mapping. */
  stun_nat_ad_filt_ad_map, 

  /* Address and port dependent filtering, endpoint dependent mapping 
   * RFC3489 symmetric NAT). */
  stun_nat_adp_filt_ad_map, 

129 130
} stun_nattype_t;

131 132
/**
 * States of the STUN client->server query process.
133 134 135 136 137
 *
 * @see stun_bind()
 * @see stun_obtain_shared_secret()
 * @see stun_test_nattype()
 * @see stun_test_lifetime()
138
 */ 
139
typedef enum stun_state_e {
140 141
  
  stun_no_assigned_event,
142

143 144 145 146 147 148 149
  /* TLS events; see stun_obtain_shared_request() */
  stun_tls_connecting,          /**< Connecting to TLS port */
  stun_tls_ssl_connecting,      /**< Started the TLS/SSL handshake */
  stun_tls_writing,             /**< Next step: send request */
  stun_tls_closing,             /**< Closing TLS connection */
  stun_tls_reading,             /**< Request send, waiting for response */
  stun_tls_done,                /**< Shared-secret acquired */
150

151
  /* STUN discovery events */
152
  stun_discovery_done,          /**< Discovery process done */
153

154
  /* STUN errors */
155
  /* Do not change the order! Errors need to be after stun_error */
156

157 158 159 160
  stun_error,                   /**< Generic error in discovery process */
  stun_tls_connection_timeout,  /**< No response to connect attempt */
  stun_tls_connection_failed,   /**< No response from TLS/SSL server  */
  stun_tls_ssl_connect_failed,  /**< TLS/SSL handshake failed */
161

162 163
  stun_discovery_error,         /**< Error in discovery process */
  stun_discovery_timeout,       /**< No response to discovery request */
164 165

} stun_state_t;
166

167 168 169
/* -------------------------------------------------------------------
 * Calback function prototypes (signals emitted by the stack) */

170 171 172 173 174 175 176
/* Per discovery */
typedef void (*stun_discovery_f)(stun_discovery_magic_t *magic,
				 stun_handle_t *sh,
				 stun_discovery_t *sd,
				 stun_action_t action,
				 stun_state_t event);

177 178
/** Callback invoked by stun handle when it has a message to send. */
typedef int (*stun_send_callback)(stun_magic_t *magic,
179
				  stun_handle_t *sh,
180 181 182 183 184
				  int socket,
				  void *data,
				  unsigned len,
				  int only_a_keepalive);

185 186 187 188
/** Callback for delivering DNS lookup results */
typedef void (*stun_dns_lookup_f)(stun_dns_lookup_t *self,
				  stun_magic_t *magic);

189 190
/* -------------------------------------------------------------------
 * Functions for managing STUN handles. */
Pekka Pessi's avatar
Pekka Pessi committed
191

192 193
SOFIAPUBFUN stun_handle_t *stun_handle_init(su_root_t *root,
					    tag_type_t, tag_value_t, ...);
194

195
SOFIAPUBFUN void stun_handle_destroy(stun_handle_t *sh);
196

197 198 199 200
SOFIAPUBFUN su_root_t *stun_root(stun_handle_t *sh);
SOFIAPUBFUN int stun_is_requested(tag_type_t tag, tag_value_t value, ...);
SOFIAPUBFUN char const *stun_str_state(stun_state_t state);
SOFIAPUBFUN su_addrinfo_t const *stun_server_address(stun_handle_t *sh);
201

202
SOFIAPUBFUN
203 204
int stun_process_message(stun_handle_t *sh, su_socket_t s,
			 su_sockaddr_t *sa, socklen_t salen,
205
			 void *data, isize_t len);
206
SOFIAPUBFUN
207 208
int stun_process_request(su_socket_t s, stun_msg_t *req,
			 int sid, su_sockaddr_t *from_addr,
209
			 socklen_t from_len);
210

211
/* ------------------------------------------------------------------- 
212 213
 * Functions for 'Binding Discovery' usage (RFC3489/3489bis) */

214
SOFIAPUBFUN
215 216 217 218
int stun_obtain_shared_secret(stun_handle_t *sh, stun_discovery_f,
			      stun_discovery_magic_t *magic,
			      tag_type_t tag, tag_value_t value, ...);

219
SOFIAPUBFUN 
220
int stun_bind(stun_handle_t *sh, 
221 222
	      stun_discovery_f, stun_discovery_magic_t *magic,
	      tag_type_t tag, tag_value_t value, ...);
Kai Vehmanen's avatar
Kai Vehmanen committed
223

224
SOFIAPUBFUN 
225 226 227
int stun_discovery_get_address(stun_discovery_t *sd,
			       void *addr,
			       socklen_t *return_addrlen);
228 229
SOFIAPUBFUN su_socket_t stun_discovery_get_socket(stun_discovery_t *sd);
SOFIAPUBFUN int stun_discovery_release_socket(stun_discovery_t *sd);
230

231
SOFIAPUBFUN
232 233 234
int stun_test_nattype(stun_handle_t *sh,
		       stun_discovery_f, stun_discovery_magic_t *magic,
		       tag_type_t tag, tag_value_t value, ...);
235 236
SOFIAPUBFUN char const *stun_nattype_str(stun_discovery_t *sd);
SOFIAPUBFUN stun_nattype_t stun_nattype(stun_discovery_t *sd);
237

238
SOFIAPUBFUN
239
int stun_test_lifetime(stun_handle_t *sh,
240 241
		       stun_discovery_f, stun_discovery_magic_t *magic,
		       tag_type_t tag, tag_value_t value, ...);
242
SOFIAPUBFUN int stun_lifetime(stun_discovery_t *sd);
243

244 245
/* ------------------------------------------------------------------- 
 * Functions for 'Connectivity Check' and 'NAT Keepalives' usages (RFC3489bis) */
246

247
SOFIAPUBFUN 
248 249
int stun_set_uname_pwd(stun_handle_t *sh,
		       const char *uname,
250
		       isize_t len_uname, 
251
		       const char *pwd,
252
		       isize_t len_pwd);
Pekka Pessi's avatar
Pekka Pessi committed
253

254
SOFIAPUBFUN int stun_msg_is_keepalive(uint16_t data);
255
SOFIAPUBFUN int stun_message_length(void *data, isize_t len, int end_of_message);
256 257 258

/* Create a keepalive dispatcher for bound SIP sockets */

259
SOFIAPUBFUN 
260
int stun_keepalive(stun_handle_t *sh,
261
		   su_sockaddr_t *sa,
262 263
		   tag_type_t tag, tag_value_t value,
		   ...);
264
SOFIAPUBFUN int stun_keepalive_destroy(stun_handle_t *sh, su_socket_t s);
265

266 267 268
/* -------------------------------------------------------------------
 * Functions for 'Short-Term password' usage (RFC3489bis) */

Kai Vehmanen's avatar
Kai Vehmanen committed
269
/* (not implemented, see stun_request_shared_secret()) */
270

271 272 273
/* -------------------------------------------------------------------
 * Functions for STUN server discovery using DNS (RFC3489/3489bis) */

274
SOFIAPUBFUN 
275 276 277 278
stun_dns_lookup_t *stun_dns_lookup(stun_magic_t *magic, 
				   su_root_t *root,
				   stun_dns_lookup_f func, 
				   const char *domain);
279
SOFIAPUBFUN void stun_dns_lookup_destroy(stun_dns_lookup_t *self);
280

281 282 283 284 285 286
SOFIAPUBFUN int stun_dns_lookup_udp_addr(stun_dns_lookup_t *,
					 const char **target, uint16_t *port);
SOFIAPUBFUN int stun_dns_lookup_tcp_addr(stun_dns_lookup_t *self,
					 const char **target, uint16_t *port);
SOFIAPUBFUN int stun_dns_lookup_stp_addr(stun_dns_lookup_t *self,
					 const char **target, uint16_t *port);
287

Pekka Pessi's avatar
Pekka Pessi committed
288 289 290
/* -------------------------------------------------------------------
 * Functions for minimal STUN server */

291 292
SOFIAPUBFUN stun_mini_t *stun_mini_create(void);
SOFIAPUBFUN void stun_mini_destroy(stun_mini_t *);
Pekka Pessi's avatar
Pekka Pessi committed
293

294 295 296 297
SOFIAPUBFUN int stun_mini_add_socket(stun_mini_t *server,
				     su_socket_t socket);
SOFIAPUBFUN int stun_mini_remove_socket(stun_mini_t *server,
					su_socket_t socket);
Pekka Pessi's avatar
Pekka Pessi committed
298

299
SOFIAPUBFUN void stun_mini_request(stun_mini_t *server, su_socket_t socket,
300 301
				   void *msg, ssize_t msglen,
				   void *addr, socklen_t addrlen);
Pekka Pessi's avatar
Pekka Pessi committed
302

303 304
SOFIA_END_DECLS

Pekka Pessi's avatar
Pekka Pessi committed
305
#endif /* !defined(STUN_H) */