coturn/src/client/ns_turn_msg_addr.c
Michael Jones 9ae1e3b3cb
Add spdx tags to all source files (#1510)
With notable exceptions of:

src/apps/common/win/*
src/apps/relay/telnet.*

The purpose of this change is to add the SPDX tags from
https://spdx.dev/, which is a linux foundation project, to the source
code.

This provides automated code provenance tools, which are used in setting
up software bill of materials reports, an easy time verifying that the
code license is known and no incompatibilities are present in a
codebase.

No copyright date, author, or license changes are made.

Note also that
7e525c8e1c
is the original commit for the ACME code (acme.h and acme.c) which was
then moved to acme.h and acme.c in this commit
d4686750ee
but neither commit indicates what license the ACME code was submitted
as.

https://github.com/coturn/coturn?tab=License-1-ov-file#readme is the
3-clause BSD license, but https://github.com/coturn/coturn/pull/672
documents that the author's intent was for the MIT license. So I've used
the SPDX tag and content of the MIT license for this change.
2025-05-30 11:56:04 +02:00

202 lines
5.0 KiB
C

/*
* SPDX-License-Identifier: BSD-3-Clause
*
* https://opensource.org/license/bsd-3-clause
*
* Copyright (C) 2011, 2012, 2013 Citrix Systems
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "ns_turn_msg_addr.h"
#include "ns_turn_defs.h" // for nswap16, nswap32
#include <string.h> // for memcpy
//////////////////////////////////////////////////////////////////////////////
int stun_addr_encode(const ioa_addr *ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id) {
if (!cfield || !clen || !ca || !tsx_id) {
return -1;
}
if (ca->ss.sa_family == AF_INET || ca->ss.sa_family == 0) {
/* IPv4 address */
*clen = 8;
cfield[0] = 0;
cfield[1] = 1; // IPv4 family
if (xor_ed) {
/* Port */
((uint16_t *)cfield)[1] = (ca->s4.sin_port) ^ nswap16(mc >> 16);
/* Address */
((uint32_t *)cfield)[1] = (ca->s4.sin_addr.s_addr) ^ nswap32(mc);
} else {
/* Port */
((uint16_t *)cfield)[1] = ca->s4.sin_port;
/* Address */
((uint32_t *)cfield)[1] = ca->s4.sin_addr.s_addr;
}
} else if (ca->ss.sa_family == AF_INET6) {
/* IPv6 address */
*clen = 20;
cfield[0] = 0;
cfield[1] = 2; // IPv6 family
if (xor_ed) {
unsigned int i;
uint8_t *dst = ((uint8_t *)cfield) + 4;
const uint8_t *src = (const uint8_t *)&(ca->s6.sin6_addr);
uint32_t magic = nswap32(mc);
/* Port */
((uint16_t *)cfield)[1] = ca->s6.sin6_port ^ nswap16(mc >> 16);
/* Address */
for (i = 0; i < 4; ++i) {
dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]);
}
for (i = 0; i < 12; ++i) {
dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]);
}
} else {
/* Port */
((uint16_t *)cfield)[1] = ca->s6.sin6_port;
/* Address */
memcpy(((uint8_t *)cfield) + 4, &ca->s6.sin6_addr, 16);
}
} else {
return -1;
}
return 0;
}
int stun_addr_decode(ioa_addr *ca, const uint8_t *cfield, int len, int xor_ed, uint32_t mc, const uint8_t *tsx_id) {
if (!cfield || !len || !ca || !tsx_id || (len < 8)) {
return -1;
}
if (cfield[0] != 0) {
return -1;
}
int sa_family;
if (cfield[1] == 1) {
sa_family = AF_INET;
} else if (cfield[1] == 2) {
sa_family = AF_INET6;
} else {
return -1;
}
ca->ss.sa_family = sa_family;
if (sa_family == AF_INET) {
if (len != 8) {
return -1;
}
/* IPv4 address */
/* Port */
ca->s4.sin_port = ((const uint16_t *)cfield)[1];
/* Address */
ca->s4.sin_addr.s_addr = ((const uint32_t *)cfield)[1];
if (xor_ed) {
ca->s4.sin_port ^= nswap16(mc >> 16);
ca->s4.sin_addr.s_addr ^= nswap32(mc);
}
} else if (sa_family == AF_INET6) {
/* IPv6 address */
if (len != 20) {
return -1;
}
/* Port */
ca->s6.sin6_port = ((const uint16_t *)cfield)[1];
/* Address */
memcpy(&ca->s6.sin6_addr, ((const uint8_t *)cfield) + 4, 16);
if (xor_ed) {
unsigned int i;
uint8_t *dst;
const uint8_t *src;
uint32_t magic = nswap32(mc);
/* Port */
ca->s6.sin6_port ^= nswap16(mc >> 16);
/* Address */
src = ((const uint8_t *)cfield) + 4;
dst = (uint8_t *)&ca->s6.sin6_addr;
for (i = 0; i < 4; ++i) {
dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]);
}
for (i = 0; i < 12; ++i) {
dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]);
}
}
} else {
return -1;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////