[LibWebRTC] ifdef cleanups
[webkit.git] / Source / WebCore / Modules / mediastream / STUNMessageParsing.cpp
blobe4d139e6198d60cfd233ac8f0494324de46bc3af
1 /*
2 * Copyright (C) 2020 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #include "config.h"
27 #include "STUNMessageParsing.h"
29 #if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
31 #include <LibWebRTCMacros.h>
32 #include <webrtc/rtc_base/byte_order.h>
34 namespace WebCore {
35 namespace WebRTC {
37 static inline bool isStunMessage(uint16_t messageType)
39 // https://tools.ietf.org/html/rfc5389#section-6 for STUN messages.
40 // TURN messages start by the channel number which is constrained by https://tools.ietf.org/html/rfc5766#section-11.
41 return !(messageType & 0xC000);
44 std::optional<STUNMessageLengths> getSTUNOrTURNMessageLengths(const uint8_t* data, size_t size)
46 if (size < 4)
47 return { };
49 auto messageType = be16toh(*reinterpret_cast<const uint16_t*>(data));
50 auto messageLength = be16toh(*reinterpret_cast<const uint16_t*>(data + 2));
52 // STUN data message header is 20 bytes.
53 if (isStunMessage(messageType)) {
54 size_t length = 20 + messageLength;
55 return STUNMessageLengths { length, length };
58 // TURN data message header is 4 bytes plus padding bytes to get 4 bytes alignment as needed.
59 size_t length = 4 + messageLength;
60 size_t roundedLength = length % 4 ? (length + 4 - (length % 4)) : length;
61 return STUNMessageLengths { length, roundedLength };
64 static inline Vector<uint8_t> extractSTUNOrTURNMessages(Vector<uint8_t>&& buffered, const Function<void(const uint8_t* data, size_t size)>& processMessage)
66 auto* data = buffered.data();
67 size_t size = buffered.size();
69 while (true) {
70 auto lengths = getSTUNOrTURNMessageLengths(data, size);
72 if (!lengths || lengths->messageLengthWithPadding > size) {
73 if (!size)
74 return { };
76 std::memcpy(buffered.data(), data, size);
77 buffered.resize(size);
78 return WTFMove(buffered);
81 processMessage(data, lengths->messageLength);
83 data += lengths->messageLengthWithPadding;
84 size -= lengths->messageLengthWithPadding;
88 static inline Vector<uint8_t> extractDataMessages(Vector<uint8_t>&& buffered, const Function<void(const uint8_t* data, size_t size)>& processMessage)
90 constexpr size_t lengthFieldSize = 2; // number of bytes read by be16toh.
92 auto* data = buffered.data();
93 size_t size = buffered.size();
95 while (true) {
96 bool canReadLength = size >= lengthFieldSize;
97 size_t length = canReadLength ? be16toh(*reinterpret_cast<const uint16_t*>(data)) : 0;
98 if (!canReadLength || length > size - lengthFieldSize) {
99 if (!size)
100 return { };
102 std::memcpy(buffered.data(), data, size);
103 buffered.resize(size);
104 return WTFMove(buffered);
107 data += lengthFieldSize;
108 size -= lengthFieldSize;
110 processMessage(data, length);
112 data += length;
113 size -= length;
117 Vector<uint8_t> extractMessages(Vector<uint8_t>&& buffer, MessageType type, const Function<void(const uint8_t* data, size_t size)>& processMessage)
119 return type == MessageType::STUN ? extractSTUNOrTURNMessages(WTFMove(buffer), processMessage) : extractDataMessages(WTFMove(buffer), processMessage);
122 } // namespace WebRTC
123 } // namespace WebCore
125 #endif // ENABLE(WEB_RTC) && USE(LIBWEBRTC)