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 */ 1018