1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/mtransport/third_party/nICEr/src/stun/stun_msg.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,358 @@ 1.4 +/* 1.5 +Copyright (c) 2007, Adobe Systems, Incorporated 1.6 +All rights reserved. 1.7 + 1.8 +Redistribution and use in source and binary forms, with or without 1.9 +modification, are permitted provided that the following conditions are 1.10 +met: 1.11 + 1.12 +* Redistributions of source code must retain the above copyright 1.13 + notice, this list of conditions and the following disclaimer. 1.14 + 1.15 +* Redistributions in binary form must reproduce the above copyright 1.16 + notice, this list of conditions and the following disclaimer in the 1.17 + documentation and/or other materials provided with the distribution. 1.18 + 1.19 +* Neither the name of Adobe Systems, Network Resonance nor the names of its 1.20 + contributors may be used to endorse or promote products derived from 1.21 + this software without specific prior written permission. 1.22 + 1.23 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.25 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.26 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.27 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.28 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.29 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.30 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.31 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.32 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.33 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.34 +*/ 1.35 + 1.36 + 1.37 +static char *RCSSTRING __UNUSED__="$Id: stun_msg.c,v 1.2 2008/04/28 18:21:30 ekr Exp $"; 1.38 + 1.39 +#include <errno.h> 1.40 +#include <csi_platform.h> 1.41 + 1.42 +#ifdef WIN32 1.43 +#include <winsock2.h> 1.44 +#include <stdlib.h> 1.45 +#include <io.h> 1.46 +#include <time.h> 1.47 +#else /* UNIX */ 1.48 +#include <string.h> 1.49 +#endif /* end UNIX */ 1.50 +#include <assert.h> 1.51 + 1.52 +#include "stun.h" 1.53 + 1.54 + 1.55 +int 1.56 +nr_stun_message_create(nr_stun_message **msg) 1.57 +{ 1.58 + int _status; 1.59 + nr_stun_message *m = 0; 1.60 + 1.61 + m = RCALLOC(sizeof(*m)); 1.62 + if (!m) 1.63 + ABORT(R_NO_MEMORY); 1.64 + 1.65 + TAILQ_INIT(&m->attributes); 1.66 + 1.67 + *msg = m; 1.68 + 1.69 + _status=0; 1.70 + abort: 1.71 + return(_status); 1.72 +} 1.73 + 1.74 +int 1.75 +nr_stun_message_create2(nr_stun_message **msg, UCHAR *buffer, int length) 1.76 +{ 1.77 + int r,_status; 1.78 + nr_stun_message *m = 0; 1.79 + 1.80 + if (length > sizeof(m->buffer)) { 1.81 + ABORT(R_BAD_DATA); 1.82 + } 1.83 + 1.84 + if ((r=nr_stun_message_create(&m))) 1.85 + ABORT(r); 1.86 + 1.87 + memcpy(m->buffer, buffer, length); 1.88 + m->length = length; 1.89 + 1.90 + *msg = m; 1.91 + 1.92 + _status=0; 1.93 + abort: 1.94 + return(_status); 1.95 +} 1.96 + 1.97 +int 1.98 +nr_stun_message_destroy(nr_stun_message **msg) 1.99 +{ 1.100 + int _status; 1.101 + nr_stun_message_attribute_head *attrs; 1.102 + nr_stun_message_attribute *attr; 1.103 + 1.104 + if (msg && *msg) { 1.105 + attrs = &(*msg)->attributes; 1.106 + while (!TAILQ_EMPTY(attrs)) { 1.107 + attr = TAILQ_FIRST(attrs); 1.108 + nr_stun_message_attribute_destroy(*msg, &attr); 1.109 + } 1.110 + 1.111 + RFREE(*msg); 1.112 + 1.113 + *msg = 0; 1.114 + } 1.115 + 1.116 + _status=0; 1.117 +/* abort: */ 1.118 + return(_status); 1.119 +} 1.120 + 1.121 +int 1.122 +nr_stun_message_attribute_create(nr_stun_message *msg, nr_stun_message_attribute **attr) 1.123 +{ 1.124 + int _status; 1.125 + nr_stun_message_attribute *a = 0; 1.126 + 1.127 + a = RCALLOC(sizeof(*a)); 1.128 + if (!a) 1.129 + ABORT(R_NO_MEMORY); 1.130 + 1.131 + TAILQ_INSERT_TAIL(&msg->attributes, a, entry); 1.132 + 1.133 + *attr = a; 1.134 + 1.135 + _status=0; 1.136 + abort: 1.137 + return(_status); 1.138 +} 1.139 + 1.140 +int 1.141 +nr_stun_message_attribute_destroy(nr_stun_message *msg, nr_stun_message_attribute **attr) 1.142 +{ 1.143 + int _status; 1.144 + nr_stun_message_attribute *a = 0; 1.145 + 1.146 + if (attr && *attr) { 1.147 + a = *attr; 1.148 + TAILQ_REMOVE(&msg->attributes, a, entry); 1.149 + 1.150 + RFREE(a); 1.151 + 1.152 + *attr = 0; 1.153 + } 1.154 + 1.155 + _status=0; 1.156 +/* abort: */ 1.157 + return(_status); 1.158 +} 1.159 + 1.160 +int 1.161 +nr_stun_message_has_attribute(nr_stun_message *msg, UINT2 type, nr_stun_message_attribute **attribute) 1.162 +{ 1.163 + nr_stun_message_attribute *attr = 0; 1.164 + 1.165 + if (attribute) 1.166 + *attribute = 0; 1.167 + 1.168 + TAILQ_FOREACH(attr, &msg->attributes, entry) { 1.169 + if (attr->type == type) 1.170 + break; 1.171 + } 1.172 + 1.173 + if (!attr || attr->invalid) 1.174 + return 0; /* does not have */ 1.175 + 1.176 + if (attribute) 1.177 + *attribute = attr; 1.178 + 1.179 + return 1; /* has */ 1.180 +} 1.181 + 1.182 +#define NR_STUN_MESSAGE_ADD_ATTRIBUTE(__type, __code) \ 1.183 + { \ 1.184 + int r,_status; \ 1.185 + nr_stun_message_attribute *attr = 0; \ 1.186 + if ((r=nr_stun_message_attribute_create(msg, &attr))) \ 1.187 + ABORT(r); \ 1.188 + attr->type = (__type); \ 1.189 + { __code } \ 1.190 + _status=0; \ 1.191 + abort: \ 1.192 + if (_status) RFREE(attr); \ 1.193 + return(_status); \ 1.194 + } 1.195 + 1.196 + 1.197 +int 1.198 +nr_stun_message_add_alternate_server_attribute(nr_stun_message *msg, nr_transport_addr *alternate_server) 1.199 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.200 + NR_STUN_ATTR_ALTERNATE_SERVER, 1.201 + { 1.202 + if ((r=nr_transport_addr_copy(&attr->u.alternate_server, alternate_server))) 1.203 + ABORT(r); 1.204 + } 1.205 +) 1.206 + 1.207 +int 1.208 +nr_stun_message_add_error_code_attribute(nr_stun_message *msg, UINT2 number, char *reason) 1.209 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.210 + NR_STUN_ATTR_ERROR_CODE, 1.211 + { 1.212 + attr->u.error_code.number = number; 1.213 + strlcpy(attr->u.error_code.reason, reason, sizeof(attr->u.error_code.reason)); 1.214 + } 1.215 +) 1.216 + 1.217 +int 1.218 +nr_stun_message_add_fingerprint_attribute(nr_stun_message *msg) 1.219 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.220 + NR_STUN_ATTR_FINGERPRINT, 1.221 + {} 1.222 +) 1.223 + 1.224 +int 1.225 +nr_stun_message_add_message_integrity_attribute(nr_stun_message *msg, Data *password) 1.226 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.227 + NR_STUN_ATTR_MESSAGE_INTEGRITY, 1.228 + { 1.229 + if (sizeof(attr->u.message_integrity.password) < password->len) 1.230 + ABORT(R_BAD_DATA); 1.231 + 1.232 + memcpy(attr->u.message_integrity.password, password->data, password->len); 1.233 + attr->u.message_integrity.passwordlen = password->len; 1.234 + } 1.235 +) 1.236 + 1.237 +int 1.238 +nr_stun_message_add_nonce_attribute(nr_stun_message *msg, char *nonce) 1.239 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.240 + NR_STUN_ATTR_NONCE, 1.241 + { strlcpy(attr->u.nonce, nonce, sizeof(attr->u.nonce)); } 1.242 +) 1.243 + 1.244 +int 1.245 +nr_stun_message_add_realm_attribute(nr_stun_message *msg, char *realm) 1.246 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.247 + NR_STUN_ATTR_REALM, 1.248 + { strlcpy(attr->u.realm, realm, sizeof(attr->u.realm)); } 1.249 +) 1.250 + 1.251 +int 1.252 +nr_stun_message_add_server_attribute(nr_stun_message *msg, char *server_name) 1.253 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.254 + NR_STUN_ATTR_SERVER, 1.255 + { strlcpy(attr->u.server_name, server_name, sizeof(attr->u.server_name)); } 1.256 +) 1.257 + 1.258 +int 1.259 +nr_stun_message_add_unknown_attributes_attribute(nr_stun_message *msg, nr_stun_attr_unknown_attributes *unknown_attributes) 1.260 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.261 + NR_STUN_ATTR_UNKNOWN_ATTRIBUTES, 1.262 + { memcpy(&attr->u.unknown_attributes, unknown_attributes, sizeof(attr->u.unknown_attributes)); } 1.263 +) 1.264 + 1.265 +int 1.266 +nr_stun_message_add_username_attribute(nr_stun_message *msg, char *username) 1.267 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.268 + NR_STUN_ATTR_USERNAME, 1.269 + { strlcpy(attr->u.username, username, sizeof(attr->u.username)); } 1.270 +) 1.271 + 1.272 +int 1.273 +nr_stun_message_add_requested_transport_attribute(nr_stun_message *msg, UCHAR protocol) 1.274 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.275 + NR_STUN_ATTR_REQUESTED_TRANSPORT, 1.276 + { attr->u.requested_transport = protocol; } 1.277 +) 1.278 + 1.279 +int 1.280 +nr_stun_message_add_xor_mapped_address_attribute(nr_stun_message *msg, nr_transport_addr *mapped_address) 1.281 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.282 + NR_STUN_ATTR_XOR_MAPPED_ADDRESS, 1.283 + { 1.284 + if ((r=nr_transport_addr_copy(&attr->u.xor_mapped_address.unmasked, mapped_address))) 1.285 + ABORT(r); 1.286 + } 1.287 +) 1.288 + 1.289 +int 1.290 +nr_stun_message_add_xor_peer_address_attribute(nr_stun_message *msg, nr_transport_addr *peer_address) 1.291 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.292 + NR_STUN_ATTR_XOR_PEER_ADDRESS, 1.293 + { 1.294 + if ((r=nr_transport_addr_copy(&attr->u.xor_mapped_address.unmasked, peer_address))) 1.295 + ABORT(r); 1.296 + } 1.297 +) 1.298 + 1.299 +#ifdef USE_ICE 1.300 +int 1.301 +nr_stun_message_add_ice_controlled_attribute(nr_stun_message *msg, UINT8 ice_controlled) 1.302 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.303 + NR_STUN_ATTR_ICE_CONTROLLED, 1.304 + { attr->u.ice_controlled = ice_controlled; } 1.305 +) 1.306 + 1.307 +int 1.308 +nr_stun_message_add_ice_controlling_attribute(nr_stun_message *msg, UINT8 ice_controlling) 1.309 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.310 + NR_STUN_ATTR_ICE_CONTROLLING, 1.311 + { attr->u.ice_controlling = ice_controlling; } 1.312 +) 1.313 + 1.314 +int 1.315 +nr_stun_message_add_priority_attribute(nr_stun_message *msg, UINT4 priority) 1.316 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.317 + NR_STUN_ATTR_PRIORITY, 1.318 + { attr->u.priority = priority; } 1.319 +) 1.320 + 1.321 +int 1.322 +nr_stun_message_add_use_candidate_attribute(nr_stun_message *msg) 1.323 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.324 + NR_STUN_ATTR_USE_CANDIDATE, 1.325 + {} 1.326 +) 1.327 +#endif /* USE_ICE */ 1.328 + 1.329 +#ifdef USE_TURN 1.330 +int 1.331 +nr_stun_message_add_data_attribute(nr_stun_message *msg, UCHAR *data, int length) 1.332 + 1.333 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.334 + NR_STUN_ATTR_DATA, 1.335 + { 1.336 + if (length > NR_STUN_MAX_MESSAGE_SIZE) 1.337 + ABORT(R_BAD_ARGS); 1.338 + 1.339 + memcpy(attr->u.data.data, data, length); 1.340 + attr->u.data.length=length; 1.341 + } 1.342 +) 1.343 + 1.344 +int 1.345 +nr_stun_message_add_lifetime_attribute(nr_stun_message *msg, UINT4 lifetime_secs) 1.346 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.347 + NR_STUN_ATTR_LIFETIME, 1.348 + { attr->u.lifetime_secs = lifetime_secs; } 1.349 +) 1.350 + 1.351 +#endif /* USE_TURN */ 1.352 + 1.353 +#ifdef USE_STUND_0_96 1.354 +int 1.355 +nr_stun_message_add_change_request_attribute(nr_stun_message *msg, UINT4 change_request) 1.356 +NR_STUN_MESSAGE_ADD_ATTRIBUTE( 1.357 + NR_STUN_ATTR_OLD_CHANGE_REQUEST, 1.358 + { attr->u.change_request = change_request; } 1.359 +) 1.360 +#endif /* USE_STUND_0_96 */ 1.361 +