Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
bdf2783a
Commit
bdf2783a
authored
Mar 27, 2021
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
还原原始文件名
parent
704421b7
显示空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
523 行增加
和
353 行删除
+523
-353
server/WebApi.cpp
+1
-1
webrtc/DtlsTransport.cpp
+1
-1
webrtc/DtlsTransport.hpp
+1
-1
webrtc/IceServer.cpp
+1
-1
webrtc/IceServer.hpp
+1
-1
webrtc/SrtpSession.cpp
+1
-1
webrtc/SrtpSession.hpp
+1
-1
webrtc/StunPacket.cpp
+316
-159
webrtc/StunPacket.hpp
+195
-0
webrtc/Utils.hpp
+0
-0
webrtc/WebRtcTransport.cpp
+1
-1
webrtc/WebRtcTransport.h
+4
-4
webrtc/logger.h
+0
-3
webrtc/stun_packet.h
+0
-179
没有找到文件。
server/WebApi.cpp
查看文件 @
bdf2783a
...
...
@@ -36,7 +36,7 @@
#include "Rtp/RtpServer.h"
#endif
#ifdef ENABLE_WEBRTC
#include "../webrtc/
webrtc_t
ransport.h"
#include "../webrtc/
WebRtcT
ransport.h"
#endif
using
namespace
toolkit
;
...
...
webrtc/
rtc_dtls_transport.cc
→
webrtc/
DtlsTransport.cpp
查看文件 @
bdf2783a
#define MS_CLASS "RTC::DtlsTransport"
// #define MS_LOG_DEV_LEVEL 3
#include "
rtc_dtls_transport.h
"
#include "
DtlsTransport.hpp
"
#include "logger.h"
#include <openssl/asn1.h>
#include <openssl/bn.h>
...
...
webrtc/
rtc_dtls_transport.h
→
webrtc/
DtlsTransport.hpp
查看文件 @
bdf2783a
#ifndef MS_RTC_DTLS_TRANSPORT_HPP
#define MS_RTC_DTLS_TRANSPORT_HPP
#include "
srtp_session.h
"
#include "
SrtpSession.hpp
"
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
...
...
webrtc/
ice_server.cc
→
webrtc/
IceServer.cpp
查看文件 @
bdf2783a
...
...
@@ -2,7 +2,7 @@
// #define MS_LOG_DEV_LEVEL 3
#include <utility>
#include "
ice_server.h
"
#include "
IceServer.hpp
"
namespace
RTC
{
...
...
webrtc/
ice_server.h
→
webrtc/
IceServer.hpp
查看文件 @
bdf2783a
#ifndef MS_RTC_ICE_SERVER_HPP
#define MS_RTC_ICE_SERVER_HPP
#include "
stun_packet.h
"
#include "
StunPacket.hpp
"
#include "logger.h"
#include <list>
#include <string>
...
...
webrtc/
srtp_session.cc
→
webrtc/
SrtpSession.cpp
查看文件 @
bdf2783a
#define MS_CLASS "RTC::SrtpSession"
// #define MS_LOG_DEV_LEVEL 3
#include "
srtp_session.h
"
#include "
SrtpSession.hpp
"
#include <cstring> // std::memset(), std::memcpy()
#include "logger.h"
...
...
webrtc/
srtp_session.h
→
webrtc/
SrtpSession.hpp
查看文件 @
bdf2783a
#ifndef MS_RTC_SRTP_SESSION_HPP
#define MS_RTC_SRTP_SESSION_HPP
#include "
utils.h
"
#include "
Utils.hpp
"
#include <srtp2/srtp.h>
#include <vector>
...
...
webrtc/
stun_packet.cc
→
webrtc/
StunPacket.cpp
查看文件 @
bdf2783a
#define MS_CLASS "RTC::StunPacket"
// #define MS_LOG_DEV
#include "stun_packet.h"
// #define MS_LOG_DEV_LEVEL 3
#include "StunPacket.hpp"
#include <cstdio> // std::snprintf()
#include <cstring> // std::memcmp(), std::memcpy()
namespace
RTC
{
static
const
uint32_t
crc32Table
[]
=
namespace
RTC
{
static
const
uint32_t
crc32Table
[]
=
{
0x00000000
,
0x77073096
,
0xee0e612c
,
0x990951ba
,
0x076dc419
,
0x706af48f
,
0xe963a535
,
0x9e6495a3
,
0x0edb8832
,
0x79dcb8a4
,
0xe0d5e91e
,
0x97d2d988
,
0x09b64c2b
,
0x7eb17cbd
,
0xe7b82d07
,
0x90bf1d91
,
0x1db71064
,
0x6ab020f2
,
0xf3b97148
,
0x84be41de
,
0x1adad47d
,
0x6ddde4eb
,
0xf4d4b551
,
0x83d385c7
,
...
...
@@ -42,9 +41,9 @@ static const uint32_t crc32Table[] =
0xaed16a4a
,
0xd9d65adc
,
0x40df0b66
,
0x37d83bf0
,
0xa9bcae53
,
0xdebb9ec5
,
0x47b2cf7f
,
0x30b5ffe9
,
0xbdbdf21c
,
0xcabac28a
,
0x53b39330
,
0x24b4a3a6
,
0xbad03605
,
0xcdd70693
,
0x54de5729
,
0x23d967bf
,
0xb3667a2e
,
0xc4614ab8
,
0x5d681b02
,
0x2a6f2b94
,
0xb40bbe37
,
0xc30c8ea1
,
0x5a05df1b
,
0x2d02ef8d
};
};
inline
uint32_t
GetCRC32
(
const
uint8_t
*
data
,
size_t
size
)
{
inline
uint32_t
GetCRC32
(
const
uint8_t
*
data
,
size_t
size
)
{
uint32_t
crc
{
0xFFFFFFFF
};
const
uint8_t
*
p
=
data
;
...
...
@@ -53,9 +52,9 @@ inline uint32_t GetCRC32(const uint8_t *data, size_t size) {
}
return
crc
^
~
0U
;
}
}
static
std
::
string
openssl_HMACsha1
(
const
void
*
key
,
size_t
key_len
,
const
void
*
data
,
size_t
data_len
){
static
std
::
string
openssl_HMACsha1
(
const
void
*
key
,
size_t
key_len
,
const
void
*
data
,
size_t
data_len
){
std
::
string
str
;
str
.
resize
(
20
);
unsigned
int
out_len
;
...
...
@@ -77,16 +76,20 @@ static std::string openssl_HMACsha1(const void *key, size_t key_len, const void
HMAC_CTX_cleanup
(
&
ctx
);
#endif //defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER > 0x10100000L)
return
str
;
}
}
/* Class variables. */
/* Class variables. */
const
uint8_t
StunPacket
::
kMagicCookie
[]
=
{
0x21
,
0x12
,
0xA4
,
0x42
};
const
uint8_t
StunPacket
::
magicCookie
[]
=
{
0x21
,
0x12
,
0xA4
,
0x42
};
/* Class methods. */
/* Class methods. */
StunPacket
*
StunPacket
::
Parse
(
const
uint8_t
*
data
,
size_t
len
)
{
if
(
!
StunPacket
::
IsStun
(
data
,
len
))
return
nullptr
;
StunPacket
*
StunPacket
::
Parse
(
const
uint8_t
*
data
,
size_t
len
)
{
MS_TRACE
();
if
(
!
StunPacket
::
IsStun
(
data
,
len
))
return
nullptr
;
/*
The message type field is decomposed further into the following
...
...
@@ -114,8 +117,10 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
uint16_t
msgLength
=
Utils
::
Byte
::
Get2Bytes
(
data
,
2
);
// length field must be total size minus header's 20 bytes, and must be multiple of 4 Bytes.
if
((
static_cast
<
size_t
>
(
msgLength
)
!=
len
-
20
)
||
((
msgLength
&
0x03
)
!=
0
))
{
ELOG_DEBUG
(
if
((
static_cast
<
size_t
>
(
msgLength
)
!=
len
-
20
)
||
((
msgLength
&
0x03
)
!=
0
))
{
MS_WARN_TAG
(
ice
,
"length field + 20 does not match total size (or it is not multiple of 4 bytes), "
"packet discarded"
);
...
...
@@ -129,8 +134,8 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
uint16_t
msgClass
=
((
data
[
0
]
&
0x01
)
<<
1
)
|
((
data
[
1
]
&
0x10
)
>>
4
);
// Create a new StunPacket (data + 8 points to the received TransactionID field).
auto
packet
=
new
StunPacket
(
static_cast
<
Class
>
(
msgClass
),
static_cast
<
Method
>
(
msgMethod
),
data
+
8
,
data
,
len
);
auto
*
packet
=
new
StunPacket
(
static_cast
<
Class
>
(
msgClass
),
static_cast
<
Method
>
(
msgMethod
),
data
+
8
,
data
,
len
);
/*
STUN Attributes
...
...
@@ -151,15 +156,16 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
*/
// Start looking for attributes after STUN header (Byte #20).
size_t
pos
{
20
};
size_t
pos
{
20
};
// Flags (positions) for special MESSAGE-INTEGRITY and FINGERPRINT attributes.
bool
hasMessageIntegrity
{
false
};
bool
hasFingerprint
{
false
};
bool
hasMessageIntegrity
{
false
};
bool
hasFingerprint
{
false
};
size_t
fingerprintAttrPos
;
// Will point to the beginning of the attribute.
uint32_t
fingerprint
;
// Holds the value of the FINGERPRINT attribute.
// Ensure there are at least 4 remaining bytes (attribute with 0 length).
while
(
pos
+
4
<=
len
)
{
while
(
pos
+
4
<=
len
)
{
// Get the attribute type.
auto
attrType
=
static_cast
<
Attribute
>
(
Utils
::
Byte
::
Get2Bytes
(
data
,
pos
));
...
...
@@ -167,24 +173,28 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
uint16_t
attrLength
=
Utils
::
Byte
::
Get2Bytes
(
data
,
pos
+
2
);
// Ensure the attribute length is not greater than the remaining size.
if
((
pos
+
4
+
attrLength
)
>
len
)
{
ELOG_DEBUG
(
"the attribute length exceeds the remaining size, packet discarded"
);
if
((
pos
+
4
+
attrLength
)
>
len
)
{
MS_WARN_TAG
(
ice
,
"the attribute length exceeds the remaining size, packet discarded"
);
delete
packet
;
return
nullptr
;
}
// FINGERPRINT must be the last attribute.
if
(
hasFingerprint
)
{
ELOG_DEBUG
(
"attribute after FINGERPRINT is not allowed, packet discarded"
);
if
(
hasFingerprint
)
{
MS_WARN_TAG
(
ice
,
"attribute after FINGERPRINT is not allowed, packet discarded"
);
delete
packet
;
return
nullptr
;
}
// After a MESSAGE-INTEGRITY attribute just FINGERPRINT is allowed.
if
(
hasMessageIntegrity
&&
attrType
!=
Attribute
::
FINGERPRINT
)
{
ELOG_DEBUG
(
if
(
hasMessageIntegrity
&&
attrType
!=
Attribute
::
FINGERPRINT
)
{
MS_WARN_TAG
(
ice
,
"attribute after MESSAGE-INTEGRITY other than FINGERPRINT is not allowed, "
"packet discarded"
);
...
...
@@ -194,18 +204,22 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
const
uint8_t
*
attrValuePos
=
data
+
pos
+
4
;
switch
(
attrType
)
{
case
Attribute
:
:
USERNAME
:
{
packet
->
SetUsername
(
reinterpret_cast
<
const
char
*>
(
attrValuePos
),
static_cast
<
size_t
>
(
attrLength
));
switch
(
attrType
)
{
case
Attribute
:
:
USERNAME
:
{
packet
->
SetUsername
(
reinterpret_cast
<
const
char
*>
(
attrValuePos
),
static_cast
<
size_t
>
(
attrLength
));
break
;
}
case
Attribute
:
:
PRIORITY
:
{
case
Attribute
:
:
PRIORITY
:
{
// Ensure attribute length is 4 bytes.
if
(
attrLength
!=
4
)
{
ELOG_DEBUG
(
"attribute PRIORITY must be 4 bytes length, packet discarded"
);
if
(
attrLength
!=
4
)
{
MS_WARN_TAG
(
ice
,
"attribute PRIORITY must be 4 bytes length, packet discarded"
);
delete
packet
;
return
nullptr
;
...
...
@@ -216,10 +230,12 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
break
;
}
case
Attribute
:
:
ICE_CONTROLLING
:
{
case
Attribute
:
:
ICE_CONTROLLING
:
{
// Ensure attribute length is 8 bytes.
if
(
attrLength
!=
8
)
{
ELOG_DEBUG
(
"attribute ICE-CONTROLLING must be 8 bytes length, packet discarded"
);
if
(
attrLength
!=
8
)
{
MS_WARN_TAG
(
ice
,
"attribute ICE-CONTROLLING must be 8 bytes length, packet discarded"
);
delete
packet
;
return
nullptr
;
...
...
@@ -230,10 +246,12 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
break
;
}
case
Attribute
:
:
ICE_CONTROLLED
:
{
case
Attribute
:
:
ICE_CONTROLLED
:
{
// Ensure attribute length is 8 bytes.
if
(
attrLength
!=
8
)
{
ELOG_DEBUG
(
"attribute ICE-CONTROLLED must be 8 bytes length, packet discarded"
);
if
(
attrLength
!=
8
)
{
MS_WARN_TAG
(
ice
,
"attribute ICE-CONTROLLED must be 8 bytes length, packet discarded"
);
delete
packet
;
return
nullptr
;
...
...
@@ -244,10 +262,12 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
break
;
}
case
Attribute
:
:
USE_CANDIDATE
:
{
case
Attribute
:
:
USE_CANDIDATE
:
{
// Ensure attribute length is 0 bytes.
if
(
attrLength
!=
0
)
{
ELOG_DEBUG
(
"attribute USE-CANDIDATE must be 0 bytes length, packet discarded"
);
if
(
attrLength
!=
0
)
{
MS_WARN_TAG
(
ice
,
"attribute USE-CANDIDATE must be 0 bytes length, packet discarded"
);
delete
packet
;
return
nullptr
;
...
...
@@ -258,10 +278,12 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
break
;
}
case
Attribute
:
:
MESSAGE_INTEGRITY
:
{
case
Attribute
:
:
MESSAGE_INTEGRITY
:
{
// Ensure attribute length is 20 bytes.
if
(
attrLength
!=
20
)
{
ELOG_DEBUG
(
"attribute MESSAGE-INTEGRITY must be 20 bytes length, packet discarded"
);
if
(
attrLength
!=
20
)
{
MS_WARN_TAG
(
ice
,
"attribute MESSAGE-INTEGRITY must be 20 bytes length, packet discarded"
);
delete
packet
;
return
nullptr
;
...
...
@@ -273,10 +295,12 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
break
;
}
case
Attribute
:
:
FINGERPRINT
:
{
case
Attribute
:
:
FINGERPRINT
:
{
// Ensure attribute length is 4 bytes.
if
(
attrLength
!=
4
)
{
ELOG_DEBUG
(
"attribute FINGERPRINT must be 4 bytes length, packet discarded"
);
if
(
attrLength
!=
4
)
{
MS_WARN_TAG
(
ice
,
"attribute FINGERPRINT must be 4 bytes length, packet discarded"
);
delete
packet
;
return
nullptr
;
...
...
@@ -290,10 +314,12 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
break
;
}
case
Attribute
:
:
ERROR_CODE
:
{
case
Attribute
:
:
ERROR_CODE
:
{
// Ensure attribute length >= 4bytes.
if
(
attrLength
<
4
)
{
ELOG_DEBUG
(
"attribute ERROR-CODE must be >= 4bytes length, packet discarded"
);
if
(
attrLength
<
4
)
{
MS_WARN_TAG
(
ice
,
"attribute ERROR-CODE must be >= 4bytes length, packet discarded"
);
delete
packet
;
return
nullptr
;
...
...
@@ -312,26 +338,31 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
}
// Set next attribute position.
pos
=
static_cast
<
size_t
>
(
Utils
::
Byte
::
PadTo4Bytes
(
static_cast
<
uint16_t
>
(
pos
+
4
+
attrLength
)));
pos
=
static_cast
<
size_t
>
(
Utils
::
Byte
::
PadTo4Bytes
(
static_cast
<
uint16_t
>
(
pos
+
4
+
attrLength
)));
}
// Ensure current position matches the total length.
if
(
pos
!=
len
)
{
ELOG_DEBUG
(
"computed packet size does not match total size, packet discarded"
);
if
(
pos
!=
len
)
{
MS_WARN_TAG
(
ice
,
"computed packet size does not match total size, packet discarded"
);
delete
packet
;
return
nullptr
;
}
// If it has FINGERPRINT attribute then verify it.
if
(
hasFingerprint
)
{
if
(
hasFingerprint
)
{
// Compute the CRC32 of the received packet up to (but excluding) the
// FINGERPRINT attribute and XOR it with 0x5354554e.
uint32_t
computedFingerprint
=
GetCRC32
(
data
,
fingerprintAttrPos
)
^
0x5354554e
;
// Compare with the FINGERPRINT value in the packet.
if
(
fingerprint
!=
computedFingerprint
)
{
ELOG_DEBUG
(
if
(
fingerprint
!=
computedFingerprint
)
{
MS_WARN_TAG
(
ice
,
"computed FINGERPRINT value does not match the value in the packet, "
"packet discarded"
);
...
...
@@ -341,41 +372,126 @@ StunPacket* StunPacket::Parse(const uint8_t* data, size_t len) {
}
return
packet
;
}
}
/* Instance methods. */
StunPacket
::
StunPacket
(
Class
klass
,
Method
method
,
const
uint8_t
*
transactionId
,
const
uint8_t
*
data
,
size_t
size
)
:
klass
(
klass
),
method
(
method
),
transactionId
(
transactionId
),
data
(
const_cast
<
uint8_t
*>
(
data
)),
size
(
size
)
{
MS_TRACE
();
}
StunPacket
::~
StunPacket
()
{
MS_TRACE
();
}
#if 0
void StunPacket::Dump() const
{
MS_TRACE();
MS_DUMP("<StunPacket>");
std::string klass;
switch (this->klass)
{
case Class::REQUEST:
klass = "Request";
break;
case Class::INDICATION:
klass = "Indication";
break;
case Class::SUCCESS_RESPONSE:
klass = "SuccessResponse";
break;
case Class::ERROR_RESPONSE:
klass = "ErrorResponse";
break;
}
if (this->method == Method::BINDING)
{
MS_DUMP(" Binding %s", klass.c_str());
}
else
{
// This prints the unknown method number. Example: TURN Allocate => 0x003.
MS_DUMP(" %s with unknown method %#.3x", klass.c_str(), static_cast<uint16_t>(this->method));
}
MS_DUMP(" size: %zu bytes", this->size);
static char transactionId[25];
/* Instance methods. */
for (int i{ 0 }; i < 12; ++i)
{
// NOTE: n must be 3 because snprintf adds a \0 after printed chars.
std::snprintf(transactionId + (i * 2), 3, "%.2x", this->transactionId[i]);
}
MS_DUMP(" transactionId: %s", transactionId);
if (this->errorCode != 0u)
MS_DUMP(" errorCode: %" PRIu16, this->errorCode);
if (!this->username.empty())
MS_DUMP(" username: %s", this->username.c_str());
if (this->priority != 0u)
MS_DUMP(" priority: %" PRIu32, this->priority);
if (this->iceControlling != 0u)
MS_DUMP(" iceControlling: %" PRIu64, this->iceControlling);
if (this->iceControlled != 0u)
MS_DUMP(" iceControlled: %" PRIu64, this->iceControlled);
if (this->hasUseCandidate)
MS_DUMP(" useCandidate");
if (this->xorMappedAddress != nullptr)
{
int family;
uint16_t port;
std::string ip;
StunPacket
::
StunPacket
(
Class
klass
,
Method
method
,
const
uint8_t
*
transactionId
,
const
uint8_t
*
data
,
size_t
size
)
:
klass
(
klass
),
method
(
method
),
transactionId
(
transactionId
),
data
(
const_cast
<
uint8_t
*>
(
data
)),
size
(
size
)
{
// MS_TRACE();
}
Utils::IP::GetAddressInfo(this->xorMappedAddress, family, ip, port);
StunPacket
::~
StunPacket
()
{
// MS_TRACE();
}
MS_DUMP(" xorMappedAddress: %s : %" PRIu16, ip.c_str(), port);
}
if (this->messageIntegrity != nullptr)
{
static char messageIntegrity[41];
StunPacket
::
Authentication
StunPacket
::
CheckAuthentication
(
const
std
::
string
&
localUsername
,
const
std
::
string
&
localPassword
)
{
// MS_TRACE();
for (int i{ 0 }; i < 20; ++i)
{
std::snprintf(messageIntegrity + (i * 2), 3, "%.2x", this->messageIntegrity[i]);
}
switch
(
this
->
klass
)
{
MS_DUMP(" messageIntegrity: %s", messageIntegrity);
}
if (this->hasFingerprint)
MS_DUMP(" has fingerprint");
MS_DUMP("</StunPacket>");
}
#endif
StunPacket
::
Authentication
StunPacket
::
CheckAuthentication
(
const
std
::
string
&
localUsername
,
const
std
::
string
&
localPassword
)
{
MS_TRACE
();
switch
(
this
->
klass
)
{
case
Class
:
:
REQUEST
:
case
Class
:
:
INDICATION
:
{
case
Class
:
:
INDICATION
:
{
// Both USERNAME and MESSAGE-INTEGRITY must be present.
if
(
this
->
messageIntegrity
==
nullptr
||
this
->
username
.
empty
())
if
(
!
this
->
messageIntegrity
||
this
->
username
.
empty
())
return
Authentication
::
BAD_REQUEST
;
// Check that USERNAME attribute begins with our local username plus ":".
size_t
localUsernameLen
=
localUsername
.
length
();
if
(
this
->
username
.
length
()
<=
localUsernameLen
||
this
->
username
.
at
(
localUsernameLen
)
!=
':'
||
(
this
->
username
.
compare
(
0
,
localUsernameLen
,
localUsername
)
!=
0
))
{
if
(
this
->
username
.
length
()
<=
localUsernameLen
||
this
->
username
.
at
(
localUsernameLen
)
!=
':'
||
(
this
->
username
.
compare
(
0
,
localUsernameLen
,
localUsername
)
!=
0
))
{
return
Authentication
::
UNAUTHORIZED
;
}
...
...
@@ -384,8 +500,9 @@ StunPacket::Authentication StunPacket::CheckAuthentication(const std::string& lo
// This method cannot check authentication in received responses (as we
// are ICE-Lite and don't generate requests).
case
Class
:
:
SUCCESS_RESPONSE
:
case
Class
:
:
ERROR_RESPONSE
:
{
// MS_ERROR("cannot check authentication for a STUN response");
case
Class
:
:
ERROR_RESPONSE
:
{
MS_ERROR
(
"cannot check authentication for a STUN response"
);
return
Authentication
::
BAD_REQUEST
;
}
...
...
@@ -414,56 +531,61 @@ StunPacket::Authentication StunPacket::CheckAuthentication(const std::string& lo
Utils
::
Byte
::
Set2Bytes
(
this
->
data
,
2
,
static_cast
<
uint16_t
>
(
this
->
size
-
20
));
return
result
;
}
}
StunPacket
*
StunPacket
::
CreateSuccessResponse
()
{
// MS_TRACE();
StunPacket
*
StunPacket
::
CreateSuccessResponse
()
{
MS_TRACE
();
//
MS_ASSERT(
//
this->klass == Class::REQUEST,
//
"attempt to create a success response for a non Request STUN packet");
MS_ASSERT
(
this
->
klass
==
Class
::
REQUEST
,
"attempt to create a success response for a non Request STUN packet"
);
return
new
StunPacket
(
Class
::
SUCCESS_RESPONSE
,
this
->
method
,
this
->
transactionId
,
nullptr
,
0
);
}
}
StunPacket
*
StunPacket
::
CreateErrorResponse
(
uint16_t
errorCode
)
{
// MS_TRACE();
StunPacket
*
StunPacket
::
CreateErrorResponse
(
uint16_t
errorCode
)
{
MS_TRACE
();
//
MS_ASSERT(
//
this->klass == Class::REQUEST,
//
"attempt to create an error response for a non Request STUN packet");
MS_ASSERT
(
this
->
klass
==
Class
::
REQUEST
,
"attempt to create an error response for a non Request STUN packet"
);
auto
response
=
auto
*
response
=
new
StunPacket
(
Class
::
ERROR_RESPONSE
,
this
->
method
,
this
->
transactionId
,
nullptr
,
0
);
response
->
SetErrorCode
(
errorCode
);
return
response
;
}
}
void
StunPacket
::
Authenticate
(
const
std
::
string
&
password
)
{
void
StunPacket
::
Authenticate
(
const
std
::
string
&
password
)
{
// Just for Request, Indication and SuccessResponse messages.
if
(
this
->
klass
==
Class
::
ERROR_RESPONSE
)
{
// MS_ERROR("cannot set password for ErrorResponse messages");
if
(
this
->
klass
==
Class
::
ERROR_RESPONSE
)
{
MS_ERROR
(
"cannot set password for ErrorResponse messages"
);
return
;
}
this
->
password
=
password
;
}
}
void
StunPacket
::
Serialize
(
uint8_t
*
buffer
)
{
// MS_TRACE();
void
StunPacket
::
Serialize
(
uint8_t
*
buffer
)
{
MS_TRACE
();
// Some useful variables.
uint16_t
usernamePaddedLen
{
0
};
uint16_t
xorMappedAddressPaddedLen
{
0
};
uint16_t
usernamePaddedLen
{
0
};
uint16_t
xorMappedAddressPaddedLen
{
0
};
bool
addXorMappedAddress
=
((
this
->
xorMappedAddress
!=
nullptr
)
&&
this
->
method
==
StunPacket
::
Method
::
BINDING
&&
this
->
klass
==
Class
::
SUCCESS_RESPONSE
);
bool
addErrorCode
=
((
this
->
errorCode
!=
0u
)
&&
this
->
klass
==
Class
::
ERROR_RESPONSE
);
bool
addMessageIntegrity
=
(
this
->
klass
!=
Class
::
ERROR_RESPONSE
&&
!
this
->
password
.
empty
());
bool
addFingerprint
{
true
};
// Do always.
bool
addFingerprint
{
true
};
// Do always.
// Update data pointer.
this
->
data
=
buffer
;
...
...
@@ -471,48 +593,61 @@ void StunPacket::Serialize(uint8_t* buffer) {
// First calculate the total required size for the entire packet.
this
->
size
=
20
;
// Header.
if
(
!
this
->
username
.
empty
())
{
if
(
!
this
->
username
.
empty
())
{
usernamePaddedLen
=
Utils
::
Byte
::
PadTo4Bytes
(
static_cast
<
uint16_t
>
(
this
->
username
.
length
()));
this
->
size
+=
4
+
usernamePaddedLen
;
}
if
(
this
->
priority
!=
0u
)
this
->
size
+=
4
+
4
;
if
(
this
->
priority
!=
0u
)
this
->
size
+=
4
+
4
;
if
(
this
->
iceControlling
!=
0u
)
this
->
size
+=
4
+
8
;
if
(
this
->
iceControlling
!=
0u
)
this
->
size
+=
4
+
8
;
if
(
this
->
iceControlled
!=
0u
)
this
->
size
+=
4
+
8
;
if
(
this
->
iceControlled
!=
0u
)
this
->
size
+=
4
+
8
;
if
(
this
->
hasUseCandidate
)
this
->
size
+=
4
;
if
(
this
->
hasUseCandidate
)
this
->
size
+=
4
;
if
(
addXorMappedAddress
)
{
switch
(
this
->
xorMappedAddress
->
sa_family
)
{
case
AF_INET
:
{
if
(
addXorMappedAddress
)
{
switch
(
this
->
xorMappedAddress
->
sa_family
)
{
case
AF_INET
:
{
xorMappedAddressPaddedLen
=
8
;
this
->
size
+=
4
+
8
;
break
;
}
case
AF_INET6
:
{
case
AF_INET6
:
{
xorMappedAddressPaddedLen
=
20
;
this
->
size
+=
4
+
20
;
break
;
}
default
:
{
// MS_ERROR("invalid inet family in XOR-MAPPED-ADDRESS attribute");
default
:
{
MS_ERROR
(
"invalid inet family in XOR-MAPPED-ADDRESS attribute"
);
addXorMappedAddress
=
false
;
}
}
}
if
(
addErrorCode
)
this
->
size
+=
4
+
4
;
if
(
addErrorCode
)
this
->
size
+=
4
+
4
;
if
(
addMessageIntegrity
)
this
->
size
+=
4
+
20
;
if
(
addMessageIntegrity
)
this
->
size
+=
4
+
20
;
if
(
addFingerprint
)
this
->
size
+=
4
+
4
;
if
(
addFingerprint
)
this
->
size
+=
4
+
4
;
// Merge class and method fields into type.
uint16_t
typeField
=
(
static_cast
<
uint16_t
>
(
this
->
method
)
&
0x0f80
)
<<
2
;
...
...
@@ -527,16 +662,17 @@ void StunPacket::Serialize(uint8_t* buffer) {
// Set length field.
Utils
::
Byte
::
Set2Bytes
(
buffer
,
2
,
static_cast
<
uint16_t
>
(
this
->
size
)
-
20
);
// Set magic cookie.
std
::
memcpy
(
buffer
+
4
,
StunPacket
::
kM
agicCookie
,
4
);
std
::
memcpy
(
buffer
+
4
,
StunPacket
::
m
agicCookie
,
4
);
// Set TransactionId field.
std
::
memcpy
(
buffer
+
8
,
this
->
transactionId
,
12
);
// Update the transaction ID pointer.
this
->
transactionId
=
buffer
+
8
;
// Add atributes.
size_t
pos
{
20
};
size_t
pos
{
20
};
// Add USERNAME.
if
(
usernamePaddedLen
!=
0u
)
{
if
(
usernamePaddedLen
!=
0u
)
{
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
,
static_cast
<
uint16_t
>
(
Attribute
::
USERNAME
));
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
+
2
,
static_cast
<
uint16_t
>
(
this
->
username
.
length
()));
std
::
memcpy
(
buffer
+
pos
+
4
,
this
->
username
.
c_str
(),
this
->
username
.
length
());
...
...
@@ -544,7 +680,8 @@ void StunPacket::Serialize(uint8_t* buffer) {
}
// Add PRIORITY.
if
(
this
->
priority
!=
0u
)
{
if
(
this
->
priority
!=
0u
)
{
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
,
static_cast
<
uint16_t
>
(
Attribute
::
PRIORITY
));
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
+
2
,
4
);
Utils
::
Byte
::
Set4Bytes
(
buffer
,
pos
+
4
,
this
->
priority
);
...
...
@@ -552,7 +689,8 @@ void StunPacket::Serialize(uint8_t* buffer) {
}
// Add ICE-CONTROLLING.
if
(
this
->
iceControlling
!=
0u
)
{
if
(
this
->
iceControlling
!=
0u
)
{
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
,
static_cast
<
uint16_t
>
(
Attribute
::
ICE_CONTROLLING
));
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
+
2
,
8
);
Utils
::
Byte
::
Set8Bytes
(
buffer
,
pos
+
4
,
this
->
iceControlling
);
...
...
@@ -560,7 +698,8 @@ void StunPacket::Serialize(uint8_t* buffer) {
}
// Add ICE-CONTROLLED.
if
(
this
->
iceControlled
!=
0u
)
{
if
(
this
->
iceControlled
!=
0u
)
{
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
,
static_cast
<
uint16_t
>
(
Attribute
::
ICE_CONTROLLED
));
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
+
2
,
8
);
Utils
::
Byte
::
Set8Bytes
(
buffer
,
pos
+
4
,
this
->
iceControlled
);
...
...
@@ -568,63 +707,73 @@ void StunPacket::Serialize(uint8_t* buffer) {
}
// Add USE-CANDIDATE.
if
(
this
->
hasUseCandidate
)
{
if
(
this
->
hasUseCandidate
)
{
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
,
static_cast
<
uint16_t
>
(
Attribute
::
USE_CANDIDATE
));
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
+
2
,
0
);
pos
+=
4
;
}
// Add XOR-MAPPED-ADDRESS
if
(
addXorMappedAddress
)
{
if
(
addXorMappedAddress
)
{
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
,
static_cast
<
uint16_t
>
(
Attribute
::
XOR_MAPPED_ADDRESS
));
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
+
2
,
xorMappedAddressPaddedLen
);
uint8_t
*
attrValue
=
buffer
+
pos
+
4
;
switch
(
this
->
xorMappedAddress
->
sa_family
)
{
case
AF_INET
:
{
switch
(
this
->
xorMappedAddress
->
sa_family
)
{
case
AF_INET
:
{
// Set first byte to 0.
attrValue
[
0
]
=
0
;
// Set inet family.
attrValue
[
1
]
=
0x01
;
// Set port and XOR it.
std
::
memcpy
(
attrValue
+
2
,
&
(
reinterpret_cast
<
const
sockaddr_in
*>
(
this
->
xorMappedAddress
))
->
sin_port
,
2
);
attrValue
[
2
]
^=
StunPacket
::
kMagicCookie
[
0
];
attrValue
[
3
]
^=
StunPacket
::
kMagicCookie
[
1
];
std
::
memcpy
(
attrValue
+
2
,
&
(
reinterpret_cast
<
const
sockaddr_in
*>
(
this
->
xorMappedAddress
))
->
sin_port
,
2
);
attrValue
[
2
]
^=
StunPacket
::
magicCookie
[
0
];
attrValue
[
3
]
^=
StunPacket
::
magicCookie
[
1
];
// Set address and XOR it.
std
::
memcpy
(
attrValue
+
4
,
&
(
reinterpret_cast
<
const
sockaddr_in
*>
(
this
->
xorMappedAddress
))
->
sin_addr
.
s_addr
,
4
);
attrValue
[
4
]
^=
StunPacket
::
kMagicCookie
[
0
];
attrValue
[
5
]
^=
StunPacket
::
kMagicCookie
[
1
];
attrValue
[
6
]
^=
StunPacket
::
kMagicCookie
[
2
];
attrValue
[
7
]
^=
StunPacket
::
kMagicCookie
[
3
];
&
(
reinterpret_cast
<
const
sockaddr_in
*>
(
this
->
xorMappedAddress
))
->
sin_addr
.
s_addr
,
4
);
attrValue
[
4
]
^=
StunPacket
::
magicCookie
[
0
];
attrValue
[
5
]
^=
StunPacket
::
magicCookie
[
1
];
attrValue
[
6
]
^=
StunPacket
::
magicCookie
[
2
];
attrValue
[
7
]
^=
StunPacket
::
magicCookie
[
3
];
pos
+=
4
+
8
;
break
;
}
case
AF_INET6
:
{
case
AF_INET6
:
{
// Set first byte to 0.
attrValue
[
0
]
=
0
;
// Set inet family.
attrValue
[
1
]
=
0x02
;
// Set port and XOR it.
std
::
memcpy
(
attrValue
+
2
,
&
(
reinterpret_cast
<
const
sockaddr_in6
*>
(
this
->
xorMappedAddress
))
->
sin6_port
,
2
);
attrValue
[
2
]
^=
StunPacket
::
kMagicCookie
[
0
];
attrValue
[
3
]
^=
StunPacket
::
kMagicCookie
[
1
];
std
::
memcpy
(
attrValue
+
2
,
&
(
reinterpret_cast
<
const
sockaddr_in6
*>
(
this
->
xorMappedAddress
))
->
sin6_port
,
2
);
attrValue
[
2
]
^=
StunPacket
::
magicCookie
[
0
];
attrValue
[
3
]
^=
StunPacket
::
magicCookie
[
1
];
// Set address and XOR it.
std
::
memcpy
(
attrValue
+
4
,
&
(
reinterpret_cast
<
const
sockaddr_in6
*>
(
this
->
xorMappedAddress
))
->
sin6_addr
.
s6_addr
,
16
);
attrValue
[
4
]
^=
StunPacket
::
kM
agicCookie
[
0
];
attrValue
[
5
]
^=
StunPacket
::
kM
agicCookie
[
1
];
attrValue
[
6
]
^=
StunPacket
::
kM
agicCookie
[
2
];
attrValue
[
7
]
^=
StunPacket
::
kM
agicCookie
[
3
];
attrValue
[
4
]
^=
StunPacket
::
m
agicCookie
[
0
];
attrValue
[
5
]
^=
StunPacket
::
m
agicCookie
[
1
];
attrValue
[
6
]
^=
StunPacket
::
m
agicCookie
[
2
];
attrValue
[
7
]
^=
StunPacket
::
m
agicCookie
[
3
];
attrValue
[
8
]
^=
this
->
transactionId
[
0
];
attrValue
[
9
]
^=
this
->
transactionId
[
1
];
attrValue
[
10
]
^=
this
->
transactionId
[
2
];
...
...
@@ -646,7 +795,8 @@ void StunPacket::Serialize(uint8_t* buffer) {
}
// Add ERROR-CODE.
if
(
addErrorCode
)
{
if
(
addErrorCode
)
{
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
,
static_cast
<
uint16_t
>
(
Attribute
::
ERROR_CODE
));
Utils
::
Byte
::
Set2Bytes
(
buffer
,
pos
+
2
,
4
);
...
...
@@ -660,7 +810,8 @@ void StunPacket::Serialize(uint8_t* buffer) {
}
// Add MESSAGE-INTEGRITY.
if
(
addMessageIntegrity
)
{
if
(
addMessageIntegrity
)
{
// Ignore FINGERPRINT.
if
(
addFingerprint
)
Utils
::
Byte
::
Set2Bytes
(
buffer
,
2
,
static_cast
<
uint16_t
>
(
this
->
size
-
20
-
8
));
...
...
@@ -677,14 +828,18 @@ void StunPacket::Serialize(uint8_t* buffer) {
pos
+=
4
+
20
;
// Restore length field.
if
(
addFingerprint
)
Utils
::
Byte
::
Set2Bytes
(
buffer
,
2
,
static_cast
<
uint16_t
>
(
this
->
size
-
20
));
}
else
{
if
(
addFingerprint
)
Utils
::
Byte
::
Set2Bytes
(
buffer
,
2
,
static_cast
<
uint16_t
>
(
this
->
size
-
20
));
}
else
{
// Unset the pointer (if it was set).
this
->
messageIntegrity
=
nullptr
;
}
// Add FINGERPRINT.
if
(
addFingerprint
)
{
if
(
addFingerprint
)
{
// Compute the CRC32 of the packet up to (but excluding) the FINGERPRINT
// attribute and XOR it with 0x5354554e.
uint32_t
computedFingerprint
=
GetCRC32
(
buffer
,
pos
)
^
0x5354554e
;
...
...
@@ -696,10 +851,12 @@ void StunPacket::Serialize(uint8_t* buffer) {
// Set flag.
this
->
hasFingerprint
=
true
;
}
else
{
}
else
{
this
->
hasFingerprint
=
false
;
}
//
MS_ASSERT(pos == this->size, "pos != this->size");
}
MS_ASSERT
(
pos
==
this
->
size
,
"pos != this->size"
);
}
}
// namespace RTC
webrtc/StunPacket.hpp
0 → 100644
查看文件 @
bdf2783a
#ifndef MS_RTC_STUN_PACKET_HPP
#define MS_RTC_STUN_PACKET_HPP
#include "logger.h"
#include "Utils.hpp"
#include <string>
namespace
RTC
{
class
StunPacket
{
public
:
// STUN message class.
enum
class
Class
:
uint16_t
{
REQUEST
=
0
,
INDICATION
=
1
,
SUCCESS_RESPONSE
=
2
,
ERROR_RESPONSE
=
3
};
// STUN message method.
enum
class
Method
:
uint16_t
{
BINDING
=
1
};
// Attribute type.
enum
class
Attribute
:
uint16_t
{
MAPPED_ADDRESS
=
0x0001
,
USERNAME
=
0x0006
,
MESSAGE_INTEGRITY
=
0x0008
,
ERROR_CODE
=
0x0009
,
UNKNOWN_ATTRIBUTES
=
0x000A
,
REALM
=
0x0014
,
NONCE
=
0x0015
,
XOR_MAPPED_ADDRESS
=
0x0020
,
PRIORITY
=
0x0024
,
USE_CANDIDATE
=
0x0025
,
SOFTWARE
=
0x8022
,
ALTERNATE_SERVER
=
0x8023
,
FINGERPRINT
=
0x8028
,
ICE_CONTROLLED
=
0x8029
,
ICE_CONTROLLING
=
0x802A
};
// Authentication result.
enum
class
Authentication
{
OK
=
0
,
UNAUTHORIZED
=
1
,
BAD_REQUEST
=
2
};
public
:
static
bool
IsStun
(
const
uint8_t
*
data
,
size_t
len
)
{
// clang-format off
return
(
// STUN headers are 20 bytes.
(
len
>=
20
)
&&
// DOC: https://tools.ietf.org/html/draft-ietf-avtcore-rfc5764-mux-fixes
(
data
[
0
]
<
3
)
&&
// Magic cookie must match.
(
data
[
4
]
==
StunPacket
::
magicCookie
[
0
])
&&
(
data
[
5
]
==
StunPacket
::
magicCookie
[
1
])
&&
(
data
[
6
]
==
StunPacket
::
magicCookie
[
2
])
&&
(
data
[
7
]
==
StunPacket
::
magicCookie
[
3
])
);
// clang-format on
}
static
StunPacket
*
Parse
(
const
uint8_t
*
data
,
size_t
len
);
private
:
static
const
uint8_t
magicCookie
[];
public
:
StunPacket
(
Class
klass
,
Method
method
,
const
uint8_t
*
transactionId
,
const
uint8_t
*
data
,
size_t
size
);
~
StunPacket
();
void
Dump
()
const
;
Class
GetClass
()
const
{
return
this
->
klass
;
}
Method
GetMethod
()
const
{
return
this
->
method
;
}
const
uint8_t
*
GetData
()
const
{
return
this
->
data
;
}
size_t
GetSize
()
const
{
return
this
->
size
;
}
void
SetUsername
(
const
char
*
username
,
size_t
len
)
{
this
->
username
.
assign
(
username
,
len
);
}
void
SetPriority
(
uint32_t
priority
)
{
this
->
priority
=
priority
;
}
void
SetIceControlling
(
uint64_t
iceControlling
)
{
this
->
iceControlling
=
iceControlling
;
}
void
SetIceControlled
(
uint64_t
iceControlled
)
{
this
->
iceControlled
=
iceControlled
;
}
void
SetUseCandidate
()
{
this
->
hasUseCandidate
=
true
;
}
void
SetXorMappedAddress
(
const
struct
sockaddr
*
xorMappedAddress
)
{
this
->
xorMappedAddress
=
xorMappedAddress
;
}
void
SetErrorCode
(
uint16_t
errorCode
)
{
this
->
errorCode
=
errorCode
;
}
void
SetMessageIntegrity
(
const
uint8_t
*
messageIntegrity
)
{
this
->
messageIntegrity
=
messageIntegrity
;
}
void
SetFingerprint
()
{
this
->
hasFingerprint
=
true
;
}
const
std
::
string
&
GetUsername
()
const
{
return
this
->
username
;
}
uint32_t
GetPriority
()
const
{
return
this
->
priority
;
}
uint64_t
GetIceControlling
()
const
{
return
this
->
iceControlling
;
}
uint64_t
GetIceControlled
()
const
{
return
this
->
iceControlled
;
}
bool
HasUseCandidate
()
const
{
return
this
->
hasUseCandidate
;
}
uint16_t
GetErrorCode
()
const
{
return
this
->
errorCode
;
}
bool
HasMessageIntegrity
()
const
{
return
(
this
->
messageIntegrity
?
true
:
false
);
}
bool
HasFingerprint
()
const
{
return
this
->
hasFingerprint
;
}
Authentication
CheckAuthentication
(
const
std
::
string
&
localUsername
,
const
std
::
string
&
localPassword
);
StunPacket
*
CreateSuccessResponse
();
StunPacket
*
CreateErrorResponse
(
uint16_t
errorCode
);
void
Authenticate
(
const
std
::
string
&
password
);
void
Serialize
(
uint8_t
*
buffer
);
private
:
// Passed by argument.
Class
klass
;
// 2 bytes.
Method
method
;
// 2 bytes.
const
uint8_t
*
transactionId
{
nullptr
};
// 12 bytes.
uint8_t
*
data
{
nullptr
};
// Pointer to binary data.
size_t
size
{
0u
};
// The full message size (including header).
// STUN attributes.
std
::
string
username
;
// Less than 513 bytes.
uint32_t
priority
{
0u
};
// 4 bytes unsigned integer.
uint64_t
iceControlling
{
0u
};
// 8 bytes unsigned integer.
uint64_t
iceControlled
{
0u
};
// 8 bytes unsigned integer.
bool
hasUseCandidate
{
false
};
// 0 bytes.
const
uint8_t
*
messageIntegrity
{
nullptr
};
// 20 bytes.
bool
hasFingerprint
{
false
};
// 4 bytes.
const
struct
sockaddr
*
xorMappedAddress
{
nullptr
};
// 8 or 20 bytes.
uint16_t
errorCode
{
0u
};
// 4 bytes (no reason phrase).
std
::
string
password
;
};
}
// namespace RTC
#endif
webrtc/
utils.h
→
webrtc/
Utils.hpp
查看文件 @
bdf2783a
File moved
webrtc/
webrtc_transport.cc
→
webrtc/
WebRtcTransport.cpp
查看文件 @
bdf2783a
#include "
webrtc_t
ransport.h"
#include "
WebRtcT
ransport.h"
#include <iostream>
#include "Rtcp/Rtcp.h"
...
...
webrtc/
webrtc_t
ransport.h
→
webrtc/
WebRtcT
ransport.h
查看文件 @
bdf2783a
...
...
@@ -3,10 +3,10 @@
#include <memory>
#include <string>
#include "
rtc_dtls_transport.h
"
#include "
ice_server.h
"
#include "
srtp_session.h
"
#include "
stun_packet.h
"
#include "
DtlsTransport.hpp
"
#include "
IceServer.hpp
"
#include "
SrtpSession.hpp
"
#include "
StunPacket.hpp
"
class
WebRtcTransport
:
public
RTC
::
DtlsTransport
::
Listener
,
public
RTC
::
IceServer
::
Listener
{
public
:
...
...
webrtc/logger.h
查看文件 @
bdf2783a
...
...
@@ -2,9 +2,6 @@
#include <stdio.h>
#include <assert.h>
#define ELOG_DEBUG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
#define ELOG_WARN(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
#define MS_TRACE()
#define MS_ERROR(fmt, ...) printf("error:" fmt "\n", ##__VA_ARGS__)
#define MS_THROW_ERROR(fmt, ...) do{ printf("throw:" fmt "\n", ##__VA_ARGS__); throw std::runtime_error("error"); } while(false);
...
...
webrtc/stun_packet.h
deleted
100644 → 0
查看文件 @
704421b7
#ifndef MS_RTC_STUN_PACKET_HPP
#define MS_RTC_STUN_PACKET_HPP
#include "logger.h"
#include "utils.h"
#include <string>
namespace
RTC
{
class
StunPacket
{
public
:
// STUN message class.
enum
class
Class
:
uint16_t
{
REQUEST
=
0
,
INDICATION
=
1
,
SUCCESS_RESPONSE
=
2
,
ERROR_RESPONSE
=
3
};
// STUN message method.
enum
class
Method
:
uint16_t
{
BINDING
=
1
};
// Attribute type.
enum
class
Attribute
:
uint16_t
{
MAPPED_ADDRESS
=
0x0001
,
USERNAME
=
0x0006
,
MESSAGE_INTEGRITY
=
0x0008
,
ERROR_CODE
=
0x0009
,
UNKNOWN_ATTRIBUTES
=
0x000A
,
REALM
=
0x0014
,
NONCE
=
0x0015
,
XOR_MAPPED_ADDRESS
=
0x0020
,
PRIORITY
=
0x0024
,
USE_CANDIDATE
=
0x0025
,
SOFTWARE
=
0x8022
,
ALTERNATE_SERVER
=
0x8023
,
FINGERPRINT
=
0x8028
,
ICE_CONTROLLED
=
0x8029
,
ICE_CONTROLLING
=
0x802A
};
// Authentication result.
enum
class
Authentication
{
OK
=
0
,
UNAUTHORIZED
=
1
,
BAD_REQUEST
=
2
};
public
:
static
bool
IsStun
(
const
uint8_t
*
data
,
size_t
len
);
static
StunPacket
*
Parse
(
const
uint8_t
*
data
,
size_t
len
);
private
:
static
const
uint8_t
kMagicCookie
[];
public
:
StunPacket
(
Class
klass
,
Method
method
,
const
uint8_t
*
transactionId
,
const
uint8_t
*
data
,
size_t
size
);
~
StunPacket
();
void
Dump
()
const
;
Class
GetClass
()
const
;
Method
GetMethod
()
const
;
const
uint8_t
*
GetData
()
const
;
size_t
GetSize
()
const
;
void
SetUsername
(
const
char
*
username
,
size_t
len
);
void
SetPriority
(
uint32_t
priority
);
void
SetIceControlling
(
uint64_t
iceControlling
);
void
SetIceControlled
(
uint64_t
iceControlled
);
void
SetUseCandidate
();
void
SetXorMappedAddress
(
const
struct
sockaddr
*
xorMappedAddress
);
void
SetErrorCode
(
uint16_t
errorCode
);
void
SetMessageIntegrity
(
const
uint8_t
*
messageIntegrity
);
void
SetFingerprint
();
const
std
::
string
&
GetUsername
()
const
;
uint32_t
GetPriority
()
const
;
uint64_t
GetIceControlling
()
const
;
uint64_t
GetIceControlled
()
const
;
bool
HasUseCandidate
()
const
;
uint16_t
GetErrorCode
()
const
;
bool
HasMessageIntegrity
()
const
;
bool
HasFingerprint
()
const
;
Authentication
CheckAuthentication
(
const
std
::
string
&
localUsername
,
const
std
::
string
&
localPassword
);
StunPacket
*
CreateSuccessResponse
();
StunPacket
*
CreateErrorResponse
(
uint16_t
errorCode
);
void
Authenticate
(
const
std
::
string
&
password
);
void
Serialize
(
uint8_t
*
buffer
);
private
:
// Passed by argument.
Class
klass
;
// 2 bytes.
Method
method
;
// 2 bytes.
const
uint8_t
*
transactionId
{
nullptr
};
// 12 bytes.
uint8_t
*
data
{
nullptr
};
// Pointer to binary data.
size_t
size
{
0
};
// The full message size (including header).
// STUN attributes.
std
::
string
username
;
// Less than 513 bytes.
uint32_t
priority
{
0
};
// 4 bytes unsigned integer.
uint64_t
iceControlling
{
0
};
// 8 bytes unsigned integer.
uint64_t
iceControlled
{
0
};
// 8 bytes unsigned integer.
bool
hasUseCandidate
{
false
};
// 0 bytes.
const
uint8_t
*
messageIntegrity
{
nullptr
};
// 20 bytes.
bool
hasFingerprint
{
false
};
// 4 bytes.
const
struct
sockaddr
*
xorMappedAddress
{
nullptr
};
// 8 or 20 bytes.
uint16_t
errorCode
{
0
};
// 4 bytes (no reason phrase).
std
::
string
password
;
};
/* Inline class methods. */
inline
bool
StunPacket
::
IsStun
(
const
uint8_t
*
data
,
size_t
len
)
{
// clang-format off
return
(
// STUN headers are 20 bytes.
(
len
>=
20
)
&&
// DOC: https://tools.ietf.org/html/draft-ietf-avtcore-rfc5764-mux-fixes
(
data
[
0
]
<
3
)
&&
// Magic cookie must match.
(
data
[
4
]
==
StunPacket
::
kMagicCookie
[
0
])
&&
(
data
[
5
]
==
StunPacket
::
kMagicCookie
[
1
])
&&
(
data
[
6
]
==
StunPacket
::
kMagicCookie
[
2
])
&&
(
data
[
7
]
==
StunPacket
::
kMagicCookie
[
3
])
);
// clang-format on
}
/* Inline instance methods. */
inline
StunPacket
::
Class
StunPacket
::
GetClass
()
const
{
return
this
->
klass
;
}
inline
StunPacket
::
Method
StunPacket
::
GetMethod
()
const
{
return
this
->
method
;
}
inline
const
uint8_t
*
StunPacket
::
GetData
()
const
{
return
this
->
data
;
}
inline
size_t
StunPacket
::
GetSize
()
const
{
return
this
->
size
;
}
inline
void
StunPacket
::
SetUsername
(
const
char
*
username
,
size_t
len
)
{
this
->
username
.
assign
(
username
,
len
);
}
inline
void
StunPacket
::
SetPriority
(
const
uint32_t
priority
)
{
this
->
priority
=
priority
;
}
inline
void
StunPacket
::
SetIceControlling
(
const
uint64_t
iceControlling
)
{
this
->
iceControlling
=
iceControlling
;
}
inline
void
StunPacket
::
SetIceControlled
(
const
uint64_t
iceControlled
)
{
this
->
iceControlled
=
iceControlled
;
}
inline
void
StunPacket
::
SetUseCandidate
()
{
this
->
hasUseCandidate
=
true
;
}
inline
void
StunPacket
::
SetXorMappedAddress
(
const
struct
sockaddr
*
xorMappedAddress
)
{
this
->
xorMappedAddress
=
xorMappedAddress
;
}
inline
void
StunPacket
::
SetErrorCode
(
uint16_t
errorCode
)
{
this
->
errorCode
=
errorCode
;
}
inline
void
StunPacket
::
SetMessageIntegrity
(
const
uint8_t
*
messageIntegrity
)
{
this
->
messageIntegrity
=
messageIntegrity
;
}
inline
void
StunPacket
::
SetFingerprint
()
{
this
->
hasFingerprint
=
true
;
}
inline
const
std
::
string
&
StunPacket
::
GetUsername
()
const
{
return
this
->
username
;
}
inline
uint32_t
StunPacket
::
GetPriority
()
const
{
return
this
->
priority
;
}
inline
uint64_t
StunPacket
::
GetIceControlling
()
const
{
return
this
->
iceControlling
;
}
inline
uint64_t
StunPacket
::
GetIceControlled
()
const
{
return
this
->
iceControlled
;
}
inline
bool
StunPacket
::
HasUseCandidate
()
const
{
return
this
->
hasUseCandidate
;
}
inline
uint16_t
StunPacket
::
GetErrorCode
()
const
{
return
this
->
errorCode
;
}
inline
bool
StunPacket
::
HasMessageIntegrity
()
const
{
return
(
this
->
messageIntegrity
?
true
:
false
);
}
inline
bool
StunPacket
::
HasFingerprint
()
const
{
return
this
->
hasFingerprint
;
}
}
// namespace RTC
#endif
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论