/* * Copyright 2020 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
// Now read all the attributes
std::deque<std::unique_ptr<StunAttribute>> attrs; while (buf.Length()) {
uint16_t key, length, value_type; if (!buf.ReadUInt16(&key)) { return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Failed to read attribute key");
} if (!buf.ReadUInt16(&length)) { return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Failed to read attribute length");
} if (!buf.ReadUInt16(&value_type)) { return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Failed to read value type");
}
StunAttributeValueType value_type_enum =
GetStunAttributeValueType(value_type);
std::unique_ptr<StunAttribute> attr(
StunAttribute::Create(value_type_enum, key, length, nullptr)); if (!attr) { return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Failed to create attribute");
} if (attr->length() != length) { return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Inconsistent attribute length");
} if (!attr->Read(&buf)) { return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Failed to read attribute content");
}
attrs.push_back(std::move(attr));
}
// The first attribute should be the version... if (attrs.empty()) { return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Empty delta!");
}
// Apply a delta return an StunUInt64Attribute to ack the update.
webrtc::RTCErrorOr<
std::pair<std::unique_ptr<StunUInt64Attribute>, std::vector<uint16_t>>>
StunDictionaryView::ApplyDelta(const StunByteStringAttribute& delta) { auto parsed_delta = ParseDelta(delta); if (!parsed_delta.ok()) { return webrtc::RTCError(parsed_delta.error());
}
// max version in Delta.
buf.WriteUInt16(StunDictionaryView::kVersionKey); // 4,5
buf.WriteUInt16(8); // 6,7
buf.WriteUInt16(STUN_VALUE_UINT64); // 8,9
buf.WriteUInt64(pending_.back().first); // 10-17 // attributes for (constauto& attr : pending_) {
buf.WriteUInt16(attr.second->type());
buf.WriteUInt16(static_cast<uint16_t>(attr.second->length()));
buf.WriteUInt16(attr.second->value_type()); if (!attr.second->Write(&buf)) {
RTC_LOG(LS_ERROR) << "Failed to write key: " << attr.second->type(); return nullptr;
}
} return std::make_unique<StunByteStringAttribute>(STUN_ATTR_GOOG_DELTA,
buf.Data(), buf.Length());
}
// Apply a delta ack, i.e prune list of pending changes. void StunDictionaryWriter::ApplyDeltaAck(const StunUInt64Attribute& ack) {
uint64_t acked_version = ack.value(); auto entries_to_remove = std::remove_if(
pending_.begin(), pending_.end(),
[acked_version](constauto& p) { return p.first <= acked_version; });
// remove tombstones. for (auto it = entries_to_remove; it != pending_.end(); ++it) {
tombstones_.erase((*it).second->type());
}
pending_.erase(entries_to_remove, pending_.end());
}
// Check if a key has a pending change (i.e a change // that has not been acked). bool StunDictionaryWriter::Pending(int key) const { for (constauto& attr : pending_) { if (attr.second->type() == key) { returntrue;
}
} returnfalse;
}
int StunDictionaryWriter::Pending() const { return pending_.size();
}
} // namespace cricket
Messung V0.5
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.