%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/data.cc |
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
#include "data.h"
#include <env-inl.h>
#include <memory_tracker-inl.h>
#include <ngtcp2/ngtcp2.h>
#include <node_sockaddr-inl.h>
#include <string_bytes.h>
#include <v8.h>
#include "defs.h"
#include "util.h"
namespace node {
using v8::Array;
using v8::BigInt;
using v8::Integer;
using v8::Local;
using v8::MaybeLocal;
using v8::Uint8Array;
using v8::Undefined;
using v8::Value;
namespace quic {
Path::Path(const SocketAddress& local, const SocketAddress& remote) {
ngtcp2_addr_init(&this->local, local.data(), local.length());
ngtcp2_addr_init(&this->remote, remote.data(), remote.length());
}
std::string Path::ToString() const {
DebugIndentScope indent;
auto prefix = indent.Prefix();
const sockaddr* local_in = reinterpret_cast<const sockaddr*>(local.addr);
auto local_addr = SocketAddress::GetAddress(local_in);
auto local_port = SocketAddress::GetPort(local_in);
const sockaddr* remote_in = reinterpret_cast<const sockaddr*>(remote.addr);
auto remote_addr = SocketAddress::GetAddress(remote_in);
auto remote_port = SocketAddress::GetPort(remote_in);
std::string res("{");
res += prefix + "local: " + local_addr + ":" + std::to_string(local_port);
res += prefix + "remote: " + remote_addr + ":" + std::to_string(remote_port);
res += indent.Close();
return res;
}
PathStorage::PathStorage() {
ngtcp2_path_storage_zero(this);
}
PathStorage::operator ngtcp2_path() {
return path;
}
// ============================================================================
Store::Store(std::shared_ptr<v8::BackingStore> store,
size_t length,
size_t offset)
: store_(std::move(store)), length_(length), offset_(offset) {
CHECK_LE(offset_, store_->ByteLength());
CHECK_LE(length_, store_->ByteLength() - offset_);
}
Store::Store(std::unique_ptr<v8::BackingStore> store,
size_t length,
size_t offset)
: store_(std::move(store)), length_(length), offset_(offset) {
CHECK_LE(offset_, store_->ByteLength());
CHECK_LE(length_, store_->ByteLength() - offset_);
}
Store::Store(v8::Local<v8::ArrayBuffer> buffer, Option option)
: Store(buffer->GetBackingStore(), buffer->ByteLength()) {
if (option == Option::DETACH) {
USE(buffer->Detach(Local<Value>()));
}
}
Store::Store(v8::Local<v8::ArrayBufferView> view, Option option)
: Store(view->Buffer()->GetBackingStore(),
view->ByteLength(),
view->ByteOffset()) {
if (option == Option::DETACH) {
USE(view->Buffer()->Detach(Local<Value>()));
}
}
v8::Local<v8::Uint8Array> Store::ToUint8Array(Environment* env) const {
return !store_
? Uint8Array::New(v8::ArrayBuffer::New(env->isolate(), 0), 0, 0)
: Uint8Array::New(v8::ArrayBuffer::New(env->isolate(), store_),
offset_,
length_);
}
Store::operator bool() const {
return store_ != nullptr;
}
size_t Store::length() const {
return length_;
}
template <typename T, typename t>
T Store::convert() const {
T buf;
buf.base =
store_ != nullptr ? static_cast<t*>(store_->Data()) + offset_ : nullptr;
buf.len = length_;
return buf;
}
Store::operator uv_buf_t() const {
return convert<uv_buf_t, char>();
}
Store::operator ngtcp2_vec() const {
return convert<ngtcp2_vec, uint8_t>();
}
Store::operator nghttp3_vec() const {
return convert<nghttp3_vec, uint8_t>();
}
void Store::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackField("store", store_);
}
// ============================================================================
namespace {
std::string TypeName(QuicError::Type type) {
switch (type) {
case QuicError::Type::APPLICATION:
return "APPLICATION";
case QuicError::Type::TRANSPORT:
return "TRANSPORT";
case QuicError::Type::VERSION_NEGOTIATION:
return "VERSION_NEGOTIATION";
case QuicError::Type::IDLE_CLOSE:
return "IDLE_CLOSE";
}
UNREACHABLE();
}
} // namespace
QuicError::QuicError(const std::string_view reason)
: reason_(reason), error_(), ptr_(&error_) {
ngtcp2_ccerr_default(&error_);
}
QuicError::QuicError(const ngtcp2_ccerr* ptr)
: reason_(reinterpret_cast<const char*>(ptr->reason), ptr->reasonlen),
ptr_(ptr) {}
QuicError::QuicError(const ngtcp2_ccerr& error)
: reason_(reinterpret_cast<const char*>(error.reason), error.reasonlen),
error_(error),
ptr_(&error_) {}
QuicError::operator bool() const {
if ((code() == QUIC_NO_ERROR && type() == Type::TRANSPORT) ||
((code() == QUIC_APP_NO_ERROR && type() == Type::APPLICATION))) {
return false;
}
return true;
}
const uint8_t* QuicError::reason_c_str() const {
return reinterpret_cast<const uint8_t*>(reason_.c_str());
}
bool QuicError::operator!=(const QuicError& other) const {
return !(*this == other);
}
bool QuicError::operator==(const QuicError& other) const {
if (this == &other) return true;
return type() == other.type() && code() == other.code() &&
frame_type() == other.frame_type();
}
QuicError::Type QuicError::type() const {
return static_cast<Type>(ptr_->type);
}
QuicError::error_code QuicError::code() const {
return ptr_->error_code;
}
uint64_t QuicError::frame_type() const {
return ptr_->frame_type;
}
const std::string_view QuicError::reason() const {
return reason_;
}
QuicError::operator const ngtcp2_ccerr&() const {
return *ptr_;
}
QuicError::operator const ngtcp2_ccerr*() const {
return ptr_;
}
MaybeLocal<Value> QuicError::ToV8Value(Environment* env) const {
Local<Value> argv[] = {
Integer::New(env->isolate(), static_cast<int>(type())),
BigInt::NewFromUnsigned(env->isolate(), code()),
Undefined(env->isolate()),
};
if (reason_.length() > 0 &&
!node::ToV8Value(env->context(), reason()).ToLocal(&argv[2])) {
return MaybeLocal<Value>();
}
return Array::New(env->isolate(), argv, arraysize(argv)).As<Value>();
}
std::string QuicError::ToString() const {
std::string str = "QuicError(";
str += TypeName(type()) + ") ";
str += std::to_string(code());
if (!reason_.empty()) str += ": " + reason_;
return str;
}
void QuicError::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackField("reason", reason_.length());
}
QuicError QuicError::ForTransport(error_code code,
const std::string_view reason) {
QuicError error(reason);
ngtcp2_ccerr_set_transport_error(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}
QuicError QuicError::ForApplication(error_code code,
const std::string_view reason) {
QuicError error(reason);
ngtcp2_ccerr_set_application_error(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}
QuicError QuicError::ForVersionNegotiation(const std::string_view reason) {
return ForNgtcp2Error(NGTCP2_ERR_RECV_VERSION_NEGOTIATION, reason);
}
QuicError QuicError::ForIdleClose(const std::string_view reason) {
return ForNgtcp2Error(NGTCP2_ERR_IDLE_CLOSE, reason);
}
QuicError QuicError::ForNgtcp2Error(int code, const std::string_view reason) {
QuicError error(reason);
ngtcp2_ccerr_set_liberr(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}
QuicError QuicError::ForTlsAlert(int code, const std::string_view reason) {
QuicError error(reason);
ngtcp2_ccerr_set_tls_alert(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}
QuicError QuicError::FromConnectionClose(ngtcp2_conn* session) {
return QuicError(ngtcp2_conn_get_ccerr(session));
}
QuicError QuicError::TRANSPORT_NO_ERROR =
QuicError::ForTransport(QuicError::QUIC_NO_ERROR);
QuicError QuicError::APPLICATION_NO_ERROR =
QuicError::ForApplication(QuicError::QUIC_APP_NO_ERROR);
QuicError QuicError::VERSION_NEGOTIATION = QuicError::ForVersionNegotiation();
QuicError QuicError::IDLE_CLOSE = QuicError::ForIdleClose();
QuicError QuicError::INTERNAL_ERROR =
QuicError::ForNgtcp2Error(NGTCP2_ERR_INTERNAL);
} // namespace quic
} // namespace node
#endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC