reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
StunMessage.hxx
Go to the documentation of this file.
1#if !defined(STUNMESSAGE_HXX)
2#define STUNMESSAGE_HXX
3
4#include <ostream>
5#include <rutil/compat.hxx>
6#include <rutil/Data.hxx>
7
8#include "StunTuple.hxx"
9
10#define STUN_MAX_UNKNOWN_ATTRIBUTES 8
11#define TURN_MAX_XOR_PEER_ADDR 8
12
13namespace reTurn
14{
15
16typedef struct { uint32_t longpart[4]; } UInt128;
17typedef struct { uint32_t longpart[3]; } UInt96;
18
19#ifdef __cplusplus
20bool operator<(const UInt128&, const UInt128&);
21bool operator==(const UInt128&, const UInt128&);
22#endif
23
25{
26public:
27 explicit StunMessage(const StunTuple& localTuple,
29 char* buf, unsigned int bufLen);
30
31 explicit StunMessage();
32
33 StunMessage(const StunMessage& message);
34 virtual ~StunMessage();
36
37 bool isValid() { return mIsValid; }
38 bool hasMagicCookie();
39 const StunTuple& getLocalTuple() const { return mLocalTuple; }
40 const StunTuple& getRemoteTuple() const { return mRemoteTuple; }
41
42 unsigned int stunEncodeMessage(char* buf, unsigned int bufLen);
43 unsigned int stunEncodeFramedMessage(char* buf, unsigned int bufLen); // Used for TURN-05 framing only
44
45 void setErrorCode(unsigned short errorCode, const char* reason);
46 void setUsername(const char* username);
47 void setPassword(const char* password);
48 void setRealm(const char* realm);
49 void setNonce(const char* nonce);
50 void setSoftware(const char* software);
51 void setTurnData(const char* data, unsigned int len);
52
53 // ICE-specific attributes
54 void setIcePriority(uint32_t priority);
55 void setIceUseCandidate();
56 void setIceControlled();
57 void setIceControlling();
58
59 void createHeader(uint16_t stunclass, uint16_t method); // Set info needed for a new stun message - set's tid as well
60 void createUsernameAndPassword(); // Ensure mRemoteTuple is set first
61 void generateShortTermPasswordForUsername(resip::Data& password); // Ensure username is set first
62 void getTupleFromUsername(StunTuple& tuple); // note: does not set transport type
67 // Verify the MESSAGE-INTEGRITY-SHA256 attribute (RFC 8489). Always returns
68 // false in builds without OpenSSL (no SHA-256 available - fail closed).
69 // Per RFC 8489 section 9.1.4/10, when both attributes are present the caller
70 // MUST prefer this over checkMessageIntegrity().
72 bool checkFingerprint();
73
75 const static uint8_t IPv4Family = 0x01;
76 const static uint8_t IPv6Family = 0x02;
77
78 const static uint8_t PropsPortEven = 0x00;
79 const static uint8_t PropsPortPair = 0x80;
80 const static uint8_t PropsNone = 0xFF;
81
82 // The following are codepoints used in the requested transport header, they
83 // are the same values used in the IPv4 and IPv6 headers
86
87 // define flags
88 const static uint32_t ChangeIpFlag = 0x04;
89 const static uint32_t ChangePortFlag = 0x02;
90
91
92 // Message Type - from RFC5389
93 //
94 // 0 1 2 3
95 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
96 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
97 // |0 0| STUN Message Type | Message Length |
98 // | |M|M|M|M|M|C|M|M|M|C|M|M|M|M| |
99 // | |1|1|9|8|7|1|6|5|4|0|3|2|1|0| |
100 // | |1|0| | | | | | | | | | | | | |
101 // | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
102 //
103 // M11 through M0 represent a 12-bit encoding of the method
104 // C1 through C0 represent a 2 bit encoding of the class.
105 // 2-bit Class Values are: 00=Request, 01=Indicaiton,
106 // 10=Success Response, 11=Error Response
107 //
108
109 const static uint16_t StunClassRequest = 0x0000;
110 const static uint16_t StunClassIndication = 0x0010;
111 const static uint16_t StunClassSuccessResponse = 0x0100;
112 const static uint16_t StunClassErrorResponse = 0x0110;
113
114 // define types for a stun message - RFC5389
115 const static uint16_t BindMethod = 0x001;
116 const static uint16_t SharedSecretMethod = 0x002; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
117
118 // define types for a turn message - per RFC5766
119 const static uint16_t TurnAllocateMethod = 0x003;
120 const static uint16_t TurnRefreshMethod = 0x004;
121 const static uint16_t TurnSendMethod = 0x006; // indication only
122 const static uint16_t TurnDataMethod = 0x007; // indication only
124 const static uint16_t TurnChannelBindMethod = 0x009;
125
126 // define stun attribute - RFC5389
127 // Comprehension required attributes
128 const static uint16_t MappedAddress = 0x0001;
129 const static uint16_t ResponseAddress = 0x0002; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
130 const static uint16_t ChangeRequest = 0x0003; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
131 const static uint16_t SourceAddress = 0x0004; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
132 const static uint16_t ChangedAddress = 0x0005; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
133 const static uint16_t Username = 0x0006;
134 const static uint16_t Password = 0x0007; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
135 const static uint16_t MessageIntegrity = 0x0008;
136 const static uint16_t ErrorCode = 0x0009;
137 const static uint16_t MessageIntegritySha256 = 0x001C; // RFC 8489
138 const static uint16_t UnknownAttribute = 0x000A;
139 const static uint16_t ReflectedFrom = 0x000B; // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
140 const static uint16_t Realm = 0x0014;
141 const static uint16_t Nonce = 0x0015;
142 const static uint16_t XorMappedAddress = 0x0020;
143 const static uint16_t XorMappedAddress_old = 0x8020; // deprecated
144 // Comprehension Optional Attributes
145 const static uint16_t Software = 0x8022;
146 const static uint16_t AlternateServer = 0x8023;
147 const static uint16_t Fingerprint = 0x8028;
148 const static uint16_t SecondaryAddress = 0x8050; // Non standard extension
149
150 // TURN specific message attributes - from behave-turn-12
151 const static uint16_t TurnChannelNumber = 0x000C;
152 const static uint16_t TurnLifetime = 0x000D;
153 const static uint16_t TurnBandwidth = 0x0010; // reserved (removed from latest draft)
154 const static uint16_t TurnXorPeerAddress = 0x0012;
155 const static uint16_t TurnData = 0x0013;
156 const static uint16_t TurnXorRelayedAddress = 0x0016;
157 const static uint16_t TurnEvenPort = 0x0018;
158 const static uint16_t TurnRequestedTransport = 0x0019;
159 const static uint16_t TurnDontFragment = 0x001a;
160 //const static uint16_t TurnTimerVal = 0x0021; // reserved (removed from latest draft)
161 const static uint16_t TurnReservationToken = 0x0022;
162 const static uint16_t TurnConnectStat = 0x0023; // tcp allocations
163 const static uint16_t TurnRequestedAddressFamily = 0x0017; // RFC 6156
164
165 // ICE specific message attributes - from draft-ietf-mmusic-ice-19
166 const static uint16_t IcePriority = 0x0024;
167 const static uint16_t IceUseCandidate = 0x0025;
168 const static uint16_t IceControlled = 0x8029;
169 const static uint16_t IceControlling = 0x802A;
170
171 const static uint32_t StunMagicCookie = 0x2112A442;
172 typedef struct
173 {
176 } Id;
177
178 typedef struct
179 {
182 union
183 {
186 };
187 } StunMsgHdr;
188
189 typedef struct
190 {
193 } StunAtrHdr;
194
195 typedef struct
196 {
199 union
200 {
201 uint32_t ipv4; // in host byte order
202 UInt128 ipv6; // in network byte order
203 } addr;
204 } StunAtrAddress;
205
212
218
219 typedef struct
220 {
221 char hash[20];
223
224 typedef struct
225 {
226 char hash[32];
228
229 typedef struct
230 {
233
242
243 // !slg! TODO make private and provide accessors
244 uint16_t mClass; // Request, Response, Indication
245 uint16_t mMethod; // Binding Request, Shared Secret Request, Allocation Request, etc.
246 bool mHasMagicCookie; // Set to true if stun magic cookie is in message header
247 StunTuple mLocalTuple; // Local address and port that received the stun message
248 StunTuple mRemoteTuple; // Remote address and port that sent the stun message
251
254
256
259
262
265
268
271
274
277
280
283
286
289
292
295
298
301
304
307
310
313
314 // Turn Attributes
317
320
323
326
329
332
335
338
340 // No attribute data
341
344
347
350
353
355
358
361
363
364 // Utility APIs
365 void applyXorToAddress(const StunAtrAddress& in, StunAtrAddress& out); // ensure tid is set first
366 static void setStunAtrAddressFromTuple(StunAtrAddress& address, const StunTuple& tuple);
367 static void setTupleFromStunAtrAddress(StunTuple& tuple, const StunAtrAddress& address); // Note: does not set transport type
368
369protected:
370
371private:
372 void init();
373
374 bool stunParseAtrXorAddress( char* body, unsigned int hdrLen, StunAtrAddress& result );
375 bool stunParseAtrAddress( char* body, unsigned int hdrLen, StunAtrAddress& result );
376 bool stunParseAtrUInt32( char* body, unsigned int hdrLen, uint32_t& result );
377 bool stunParseAtrUInt64( char* body, unsigned int hdrLen, uint64_t& result );
378 bool stunParseAtrError( char* body, unsigned int hdrLen, StunAtrError& result );
379 bool stunParseAtrUnknown( char* body, unsigned int hdrLen, StunAtrUnknown& result );
380 bool stunParseAtrIntegrity( char* body, unsigned int hdrLen, StunAtrIntegrity& result );
381 bool stunParseAtrIntegritySha256( char* body, unsigned int hdrLen, StunAtrIntegritySha256& result );
382 bool stunParseAtrEvenPort( char* body, unsigned int hdrLen, TurnAtrEvenPort& result );
383
384 bool stunParseMessage( char* buf, unsigned int bufLen);
385
386 char* encode16(char* buf, uint16_t data);
387 char* encode32(char* buf, uint32_t data);
388 char* encode64(char* buf, const uint64_t data);
389 char* encode(char* buf, const char* data, unsigned int length);
390 char* encodeTurnData(char *ptr, const resip::Data* td);
391 char* encodeAtrUInt32(char* ptr, uint16_t type, uint32_t value);
392 char* encodeAtrUInt64(char* ptr, uint16_t type, uint64_t value);
393 char* encodeAtrXorAddress(char* ptr, uint16_t type, const StunAtrAddress& atr);
394 char* encodeAtrAddress(char* ptr, uint16_t type, const StunAtrAddress& atr);
395 char* encodeAtrError(char* ptr, const StunAtrError& atr);
396 char* encodeAtrUnknown(char* ptr, const StunAtrUnknown& atr);
397 char* encodeAtrString(char* ptr, uint16_t type, const resip::Data* atr, uint16_t maxBytes);
398 char* encodeAtrIntegrity(char* ptr, const StunAtrIntegrity& atr);
399 char* encodeAtrIntegritySha256(char* ptr, const StunAtrIntegritySha256& atr);
400 char* encodeAtrEvenPort(char* ptr, const TurnAtrEvenPort& atr);
401 void computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey);
402#ifdef USE_SSL
403 void computeHmacSha256(char* hmac, const char* input, int length, const char* key, int sizeKey);
404#endif
405
406 bool mIsValid;
407};
408
412
413}
414
415#endif
416
417
418/* ====================================================================
419
420 Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
421 Copyright (c) 2007-2008, Plantronics, Inc.
422 All rights reserved.
423
424 Redistribution and use in source and binary forms, with or without
425 modification, are permitted provided that the following conditions are
426 met:
427
428 1. Redistributions of source code must retain the above copyright
429 notice, this list of conditions and the following disclaimer.
430
431 2. Redistributions in binary form must reproduce the above copyright
432 notice, this list of conditions and the following disclaimer in the
433 documentation and/or other materials provided with the distribution.
434
435 3. Neither the name of Plantronics nor the names of its contributors
436 may be used to endorse or promote products derived from this
437 software without specific prior written permission.
438
439 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
440 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
441 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
442 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
443 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
444 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
445 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
446 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
447 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
448 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
449 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
450
451 ==================================================================== */
#define TURN_MAX_XOR_PEER_ADDR
#define STUN_MAX_UNKNOWN_ATTRIBUTES
Definition Stun.hxx:22
uint64_t mIceControlledTieBreaker
static const uint16_t AlternateServer
static const uint8_t IPv4Family
define stun address families
static const uint16_t StunClassSuccessResponse
static const uint16_t SharedSecretMethod
static const uint16_t BindMethod
uint64_t mIceControllingTieBreaker
StunAtrAddress mMappedAddress
static const uint8_t PropsNone
static const uint16_t UnknownAttribute
static const uint16_t TurnBandwidth
bool checkMessageIntegritySha256(const resip::Data &hmacKey)
StunAtrError mErrorCode
static const uint16_t IceUseCandidate
void setTurnData(const char *data, unsigned int len)
void setPassword(const char *password)
uint16_t mMessageIntegritySha256MsgLength
static const uint16_t TurnDontFragment
void createHeader(uint16_t stunclass, uint16_t method)
static const uint16_t XorMappedAddress
StunAtrAddress mSecondaryAddress
const StunTuple & getLocalTuple() const
void getTupleFromUsername(StunTuple &tuple)
void generateShortTermPasswordForUsername(resip::Data &password)
static const uint16_t MessageIntegritySha256
static const uint16_t Realm
static const uint16_t SecondaryAddress
static const uint16_t TurnSendMethod
StunAtrUnknown mUnknownAttributes
uint64_t mTurnReservationToken
static const uint16_t Username
static const uint32_t ChangeIpFlag
resip::Data * mUsername
uint8_t mTurnRequestedTransport
StunAtrUnknown mUnknownRequiredAttributes
void applyXorToAddress(const StunAtrAddress &in, StunAtrAddress &out)
resip::Data * mSoftware
uint16_t mMessageIntegrityMsgLength
static const uint16_t XorMappedAddress_old
static const uint16_t TurnReservationToken
const StunTuple & getRemoteTuple() const
uint16_t mTurnRequestedAddressFamily
static const uint16_t TurnEvenPort
static const uint16_t StunClassErrorResponse
resip::Data * mPassword
StunAtrAddress mChangedAddress
static const uint16_t TurnCreatePermissionMethod
void setRealm(const char *realm)
static const uint16_t TurnXorRelayedAddress
unsigned int stunEncodeFramedMessage(char *buf, unsigned int bufLen)
static const uint16_t IcePriority
void setUsername(const char *username)
static const uint16_t TurnData
static const uint16_t Software
static const uint16_t StunClassRequest
static const uint16_t ChangeRequest
StunAtrAddress mTurnXorPeerAddress[TURN_MAX_XOR_PEER_ADDR]
void calculateHmacKey(resip::Data &hmacKey, const resip::Data &longtermAuthenticationPassword)
static const uint16_t TurnAllocateMethod
StunAtrAddress mReflectedFrom
resip::Data * mTurnData
static const uint16_t SourceAddress
StunAtrAddress mXorMappedAddress
bool checkMessageIntegrity(const resip::Data &hmacKey)
void setSoftware(const char *software)
static const uint32_t ChangePortFlag
void setErrorCode(unsigned short errorCode, const char *reason)
static const uint16_t MessageIntegrity
static const uint16_t TurnLifetime
static const uint32_t RequestedTransportTcp
StunAtrAddress mAlternateServer
static const uint16_t Fingerprint
StunAtrIntegritySha256 mMessageIntegritySha256
StunMessage & operator=(const StunMessage &rhs)
static const uint16_t Password
static const uint16_t ErrorCode
StunAtrAddress mResponseAddress
static const uint16_t TurnChannelNumber
static const uint16_t TurnDataMethod
static const uint16_t TurnRequestedTransport
StunAtrIntegrity mMessageIntegrity
static const uint16_t TurnXorPeerAddress
resip::Data * mRealm
static void setStunAtrAddressFromTuple(StunAtrAddress &address, const StunTuple &tuple)
static const uint8_t IPv6Family
static const uint32_t StunMagicCookie
static const uint8_t PropsPortEven
unsigned int stunEncodeMessage(char *buf, unsigned int bufLen)
static const uint16_t TurnConnectStat
void calculateHmacKeyForHa1(resip::Data &hmacKey, const resip::Data &ha1)
static const uint16_t MappedAddress
void setNonce(const char *nonce)
static const uint16_t TurnRefreshMethod
static const uint16_t ReflectedFrom
static const uint16_t IceControlled
static const uint8_t PropsPortPair
resip::Data * mNonce
static const uint16_t IceControlling
static const uint16_t Nonce
static const uint16_t TurnRequestedAddressFamily
static const uint32_t RequestedTransportUdp
void setIcePriority(uint32_t priority)
StunAtrAddress mTurnXorRelayedAddress
static const uint16_t TurnChannelBindMethod
StunAtrAddress mSourceAddress
static const uint16_t ResponseAddress
static const uint16_t ChangedAddress
TurnAtrEvenPort mTurnEvenPort
static const uint16_t StunClassIndication
static void setTupleFromStunAtrAddress(StunTuple &tuple, const StunAtrAddress &address)
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
bool operator==(const UInt128 &lhs, const UInt128 &rhs)
bool operator<(const UInt128 &lhs, const UInt128 &rhs)
EncodeStream & operator<<(EncodeStream &strm, const UInt128 &r)
#define EncodeStream
unsigned short uint16_t
Definition stdint.h:84
unsigned int uint32_t
Definition stdint.h:85
unsigned char uint8_t
Definition stdint.h:83
unsigned __int64 uint64_t
Definition stdint.h:95
void list()
Definition userAdmin.cxx:66