michael@0: /* michael@0: Copyright (c) 2007, Adobe Systems, Incorporated michael@0: All rights reserved. michael@0: michael@0: Redistribution and use in source and binary forms, with or without michael@0: modification, are permitted provided that the following conditions are michael@0: met: michael@0: michael@0: * Redistributions of source code must retain the above copyright michael@0: notice, this list of conditions and the following disclaimer. michael@0: michael@0: * Redistributions in binary form must reproduce the above copyright michael@0: notice, this list of conditions and the following disclaimer in the michael@0: documentation and/or other materials provided with the distribution. michael@0: michael@0: * Neither the name of Adobe Systems, Network Resonance nor the names of its michael@0: contributors may be used to endorse or promote products derived from michael@0: this software without specific prior written permission. michael@0: michael@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR michael@0: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT michael@0: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, michael@0: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT michael@0: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, michael@0: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY michael@0: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE michael@0: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: */ michael@0: michael@0: michael@0: michael@0: #ifndef _stun_msg_h michael@0: #define _stun_msg_h michael@0: michael@0: #include "csi_platform.h" michael@0: #include "nr_api.h" michael@0: #include "transport_addr.h" michael@0: michael@0: #define NR_STUN_MAX_USERNAME_BYTES 513 michael@0: #define NR_STUN_MAX_ERROR_CODE_REASON_BYTES 763 michael@0: #define NR_STUN_MAX_ERROR_CODE_REASON_CHARS 128 michael@0: #define NR_STUN_MAX_REALM_BYTES 763 michael@0: #define NR_STUN_MAX_REALM_CHARS 128 michael@0: #define NR_STUN_MAX_NONCE_BYTES 763 michael@0: #define NR_STUN_MAX_NONCE_CHARS 128 michael@0: #define NR_STUN_MAX_SERVER_BYTES 763 michael@0: #define NR_STUN_MAX_SERVER_CHARS 128 michael@0: #define NR_STUN_MAX_STRING_SIZE 763 /* any possible string */ michael@0: #define NR_STUN_MAX_UNKNOWN_ATTRIBUTES 16 michael@0: #define NR_STUN_MAX_MESSAGE_SIZE 2048 michael@0: michael@0: #define NR_STUN_MAGIC_COOKIE 0x2112A442 michael@0: #define NR_STUN_MAGIC_COOKIE2 0xc5cb4e1d /* used recognize old stun messages */ michael@0: michael@0: typedef struct { UCHAR octet[12]; } UINT12; michael@0: michael@0: typedef struct nr_stun_attr_error_code_ { michael@0: UINT2 number; michael@0: char reason[NR_STUN_MAX_ERROR_CODE_REASON_BYTES+1]; /* +1 for \0 */ michael@0: } nr_stun_attr_error_code; michael@0: michael@0: typedef struct nr_stun_attr_fingerprint_ { michael@0: UINT4 checksum; michael@0: int valid; michael@0: } nr_stun_attr_fingerprint; michael@0: michael@0: typedef struct nr_stun_attr_message_integrity_ { michael@0: UCHAR hash[20]; michael@0: int unknown_user; michael@0: UCHAR password[1024]; michael@0: int passwordlen; michael@0: int valid; michael@0: } nr_stun_attr_message_integrity; michael@0: michael@0: typedef struct nr_stun_attr_unknown_attributes_ { michael@0: UINT2 attribute[NR_STUN_MAX_UNKNOWN_ATTRIBUTES]; michael@0: int num_attributes; michael@0: } nr_stun_attr_unknown_attributes; michael@0: michael@0: typedef struct nr_stun_attr_xor_mapped_address_ { michael@0: nr_transport_addr masked; michael@0: nr_transport_addr unmasked; michael@0: } nr_stun_attr_xor_mapped_address; michael@0: michael@0: typedef struct nr_stun_attr_data_ { michael@0: UCHAR data[NR_STUN_MAX_MESSAGE_SIZE]; michael@0: int length; michael@0: } nr_stun_attr_data; michael@0: michael@0: michael@0: typedef struct nr_stun_encoded_attribute_ { michael@0: UINT2 type; michael@0: UINT2 length; michael@0: UCHAR value[NR_STUN_MAX_MESSAGE_SIZE]; michael@0: } nr_stun_encoded_attribute; michael@0: michael@0: typedef struct nr_stun_message_attribute_ { michael@0: UINT2 type; michael@0: UINT2 length; michael@0: union { michael@0: nr_transport_addr address; michael@0: nr_transport_addr alternate_server; michael@0: nr_stun_attr_error_code error_code; michael@0: nr_stun_attr_fingerprint fingerprint; michael@0: nr_transport_addr mapped_address; michael@0: nr_stun_attr_message_integrity message_integrity; michael@0: char nonce[NR_STUN_MAX_NONCE_BYTES+1]; /* +1 for \0 */ michael@0: char realm[NR_STUN_MAX_REALM_BYTES+1]; /* +1 for \0 */ michael@0: nr_stun_attr_xor_mapped_address relay_address; michael@0: char server_name[NR_STUN_MAX_SERVER_BYTES+1]; /* +1 for \0 */ michael@0: nr_stun_attr_unknown_attributes unknown_attributes; michael@0: char username[NR_STUN_MAX_USERNAME_BYTES+1]; /* +1 for \0 */ michael@0: nr_stun_attr_xor_mapped_address xor_mapped_address; michael@0: michael@0: #ifdef USE_ICE michael@0: UINT4 priority; michael@0: UINT8 ice_controlled; michael@0: UINT8 ice_controlling; michael@0: #endif /* USE_ICE */ michael@0: michael@0: #ifdef USE_TURN michael@0: UINT4 lifetime_secs; michael@0: nr_transport_addr remote_address; michael@0: UCHAR requested_transport; michael@0: nr_stun_attr_data data; michael@0: #endif /* USE_TURN */ michael@0: michael@0: #ifdef USE_STUND_0_96 michael@0: UINT4 change_request; michael@0: #endif /* USE_STUND_0_96 */ michael@0: michael@0: /* make sure there's enough room here to place any possible michael@0: * attribute */ michael@0: UCHAR largest_possible_attribute[NR_STUN_MAX_MESSAGE_SIZE]; michael@0: } u; michael@0: nr_stun_encoded_attribute *encoding; michael@0: int encoding_length; michael@0: char *name; michael@0: char *type_name; michael@0: int invalid; michael@0: TAILQ_ENTRY(nr_stun_message_attribute_) entry; michael@0: } nr_stun_message_attribute; michael@0: michael@0: typedef TAILQ_HEAD(nr_stun_message_attribute_head_,nr_stun_message_attribute_) nr_stun_message_attribute_head; michael@0: michael@0: typedef struct nr_stun_message_header_ { michael@0: UINT2 type; michael@0: UINT2 length; michael@0: UINT4 magic_cookie; michael@0: UINT12 id; michael@0: } nr_stun_message_header; michael@0: michael@0: typedef struct nr_stun_message_ { michael@0: char *name; michael@0: UCHAR buffer[NR_STUN_MAX_MESSAGE_SIZE]; michael@0: int length; michael@0: nr_stun_message_header header; michael@0: int comprehension_required_unknown_attributes; michael@0: int comprehension_optional_unknown_attributes; michael@0: nr_stun_message_attribute_head attributes; michael@0: } nr_stun_message; michael@0: michael@0: int nr_stun_message_create(nr_stun_message **msg); michael@0: int nr_stun_message_create2(nr_stun_message **msg, UCHAR *buffer, int length); michael@0: int nr_stun_message_destroy(nr_stun_message **msg); michael@0: michael@0: int nr_stun_message_attribute_create(nr_stun_message *msg, nr_stun_message_attribute **attr); michael@0: int nr_stun_message_attribute_destroy(nr_stun_message *msg, nr_stun_message_attribute **attr); michael@0: michael@0: int nr_stun_message_has_attribute(nr_stun_message *msg, UINT2 type, nr_stun_message_attribute **attribute); michael@0: michael@0: int nr_stun_message_add_alternate_server_attribute(nr_stun_message *msg, nr_transport_addr *alternate_server); michael@0: int nr_stun_message_add_error_code_attribute(nr_stun_message *msg, UINT2 number, char *reason); michael@0: int nr_stun_message_add_fingerprint_attribute(nr_stun_message *msg); michael@0: int nr_stun_message_add_message_integrity_attribute(nr_stun_message *msg, Data *password); michael@0: int nr_stun_message_add_nonce_attribute(nr_stun_message *msg, char *nonce); michael@0: int nr_stun_message_add_realm_attribute(nr_stun_message *msg, char *realm); michael@0: int nr_stun_message_add_server_attribute(nr_stun_message *msg, char *server_name); michael@0: int nr_stun_message_add_unknown_attributes_attribute(nr_stun_message *msg, nr_stun_attr_unknown_attributes *unknown_attributes); michael@0: int nr_stun_message_add_username_attribute(nr_stun_message *msg, char *username); michael@0: int nr_stun_message_add_xor_mapped_address_attribute(nr_stun_message *msg, nr_transport_addr *mapped_address); michael@0: michael@0: #ifdef USE_ICE michael@0: int nr_stun_message_add_ice_controlled_attribute(nr_stun_message *msg, UINT8 ice_controlled); michael@0: int nr_stun_message_add_ice_controlling_attribute(nr_stun_message *msg, UINT8 ice_controlling); michael@0: int nr_stun_message_add_priority_attribute(nr_stun_message *msg, UINT4 priority); michael@0: int nr_stun_message_add_use_candidate_attribute(nr_stun_message *msg); michael@0: #endif /* USE_ICE */ michael@0: michael@0: #ifdef USE_TURN michael@0: int nr_stun_message_add_data_attribute(nr_stun_message *msg, UCHAR *data, int length); michael@0: int nr_stun_message_add_lifetime_attribute(nr_stun_message *msg, UINT4 lifetime_secs); michael@0: int nr_stun_message_add_requested_transport_attribute(nr_stun_message *msg, UCHAR transport); michael@0: int michael@0: nr_stun_message_add_xor_peer_address_attribute(nr_stun_message *msg, nr_transport_addr *peer_address); michael@0: #endif /* USE_TURN */ michael@0: michael@0: #ifdef USE_STUND_0_96 michael@0: int nr_stun_message_add_change_request_attribute(nr_stun_message *msg, UINT4 change_request); michael@0: #endif /* USE_STUND_0_96 */ michael@0: michael@0: #endif michael@0: