1 /**
2  * @file stun/req.c  STUN request
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #include <re_types.h>
7 #include <re_sys.h>
8 #include <re_mem.h>
9 #include <re_mbuf.h>
10 #include <re_sa.h>
11 #include <re_list.h>
12 #include <re_stun.h>
13 #include "stun.h"
14 
15 
16 /**
17  * Send a STUN request using a client transaction
18  *
19  * @param ctp     Pointer to allocated client transaction (optional)
20  * @param stun    STUN Instance
21  * @param proto   Transport Protocol
22  * @param sock    Socket; UDP (struct udp_sock) or TCP (struct tcp_conn)
23  * @param dst     Destination network address
24  * @param presz   Number of bytes in preamble, if sending over TURN
25  * @param method  STUN Method
26  * @param key     Authentication key (optional)
27  * @param keylen  Number of bytes in authentication key
28  * @param fp      Use STUN Fingerprint attribute
29  * @param resph   Response handler
30  * @param arg     Response handler argument
31  * @param attrc   Number of attributes to encode (variable arguments)
32  * @param ...     Variable list of attribute-tuples
33  *                Each attribute has 2 arguments, attribute type and value
34  *
35  * @return 0 if success, otherwise errorcode
36  */
37 int stun_request(struct stun_ctrans **ctp, struct stun *stun, int proto,
38 		 void *sock, const struct sa *dst, size_t presz,
39 		 uint16_t method, const uint8_t *key, size_t keylen, bool fp,
40 		 stun_resp_h *resph, void *arg, uint32_t attrc, ...)
41 {
42 	uint8_t tid[STUN_TID_SIZE];
43 	struct mbuf *mb;
44 	uint32_t i;
45 	va_list ap;
46 	int err;
47 
48 	if (!stun)
49 		return EINVAL;
50 
51 	mb = mbuf_alloc(512);
52 	if (!mb)
53 		return ENOMEM;
54 
55 	for (i=0; i<STUN_TID_SIZE; i++)
56 		tid[i] = rand_u32();
57 
58 	va_start(ap, attrc);
59 	mb->pos = presz;
60 	err = stun_msg_vencode(mb, method, STUN_CLASS_REQUEST,
61 			       tid, NULL, key, keylen, fp, 0x00, attrc, ap);
62 	va_end(ap);
63 	if (err)
64 		goto out;
65 
66 	mb->pos = presz;
67 	err = stun_ctrans_request(ctp, stun, proto, sock, dst, mb, tid, method,
68 				  key, keylen, resph, arg);
69 	if (err)
70 		goto out;
71 
72  out:
73 	mem_deref(mb);
74 
75 	return err;
76 }
77