Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / stun / stunmessage.h
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2008-2009 Collabora Ltd.
5  *  Contact: Youness Alaoui
6  * (C) 2008-2009 Nokia Corporation. All rights reserved.
7  *  Contact: Rémi Denis-Courmont
8  *
9  * The contents of this file are subject to the Mozilla Public License Version
10  * 1.1 (the "License"); you may not use this file except in compliance with
11  * the License. You may obtain a copy of the License at
12  * http://www.mozilla.org/MPL/
13  *
14  * Software distributed under the License is distributed on an "AS IS" basis,
15  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16  * for the specific language governing rights and limitations under the
17  * License.
18  *
19  * The Original Code is the Nice GLib ICE library.
20  *
21  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
22  * Corporation. All Rights Reserved.
23  *
24  * Contributors:
25  *   Youness Alaoui, Collabora Ltd.
26  *   Rémi Denis-Courmont, Nokia
27  *
28  * Alternatively, the contents of this file may be used under the terms of the
29  * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
30  * case the provisions of LGPL are applicable instead of those above. If you
31  * wish to allow use of your version of this file only under the terms of the
32  * LGPL and not to allow others to use your version of this file under the
33  * MPL, indicate your decision by deleting the provisions above and replace
34  * them with the notice and other provisions required by the LGPL. If you do
35  * not delete the provisions above, a recipient may use your version of this
36  * file under either the MPL or the LGPL.
37  */
38
39 #ifndef _STUN_MESSAGE_H
40 #define _STUN_MESSAGE_H
41
42
43 /**
44  * SECTION:stunmessage
45  * @short_description: STUN messages parsing and formatting functions
46  * @include: stun/stunmessage.h
47  * @see_also: #StunAgent
48  * @stability: Stable
49  *
50  * The STUN Messages API allows you to create STUN messages easily as well as to
51  * parse existing messages.
52  *
53  */
54
55
56 #ifdef _WIN32
57 #include "win32_common.h"
58 #else
59 #include <stdint.h>
60 #include <stdbool.h>
61 #endif
62
63 #include <sys/types.h>
64
65 #ifdef _WIN32
66 #include <winsock2.h>
67 #include <ws2tcpip.h>
68 #else
69 #include <sys/socket.h>
70 #include <arpa/inet.h>
71 #endif
72
73 #include "constants.h"
74
75 typedef struct _StunMessage StunMessage;
76
77 /**
78  * StunClass:
79  * @STUN_REQUEST: A STUN Request message
80  * @STUN_INDICATION: A STUN indication message
81  * @STUN_RESPONSE: A STUN Response message
82  * @STUN_ERROR: A STUN Error message
83  *
84  * This enum is used to represent the class of
85  * a STUN message, as defined in RFC5389
86  */
87
88 /* Message classes */
89 typedef enum
90 {
91   STUN_REQUEST=0,
92   STUN_INDICATION=1,
93   STUN_RESPONSE=2,
94   STUN_ERROR=3
95 } StunClass;
96
97
98 /**
99  * StunMethod:
100  * @STUN_BINDING: The Binding method as defined by the RFC5389
101  * @STUN_SHARED_SECRET: The Shared-Secret method as defined by the RFC3489
102  * @STUN_ALLOCATE: The Allocate method as defined by the TURN draft 12
103  * @STUN_SET_ACTIVE_DST: The Set-Active-Destination method as defined by
104  * the TURN draft 4
105  * @STUN_REFRESH: The Refresh method as defined by the TURN draft 12
106  * @STUN_SEND: The Send method as defined by the TURN draft 00
107  * @STUN_CONNECT: The Connect method as defined by the TURN draft 4
108  * @STUN_OLD_SET_ACTIVE_DST: The older Set-Active-Destination method as
109  * defined by the TURN draft 0
110  * @STUN_IND_SEND: The Send method used in indication messages as defined
111  * by the TURN draft 12
112  * @STUN_IND_DATA: The Data method used in indication messages as defined
113  * by the TURN draft 12
114  * @STUN_IND_CONNECT_STATUS:  The Connect-Status method used in indication
115  * messages as defined by the TURN draft 4
116  * @STUN_CREATEPERMISSION: The CreatePermission method as defined by
117  * the TURN draft 12
118  * @STUN_CHANNELBIND: The ChannelBind method as defined by the TURN draft 12
119  *
120  * This enum is used to represent the method of
121  * a STUN message, as defined by various RFCs
122  */
123 /* Message methods */
124 typedef enum
125 {
126   STUN_BINDING=0x001,    /* RFC5389 */
127   STUN_SHARED_SECRET=0x002,  /* old RFC3489 */
128   STUN_ALLOCATE=0x003,    /* TURN-12 */
129   STUN_SET_ACTIVE_DST=0x004,  /* TURN-04 */
130   STUN_REFRESH=0x004,  /* TURN-12 */
131   STUN_SEND=0x004,  /* TURN-00 */
132   STUN_CONNECT=0x005,    /* TURN-04 */
133   STUN_OLD_SET_ACTIVE_DST=0x006,  /* TURN-00 */
134   STUN_IND_SEND=0x006,    /* TURN-12 */
135   STUN_IND_DATA=0x007,    /* TURN-12 */
136   STUN_IND_CONNECT_STATUS=0x008,  /* TURN-04 */
137   STUN_CREATEPERMISSION= 0x008, /* TURN-12 */
138   STUN_CHANNELBIND= 0x009 /* TURN-12 */
139 } StunMethod;
140
141 /**
142  * StunAttribute:
143  * @STUN_ATTRIBUTE_MAPPED_ADDRESS: The MAPPED-ADDRESS attribute as defined
144  * by RFC5389
145  * @STUN_ATTRIBUTE_RESPONSE_ADDRESS: The RESPONSE-ADDRESS attribute as defined
146  * by RFC3489
147  * @STUN_ATTRIBUTE_CHANGE_REQUEST: The CHANGE-REQUEST attribute as defined by
148  * RFC3489
149  * @STUN_ATTRIBUTE_SOURCE_ADDRESS: The SOURCE-ADDRESS attribute as defined by
150  * RFC3489
151  * @STUN_ATTRIBUTE_CHANGED_ADDRESS: The CHANGED-ADDRESS attribute as defined
152  * by RFC3489
153  * @STUN_ATTRIBUTE_USERNAME: The USERNAME attribute as defined by RFC5389
154  * @STUN_ATTRIBUTE_PASSWORD: The PASSWORD attribute as defined by RFC3489
155  * @STUN_ATTRIBUTE_MESSAGE_INTEGRITY: The MESSAGE-INTEGRITY attribute as defined
156  * by RFC5389
157  * @STUN_ATTRIBUTE_ERROR_CODE: The ERROR-CODE attribute as defined by RFC5389
158  * @STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES: The UNKNOWN-ATTRIBUTES attribute as
159  * defined by RFC5389
160  * @STUN_ATTRIBUTE_REFLECTED_FROM: The REFLECTED-FROM attribute as defined
161  * by RFC3489
162  * @STUN_ATTRIBUTE_CHANNEL_NUMBER: The CHANNEL-NUMBER attribute as defined by
163  * TURN draft 09 and 12
164  * @STUN_ATTRIBUTE_LIFETIME: The LIFETIME attribute as defined by TURN
165  * draft 04, 09 and 12
166  * @STUN_ATTRIBUTE_MS_ALTERNATE_SERVER: The ALTERNATE-SERVER attribute as
167  * defined by [MS-TURN]
168  * @STUN_ATTRIBUTE_MAGIC_COOKIE: The MAGIC-COOKIE attribute as defined by
169  * the rosenberg-midcom TURN draft 08
170  * @STUN_ATTRIBUTE_BANDWIDTH: The BANDWIDTH attribute as defined by TURN draft 04
171  * @STUN_ATTRIBUTE_DESTINATION_ADDRESS: The DESTINATION-ADDRESS attribute as
172  * defined by the rosenberg-midcom TURN draft 08
173  * @STUN_ATTRIBUTE_REMOTE_ADDRESS: The REMOTE-ADDRESS attribute as defined by
174  * TURN draft 04
175  * @STUN_ATTRIBUTE_PEER_ADDRESS: The PEER-ADDRESS attribute as defined by
176  * TURN draft 09
177  * @STUN_ATTRIBUTE_XOR_PEER_ADDRESS: The XOR-PEER-ADDRESS attribute as defined
178  * by TURN draft 12
179  * @STUN_ATTRIBUTE_DATA: The DATA attribute as defined by TURN draft 04,
180  * 09 and 12
181  * @STUN_ATTRIBUTE_REALM: The REALM attribute as defined by RFC5389
182  * @STUN_ATTRIBUTE_NONCE: The NONCE attribute as defined by RFC5389
183  * @STUN_ATTRIBUTE_RELAY_ADDRESS: The RELAY-ADDRESS attribute as defined by
184  * TURN draft 04
185  * @STUN_ATTRIBUTE_RELAYED_ADDRESS: The RELAYED-ADDRESS attribute as defined by
186  * TURN draft 09
187  * @STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS: The XOR-RELAYED-ADDRESS attribute as
188  * defined by TURN draft 12
189  * @STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE: The REQUESTED-ADDRESS-TYPE attribute
190  * as defined by TURN-IPV6 draft 05
191  * @STUN_ATTRIBUTE_REQUESTED_PORT_PROPS: The REQUESTED-PORT-PROPS attribute
192  * as defined by TURN draft 04
193  * @STUN_ATTRIBUTE_REQUESTED_PROPS: The REQUESTED-PROPS attribute as defined
194  * by TURN draft 09
195  * @STUN_ATTRIBUTE_EVEN_PORT: The EVEN-PORT attribute as defined by TURN draft 12
196  * @STUN_ATTRIBUTE_REQUESTED_TRANSPORT: The REQUESTED-TRANSPORT attribute as
197  * defined by TURN draft 12
198  * @STUN_ATTRIBUTE_DONT_FRAGMENT: The DONT-FRAGMENT attribute as defined
199  * by TURN draft 12
200  * @STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS: The XOR-MAPPED-ADDRESS attribute as
201  * defined by RFC5389
202  * @STUN_ATTRIBUTE_TIMER_VAL: The TIMER-VAL attribute as defined by TURN draft 04
203  * @STUN_ATTRIBUTE_REQUESTED_IP: The REQUESTED-IP attribute as defined by
204  * TURN draft 04
205  * @STUN_ATTRIBUTE_RESERVATION_TOKEN: The RESERVATION-TOKEN attribute as defined
206  * by TURN draft 09 and 12
207  * @STUN_ATTRIBUTE_CONNECT_STAT: The CONNECT-STAT attribute as defined by TURN
208  * draft 04
209  * @STUN_ATTRIBUTE_PRIORITY: The PRIORITY attribute as defined by ICE draft 19
210  * @STUN_ATTRIBUTE_USE_CANDIDATE: The USE-CANDIDATE attribute as defined by
211  * ICE draft 19
212  * @STUN_ATTRIBUTE_OPTIONS: The OPTIONS optional attribute as defined by
213  * libjingle
214  * @STUN_ATTRIBUTE_MS_VERSION: The MS-VERSION optional attribute as defined
215  * by [MS-TURN]
216  * @STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS: The XOR-MAPPED-ADDRESS optional
217  * attribute as defined by [MS-TURN]
218  * @STUN_ATTRIBUTE_SOFTWARE: The SOFTWARE optional attribute as defined by RFC5389
219  * @STUN_ATTRIBUTE_ALTERNATE_SERVER: The ALTERNATE-SERVER optional attribute as
220  * defined by RFC5389
221  * @STUN_ATTRIBUTE_FINGERPRINT: The FINGERPRINT optional attribute as defined
222  * by RFC5389
223  * @STUN_ATTRIBUTE_ICE_CONTROLLED: The ICE-CONTROLLED optional attribute as
224  * defined by ICE draft 19
225  * @STUN_ATTRIBUTE_ICE_CONTROLLING: The ICE-CONTROLLING optional attribute as
226  * defined by ICE draft 19
227  * @STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER: The MS-SEQUENCE NUMBER optional attribute
228  * as defined by [MS-TURN]
229  * @STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER: The CANDIDATE-IDENTIFIER optional
230  * attribute as defined by [MS-ICE2]
231  * @STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION: The IMPLEMENTATION-VERSION
232  * optional attribute as defined by [MS-ICE2]
233  * @STUN_ATTRIBUTE_NOMINATION: The NOMINATION attribute as defined by
234  * draft-thatcher-ice-renomination-00 and deployed in Google Chrome
235  *
236  * Known STUN attribute types as defined by various RFCs and drafts
237  */
238 /* Should be in sync with stun_is_unknown() */
239 typedef enum
240 {
241   /* Mandatory attributes */
242   /* 0x0000 */        /* reserved */
243   STUN_ATTRIBUTE_MAPPED_ADDRESS=0x0001,    /* RFC5389 */
244   STUN_ATTRIBUTE_RESPONSE_ADDRESS=0x0002,  /* old RFC3489 */
245   STUN_ATTRIBUTE_CHANGE_REQUEST=0x0003,    /* old RFC3489 */
246   STUN_ATTRIBUTE_SOURCE_ADDRESS=0x0004,    /* old RFC3489 */
247   STUN_ATTRIBUTE_CHANGED_ADDRESS=0x0005,  /* old RFC3489 */
248   STUN_ATTRIBUTE_USERNAME=0x0006,      /* RFC5389 */
249   STUN_ATTRIBUTE_PASSWORD=0x0007,    /* old RFC3489 */
250   STUN_ATTRIBUTE_MESSAGE_INTEGRITY=0x0008,    /* RFC5389 */
251   STUN_ATTRIBUTE_ERROR_CODE=0x0009,      /* RFC5389 */
252   STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES=0x000A,    /* RFC5389 */
253   STUN_ATTRIBUTE_REFLECTED_FROM=0x000B,    /* old RFC3489 */
254   STUN_ATTRIBUTE_CHANNEL_NUMBER=0x000C,        /* TURN-12 */
255   STUN_ATTRIBUTE_LIFETIME=0x000D,      /* TURN-12 */
256   /* MS_ALTERNATE_SERVER is only used by Microsoft's dialect, probably should
257    * not to be placed in STUN_ALL_KNOWN_ATTRIBUTES */
258   STUN_ATTRIBUTE_MS_ALTERNATE_SERVER=0x000E, /* MS-TURN */
259   STUN_ATTRIBUTE_MAGIC_COOKIE=0x000F,        /* midcom-TURN 08 */
260   STUN_ATTRIBUTE_BANDWIDTH=0x0010,      /* TURN-04 */
261   STUN_ATTRIBUTE_DESTINATION_ADDRESS=0x0011,        /* midcom-TURN 08 */
262   STUN_ATTRIBUTE_REMOTE_ADDRESS=0x0012,    /* TURN-04 */
263   STUN_ATTRIBUTE_PEER_ADDRESS=0x0012,    /* TURN-09 */
264   STUN_ATTRIBUTE_XOR_PEER_ADDRESS=0x0012,    /* TURN-12 */
265   STUN_ATTRIBUTE_DATA=0x0013,      /* TURN-12 */
266   STUN_ATTRIBUTE_REALM=0x0014,      /* RFC5389 */
267   STUN_ATTRIBUTE_NONCE=0x0015,      /* RFC5389 */
268   STUN_ATTRIBUTE_RELAY_ADDRESS=0x0016,    /* TURN-04 */
269   STUN_ATTRIBUTE_RELAYED_ADDRESS=0x0016,    /* TURN-09 */
270   STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS=0x0016,    /* TURN-12 */
271   STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE=0x0017,  /* TURN-IPv6-05 */
272   STUN_ATTRIBUTE_REQUESTED_PORT_PROPS=0x0018,  /* TURN-04 */
273   STUN_ATTRIBUTE_REQUESTED_PROPS=0x0018,  /* TURN-09 */
274   STUN_ATTRIBUTE_EVEN_PORT=0x0018,  /* TURN-12 */
275   STUN_ATTRIBUTE_REQUESTED_TRANSPORT=0x0019,  /* TURN-12 */
276   STUN_ATTRIBUTE_DONT_FRAGMENT=0x001A,  /* TURN-12 */
277   /* 0x001B */        /* reserved */
278   /* 0x001C */        /* reserved */
279   /* 0x001D */        /* reserved */
280   /* 0x001E */        /* reserved */
281   /* 0x001F */        /* reserved */
282   STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS=0x0020,    /* RFC5389 */
283   STUN_ATTRIBUTE_TIMER_VAL=0x0021,      /* TURN-04 */
284   STUN_ATTRIBUTE_REQUESTED_IP=0x0022,    /* TURN-04 */
285   STUN_ATTRIBUTE_RESERVATION_TOKEN=0x0022,    /* TURN-09 */
286   STUN_ATTRIBUTE_CONNECT_STAT=0x0023,    /* TURN-04 */
287   STUN_ATTRIBUTE_PRIORITY=0x0024,      /* ICE-19 */
288   STUN_ATTRIBUTE_USE_CANDIDATE=0x0025,    /* ICE-19 */
289   /* 0x0026 */        /* reserved */
290   /* 0x0027 */        /* reserved */
291   /* 0x0028 */        /* reserved */
292   /* 0x0029 */        /* reserved */
293   /* 0x002A-0x7fff */      /* reserved */
294
295   /* Optional attributes */
296   /* 0x8000-0x8021 */      /* reserved */
297   STUN_ATTRIBUTE_OPTIONS=0x8001, /* libjingle */
298   STUN_ATTRIBUTE_MS_VERSION=0x8008,    /* MS-TURN */
299   STUN_ATTRIBUTE_MS_XOR_MAPPED_ADDRESS=0x8020,    /* MS-TURN */
300   STUN_ATTRIBUTE_SOFTWARE=0x8022,      /* RFC5389 */
301   STUN_ATTRIBUTE_ALTERNATE_SERVER=0x8023,    /* RFC5389 */
302   /* 0x8024 */        /* reserved */
303   /* 0x8025 */        /* reserved */
304   /* 0x8026 */        /* reserved */
305   /* 0x8027 */        /* reserved */
306   STUN_ATTRIBUTE_FINGERPRINT=0x8028,    /* RFC5389 */
307   STUN_ATTRIBUTE_ICE_CONTROLLED=0x8029,    /* ICE-19 */
308   STUN_ATTRIBUTE_ICE_CONTROLLING=0x802A,    /* ICE-19 */
309   /* 0x802B-0x804F */      /* reserved */
310   STUN_ATTRIBUTE_MS_SEQUENCE_NUMBER=0x8050,     /* MS-TURN */
311   /* 0x8051-0x8053 */      /* reserved */
312   STUN_ATTRIBUTE_CANDIDATE_IDENTIFIER=0x8054,     /* MS-ICE2 */
313   /* 0x8055-0x806F */      /* reserved */
314   STUN_ATTRIBUTE_MS_IMPLEMENTATION_VERSION=0x8070, /* MS-ICE2 */
315   /* 0x8071-0xC000 */      /* reserved */
316   STUN_ATTRIBUTE_NOMINATION=0xC001 /* https://tools.ietf.org/html/draft-thatcher-ice-renomination-00 */
317   /* 0xC002-0xFFFF */      /* reserved */
318 } StunAttribute;
319
320
321 /**
322  * STUN_ALL_KNOWN_ATTRIBUTES:
323  *
324  * An array containing all the currently known and defined mandatory attributes
325  * from StunAttribute
326  */
327 /* Should be in sync with StunAttribute */
328 static const uint16_t STUN_ALL_KNOWN_ATTRIBUTES[] =
329   {
330     STUN_ATTRIBUTE_MAPPED_ADDRESS,
331     STUN_ATTRIBUTE_RESPONSE_ADDRESS,
332     STUN_ATTRIBUTE_CHANGE_REQUEST,
333     STUN_ATTRIBUTE_SOURCE_ADDRESS,
334     STUN_ATTRIBUTE_CHANGED_ADDRESS,
335     STUN_ATTRIBUTE_USERNAME,
336     STUN_ATTRIBUTE_PASSWORD,
337     STUN_ATTRIBUTE_MESSAGE_INTEGRITY,
338     STUN_ATTRIBUTE_ERROR_CODE,
339     STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES,
340     STUN_ATTRIBUTE_REFLECTED_FROM,
341     STUN_ATTRIBUTE_CHANNEL_NUMBER,
342     STUN_ATTRIBUTE_LIFETIME,
343     STUN_ATTRIBUTE_MAGIC_COOKIE,
344     STUN_ATTRIBUTE_BANDWIDTH,
345     STUN_ATTRIBUTE_DESTINATION_ADDRESS,
346     STUN_ATTRIBUTE_REMOTE_ADDRESS,
347     STUN_ATTRIBUTE_PEER_ADDRESS,
348     STUN_ATTRIBUTE_XOR_PEER_ADDRESS,
349     STUN_ATTRIBUTE_DATA,
350     STUN_ATTRIBUTE_REALM,
351     STUN_ATTRIBUTE_NONCE,
352     STUN_ATTRIBUTE_RELAY_ADDRESS,
353     STUN_ATTRIBUTE_RELAYED_ADDRESS,
354     STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,
355     STUN_ATTRIBUTE_REQUESTED_ADDRESS_TYPE,
356     STUN_ATTRIBUTE_REQUESTED_PORT_PROPS,
357     STUN_ATTRIBUTE_REQUESTED_PROPS,
358     STUN_ATTRIBUTE_EVEN_PORT,
359     STUN_ATTRIBUTE_REQUESTED_TRANSPORT,
360     STUN_ATTRIBUTE_DONT_FRAGMENT,
361     STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
362     STUN_ATTRIBUTE_TIMER_VAL,
363     STUN_ATTRIBUTE_REQUESTED_IP,
364     STUN_ATTRIBUTE_RESERVATION_TOKEN,
365     STUN_ATTRIBUTE_CONNECT_STAT,
366     STUN_ATTRIBUTE_PRIORITY,
367     STUN_ATTRIBUTE_USE_CANDIDATE,
368     0
369   };
370
371 /**
372  * STUN_MSOC_KNOWN_ATTRIBUTES:
373  *
374  * An array containing all the currently known mandatory attributes used by
375  * Microsoft Office Communicator as defined in [MS-TURN]
376  */
377 static const uint16_t STUN_MSOC_KNOWN_ATTRIBUTES[] =
378   {
379     STUN_ATTRIBUTE_MAPPED_ADDRESS,
380     STUN_ATTRIBUTE_USERNAME,
381     STUN_ATTRIBUTE_MESSAGE_INTEGRITY,
382     STUN_ATTRIBUTE_ERROR_CODE,
383     STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES,
384     STUN_ATTRIBUTE_LIFETIME,
385     STUN_ATTRIBUTE_MS_ALTERNATE_SERVER,
386     STUN_ATTRIBUTE_MAGIC_COOKIE,
387     STUN_ATTRIBUTE_BANDWIDTH,
388     STUN_ATTRIBUTE_DESTINATION_ADDRESS,
389     STUN_ATTRIBUTE_REMOTE_ADDRESS,
390     STUN_ATTRIBUTE_DATA,
391     /* REALM and NONCE have swapped hexadecimal IDs in [MS-TURN]. Libnice users
392      * or developers can still use these enumeration values in their original
393      * meanings from StunAttribute anywhere in the code, as stun_message_find()
394      * and stun_message_append() will choose correct ID in MSOC compatibility
395      * modes. */
396     STUN_ATTRIBUTE_NONCE,
397     STUN_ATTRIBUTE_REALM,
398     0
399   };
400
401 /**
402  * StunTransactionId:
403  *
404  * A type that holds a STUN transaction id.
405  */
406 typedef uint8_t StunTransactionId[STUN_MESSAGE_TRANS_ID_LEN];
407
408
409 /**
410  * StunError:
411  * @STUN_ERROR_TRY_ALTERNATE: The ERROR-CODE value for the
412  * "Try Alternate" error as defined in RFC5389
413  * @STUN_ERROR_BAD_REQUEST: The ERROR-CODE value for the
414  * "Bad Request" error as defined in RFC5389
415  * @STUN_ERROR_UNAUTHORIZED: The ERROR-CODE value for the
416  * "Unauthorized" error as defined in RFC5389
417  * @STUN_ERROR_UNKNOWN_ATTRIBUTE: The ERROR-CODE value for the
418  * "Unknown Attribute" error as defined in RFC5389
419  * @STUN_ERROR_ALLOCATION_MISMATCH:The ERROR-CODE value for the
420  * "Allocation Mismatch" error as defined in TURN draft 12.
421  * Equivalent to the "No Binding" error defined in TURN draft 04.
422  * @STUN_ERROR_STALE_NONCE: The ERROR-CODE value for the
423  * "Stale Nonce" error as defined in RFC5389
424  * @STUN_ERROR_ACT_DST_ALREADY: The ERROR-CODE value for the
425  * "Active Destination Already Set" error as defined in TURN draft 04.
426  * @STUN_ERROR_UNSUPPORTED_FAMILY: The ERROR-CODE value for the
427  * "Address Family not Supported" error as defined in TURN IPV6 Draft 05.
428  * @STUN_ERROR_WRONG_CREDENTIALS: The ERROR-CODE value for the
429  * "Wrong Credentials" error as defined in TURN Draft 12.
430  * @STUN_ERROR_UNSUPPORTED_TRANSPORT:he ERROR-CODE value for the
431  * "Unsupported Transport Protocol" error as defined in TURN Draft 12.
432  * @STUN_ERROR_INVALID_IP: The ERROR-CODE value for the
433  * "Invalid IP Address" error as defined in TURN draft 04.
434  * @STUN_ERROR_INVALID_PORT: The ERROR-CODE value for the
435  * "Invalid Port" error as defined in TURN draft 04.
436  * @STUN_ERROR_OP_TCP_ONLY: The ERROR-CODE value for the
437  * "Operation for TCP Only" error as defined in TURN draft 04.
438  * @STUN_ERROR_CONN_ALREADY: The ERROR-CODE value for the
439  * "Connection Already Exists" error as defined in TURN draft 04.
440  * @STUN_ERROR_ALLOCATION_QUOTA_REACHED: The ERROR-CODE value for the
441  * "Allocation Quota Reached" error as defined in TURN draft 12.
442  * @STUN_ERROR_ROLE_CONFLICT:The ERROR-CODE value for the
443  * "Role Conflict" error as defined in ICE draft 19.
444  * @STUN_ERROR_SERVER_ERROR: The ERROR-CODE value for the
445  * "Server Error" error as defined in RFC5389
446  * @STUN_ERROR_SERVER_CAPACITY: The ERROR-CODE value for the
447  * "Insufficient Capacity" error as defined in TURN draft 04.
448  * @STUN_ERROR_INSUFFICIENT_CAPACITY: The ERROR-CODE value for the
449  * "Insufficient Capacity" error as defined in TURN draft 12.
450  * @STUN_ERROR_MAX: The maximum possible ERROR-CODE value as defined by RFC 5389.
451  *
452  * STUN error codes as defined by various RFCs and drafts
453  */
454 /* Should be in sync with stun_strerror() */
455 typedef enum
456 {
457   STUN_ERROR_TRY_ALTERNATE=300,      /* RFC5389 */
458   STUN_ERROR_BAD_REQUEST=400,      /* RFC5389 */
459   STUN_ERROR_UNAUTHORIZED=401,      /* RFC5389 */
460   STUN_ERROR_UNKNOWN_ATTRIBUTE=420,    /* RFC5389 */
461   STUN_ERROR_ALLOCATION_MISMATCH=437,   /* TURN-12 */
462   STUN_ERROR_STALE_NONCE=438,      /* RFC5389 */
463   STUN_ERROR_ACT_DST_ALREADY=439,    /* TURN-04 */
464   STUN_ERROR_UNSUPPORTED_FAMILY=440,      /* TURN-IPv6-05 */
465   STUN_ERROR_WRONG_CREDENTIALS=441,    /* TURN-12 */
466   STUN_ERROR_UNSUPPORTED_TRANSPORT=442,    /* TURN-12 */
467   STUN_ERROR_INVALID_IP=443,      /* TURN-04 */
468   STUN_ERROR_INVALID_PORT=444,      /* TURN-04 */
469   STUN_ERROR_OP_TCP_ONLY=445,      /* TURN-04 */
470   STUN_ERROR_CONN_ALREADY=446,      /* TURN-04 */
471   STUN_ERROR_ALLOCATION_QUOTA_REACHED=486,    /* TURN-12 */
472   STUN_ERROR_ROLE_CONFLICT=487,      /* ICE-19 */
473   STUN_ERROR_SERVER_ERROR=500,      /* RFC5389 */
474   STUN_ERROR_SERVER_CAPACITY=507,    /* TURN-04 */
475   STUN_ERROR_INSUFFICIENT_CAPACITY=508,    /* TURN-12 */
476   STUN_ERROR_MAX=699
477 } StunError;
478
479
480 /**
481  * StunMessageReturn:
482  * @STUN_MESSAGE_RETURN_SUCCESS: The operation was successful
483  * @STUN_MESSAGE_RETURN_NOT_FOUND: The attribute was not found
484  * @STUN_MESSAGE_RETURN_INVALID: The argument or data is invalid
485  * @STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE: There is not enough space in the
486  * message to append data to it, or not enough in an argument to fill it with
487  * the data requested.
488  * @STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS: The address in the arguments or in
489  * the STUN message is not supported.
490  *
491  * The return value of most stun_message_* functions.
492  * This enum will report on whether an operation was successful or not
493  * and what error occured if any.
494  */
495 typedef enum
496 {
497   STUN_MESSAGE_RETURN_SUCCESS,
498   STUN_MESSAGE_RETURN_NOT_FOUND,
499   STUN_MESSAGE_RETURN_INVALID,
500   STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE,
501   STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS
502 } StunMessageReturn;
503
504 #include "stunagent.h"
505
506 /**
507  * STUN_MAX_MESSAGE_SIZE:
508  *
509  * The Maximum size of a STUN message
510  */
511 #define STUN_MAX_MESSAGE_SIZE 65552
512
513 /**
514  * StunMessage:
515  * @agent: The agent that created or validated this message
516  * @buffer: The buffer containing the STUN message
517  * @buffer_len: The length of the buffer (not the size of the message)
518  * @key: The short term credentials key to use for authentication validation
519  * or that was used to finalize this message
520  * @key_len: The length of the associated key
521  * @long_term_key: The long term credential key to use for authentication
522  * validation or that was used to finalize this message
523  * @long_term_valid: Whether or not the #long_term_key variable contains valid
524  * data
525  *
526  * This structure represents a STUN message
527  */
528 struct _StunMessage {
529   StunAgent *agent;
530   uint8_t *buffer;
531   size_t buffer_len;
532   uint8_t *key;
533   size_t key_len;
534   uint8_t long_term_key[16];
535   bool long_term_valid;
536 };
537
538 /**
539  * stun_message_init:
540  * @msg: The #StunMessage to initialize
541  * @c: STUN message class (host byte order)
542  * @m: STUN message method (host byte order)
543  * @id: 16-bytes transaction ID
544  *
545  * Initializes a STUN message buffer, with no attributes.
546  * Returns: %TRUE if the initialization was successful
547  */
548 bool stun_message_init (StunMessage *msg, StunClass c, StunMethod m,
549     const StunTransactionId id);
550
551 /**
552  * stun_message_length:
553  * @msg: The #StunMessage
554  *
555  * Get the length of the message (including the header)
556  *
557  * Returns: The length of the message
558  */
559 uint16_t stun_message_length (const StunMessage *msg);
560
561 /**
562  * stun_message_find:
563  * @msg: The #StunMessage
564  * @type: The #StunAttribute to find
565  * @palen: A pointer to store the length of the attribute
566  *
567  * Finds an attribute in a STUN message and fetches its content
568  *
569  * Returns: A pointer to the start of the attribute payload if found,
570  * otherwise NULL.
571  */
572 const void * stun_message_find (const StunMessage * msg, StunAttribute type,
573     uint16_t *palen);
574
575
576 /**
577  * stun_message_find_flag:
578  * @msg: The #StunMessage
579  * @type: The #StunAttribute to find
580  *
581  * Looks for a flag attribute within a valid STUN message.
582  *
583  * Returns: A #StunMessageReturn value.
584  * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not zero.
585  */
586 StunMessageReturn stun_message_find_flag (const StunMessage *msg,
587     StunAttribute type);
588
589 /**
590  * stun_message_find32:
591  * @msg: The #StunMessage
592  * @type: The #StunAttribute to find
593  * @pval: A pointer where to store the value (host byte order)
594  *
595  * Extracts a 32-bits attribute from a STUN message.
596  *
597  * Returns:  A #StunMessageReturn value.
598  * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not
599  * 4 bytes.
600  */
601 StunMessageReturn stun_message_find32 (const StunMessage *msg,
602     StunAttribute type, uint32_t *pval);
603
604 /**
605  * stun_message_find64:
606  * @msg: The #StunMessage
607  * @type: The #StunAttribute to find
608  * @pval: A pointer where to store the value (host byte order)
609  *
610  * Extracts a 64-bits attribute from a STUN message.
611  *
612  * Returns:  A #StunMessageReturn value.
613  * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute's size is not
614  * 8 bytes.
615  */
616 StunMessageReturn stun_message_find64 (const StunMessage *msg,
617     StunAttribute type, uint64_t *pval);
618
619 /**
620  * stun_message_find_string:
621  * @msg: The #StunMessage
622  * @type: The #StunAttribute to find
623  * @buf: A pointer where to store the data
624  * @buflen: The length of the buffer
625  *
626  * Extracts an UTF-8 string from a valid STUN message.
627  *
628  * Returns: A #StunMessageReturn value.
629  * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute is improperly
630  * encoded
631  * %STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE is return if the buffer size is too
632  * small to hold the string
633  *
634  <note>
635    <para>
636     The string will be nul-terminated.
637    </para>
638  </note>
639  *
640  */
641 StunMessageReturn stun_message_find_string (const StunMessage *msg,
642     StunAttribute type, char *buf, size_t buflen);
643
644 /**
645  * stun_message_find_addr:
646  * @msg: The #StunMessage
647  * @type: The #StunAttribute to find
648  * @addr: The #sockaddr to be filled
649  * @addrlen: The size of the @addr variable. Must be set to the size of the
650  * @addr socket address and will be set to the size of the extracted socket
651  * address.
652  *
653  * Extracts a network address attribute from a STUN message.
654  *
655  * Returns: A #StunMessageReturn value.
656  * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is
657  * wrong or if the @addrlen is too small
658  * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.
659  */
660 StunMessageReturn stun_message_find_addr (const StunMessage *msg,
661     StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen);
662
663 /**
664  * stun_message_find_xor_addr:
665  * @msg: The #StunMessage
666  * @type: The #StunAttribute to find
667  * @addr: The #sockaddr to be filled
668  * @addrlen: The size of the @addr variable. Must be set to the size of the
669  * @addr socket address and will be set to the size of the
670  * extracted socket address.
671  *
672  * Extracts an obfuscated network address attribute from a STUN message.
673  *
674  * Returns: A #StunMessageReturn value.
675  * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is
676  * wrong or if the @addrlen is too small
677  * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.
678  */
679 StunMessageReturn stun_message_find_xor_addr (const StunMessage *msg,
680     StunAttribute type, struct sockaddr_storage *addr, socklen_t *addrlen);
681
682 /**
683  * stun_message_find_xor_addr_full:
684  * @msg: The #StunMessage
685  * @type: The #StunAttribute to find
686  * @addr: The #sockaddr to be filled
687  * @addrlen: The size of the @addr variable. Must be set to the size of the
688  * @addr socket address and will be set to the size of the
689  * extracted socket address.
690  * @magic_cookie: The magic cookie to use to XOR the address.
691  *
692  * Extracts an obfuscated network address attribute from a STUN message.
693  *
694  * Returns: A #StunMessageReturn value.
695  * %STUN_MESSAGE_RETURN_INVALID is returned if the attribute payload size is
696  * wrong or if the @addrlen is too small
697  * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.
698  */
699 StunMessageReturn stun_message_find_xor_addr_full (const StunMessage *msg,
700     StunAttribute type, struct sockaddr_storage *addr,
701     socklen_t *addrlen, uint32_t magic_cookie);
702
703
704 /**
705  * stun_message_find_error:
706  * @msg: The #StunMessage
707  * @code: A  pointer where to store the value
708  *
709  * Extract the error response code from a STUN message
710  *
711  * Returns: A #StunMessageReturn value.
712  * %STUN_MESSAGE_RETURN_INVALID is returned if the value is invalid
713  */
714 StunMessageReturn stun_message_find_error (const StunMessage *msg, int *code);
715
716
717 /**
718  * stun_message_append:
719  * @msg: The #StunMessage
720  * @type: The #StunAttribute to append
721  * @length: The length of the attribute
722  *
723  * Reserves room for appending an attribute to an unfinished STUN message.
724  *
725  * Returns: A pointer to an unitialized buffer of @length bytes to
726  * where the attribute payload must be written, or NULL if there is not
727  * enough room in the STUN message buffer.
728  */
729 void *stun_message_append (StunMessage *msg, StunAttribute type,
730     size_t length);
731
732 /**
733  * stun_message_append_bytes:
734  * @msg: The #StunMessage
735  * @type: The #StunAttribute to append
736  * @data: The data to append
737  * @len: The length of the attribute
738  *
739  * Appends a binary value to a STUN message
740  *
741  * Returns: A #StunMessageReturn value.
742  */
743 StunMessageReturn stun_message_append_bytes (StunMessage *msg,
744     StunAttribute type, const void *data, size_t len);
745
746 /**
747  * stun_message_append_flag:
748  * @msg: The #StunMessage
749  * @type: The #StunAttribute to append
750  *
751  * Appends an empty flag attribute to a STUN message
752  *
753  * Returns: A #StunMessageReturn value.
754  */
755 StunMessageReturn stun_message_append_flag (StunMessage *msg,
756     StunAttribute type);
757
758 /**
759  * stun_message_append32:
760  * @msg: The #StunMessage
761  * @type: The #StunAttribute to append
762  * @value: The value to append (host byte order)
763  *
764  * Appends a 32-bits value attribute to a STUN message
765  *
766  * Returns: A #StunMessageReturn value.
767  */
768 StunMessageReturn stun_message_append32 (StunMessage *msg,
769     StunAttribute type, uint32_t value);
770
771 /**
772  * stun_message_append64:
773  * @msg: The #StunMessage
774  * @type: The #StunAttribute to append
775  * @value: The value to append (host byte order)
776  *
777  * Appends a 64-bits value attribute to a STUN message
778  *
779  * Returns: A #StunMessageReturn value.
780  */
781 StunMessageReturn stun_message_append64 (StunMessage *msg,
782     StunAttribute type, uint64_t value);
783
784 /**
785  * stun_message_append_string:
786  * @msg: The #StunMessage
787  * @type: The #StunAttribute to append
788  * @str: The string to append
789  *
790  * Adds an attribute from a nul-terminated string to a STUN message
791  *
792  * Returns: A #StunMessageReturn value.
793  */
794 StunMessageReturn stun_message_append_string (StunMessage *msg,
795     StunAttribute type, const char *str);
796
797 /**
798  * stun_message_append_addr:
799  * @msg: The #StunMessage
800  * @type: The #StunAttribute to append
801  * @addr: The #sockaddr to be append
802  * @addrlen: The size of the @addr variable.
803  *
804  * Append a network address attribute to a STUN message
805  *
806  * Returns: A #StunMessageReturn value.
807  * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small
808  * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.
809  */
810 StunMessageReturn stun_message_append_addr (StunMessage * msg,
811     StunAttribute type, const struct sockaddr *addr, socklen_t addrlen);
812
813 /**
814  * stun_message_append_xor_addr:
815  * @msg: The #StunMessage
816  * @type: The #StunAttribute to append
817  * @addr: The #sockaddr to be append
818  * @addrlen: The size of the @addr variable.
819  *
820  * Append an obfuscated network address attribute to a STUN message
821  *
822  * Returns: A #StunMessageReturn value.
823  * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small
824  * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.
825  */
826 StunMessageReturn stun_message_append_xor_addr (StunMessage * msg,
827     StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen);
828
829 /**
830  * stun_message_append_xor_addr_full:
831  * @msg: The #StunMessage
832  * @type: The #StunAttribute to append
833  * @addr: The #sockaddr to be append
834  * @addrlen: The size of the @addr variable.
835  * @magic_cookie: The magic cookie to use to XOR the address.
836  *
837  * Append an obfuscated network address attribute from a STUN message.
838  *
839  * Returns: A #StunMessageReturn value.
840  * %STUN_MESSAGE_RETURN_INVALID is returned if the @addrlen is too small
841  * %STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS if the address family is unknown.
842  */
843 StunMessageReturn stun_message_append_xor_addr_full (StunMessage * msg,
844     StunAttribute type, const struct sockaddr_storage *addr, socklen_t addrlen,
845     uint32_t magic_cookie);
846
847 /**
848  * stun_message_append_error:
849  * @msg: The #StunMessage
850  * @code: The error code value
851  *
852  * Appends the ERROR-CODE attribute to the STUN message and fills it according
853  * to #code
854  *
855  * Returns: A #StunMessageReturn value.
856  */
857 StunMessageReturn stun_message_append_error (StunMessage * msg,
858     StunError code);
859
860 /**
861  * STUN_MESSAGE_BUFFER_INCOMPLETE:
862  *
863  * Convenience macro for stun_message_validate_buffer_length() meaning that the
864  * data to validate does not hold a complete STUN message
865  */
866 #define STUN_MESSAGE_BUFFER_INCOMPLETE 0
867
868 /**
869  * STUN_MESSAGE_BUFFER_INVALID:
870  *
871  * Convenience macro for stun_message_validate_buffer_length() meaning that the
872  * data to validate is not a valid STUN message
873  */
874 #define STUN_MESSAGE_BUFFER_INVALID -1
875
876
877 /**
878  * stun_message_validate_buffer_length:
879  * @msg: The buffer to validate
880  * @length: The length of the buffer
881  * @has_padding: Set TRUE if attributes should be padded to multiple of 4 bytes
882  *
883  * This function will take a data buffer and will try to validate whether it is
884  * a STUN message or if it's not or if it's an incomplete STUN message and will
885  * provide us with the length of the STUN message.
886  *
887  * Returns: The length of the valid STUN message in the buffer.
888  * <para> See also: #STUN_MESSAGE_BUFFER_INCOMPLETE </para>
889  * <para> See also: #STUN_MESSAGE_BUFFER_INVALID </para>
890  */
891 int stun_message_validate_buffer_length (const uint8_t *msg, size_t length,
892     bool has_padding);
893
894 /**
895  * StunInputVector:
896  * @buffer: a buffer containing already-received binary data
897  * @size: length of @buffer, in bytes
898  *
899  * Container for a single buffer which also stores its length. This is designed
900  * for vectored I/O: typically an array of #StunInputVectors is passed to
901  * functions, providing multiple buffers which store logically contiguous
902  * received data.
903  *
904  * This is guaranteed to be layed out identically in memory to #GInputVector.
905  *
906  * Since: 0.1.5
907  */
908 typedef struct {
909   const uint8_t *buffer;
910   size_t size;
911 } StunInputVector;
912
913 /**
914  * stun_message_validate_buffer_length_fast:
915  * @buffers: (array length=n_buffers) (in caller-allocated): array of contiguous
916  * #StunInputVectors containing already-received message data
917  * @n_buffers: number of entries in @buffers or if -1 , then buffers is
918  *  terminated by a #StunInputVector with the buffer pointer being %NULL.
919  * @total_length: total number of valid bytes stored consecutively in @buffers
920  * @has_padding: %TRUE if attributes should be padded to 4-byte boundaries
921  *
922  * Quickly validate whether the message in the given @buffers is potentially a
923  * valid STUN message, an incomplete STUN message, or if it’s definitely not one
924  * at all.
925  *
926  * This is designed as a first-pass validation only, and does not check the
927  * message’s attributes for validity. If this function returns success, the
928  * buffers can be compacted and a more thorough validation can be performed
929  * using stun_message_validate_buffer_length(). If it fails, the buffers
930  * definitely do not contain a complete, valid STUN message.
931  *
932  * Returns: The length of the valid STUN message in the buffer, or zero or -1 on
933  * failure
934  * <para> See also: #STUN_MESSAGE_BUFFER_INCOMPLETE </para>
935  * <para> See also: #STUN_MESSAGE_BUFFER_INVALID </para>
936  *
937  * Since: 0.1.5
938  */
939 ssize_t stun_message_validate_buffer_length_fast (StunInputVector *buffers,
940     int n_buffers, size_t total_length, bool has_padding);
941
942 /**
943  * stun_message_id:
944  * @msg: The #StunMessage
945  * @id: The #StunTransactionId to fill
946  *
947  * Retreive the STUN transaction id from a STUN message
948  */
949 void stun_message_id (const StunMessage *msg, StunTransactionId id);
950
951 /**
952  * stun_message_get_class:
953  * @msg: The #StunMessage
954  *
955  * Retreive the STUN class from a STUN message
956  *
957  * Returns: The #StunClass
958  */
959 StunClass stun_message_get_class (const StunMessage *msg);
960
961 /**
962  * stun_message_get_method:
963  * @msg: The #StunMessage
964  *
965  * Retreive the STUN method from a STUN message
966  *
967  * Returns: The #StunMethod
968  */
969 StunMethod stun_message_get_method (const StunMessage *msg);
970
971 /**
972  * stun_message_has_attribute:
973  * @msg: The #StunMessage
974  * @type: The #StunAttribute to look for
975  *
976  * Checks if an attribute is present within a STUN message.
977  *
978  * Returns: %TRUE if the attribute is found, %FALSE otherwise
979  */
980 bool stun_message_has_attribute (const StunMessage *msg, StunAttribute type);
981
982
983 /* Defined in stun5389.c */
984 /**
985  * stun_message_has_cookie:
986  * @msg: The #StunMessage
987  *
988  * Checks if the STUN message has a RFC5389 compatible cookie
989  *
990  * Returns: %TRUE if the cookie is present, %FALSE otherwise
991  */
992 bool stun_message_has_cookie (const StunMessage *msg);
993
994
995 /**
996  * stun_optional:
997  * @t: An attribute type
998  *
999  * Helper function that checks whether a STUN attribute is a mandatory
1000  * or an optional attribute
1001  *
1002  * Returns: %TRUE if the attribute is an optional one
1003  */
1004 bool stun_optional (uint16_t t);
1005
1006 /**
1007  * stun_strerror:
1008  * @code: host-byte order error code
1009  *
1010  * Transforms a STUN error-code into a human readable string
1011  *
1012  * Returns: A static pointer to a nul-terminated error message string.
1013  */
1014 const char *stun_strerror (StunError code);
1015
1016
1017 #endif /* _STUN_MESSAGE_H */