1 /* $Id$ */
2 /*
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <pjnath/stun_sock.h>
21 #include <pjnath/errno.h>
22 #include <pjnath/stun_transaction.h>
23 #include <pjnath/stun_session.h>
24 #include <pjlib-util/srv_resolver.h>
25 #include <pj/activesock.h>
26 #include <pj/addr_resolv.h>
27 #include <pj/array.h>
28 #include <pj/assert.h>
29 #include <pj/ip_helper.h>
30 #include <pj/log.h>
31 #include <pj/os.h>
32 #include <pj/pool.h>
33 #include <pj/rand.h>
34 
35 #if 1
36 #  define TRACE_(x)	PJ_LOG(5,x)
37 #else
38 #  define TRACE_(x)
39 #endif
40 
41 enum { MAX_BIND_RETRY = 100 };
42 
43 struct pj_stun_sock
44 {
45     char		*obj_name;	/* Log identification	    */
46     pj_pool_t		*pool;		/* Pool			    */
47     void		*user_data;	/* Application user data    */
48     pj_bool_t		 is_destroying; /* Destroy already called   */
49     int			 af;		/* Address family	    */
50     pj_stun_config	 stun_cfg;	/* STUN config (ioqueue etc)*/
51     pj_stun_sock_cb	 cb;		/* Application callbacks    */
52 
53     int			 ka_interval;	/* Keep alive interval	    */
54     pj_timer_entry	 ka_timer;	/* Keep alive timer.	    */
55 
56     pj_sockaddr		 srv_addr;	/* Resolved server addr	    */
57     pj_sockaddr		 mapped_addr;	/* Our public address	    */
58 
59     pj_dns_srv_async_query *q;		/* Pending DNS query	    */
60     pj_sock_t		 sock_fd;	/* Socket descriptor	    */
61     pj_activesock_t	*active_sock;	/* Active socket object	    */
62     pj_ioqueue_op_key_t	 send_key;	/* Default send key for app */
63     pj_ioqueue_op_key_t	 int_send_key;	/* Send key for internal    */
64     pj_status_t		 last_err;	/* Last error status	    */
65 
66     pj_uint16_t		 tsx_id[6];	/* .. to match STUN msg	    */
67     pj_stun_session	*stun_sess;	/* STUN session		    */
68     pj_grp_lock_t	*grp_lock;	/* Session group lock	    */
69 };
70 
71 /*
72  * Prototypes for static functions
73  */
74 
75 /* Destructor for group lock */
76 static void stun_sock_destructor(void *obj);
77 
78 /* This callback is called by the STUN session to send packet */
79 static pj_status_t sess_on_send_msg(pj_stun_session *sess,
80 				    void *token,
81 				    const void *pkt,
82 				    pj_size_t pkt_size,
83 				    const pj_sockaddr_t *dst_addr,
84 				    unsigned addr_len);
85 
86 /* This callback is called by the STUN session when outgoing transaction
87  * is complete
88  */
89 static void sess_on_request_complete(pj_stun_session *sess,
90 				     pj_status_t status,
91 				     void *token,
92 				     pj_stun_tx_data *tdata,
93 				     const pj_stun_msg *response,
94 				     const pj_sockaddr_t *src_addr,
95 				     unsigned src_addr_len);
96 /* DNS resolver callback */
97 static void dns_srv_resolver_cb(void *user_data,
98 				pj_status_t status,
99 				const pj_dns_srv_record *rec);
100 
101 /* Start sending STUN Binding request */
102 static pj_status_t get_mapped_addr(pj_stun_sock *stun_sock);
103 
104 /* Callback from active socket when incoming packet is received */
105 static pj_bool_t on_data_recvfrom(pj_activesock_t *asock,
106 				  void *data,
107 				  pj_size_t size,
108 				  const pj_sockaddr_t *src_addr,
109 				  int addr_len,
110 				  pj_status_t status);
111 
112 /* Callback from active socket about send status */
113 static pj_bool_t on_data_sent(pj_activesock_t *asock,
114 			      pj_ioqueue_op_key_t *send_key,
115 			      pj_ssize_t sent);
116 
117 /* Schedule keep-alive timer */
118 static void start_ka_timer(pj_stun_sock *stun_sock);
119 
120 /* Keep-alive timer callback */
121 static void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te);
122 
123 #define INTERNAL_MSG_TOKEN  (void*)(pj_ssize_t)1
124 
125 
126 /*
127  * Retrieve the name representing the specified operation.
128  */
pj_stun_sock_op_name(pj_stun_sock_op op)129 PJ_DEF(const char*) pj_stun_sock_op_name(pj_stun_sock_op op)
130 {
131     const char *names[] = {
132 	"?",
133 	"DNS resolution",
134 	"STUN Binding request",
135 	"Keep-alive",
136 	"Mapped addr. changed"
137     };
138 
139     return op < PJ_ARRAY_SIZE(names) ? names[op] : "???";
140 }
141 
142 
143 /*
144  * Initialize the STUN transport setting with its default values.
145  */
pj_stun_sock_cfg_default(pj_stun_sock_cfg * cfg)146 PJ_DEF(void) pj_stun_sock_cfg_default(pj_stun_sock_cfg *cfg)
147 {
148     pj_bzero(cfg, sizeof(*cfg));
149     cfg->max_pkt_size = PJ_STUN_SOCK_PKT_LEN;
150     cfg->async_cnt = 1;
151     cfg->ka_interval = PJ_STUN_KEEP_ALIVE_SEC;
152     cfg->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
153     cfg->qos_ignore_error = PJ_TRUE;
154 }
155 
156 
157 /* Check that configuration setting is valid */
pj_stun_sock_cfg_is_valid(const pj_stun_sock_cfg * cfg)158 static pj_bool_t pj_stun_sock_cfg_is_valid(const pj_stun_sock_cfg *cfg)
159 {
160     return cfg->max_pkt_size > 1 && cfg->async_cnt >= 1;
161 }
162 
163 /*
164  * Create the STUN transport using the specified configuration.
165  */
pj_stun_sock_create(pj_stun_config * stun_cfg,const char * name,int af,const pj_stun_sock_cb * cb,const pj_stun_sock_cfg * cfg,void * user_data,pj_stun_sock ** p_stun_sock)166 PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg,
167 					 const char *name,
168 					 int af,
169 					 const pj_stun_sock_cb *cb,
170 					 const pj_stun_sock_cfg *cfg,
171 					 void *user_data,
172 					 pj_stun_sock **p_stun_sock)
173 {
174     pj_pool_t *pool;
175     pj_stun_sock *stun_sock;
176     pj_stun_sock_cfg default_cfg;
177     pj_sockaddr bound_addr;
178     unsigned i;
179     pj_uint16_t max_bind_retry;
180     pj_status_t status;
181 
182     PJ_ASSERT_RETURN(stun_cfg && cb && p_stun_sock, PJ_EINVAL);
183     PJ_ASSERT_RETURN(af==pj_AF_INET()||af==pj_AF_INET6(), PJ_EAFNOTSUP);
184     PJ_ASSERT_RETURN(!cfg || pj_stun_sock_cfg_is_valid(cfg), PJ_EINVAL);
185     PJ_ASSERT_RETURN(cb->on_status, PJ_EINVAL);
186 
187     status = pj_stun_config_check_valid(stun_cfg);
188     if (status != PJ_SUCCESS)
189 	return status;
190 
191     if (name == NULL)
192 	name = "stuntp%p";
193 
194     if (cfg == NULL) {
195 	pj_stun_sock_cfg_default(&default_cfg);
196 	cfg = &default_cfg;
197     }
198 
199 
200     /* Create structure */
201     pool = pj_pool_create(stun_cfg->pf, name, 256, 512, NULL);
202     stun_sock = PJ_POOL_ZALLOC_T(pool, pj_stun_sock);
203     stun_sock->pool = pool;
204     stun_sock->obj_name = pool->obj_name;
205     stun_sock->user_data = user_data;
206     stun_sock->af = af;
207     stun_sock->sock_fd = PJ_INVALID_SOCKET;
208     pj_memcpy(&stun_sock->stun_cfg, stun_cfg, sizeof(*stun_cfg));
209     pj_memcpy(&stun_sock->cb, cb, sizeof(*cb));
210 
211     stun_sock->ka_interval = cfg->ka_interval;
212     if (stun_sock->ka_interval == 0)
213 	stun_sock->ka_interval = PJ_STUN_KEEP_ALIVE_SEC;
214 
215     if (cfg->grp_lock) {
216 	stun_sock->grp_lock = cfg->grp_lock;
217     } else {
218 	status = pj_grp_lock_create(pool, NULL, &stun_sock->grp_lock);
219 	if (status != PJ_SUCCESS) {
220 	    pj_pool_release(pool);
221 	    return status;
222 	}
223     }
224 
225     pj_grp_lock_add_ref(stun_sock->grp_lock);
226     pj_grp_lock_add_handler(stun_sock->grp_lock, pool, stun_sock,
227 			    &stun_sock_destructor);
228 
229     /* Create socket and bind socket */
230     status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &stun_sock->sock_fd);
231     if (status != PJ_SUCCESS)
232 	goto on_error;
233 
234     /* Apply QoS, if specified */
235     status = pj_sock_apply_qos2(stun_sock->sock_fd, cfg->qos_type,
236 				&cfg->qos_params, 2, stun_sock->obj_name,
237 				NULL);
238     if (status != PJ_SUCCESS && !cfg->qos_ignore_error)
239 	goto on_error;
240 
241     /* Apply socket buffer size */
242     if (cfg->so_rcvbuf_size > 0) {
243 	unsigned sobuf_size = cfg->so_rcvbuf_size;
244 	status = pj_sock_setsockopt_sobuf(stun_sock->sock_fd, pj_SO_RCVBUF(),
245 					  PJ_TRUE, &sobuf_size);
246 	if (status != PJ_SUCCESS) {
247 	    PJ_PERROR(3, (stun_sock->obj_name, status,
248 			  "Failed setting SO_RCVBUF"));
249 	} else {
250 	    if (sobuf_size < cfg->so_rcvbuf_size) {
251 		PJ_LOG(4, (stun_sock->obj_name,
252 			   "Warning! Cannot set SO_RCVBUF as configured, "
253 			   "now=%d, configured=%d",
254 			   sobuf_size, cfg->so_rcvbuf_size));
255 	    } else {
256 		PJ_LOG(5, (stun_sock->obj_name, "SO_RCVBUF set to %d",
257 			   sobuf_size));
258 	    }
259 	}
260     }
261     if (cfg->so_sndbuf_size > 0) {
262 	unsigned sobuf_size = cfg->so_sndbuf_size;
263 	status = pj_sock_setsockopt_sobuf(stun_sock->sock_fd, pj_SO_SNDBUF(),
264 					  PJ_TRUE, &sobuf_size);
265 	if (status != PJ_SUCCESS) {
266 	    PJ_PERROR(3, (stun_sock->obj_name, status,
267 			  "Failed setting SO_SNDBUF"));
268 	} else {
269 	    if (sobuf_size < cfg->so_sndbuf_size) {
270 		PJ_LOG(4, (stun_sock->obj_name,
271 			   "Warning! Cannot set SO_SNDBUF as configured, "
272 			   "now=%d, configured=%d",
273 			   sobuf_size, cfg->so_sndbuf_size));
274 	    } else {
275 		PJ_LOG(5, (stun_sock->obj_name, "SO_SNDBUF set to %d",
276 			   sobuf_size));
277 	    }
278 	}
279     }
280 
281     /* Bind socket */
282     max_bind_retry = MAX_BIND_RETRY;
283     if (cfg->port_range && cfg->port_range < max_bind_retry)
284 	max_bind_retry = cfg->port_range;
285     pj_sockaddr_init(af, &bound_addr, NULL, 0);
286     if (cfg->bound_addr.addr.sa_family == pj_AF_INET() ||
287 	cfg->bound_addr.addr.sa_family == pj_AF_INET6())
288     {
289 	pj_sockaddr_cp(&bound_addr, &cfg->bound_addr);
290     }
291     status = pj_sock_bind_random(stun_sock->sock_fd, &bound_addr,
292 				 cfg->port_range, max_bind_retry);
293     if (status != PJ_SUCCESS)
294 	goto on_error;
295 
296     /* Create more useful information string about this transport */
297 #if 0
298     {
299 	pj_sockaddr bound_addr;
300 	int addr_len = sizeof(bound_addr);
301 
302 	status = pj_sock_getsockname(stun_sock->sock_fd, &bound_addr,
303 				     &addr_len);
304 	if (status != PJ_SUCCESS)
305 	    goto on_error;
306 
307 	stun_sock->info = pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+10);
308 	pj_sockaddr_print(&bound_addr, stun_sock->info,
309 			  PJ_INET6_ADDRSTRLEN, 3);
310     }
311 #endif
312 
313     /* Init active socket configuration */
314     {
315 	pj_activesock_cfg activesock_cfg;
316 	pj_activesock_cb activesock_cb;
317 
318 	pj_activesock_cfg_default(&activesock_cfg);
319 	activesock_cfg.grp_lock = stun_sock->grp_lock;
320 	activesock_cfg.async_cnt = cfg->async_cnt;
321 	activesock_cfg.concurrency = 0;
322 
323 	/* Create the active socket */
324 	pj_bzero(&activesock_cb, sizeof(activesock_cb));
325 	activesock_cb.on_data_recvfrom = &on_data_recvfrom;
326 	activesock_cb.on_data_sent = &on_data_sent;
327 	status = pj_activesock_create(pool, stun_sock->sock_fd,
328 				      pj_SOCK_DGRAM(),
329 				      &activesock_cfg, stun_cfg->ioqueue,
330 				      &activesock_cb, stun_sock,
331 				      &stun_sock->active_sock);
332 	if (status != PJ_SUCCESS)
333 	    goto on_error;
334 
335 	/* Start asynchronous read operations */
336 	status = pj_activesock_start_recvfrom(stun_sock->active_sock, pool,
337 					      cfg->max_pkt_size, 0);
338 	if (status != PJ_SUCCESS)
339 	    goto on_error;
340 
341 	/* Init send keys */
342 	pj_ioqueue_op_key_init(&stun_sock->send_key,
343 			       sizeof(stun_sock->send_key));
344 	pj_ioqueue_op_key_init(&stun_sock->int_send_key,
345 			       sizeof(stun_sock->int_send_key));
346     }
347 
348     /* Create STUN session */
349     {
350 	pj_stun_session_cb sess_cb;
351 
352 	pj_bzero(&sess_cb, sizeof(sess_cb));
353 	sess_cb.on_request_complete = &sess_on_request_complete;
354 	sess_cb.on_send_msg = &sess_on_send_msg;
355 	status = pj_stun_session_create(&stun_sock->stun_cfg,
356 					stun_sock->obj_name,
357 					&sess_cb, PJ_FALSE,
358 					stun_sock->grp_lock,
359 					&stun_sock->stun_sess);
360 	if (status != PJ_SUCCESS)
361 	    goto on_error;
362     }
363 
364     /* Associate us with the STUN session */
365     pj_stun_session_set_user_data(stun_sock->stun_sess, stun_sock);
366 
367     /* Initialize random numbers to be used as STUN transaction ID for
368      * outgoing Binding request. We use the 80bit number to distinguish
369      * STUN messages we sent with STUN messages that the application sends.
370      * The last 16bit value in the array is a counter.
371      */
372     for (i=0; i<PJ_ARRAY_SIZE(stun_sock->tsx_id); ++i) {
373 	stun_sock->tsx_id[i] = (pj_uint16_t) pj_rand();
374     }
375     stun_sock->tsx_id[5] = 0;
376 
377 
378     /* Init timer entry */
379     stun_sock->ka_timer.cb = &ka_timer_cb;
380     stun_sock->ka_timer.user_data = stun_sock;
381 
382     /* Done */
383     *p_stun_sock = stun_sock;
384     return PJ_SUCCESS;
385 
386 on_error:
387     pj_stun_sock_destroy(stun_sock);
388     return status;
389 }
390 
391 /* Start socket. */
pj_stun_sock_start(pj_stun_sock * stun_sock,const pj_str_t * domain,pj_uint16_t default_port,pj_dns_resolver * resolver)392 PJ_DEF(pj_status_t) pj_stun_sock_start( pj_stun_sock *stun_sock,
393 				        const pj_str_t *domain,
394 				        pj_uint16_t default_port,
395 				        pj_dns_resolver *resolver)
396 {
397     pj_status_t status;
398 
399     PJ_ASSERT_RETURN(stun_sock && domain && default_port, PJ_EINVAL);
400 
401     pj_grp_lock_acquire(stun_sock->grp_lock);
402 
403     /* Check whether the domain contains IP address */
404     stun_sock->srv_addr.addr.sa_family = (pj_uint16_t)stun_sock->af;
405     status = pj_inet_pton(stun_sock->af, domain,
406 			  pj_sockaddr_get_addr(&stun_sock->srv_addr));
407     if (status != PJ_SUCCESS) {
408 	stun_sock->srv_addr.addr.sa_family = (pj_uint16_t)0;
409     }
410 
411     /* If resolver is set, try to resolve with DNS SRV first. It
412      * will fallback to DNS A/AAAA when no SRV record is found.
413      */
414     if (status != PJ_SUCCESS && resolver) {
415 	const pj_str_t res_name = pj_str("_stun._udp.");
416 	unsigned opt;
417 
418 	pj_assert(stun_sock->q == NULL);
419 
420 	/* Init DNS resolution option */
421 	if (stun_sock->af == pj_AF_INET6())
422 	    opt = (PJ_DNS_SRV_RESOLVE_AAAA_ONLY | PJ_DNS_SRV_FALLBACK_AAAA);
423 	else
424 	    opt = PJ_DNS_SRV_FALLBACK_A;
425 
426 	stun_sock->last_err = PJ_SUCCESS;
427 	status = pj_dns_srv_resolve(domain, &res_name, default_port,
428 				    stun_sock->pool, resolver, opt,
429 				    stun_sock, &dns_srv_resolver_cb,
430 				    &stun_sock->q);
431 	if (status != PJ_SUCCESS) {
432 	    PJ_PERROR(4,(stun_sock->obj_name, status,
433 			 "Failed in pj_dns_srv_resolve()"));
434 	} else {
435 	    /* DNS SRV callback may have been called here, such as when
436 	     * the result is cached, so we need to check the last error
437 	     * status. If the callback hasn't been called, processing
438 	     * will resume later.
439 	     */
440 	    status = stun_sock->last_err;
441 	    if (stun_sock->last_err != PJ_SUCCESS) {
442 	    	PJ_PERROR(4,(stun_sock->obj_name, status,
443 			     "Failed in sending Binding request (2)"));
444 	    }
445 	}
446 
447     } else {
448 
449 	if (status != PJ_SUCCESS) {
450 	    pj_addrinfo ai;
451 	    unsigned cnt = 1;
452 
453 	    status = pj_getaddrinfo(stun_sock->af, domain, &cnt, &ai);
454 	    if (cnt == 0)
455 		status = PJ_EAFNOTSUP;
456 
457 	    if (status != PJ_SUCCESS) {
458 		PJ_PERROR(4,(stun_sock->obj_name, status,
459 			     "Failed in pj_getaddrinfo()"));
460 	        pj_grp_lock_release(stun_sock->grp_lock);
461 		return status;
462 	    }
463 
464 	    pj_sockaddr_cp(&stun_sock->srv_addr, &ai.ai_addr);
465 	}
466 
467 	pj_sockaddr_set_port(&stun_sock->srv_addr, (pj_uint16_t)default_port);
468 
469 	/* Start sending Binding request */
470 	status = get_mapped_addr(stun_sock);
471 	if (status != PJ_SUCCESS) {
472 	    PJ_PERROR(4,(stun_sock->obj_name, status,
473 			 "Failed in sending Binding request"));
474 	}
475     }
476 
477     pj_grp_lock_release(stun_sock->grp_lock);
478     return status;
479 }
480 
481 /* Destructor */
stun_sock_destructor(void * obj)482 static void stun_sock_destructor(void *obj)
483 {
484     pj_stun_sock *stun_sock = (pj_stun_sock*)obj;
485 
486     if (stun_sock->q) {
487 	pj_dns_srv_cancel_query(stun_sock->q, PJ_FALSE);
488 	stun_sock->q = NULL;
489     }
490 
491     /*
492     if (stun_sock->stun_sess) {
493 	pj_stun_session_destroy(stun_sock->stun_sess);
494 	stun_sock->stun_sess = NULL;
495     }
496     */
497 
498     pj_pool_safe_release(&stun_sock->pool);
499 
500     TRACE_(("", "STUN sock %p destroyed", stun_sock));
501 
502 }
503 
504 /* Destroy */
pj_stun_sock_destroy(pj_stun_sock * stun_sock)505 PJ_DEF(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *stun_sock)
506 {
507     TRACE_((stun_sock->obj_name, "STUN sock %p request, ref_cnt=%d",
508 	    stun_sock, pj_grp_lock_get_ref(stun_sock->grp_lock)));
509 
510     pj_grp_lock_acquire(stun_sock->grp_lock);
511     if (stun_sock->is_destroying) {
512 	/* Destroy already called */
513 	pj_grp_lock_release(stun_sock->grp_lock);
514 	return PJ_EINVALIDOP;
515     }
516 
517     stun_sock->is_destroying = PJ_TRUE;
518     pj_timer_heap_cancel_if_active(stun_sock->stun_cfg.timer_heap,
519                                    &stun_sock->ka_timer, 0);
520 
521     if (stun_sock->active_sock != NULL) {
522 	stun_sock->sock_fd = PJ_INVALID_SOCKET;
523 	pj_activesock_close(stun_sock->active_sock);
524     } else if (stun_sock->sock_fd != PJ_INVALID_SOCKET) {
525 	pj_sock_close(stun_sock->sock_fd);
526 	stun_sock->sock_fd = PJ_INVALID_SOCKET;
527     }
528 
529     if (stun_sock->stun_sess) {
530 	pj_stun_session_destroy(stun_sock->stun_sess);
531     }
532     pj_grp_lock_dec_ref(stun_sock->grp_lock);
533     pj_grp_lock_release(stun_sock->grp_lock);
534     return PJ_SUCCESS;
535 }
536 
537 /* Associate user data */
pj_stun_sock_set_user_data(pj_stun_sock * stun_sock,void * user_data)538 PJ_DEF(pj_status_t) pj_stun_sock_set_user_data( pj_stun_sock *stun_sock,
539 					        void *user_data)
540 {
541     PJ_ASSERT_RETURN(stun_sock, PJ_EINVAL);
542     stun_sock->user_data = user_data;
543     return PJ_SUCCESS;
544 }
545 
546 
547 /* Get user data */
pj_stun_sock_get_user_data(pj_stun_sock * stun_sock)548 PJ_DEF(void*) pj_stun_sock_get_user_data(pj_stun_sock *stun_sock)
549 {
550     PJ_ASSERT_RETURN(stun_sock, NULL);
551     return stun_sock->user_data;
552 }
553 
554 /* Get group lock */
pj_stun_sock_get_grp_lock(pj_stun_sock * stun_sock)555 PJ_DECL(pj_grp_lock_t *) pj_stun_sock_get_grp_lock(pj_stun_sock *stun_sock)
556 {
557     PJ_ASSERT_RETURN(stun_sock, NULL);
558     return stun_sock->grp_lock;
559 }
560 
561 /* Notify application that session has failed */
sess_fail(pj_stun_sock * stun_sock,pj_stun_sock_op op,pj_status_t status)562 static pj_bool_t sess_fail(pj_stun_sock *stun_sock,
563 			   pj_stun_sock_op op,
564 			   pj_status_t status)
565 {
566     pj_bool_t ret;
567 
568     PJ_PERROR(4,(stun_sock->obj_name, status,
569 	         "Session failed because %s failed",
570 		 pj_stun_sock_op_name(op)));
571 
572     ret = (*stun_sock->cb.on_status)(stun_sock, op, status);
573 
574     return ret;
575 }
576 
577 /* DNS resolver callback */
dns_srv_resolver_cb(void * user_data,pj_status_t status,const pj_dns_srv_record * rec)578 static void dns_srv_resolver_cb(void *user_data,
579 				pj_status_t status,
580 				const pj_dns_srv_record *rec)
581 {
582     pj_stun_sock *stun_sock = (pj_stun_sock*) user_data;
583 
584     pj_grp_lock_acquire(stun_sock->grp_lock);
585 
586     /* Clear query */
587     stun_sock->q = NULL;
588 
589     /* Handle error */
590     if (status != PJ_SUCCESS) {
591         stun_sock->last_err = status;
592 	sess_fail(stun_sock, PJ_STUN_SOCK_DNS_OP, status);
593 	pj_grp_lock_release(stun_sock->grp_lock);
594 	return;
595     }
596 
597     pj_assert(rec->count);
598     pj_assert(rec->entry[0].server.addr_count);
599     pj_assert(rec->entry[0].server.addr[0].af == stun_sock->af);
600 
601     /* Set the address */
602     pj_sockaddr_init(stun_sock->af, &stun_sock->srv_addr, NULL,
603 		     rec->entry[0].port);
604     if (stun_sock->af == pj_AF_INET6()) {
605 	stun_sock->srv_addr.ipv6.sin6_addr =
606 				    rec->entry[0].server.addr[0].ip.v6;
607     } else {
608 	stun_sock->srv_addr.ipv4.sin_addr =
609 				    rec->entry[0].server.addr[0].ip.v4;
610     }
611 
612     /* Start sending Binding request */
613     stun_sock->last_err = get_mapped_addr(stun_sock);
614 
615     pj_grp_lock_release(stun_sock->grp_lock);
616 }
617 
618 
619 /* Start sending STUN Binding request */
get_mapped_addr(pj_stun_sock * stun_sock)620 static pj_status_t get_mapped_addr(pj_stun_sock *stun_sock)
621 {
622     pj_stun_tx_data *tdata;
623     pj_status_t status;
624 
625     /* Increment request counter and create STUN Binding request */
626     ++stun_sock->tsx_id[5];
627     status = pj_stun_session_create_req(stun_sock->stun_sess,
628 					PJ_STUN_BINDING_REQUEST,
629 					PJ_STUN_MAGIC,
630 					(const pj_uint8_t*)stun_sock->tsx_id,
631 					&tdata);
632     if (status != PJ_SUCCESS)
633 	goto on_error;
634 
635     /* Send request */
636     status=pj_stun_session_send_msg(stun_sock->stun_sess, INTERNAL_MSG_TOKEN,
637 				    PJ_FALSE, PJ_TRUE, &stun_sock->srv_addr,
638 				    pj_sockaddr_get_len(&stun_sock->srv_addr),
639 				    tdata);
640     if (status != PJ_SUCCESS)
641 	goto on_error;
642 
643     return PJ_SUCCESS;
644 
645 on_error:
646     sess_fail(stun_sock, PJ_STUN_SOCK_BINDING_OP, status);
647     return status;
648 }
649 
650 /* Get info */
pj_stun_sock_get_info(pj_stun_sock * stun_sock,pj_stun_sock_info * info)651 PJ_DEF(pj_status_t) pj_stun_sock_get_info( pj_stun_sock *stun_sock,
652 					   pj_stun_sock_info *info)
653 {
654     int addr_len;
655     pj_status_t status;
656 
657     PJ_ASSERT_RETURN(stun_sock && info, PJ_EINVAL);
658 
659     pj_grp_lock_acquire(stun_sock->grp_lock);
660 
661     /* Copy STUN server address and mapped address */
662     pj_memcpy(&info->srv_addr, &stun_sock->srv_addr,
663 	      sizeof(pj_sockaddr));
664     pj_memcpy(&info->mapped_addr, &stun_sock->mapped_addr,
665 	      sizeof(pj_sockaddr));
666 
667     /* Retrieve bound address */
668     addr_len = sizeof(info->bound_addr);
669     status = pj_sock_getsockname(stun_sock->sock_fd, &info->bound_addr,
670 				 &addr_len);
671     if (status != PJ_SUCCESS) {
672 	pj_grp_lock_release(stun_sock->grp_lock);
673 	return status;
674     }
675 
676     /* If socket is bound to a specific interface, then only put that
677      * interface in the alias list. Otherwise query all the interfaces
678      * in the host.
679      */
680     if (pj_sockaddr_has_addr(&info->bound_addr)) {
681 	info->alias_cnt = 1;
682 	pj_sockaddr_cp(&info->aliases[0], &info->bound_addr);
683     } else {
684 	pj_sockaddr def_addr;
685 	pj_uint16_t port = pj_sockaddr_get_port(&info->bound_addr);
686 	pj_enum_ip_option enum_opt;
687 	unsigned i;
688 
689 	/* Get the default address */
690 	status = pj_gethostip(stun_sock->af, &def_addr);
691 	if (status != PJ_SUCCESS) {
692 	    PJ_PERROR(4,(stun_sock->obj_name, status,
693 			 "Failed in getting default address for STUN info"));
694 	    pj_grp_lock_release(stun_sock->grp_lock);
695 	    return status;
696 	}
697 
698 	pj_sockaddr_set_port(&def_addr, port);
699 
700 	/* Enum all IP interfaces in the host */
701 	pj_enum_ip_option_default(&enum_opt);
702 	enum_opt.af = stun_sock->af;
703 	enum_opt.omit_deprecated_ipv6 = PJ_TRUE;
704 	info->alias_cnt = PJ_ARRAY_SIZE(info->aliases);
705 	status = pj_enum_ip_interface2(&enum_opt, &info->alias_cnt,
706 				       info->aliases);
707 	if (status == PJ_ENOTSUP) {
708 	    /* Try again without omitting deprecated IPv6 addresses */
709 	    enum_opt.omit_deprecated_ipv6 = PJ_FALSE;
710 	    status = pj_enum_ip_interface2(&enum_opt, &info->alias_cnt,
711 					   info->aliases);
712 	}
713 
714 	if (status != PJ_SUCCESS) {
715 	    /* If enumeration fails, just return the default address */
716 	    PJ_PERROR(4,(stun_sock->obj_name, status,
717 			 "Failed in enumerating interfaces for STUN info, "
718 			 "returning default address only"));
719 	    info->alias_cnt = 1;
720 	    pj_sockaddr_cp(&info->aliases[0], &def_addr);
721 	}
722 
723 	/* Set the port number for each address.
724 	 */
725 	for (i=0; i<info->alias_cnt; ++i) {
726 	    pj_sockaddr_set_port(&info->aliases[i], port);
727 	}
728 
729 	/* Put the default IP in the first slot */
730 	for (i=0; i<info->alias_cnt; ++i) {
731 	    if (pj_sockaddr_cmp(&info->aliases[i], &def_addr)==0) {
732 		if (i!=0) {
733 		    pj_sockaddr_cp(&info->aliases[i], &info->aliases[0]);
734 		    pj_sockaddr_cp(&info->aliases[0], &def_addr);
735 		}
736 		break;
737 	    }
738 	}
739     }
740 
741     pj_grp_lock_release(stun_sock->grp_lock);
742     return PJ_SUCCESS;
743 }
744 
745 /* Send application data */
pj_stun_sock_sendto(pj_stun_sock * stun_sock,pj_ioqueue_op_key_t * send_key,const void * pkt,unsigned pkt_len,unsigned flag,const pj_sockaddr_t * dst_addr,unsigned addr_len)746 PJ_DEF(pj_status_t) pj_stun_sock_sendto( pj_stun_sock *stun_sock,
747 					 pj_ioqueue_op_key_t *send_key,
748 					 const void *pkt,
749 					 unsigned pkt_len,
750 					 unsigned flag,
751 					 const pj_sockaddr_t *dst_addr,
752 					 unsigned addr_len)
753 {
754     pj_ssize_t size;
755     pj_status_t status;
756 
757     PJ_ASSERT_RETURN(stun_sock && pkt && dst_addr && addr_len, PJ_EINVAL);
758 
759     pj_grp_lock_acquire(stun_sock->grp_lock);
760 
761     if (!stun_sock->active_sock) {
762 	/* We have been shutdown, but this callback may still get called
763 	 * by retransmit timer.
764 	 */
765 	pj_grp_lock_release(stun_sock->grp_lock);
766 	return PJ_EINVALIDOP;
767     }
768 
769     if (send_key==NULL)
770 	send_key = &stun_sock->send_key;
771 
772     size = pkt_len;
773     status = pj_activesock_sendto(stun_sock->active_sock, send_key,
774                                   pkt, &size, flag, dst_addr, addr_len);
775 
776     pj_grp_lock_release(stun_sock->grp_lock);
777     return status;
778 }
779 
780 /* This callback is called by the STUN session to send packet */
sess_on_send_msg(pj_stun_session * sess,void * token,const void * pkt,pj_size_t pkt_size,const pj_sockaddr_t * dst_addr,unsigned addr_len)781 static pj_status_t sess_on_send_msg(pj_stun_session *sess,
782 				    void *token,
783 				    const void *pkt,
784 				    pj_size_t pkt_size,
785 				    const pj_sockaddr_t *dst_addr,
786 				    unsigned addr_len)
787 {
788     pj_stun_sock *stun_sock;
789     pj_ssize_t size;
790 
791     stun_sock = (pj_stun_sock *) pj_stun_session_get_user_data(sess);
792     if (!stun_sock || !stun_sock->active_sock) {
793 	/* We have been shutdown, but this callback may still get called
794 	 * by retransmit timer.
795 	 */
796 	return PJ_EINVALIDOP;
797     }
798 
799     pj_assert(token==INTERNAL_MSG_TOKEN);
800     PJ_UNUSED_ARG(token);
801 
802     size = pkt_size;
803     return pj_activesock_sendto(stun_sock->active_sock,
804 				&stun_sock->int_send_key,
805 				pkt, &size, 0, dst_addr, addr_len);
806 }
807 
808 /* This callback is called by the STUN session when outgoing transaction
809  * is complete
810  */
sess_on_request_complete(pj_stun_session * sess,pj_status_t status,void * token,pj_stun_tx_data * tdata,const pj_stun_msg * response,const pj_sockaddr_t * src_addr,unsigned src_addr_len)811 static void sess_on_request_complete(pj_stun_session *sess,
812 				     pj_status_t status,
813 				     void *token,
814 				     pj_stun_tx_data *tdata,
815 				     const pj_stun_msg *response,
816 				     const pj_sockaddr_t *src_addr,
817 				     unsigned src_addr_len)
818 {
819     pj_stun_sock *stun_sock;
820     const pj_stun_sockaddr_attr *mapped_attr;
821     pj_stun_sock_op op;
822     pj_bool_t mapped_changed;
823     pj_bool_t resched = PJ_TRUE;
824 
825     stun_sock = (pj_stun_sock *) pj_stun_session_get_user_data(sess);
826     if (!stun_sock)
827 	return;
828 
829     PJ_UNUSED_ARG(tdata);
830     PJ_UNUSED_ARG(token);
831     PJ_UNUSED_ARG(src_addr);
832     PJ_UNUSED_ARG(src_addr_len);
833 
834     /* Check if this is a keep-alive or the first Binding request */
835     if (pj_sockaddr_has_addr(&stun_sock->mapped_addr))
836 	op = PJ_STUN_SOCK_KEEP_ALIVE_OP;
837     else
838 	op = PJ_STUN_SOCK_BINDING_OP;
839 
840     /* Handle failure */
841     if (status != PJ_SUCCESS) {
842 	resched = sess_fail(stun_sock, op, status);
843 	goto on_return;
844     }
845 
846     /* Get XOR-MAPPED-ADDRESS, or MAPPED-ADDRESS when XOR-MAPPED-ADDRESS
847      * doesn't exist.
848      */
849     mapped_attr = (const pj_stun_sockaddr_attr*)
850 		  pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR,
851 					0);
852     if (mapped_attr==NULL) {
853 	mapped_attr = (const pj_stun_sockaddr_attr*)
854 		      pj_stun_msg_find_attr(response, PJ_STUN_ATTR_MAPPED_ADDR,
855 					0);
856     }
857 
858     if (mapped_attr == NULL) {
859 	resched = sess_fail(stun_sock, op, PJNATH_ESTUNNOMAPPEDADDR);
860 	goto on_return;
861     }
862 
863     /* Determine if mapped address has changed, and save the new mapped
864      * address and call callback if so
865      */
866     mapped_changed = !pj_sockaddr_has_addr(&stun_sock->mapped_addr) ||
867 		     pj_sockaddr_cmp(&stun_sock->mapped_addr,
868 				     &mapped_attr->sockaddr) != 0;
869     if (mapped_changed) {
870 	/* Print mapped adress */
871 	{
872 	    char addrinfo[PJ_INET6_ADDRSTRLEN+10];
873 	    PJ_LOG(4,(stun_sock->obj_name,
874 		      "STUN mapped address found/changed: %s",
875 		      pj_sockaddr_print(&mapped_attr->sockaddr,
876 					addrinfo, sizeof(addrinfo), 3)));
877 	}
878 
879 	pj_sockaddr_cp(&stun_sock->mapped_addr, &mapped_attr->sockaddr);
880 
881 	if (op==PJ_STUN_SOCK_KEEP_ALIVE_OP)
882 	    op = PJ_STUN_SOCK_MAPPED_ADDR_CHANGE;
883     }
884 
885     /* Notify user */
886     resched = (*stun_sock->cb.on_status)(stun_sock, op, PJ_SUCCESS);
887 
888 on_return:
889     /* Start/restart keep-alive timer */
890     if (resched)
891 	start_ka_timer(stun_sock);
892 }
893 
894 /* Schedule keep-alive timer */
start_ka_timer(pj_stun_sock * stun_sock)895 static void start_ka_timer(pj_stun_sock *stun_sock)
896 {
897     pj_timer_heap_cancel_if_active(stun_sock->stun_cfg.timer_heap,
898                                    &stun_sock->ka_timer, 0);
899 
900     pj_assert(stun_sock->ka_interval != 0);
901     if (stun_sock->ka_interval > 0 && !stun_sock->is_destroying) {
902 	pj_time_val delay;
903 
904 	delay.sec = stun_sock->ka_interval;
905 	delay.msec = 0;
906 
907 	pj_timer_heap_schedule_w_grp_lock(stun_sock->stun_cfg.timer_heap,
908 	                                  &stun_sock->ka_timer,
909 	                                  &delay, PJ_TRUE,
910 	                                  stun_sock->grp_lock);
911     }
912 }
913 
914 /* Keep-alive timer callback */
ka_timer_cb(pj_timer_heap_t * th,pj_timer_entry * te)915 static void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te)
916 {
917     pj_stun_sock *stun_sock;
918 
919     stun_sock = (pj_stun_sock *) te->user_data;
920 
921     PJ_UNUSED_ARG(th);
922     pj_grp_lock_acquire(stun_sock->grp_lock);
923 
924     /* Time to send STUN Binding request */
925     if (get_mapped_addr(stun_sock) != PJ_SUCCESS) {
926 	pj_grp_lock_release(stun_sock->grp_lock);
927 	return;
928     }
929 
930     /* Next keep-alive timer will be scheduled once the request
931      * is complete.
932      */
933     pj_grp_lock_release(stun_sock->grp_lock);
934 }
935 
936 /* Callback from active socket when incoming packet is received */
on_data_recvfrom(pj_activesock_t * asock,void * data,pj_size_t size,const pj_sockaddr_t * src_addr,int addr_len,pj_status_t status)937 static pj_bool_t on_data_recvfrom(pj_activesock_t *asock,
938 				  void *data,
939 				  pj_size_t size,
940 				  const pj_sockaddr_t *src_addr,
941 				  int addr_len,
942 				  pj_status_t status)
943 {
944     pj_stun_sock *stun_sock;
945     pj_stun_msg_hdr *hdr;
946     pj_uint16_t type;
947 
948     stun_sock = (pj_stun_sock*) pj_activesock_get_user_data(asock);
949     if (!stun_sock)
950 	return PJ_FALSE;
951 
952     /* Log socket error */
953     if (status != PJ_SUCCESS) {
954 	PJ_PERROR(2,(stun_sock->obj_name, status, "recvfrom() error"));
955 	return PJ_TRUE;
956     }
957 
958     pj_grp_lock_acquire(stun_sock->grp_lock);
959 
960     /* Check that this is STUN message */
961     status = pj_stun_msg_check((const pj_uint8_t*)data, size,
962     			       PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET);
963     if (status != PJ_SUCCESS) {
964 	/* Not STUN -- give it to application */
965 	goto process_app_data;
966     }
967 
968     /* Treat packet as STUN header and copy the STUN message type.
969      * We don't want to access the type directly from the header
970      * since it may not be properly aligned.
971      */
972     hdr = (pj_stun_msg_hdr*) data;
973     pj_memcpy(&type, &hdr->type, 2);
974     type = pj_ntohs(type);
975 
976     /* If the packet is a STUN Binding response and part of the
977      * transaction ID matches our internal ID, then this is
978      * our internal STUN message (Binding request or keep alive).
979      * Give it to our STUN session.
980      */
981     if (!PJ_STUN_IS_RESPONSE(type) ||
982 	PJ_STUN_GET_METHOD(type) != PJ_STUN_BINDING_METHOD ||
983 	pj_memcmp(hdr->tsx_id, stun_sock->tsx_id, 10) != 0)
984     {
985 	/* Not STUN Binding response, or STUN transaction ID mismatch.
986 	 * This is not our message too -- give it to application.
987 	 */
988 	goto process_app_data;
989     }
990 
991     /* This is our STUN Binding response. Give it to the STUN session */
992     status = pj_stun_session_on_rx_pkt(stun_sock->stun_sess, data, size,
993 				       PJ_STUN_IS_DATAGRAM, NULL, NULL,
994 				       src_addr, addr_len);
995 
996     status = pj_grp_lock_release(stun_sock->grp_lock);
997 
998     return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE;
999 
1000 process_app_data:
1001     if (stun_sock->cb.on_rx_data) {
1002 	(*stun_sock->cb.on_rx_data)(stun_sock, data, (unsigned)size,
1003 				    src_addr, addr_len);
1004 	status = pj_grp_lock_release(stun_sock->grp_lock);
1005 	return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE;
1006     }
1007 
1008     status = pj_grp_lock_release(stun_sock->grp_lock);
1009     return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE;
1010 }
1011 
1012 /* Callback from active socket about send status */
on_data_sent(pj_activesock_t * asock,pj_ioqueue_op_key_t * send_key,pj_ssize_t sent)1013 static pj_bool_t on_data_sent(pj_activesock_t *asock,
1014 			      pj_ioqueue_op_key_t *send_key,
1015 			      pj_ssize_t sent)
1016 {
1017     pj_stun_sock *stun_sock;
1018 
1019     stun_sock = (pj_stun_sock*) pj_activesock_get_user_data(asock);
1020     if (!stun_sock)
1021 	return PJ_FALSE;
1022 
1023     /* Don't report to callback if this is internal message */
1024     if (send_key == &stun_sock->int_send_key) {
1025 	return PJ_TRUE;
1026     }
1027 
1028     /* Report to callback */
1029     if (stun_sock->cb.on_data_sent) {
1030 	pj_bool_t ret;
1031 
1032 	pj_grp_lock_acquire(stun_sock->grp_lock);
1033 
1034 	/* If app gives NULL send_key in sendto() function, then give
1035 	 * NULL in the callback too
1036 	 */
1037 	if (send_key == &stun_sock->send_key)
1038 	    send_key = NULL;
1039 
1040 	/* Call callback */
1041 	ret = (*stun_sock->cb.on_data_sent)(stun_sock, send_key, sent);
1042 
1043 	pj_grp_lock_release(stun_sock->grp_lock);
1044 	return ret;
1045     }
1046 
1047     return PJ_TRUE;
1048 }
1049 
1050