Re-resolve the STUN address if a STUN poll fails for res_stun_monitor.
[asterisk/asterisk.git] / main / stun.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2008, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  *
22  * \brief STUN Support
23  *
24  * \author Mark Spencer <markster@digium.com>
25  *
26  * \note STUN is defined in RFC 3489.
27  */
28
29 #include "asterisk.h"
30
31 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32
33 #include "asterisk/_private.h"
34 #include "asterisk/stun.h"
35 #include "asterisk/cli.h"
36 #include "asterisk/utils.h"
37 #include "asterisk/channel.h"
38
39 static int stundebug;                   /*!< Are we debugging stun? */
40
41 /*!
42  * \brief STUN support code
43  *
44  * This code provides some support for doing STUN transactions.
45  * Eventually it should be moved elsewhere as other protocols
46  * than RTP can benefit from it - e.g. SIP.
47  * STUN is described in RFC3489 and it is based on the exchange
48  * of UDP packets between a client and one or more servers to
49  * determine the externally visible address (and port) of the client
50  * once it has gone through the NAT boxes that connect it to the
51  * outside.
52  * The simplest request packet is just the header defined in
53  * struct stun_header, and from the response we may just look at
54  * one attribute, STUN_MAPPED_ADDRESS, that we find in the response.
55  * By doing more transactions with different server addresses we
56  * may determine more about the behaviour of the NAT boxes, of
57  * course - the details are in the RFC.
58  *
59  * All STUN packets start with a simple header made of a type,
60  * length (excluding the header) and a 16-byte random transaction id.
61  * Following the header we may have zero or more attributes, each
62  * structured as a type, length and a value (whose format depends
63  * on the type, but often contains addresses).
64  * Of course all fields are in network format.
65  */
66
67 typedef struct { unsigned int id[4]; } __attribute__((packed)) stun_trans_id;
68
69 struct stun_header {
70         unsigned short msgtype;
71         unsigned short msglen;
72         stun_trans_id  id;
73         unsigned char ies[0];
74 } __attribute__((packed));
75
76 struct stun_attr {
77         unsigned short attr;
78         unsigned short len;
79         unsigned char value[0];
80 } __attribute__((packed));
81
82 /*
83  * The format normally used for addresses carried by STUN messages.
84  */
85 struct stun_addr {
86         unsigned char unused;
87         unsigned char family;
88         unsigned short port;
89         unsigned int addr;
90 } __attribute__((packed));
91
92 /*! \brief STUN message types
93  * 'BIND' refers to transactions used to determine the externally
94  * visible addresses. 'SEC' refers to transactions used to establish
95  * a session key for subsequent requests.
96  * 'SEC' functionality is not supported here.
97  */
98
99 #define STUN_BINDREQ    0x0001
100 #define STUN_BINDRESP   0x0101
101 #define STUN_BINDERR    0x0111
102 #define STUN_SECREQ     0x0002
103 #define STUN_SECRESP    0x0102
104 #define STUN_SECERR     0x0112
105
106 /*! \brief Basic attribute types in stun messages.
107  * Messages can also contain custom attributes (codes above 0x7fff)
108  */
109 #define STUN_MAPPED_ADDRESS     0x0001
110 #define STUN_RESPONSE_ADDRESS   0x0002
111 #define STUN_CHANGE_REQUEST     0x0003
112 #define STUN_SOURCE_ADDRESS     0x0004
113 #define STUN_CHANGED_ADDRESS    0x0005
114 #define STUN_USERNAME           0x0006
115 #define STUN_PASSWORD           0x0007
116 #define STUN_MESSAGE_INTEGRITY  0x0008
117 #define STUN_ERROR_CODE         0x0009
118 #define STUN_UNKNOWN_ATTRIBUTES 0x000a
119 #define STUN_REFLECTED_FROM     0x000b
120
121 /*! \brief helper function to print message names */
122 static const char *stun_msg2str(int msg)
123 {
124         switch (msg) {
125         case STUN_BINDREQ:
126                 return "Binding Request";
127         case STUN_BINDRESP:
128                 return "Binding Response";
129         case STUN_BINDERR:
130                 return "Binding Error Response";
131         case STUN_SECREQ:
132                 return "Shared Secret Request";
133         case STUN_SECRESP:
134                 return "Shared Secret Response";
135         case STUN_SECERR:
136                 return "Shared Secret Error Response";
137         }
138         return "Non-RFC3489 Message";
139 }
140
141 /*! \brief helper function to print attribute names */
142 static const char *stun_attr2str(int msg)
143 {
144         switch (msg) {
145         case STUN_MAPPED_ADDRESS:
146                 return "Mapped Address";
147         case STUN_RESPONSE_ADDRESS:
148                 return "Response Address";
149         case STUN_CHANGE_REQUEST:
150                 return "Change Request";
151         case STUN_SOURCE_ADDRESS:
152                 return "Source Address";
153         case STUN_CHANGED_ADDRESS:
154                 return "Changed Address";
155         case STUN_USERNAME:
156                 return "Username";
157         case STUN_PASSWORD:
158                 return "Password";
159         case STUN_MESSAGE_INTEGRITY:
160                 return "Message Integrity";
161         case STUN_ERROR_CODE:
162                 return "Error Code";
163         case STUN_UNKNOWN_ATTRIBUTES:
164                 return "Unknown Attributes";
165         case STUN_REFLECTED_FROM:
166                 return "Reflected From";
167         }
168         return "Non-RFC3489 Attribute";
169 }
170
171 /*! \brief here we store credentials extracted from a message */
172 struct stun_state {
173         const char *username;
174         const char *password;
175 };
176
177 static int stun_process_attr(struct stun_state *state, struct stun_attr *attr)
178 {
179         if (stundebug)
180                 ast_verbose("Found STUN Attribute %s (%04x), length %d\n",
181                             stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
182         switch (ntohs(attr->attr)) {
183         case STUN_USERNAME:
184                 state->username = (const char *) (attr->value);
185                 break;
186         case STUN_PASSWORD:
187                 state->password = (const char *) (attr->value);
188                 break;
189         default:
190                 if (stundebug)
191                         ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n",
192                                     stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
193         }
194         return 0;
195 }
196
197 /*! \brief append a string to an STUN message */
198 static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
199 {
200         int size = sizeof(**attr) + strlen(s);
201         if (*left > size) {
202                 (*attr)->attr = htons(attrval);
203                 (*attr)->len = htons(strlen(s));
204                 memcpy((*attr)->value, s, strlen(s));
205                 (*attr) = (struct stun_attr *)((*attr)->value + strlen(s));
206                 *len += size;
207                 *left -= size;
208         }
209 }
210
211 /*! \brief append an address to an STUN message */
212 static void append_attr_address(struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left)
213 {
214         int size = sizeof(**attr) + 8;
215         struct stun_addr *addr;
216         if (*left > size) {
217                 (*attr)->attr = htons(attrval);
218                 (*attr)->len = htons(8);
219                 addr = (struct stun_addr *)((*attr)->value);
220                 addr->unused = 0;
221                 addr->family = 0x01;
222                 addr->port = sin->sin_port;
223                 addr->addr = sin->sin_addr.s_addr;
224                 (*attr) = (struct stun_attr *)((*attr)->value + 8);
225                 *len += size;
226                 *left -= size;
227         }
228 }
229
230 /*! \brief wrapper to send an STUN message */
231 static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp)
232 {
233         return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0,
234                       (struct sockaddr *)dst, sizeof(*dst));
235 }
236
237 /*!
238  * \internal
239  * \brief Compare the STUN tranaction IDs.
240  *
241  * \param left Transaction ID.
242  * \param right Transaction ID.
243  *
244  * \retval 0 if match.
245  * \retval non-zero if not match.
246  */
247 static int stun_id_cmp(stun_trans_id *left, stun_trans_id *right)
248 {
249         return memcmp(left, right, sizeof(*left));
250 }
251
252 /*! \brief helper function to generate a random request id */
253 static void stun_req_id(struct stun_header *req)
254 {
255         int x;
256         for (x = 0; x < 4; x++)
257                 req->id.id[x] = ast_random();
258 }
259
260 int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
261 {
262         struct stun_header *hdr = (struct stun_header *)data;
263         struct stun_attr *attr;
264         struct stun_state st;
265         int ret = AST_STUN_IGNORE;
266         int x;
267
268         /* On entry, 'len' is the length of the udp payload. After the
269          * initial checks it becomes the size of unprocessed options,
270          * while 'data' is advanced accordingly.
271          */
272         if (len < sizeof(struct stun_header)) {
273                 ast_debug(1, "Runt STUN packet (only %d, wanting at least %d)\n", (int) len, (int) sizeof(struct stun_header));
274                 return -1;
275         }
276         len -= sizeof(struct stun_header);
277         data += sizeof(struct stun_header);
278         x = ntohs(hdr->msglen); /* len as advertised in the message */
279         if (stundebug)
280                 ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), x);
281         if (x > len) {
282                 ast_debug(1, "Scrambled STUN packet length (got %d, expecting %d)\n", x, (int)len);
283         } else
284                 len = x;
285         memset(&st, 0, sizeof(st));
286         while (len) {
287                 if (len < sizeof(struct stun_attr)) {
288                         ast_debug(1, "Runt Attribute (got %d, expecting %d)\n", (int)len, (int) sizeof(struct stun_attr));
289                         break;
290                 }
291                 attr = (struct stun_attr *)data;
292                 /* compute total attribute length */
293                 x = ntohs(attr->len) + sizeof(struct stun_attr);
294                 if (x > len) {
295                         ast_debug(1, "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n", x, (int)len);
296                         break;
297                 }
298                 if (stun_cb)
299                         stun_cb(attr, arg);
300                 if (stun_process_attr(&st, attr)) {
301                         ast_debug(1, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr));
302                         break;
303                 }
304                 /* Clear attribute id: in case previous entry was a string,
305                  * this will act as the terminator for the string.
306                  */
307                 attr->attr = 0;
308                 data += x;
309                 len -= x;
310         }
311         /* Null terminate any string.
312          * XXX NOTE, we write past the size of the buffer passed by the
313          * caller, so this is potentially dangerous. The only thing that
314          * saves us is that usually we read the incoming message in a
315          * much larger buffer in the struct ast_rtp
316          */
317         *data = '\0';
318
319         /* Now prepare to generate a reply, which at the moment is done
320          * only for properly formed (len == 0) STUN_BINDREQ messages.
321          */
322         if (len == 0) {
323                 unsigned char respdata[1024];
324                 struct stun_header *resp = (struct stun_header *)respdata;
325                 int resplen = 0;        /* len excluding header */
326                 int respleft = sizeof(respdata) - sizeof(struct stun_header);
327
328                 resp->id = hdr->id;
329                 resp->msgtype = 0;
330                 resp->msglen = 0;
331                 attr = (struct stun_attr *)resp->ies;
332                 switch (ntohs(hdr->msgtype)) {
333                 case STUN_BINDREQ:
334                         if (stundebug)
335                                 ast_verbose("STUN Bind Request, username: %s\n",
336                                             st.username ? st.username : "<none>");
337                         if (st.username)
338                                 append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, &respleft);
339                         append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft);
340                         resp->msglen = htons(resplen);
341                         resp->msgtype = htons(STUN_BINDRESP);
342                         stun_send(s, src, resp);
343                         ret = AST_STUN_ACCEPT;
344                         break;
345                 default:
346                         if (stundebug)
347                                 ast_verbose("Dunno what to do with STUN message %04x (%s)\n", ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype)));
348                 }
349         }
350         return ret;
351 }
352
353 /*! \brief Extract the STUN_MAPPED_ADDRESS from the stun response.
354  * This is used as a callback for stun_handle_response
355  * when called from ast_stun_request.
356  */
357 static int stun_get_mapped(struct stun_attr *attr, void *arg)
358 {
359         struct stun_addr *addr = (struct stun_addr *)(attr + 1);
360         struct sockaddr_in *sa = (struct sockaddr_in *)arg;
361
362         if (ntohs(attr->attr) != STUN_MAPPED_ADDRESS || ntohs(attr->len) != 8)
363                 return 1;       /* not us. */
364         sa->sin_port = addr->port;
365         sa->sin_addr.s_addr = addr->addr;
366         return 0;
367 }
368
369 int ast_stun_request(int s, struct sockaddr_in *dst,
370         const char *username, struct sockaddr_in *answer)
371 {
372         struct stun_header *req;
373         struct stun_header *rsp;
374         unsigned char req_buf[1024];
375         unsigned char rsp_buf[1024];
376         int reqlen, reqleft;
377         struct stun_attr *attr;
378         int res = -1;
379         int retry;
380
381         if (answer) {
382                 /* Always clear answer in case the request fails. */
383                 memset(answer, 0, sizeof(struct sockaddr_in));
384         }
385
386         /* Create STUN bind request */
387         req = (struct stun_header *) req_buf;
388         stun_req_id(req);
389         reqlen = 0;
390         reqleft = sizeof(req_buf) - sizeof(struct stun_header);
391         req->msgtype = 0;
392         req->msglen = 0;
393         attr = (struct stun_attr *) req->ies;
394         if (username) {
395                 append_attr_string(&attr, STUN_USERNAME, username, &reqlen, &reqleft);
396         }
397         req->msglen = htons(reqlen);
398         req->msgtype = htons(STUN_BINDREQ);
399
400         for (retry = 0; retry++ < 3;) { /* XXX make retries configurable */
401                 /* send request, possibly wait for reply */
402                 struct sockaddr_in src;
403                 socklen_t srclen;
404
405                 /* Send STUN message. */
406                 res = stun_send(s, dst, req);
407                 if (res < 0) {
408                         ast_debug(1, "stun_send try %d failed: %s\n", retry, strerror(errno));
409                         break;
410                 }
411                 if (!answer) {
412                         /* Successful send since we don't care about any response. */
413                         res = 0;
414                         break;
415                 }
416
417 try_again:
418                 /* Wait for response. */
419                 {
420                         struct pollfd pfds = { .fd = s, .events = POLLIN };
421
422                         res = ast_poll(&pfds, 1, 3000);
423                         if (res < 0) {
424                                 /* Error */
425                                 continue;
426                         }
427                         if (!res) {
428                                 /* No response, timeout */
429                                 res = 1;
430                                 continue;
431                         }
432                 }
433
434                 /* Read STUN response. */
435                 memset(&src, 0, sizeof(src));
436                 srclen = sizeof(src);
437                 /* XXX pass sizeof(rsp_buf) - 1 in the size, because stun_handle_packet might
438                  * write past the end of the buffer.
439                  */
440                 res = recvfrom(s, rsp_buf, sizeof(rsp_buf) - 1,
441                         0, (struct sockaddr *) &src, &srclen);
442                 if (res < 0) {
443                         ast_debug(1, "recvfrom try %d failed: %s\n", retry, strerror(errno));
444                         break;
445                 }
446
447                 /* Process the STUN response. */
448                 rsp = (struct stun_header *) rsp_buf;
449                 if (ast_stun_handle_packet(s, &src, rsp_buf, res, stun_get_mapped, answer)
450                         || (rsp->msgtype != htons(STUN_BINDRESP)
451                                 && rsp->msgtype != htons(STUN_BINDERR))
452                         || stun_id_cmp(&req->id, &rsp->id)) {
453                         /* Bad STUN packet, not right type, or transaction ID did not match. */
454                         memset(answer, 0, sizeof(struct sockaddr_in));
455
456                         /* Was not a resonse to our request. */
457                         goto try_again;
458                 }
459                 /* Success.  answer contains the external address if available. */
460                 res = 0;
461                 break;
462         }
463         return res;
464 }
465
466 static char *handle_cli_stun_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
467 {
468         switch (cmd) {
469         case CLI_INIT:
470                 e->command = "stun set debug {on|off}";
471                 e->usage =
472                         "Usage: stun set debug {on|off}\n"
473                         "       Enable/Disable STUN (Simple Traversal of UDP through NATs)\n"
474                         "       debugging\n";
475                 return NULL;
476         case CLI_GENERATE:
477                 return NULL;
478         }
479
480         if (a->argc != e->args)
481                 return CLI_SHOWUSAGE;
482
483         if (!strncasecmp(a->argv[e->args-1], "on", 2))
484                 stundebug = 1;
485         else if (!strncasecmp(a->argv[e->args-1], "off", 3))
486                 stundebug = 0;
487         else
488                 return CLI_SHOWUSAGE;
489
490         ast_cli(a->fd, "STUN Debugging %s\n", stundebug ? "Enabled" : "Disabled");
491         return CLI_SUCCESS;
492 }
493
494 static struct ast_cli_entry cli_stun[] = {
495         AST_CLI_DEFINE(handle_cli_stun_set_debug, "Enable/Disable STUN debugging"),
496 };
497
498 /*! \brief Initialize the STUN system in Asterisk */
499 void ast_stun_init(void)
500 {
501         ast_cli_register_multiple(cli_stun, sizeof(cli_stun) / sizeof(struct ast_cli_entry));
502 }