Coverage Report

Created: 2025-07-11 06:49

/src/coturn/src/client/ns_turn_msg_addr.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SPDX-License-Identifier: BSD-3-Clause
3
 *
4
 * https://opensource.org/license/bsd-3-clause
5
 *
6
 * Copyright (C) 2011, 2012, 2013 Citrix Systems
7
 *
8
 * All rights reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. Neither the name of the project nor the names of its contributors
19
 *    may be used to endorse or promote products derived from this software
20
 *    without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
 * SUCH DAMAGE.
33
 */
34
35
#include "ns_turn_msg_addr.h"
36
#include "ns_turn_defs.h" // for nswap16, nswap32
37
38
#include <string.h> // for memcpy
39
40
//////////////////////////////////////////////////////////////////////////////
41
42
0
int stun_addr_encode(const ioa_addr *ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id) {
43
44
0
  if (!cfield || !clen || !ca || !tsx_id) {
45
0
    return -1;
46
0
  }
47
48
0
  if (ca->ss.sa_family == AF_INET || ca->ss.sa_family == 0) {
49
50
    /* IPv4 address */
51
52
0
    *clen = 8;
53
54
0
    cfield[0] = 0;
55
0
    cfield[1] = 1; // IPv4 family
56
57
0
    if (xor_ed) {
58
59
      /* Port */
60
0
      ((uint16_t *)cfield)[1] = (ca->s4.sin_port) ^ nswap16(mc >> 16);
61
62
      /* Address */
63
0
      ((uint32_t *)cfield)[1] = (ca->s4.sin_addr.s_addr) ^ nswap32(mc);
64
65
0
    } else {
66
67
      /* Port */
68
0
      ((uint16_t *)cfield)[1] = ca->s4.sin_port;
69
70
      /* Address */
71
0
      ((uint32_t *)cfield)[1] = ca->s4.sin_addr.s_addr;
72
0
    }
73
74
0
  } else if (ca->ss.sa_family == AF_INET6) {
75
76
    /* IPv6 address */
77
78
0
    *clen = 20;
79
80
0
    cfield[0] = 0;
81
0
    cfield[1] = 2; // IPv6 family
82
83
0
    if (xor_ed) {
84
85
0
      unsigned int i;
86
0
      uint8_t *dst = ((uint8_t *)cfield) + 4;
87
0
      const uint8_t *src = (const uint8_t *)&(ca->s6.sin6_addr);
88
0
      uint32_t magic = nswap32(mc);
89
90
      /* Port */
91
0
      ((uint16_t *)cfield)[1] = ca->s6.sin6_port ^ nswap16(mc >> 16);
92
93
      /* Address */
94
95
0
      for (i = 0; i < 4; ++i) {
96
0
        dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]);
97
0
      }
98
0
      for (i = 0; i < 12; ++i) {
99
0
        dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]);
100
0
      }
101
102
0
    } else {
103
104
      /* Port */
105
0
      ((uint16_t *)cfield)[1] = ca->s6.sin6_port;
106
107
      /* Address */
108
0
      memcpy(((uint8_t *)cfield) + 4, &ca->s6.sin6_addr, 16);
109
0
    }
110
111
0
  } else {
112
0
    return -1;
113
0
  }
114
115
0
  return 0;
116
0
}
117
118
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) {
119
120
0
  if (!cfield || !len || !ca || !tsx_id || (len < 8)) {
121
0
    return -1;
122
0
  }
123
124
0
  if (cfield[0] != 0) {
125
0
    return -1;
126
0
  }
127
128
0
  int sa_family;
129
130
0
  if (cfield[1] == 1) {
131
0
    sa_family = AF_INET;
132
0
  } else if (cfield[1] == 2) {
133
0
    sa_family = AF_INET6;
134
0
  } else {
135
0
    return -1;
136
0
  }
137
138
0
  ca->ss.sa_family = sa_family;
139
140
0
  if (sa_family == AF_INET) {
141
142
0
    if (len != 8) {
143
0
      return -1;
144
0
    }
145
146
    /* IPv4 address */
147
148
    /* Port */
149
0
    ca->s4.sin_port = ((const uint16_t *)cfield)[1];
150
151
    /* Address */
152
0
    ca->s4.sin_addr.s_addr = ((const uint32_t *)cfield)[1];
153
154
0
    if (xor_ed) {
155
0
      ca->s4.sin_port ^= nswap16(mc >> 16);
156
0
      ca->s4.sin_addr.s_addr ^= nswap32(mc);
157
0
    }
158
159
0
  } else if (sa_family == AF_INET6) {
160
161
    /* IPv6 address */
162
163
0
    if (len != 20) {
164
0
      return -1;
165
0
    }
166
167
    /* Port */
168
0
    ca->s6.sin6_port = ((const uint16_t *)cfield)[1];
169
170
    /* Address */
171
0
    memcpy(&ca->s6.sin6_addr, ((const uint8_t *)cfield) + 4, 16);
172
173
0
    if (xor_ed) {
174
175
0
      unsigned int i;
176
0
      uint8_t *dst;
177
0
      const uint8_t *src;
178
0
      uint32_t magic = nswap32(mc);
179
180
      /* Port */
181
0
      ca->s6.sin6_port ^= nswap16(mc >> 16);
182
183
      /* Address */
184
0
      src = ((const uint8_t *)cfield) + 4;
185
0
      dst = (uint8_t *)&ca->s6.sin6_addr;
186
0
      for (i = 0; i < 4; ++i) {
187
0
        dst[i] = (uint8_t)(src[i] ^ ((const uint8_t *)&magic)[i]);
188
0
      }
189
0
      for (i = 0; i < 12; ++i) {
190
0
        dst[i + 4] = (uint8_t)(src[i + 4] ^ tsx_id[i]);
191
0
      }
192
0
    }
193
194
0
  } else {
195
0
    return -1;
196
0
  }
197
198
0
  return 0;
199
0
}
200
201
//////////////////////////////////////////////////////////////////////////////