1 /**
2 * @file stun/rep.c STUN reply
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6 #include <re_types.h>
7 #include <re_mem.h>
8 #include <re_mbuf.h>
9 #include <re_sa.h>
10 #include <re_list.h>
11 #include <re_stun.h>
12 #include "stun.h"
13
14
15 /**
16 * Send a STUN response message
17 *
18 * @param proto Transport Protocol
19 * @param sock Socket; UDP (struct udp_sock) or TCP (struct tcp_conn)
20 * @param dst Destination network address
21 * @param presz Number of bytes in preamble, if sending over TURN
22 * @param req Matching STUN request
23 * @param key Authentication key (optional)
24 * @param keylen Number of bytes in authentication key
25 * @param fp Use STUN Fingerprint attribute
26 * @param attrc Number of attributes to encode (variable arguments)
27 * @param ... Variable list of attribute-tuples
28 * Each attribute has 2 arguments, attribute type and value
29 *
30 * @return 0 if success, otherwise errorcode
31 */
stun_reply(int proto,void * sock,const struct sa * dst,size_t presz,const struct stun_msg * req,const uint8_t * key,size_t keylen,bool fp,uint32_t attrc,...)32 int stun_reply(int proto, void *sock, const struct sa *dst, size_t presz,
33 const struct stun_msg *req, const uint8_t *key,
34 size_t keylen, bool fp, uint32_t attrc, ...)
35 {
36 struct mbuf *mb = NULL;
37 int err = ENOMEM;
38 va_list ap;
39
40 if (!sock || !req)
41 return EINVAL;
42
43 mb = mbuf_alloc(256);
44 if (!mb)
45 goto out;
46
47 va_start(ap, attrc);
48 mb->pos = presz;
49 err = stun_msg_vencode(mb, stun_msg_method(req),
50 STUN_CLASS_SUCCESS_RESP, stun_msg_tid(req),
51 NULL, key, keylen, fp, 0x00, attrc, ap);
52 va_end(ap);
53 if (err)
54 goto out;
55
56 mb->pos = presz;
57 err = stun_send(proto, sock, dst, mb);
58
59 out:
60 mem_deref(mb);
61
62 return err;
63 }
64
65
66 /**
67 * Send a STUN error response
68 *
69 * @param proto Transport Protocol
70 * @param sock Socket; UDP (struct udp_sock) or TCP (struct tcp_conn)
71 * @param dst Destination network address
72 * @param presz Number of bytes in preamble, if sending over TURN
73 * @param req Matching STUN request
74 * @param scode Status code
75 * @param reason Reason string
76 * @param key Authentication key (optional)
77 * @param keylen Number of bytes in authentication key
78 * @param fp Use STUN Fingerprint attribute
79 * @param attrc Number of attributes to encode (variable arguments)
80 * @param ... Variable list of attribute-tuples
81 * Each attribute has 2 arguments, attribute type and value
82 *
83 * @return 0 if success, otherwise errorcode
84 */
stun_ereply(int proto,void * sock,const struct sa * dst,size_t presz,const struct stun_msg * req,uint16_t scode,const char * reason,const uint8_t * key,size_t keylen,bool fp,uint32_t attrc,...)85 int stun_ereply(int proto, void *sock, const struct sa *dst, size_t presz,
86 const struct stun_msg *req, uint16_t scode,
87 const char *reason, const uint8_t *key, size_t keylen,
88 bool fp, uint32_t attrc, ...)
89 {
90 struct stun_errcode ec;
91 struct mbuf *mb = NULL;
92 int err = ENOMEM;
93 va_list ap;
94
95 if (!sock || !req || !scode || !reason)
96 return EINVAL;
97
98 mb = mbuf_alloc(256);
99 if (!mb)
100 goto out;
101
102 ec.code = scode;
103 ec.reason = (char *)reason;
104
105 va_start(ap, attrc);
106 mb->pos = presz;
107 err = stun_msg_vencode(mb, stun_msg_method(req), STUN_CLASS_ERROR_RESP,
108 stun_msg_tid(req), &ec, key, keylen,
109 fp, 0x00, attrc, ap);
110 va_end(ap);
111 if (err)
112 goto out;
113
114 mb->pos = presz;
115 err = stun_send(proto, sock, dst, mb);
116
117 out:
118 mem_deref(mb);
119
120 return err;
121 }
122