protocol-quic 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/ext/source/Protocol/QUIC/Address.cpp +122 -0
- data/ext/source/Protocol/QUIC/Address.hpp +30 -0
- data/ext/source/Protocol/QUIC/Client.cpp +157 -0
- data/ext/source/Protocol/QUIC/Client.hpp +27 -0
- data/ext/source/Protocol/QUIC/Configuration.cpp +74 -0
- data/ext/source/Protocol/QUIC/Configuration.hpp +27 -0
- data/ext/source/Protocol/QUIC/Connection.cpp +50 -0
- data/ext/source/Protocol/QUIC/Connection.hpp +29 -0
- data/ext/source/Protocol/QUIC/Dispatcher.cpp +190 -0
- data/ext/source/Protocol/QUIC/Dispatcher.hpp +27 -0
- data/ext/source/Protocol/QUIC/PacketHeader.cpp +59 -0
- data/ext/source/Protocol/QUIC/PacketHeader.hpp +29 -0
- data/ext/source/Protocol/QUIC/Reference.hpp +31 -0
- data/ext/source/Protocol/QUIC/Server.cpp +165 -0
- data/ext/source/Protocol/QUIC/Server.hpp +27 -0
- data/ext/source/Protocol/QUIC/Socket.cpp +103 -0
- data/ext/source/Protocol/QUIC/Socket.hpp +29 -0
- data/ext/source/Protocol/QUIC/Stream.cpp +96 -0
- data/ext/source/Protocol/QUIC/Stream.hpp +29 -0
- data/ext/source/Protocol/QUIC/TLS/ClientContext.cpp +61 -0
- data/ext/source/Protocol/QUIC/TLS/ClientContext.hpp +27 -0
- data/ext/source/Protocol/QUIC/TLS/Context.cpp +116 -0
- data/ext/source/Protocol/QUIC/TLS/Context.hpp +27 -0
- data/ext/source/Protocol/QUIC/TLS/ServerContext.cpp +61 -0
- data/ext/source/Protocol/QUIC/TLS/ServerContext.hpp +27 -0
- data/ext/source/Protocol/QUIC.cpp +36 -0
- data/ext/source/Protocol/QUIC.hpp +15 -0
- data/lib/protocol/quic/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +28 -1
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
|
|
2
|
+
#include "Dispatcher.hpp"
|
|
3
|
+
|
|
4
|
+
#include "Socket.hpp"
|
|
5
|
+
#include "Address.hpp"
|
|
6
|
+
#include "PacketHeader.hpp"
|
|
7
|
+
|
|
8
|
+
#include "Configuration.hpp"
|
|
9
|
+
#include "TLS/ServerContext.hpp"
|
|
10
|
+
|
|
11
|
+
#include "Server.hpp"
|
|
12
|
+
|
|
13
|
+
#include "Reference.hpp"
|
|
14
|
+
|
|
15
|
+
#include <unordered_map>
|
|
16
|
+
|
|
17
|
+
class RubyDispatcher final : public Protocol::QUIC::Dispatcher {
|
|
18
|
+
public:
|
|
19
|
+
VALUE self;
|
|
20
|
+
|
|
21
|
+
private:
|
|
22
|
+
VALUE _ruby_configuration;
|
|
23
|
+
VALUE _ruby_tls_context;
|
|
24
|
+
std::unordered_map<Protocol::QUIC::Server *, VALUE> _ruby_servers;
|
|
25
|
+
std::unordered_map<Protocol::QUIC::Socket *, VALUE> _ruby_sockets;
|
|
26
|
+
|
|
27
|
+
public:
|
|
28
|
+
RubyDispatcher(VALUE self, VALUE configuration, VALUE tls_context) : Protocol::QUIC::Dispatcher(*Protocol_QUIC_Configuration_get(configuration), *Protocol_QUIC_TLS_ServerContext_get(tls_context)), self(self), _ruby_configuration(configuration), _ruby_tls_context(tls_context)
|
|
29
|
+
{
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
~RubyDispatcher() {
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
VALUE ruby_configuration() noexcept {return _ruby_configuration;}
|
|
36
|
+
VALUE ruby_tls_context() noexcept {return _ruby_tls_context;}
|
|
37
|
+
|
|
38
|
+
Protocol::QUIC::Server * listen(VALUE ruby_socket)
|
|
39
|
+
{
|
|
40
|
+
auto socket = Protocol_QUIC_Socket_get(ruby_socket);
|
|
41
|
+
|
|
42
|
+
_ruby_sockets[socket] = ruby_socket;
|
|
43
|
+
|
|
44
|
+
return Protocol::QUIC::Dispatcher::listen(*socket);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Protocol::QUIC::Server * create_server(Protocol::QUIC::Socket &socket, const Protocol::QUIC::Address &address, const ngtcp2_pkt_hd &packet_header) override
|
|
48
|
+
{
|
|
49
|
+
auto iterator = _ruby_sockets.find(&socket);
|
|
50
|
+
|
|
51
|
+
if (iterator == _ruby_sockets.end()) {
|
|
52
|
+
rb_raise(rb_eRuntimeError, "Could not find Ruby socket wrapper for native socket.");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
VALUE ruby_socket = iterator->second;
|
|
56
|
+
VALUE ruby_address = Protocol_QUIC_Address_wrap(Protocol_QUIC_Address, address);
|
|
57
|
+
|
|
58
|
+
VALUE ruby_packet_header = Protocol_QUIC_PacketHeader_allocate(Protocol_QUIC_PacketHeader);
|
|
59
|
+
ValueReference ruby_packet_header_reference(ruby_packet_header, packet_header);
|
|
60
|
+
|
|
61
|
+
VALUE server = rb_funcall(self, rb_intern("create_server"), 3, ruby_socket, ruby_address, ruby_packet_header);
|
|
62
|
+
auto native_server = Protocol_QUIC_Server_get(server);
|
|
63
|
+
|
|
64
|
+
_ruby_servers[native_server] = server;
|
|
65
|
+
|
|
66
|
+
return native_server;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
void remove(Protocol::QUIC::Server * server) override
|
|
70
|
+
{
|
|
71
|
+
Protocol::QUIC::Dispatcher::remove(server);
|
|
72
|
+
_ruby_servers.erase(server);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void mark() {
|
|
76
|
+
rb_gc_mark_movable(self);
|
|
77
|
+
rb_gc_mark_movable(_ruby_configuration);
|
|
78
|
+
rb_gc_mark_movable(_ruby_tls_context);
|
|
79
|
+
|
|
80
|
+
for (auto & [server, ruby_server] : _ruby_servers) {
|
|
81
|
+
rb_gc_mark_movable(ruby_server);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (auto & [socket, ruby_socket] : _ruby_sockets) {
|
|
85
|
+
rb_gc_mark_movable(ruby_socket);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void compact() {
|
|
90
|
+
self = rb_gc_location(self);
|
|
91
|
+
_ruby_configuration = rb_gc_location(_ruby_configuration);
|
|
92
|
+
_ruby_tls_context = rb_gc_location(_ruby_tls_context);
|
|
93
|
+
|
|
94
|
+
for (auto & [server, ruby_server] : _ruby_servers) {
|
|
95
|
+
ruby_server = rb_gc_location(ruby_server);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (auto & [socket, ruby_socket] : _ruby_sockets) {
|
|
99
|
+
ruby_socket = rb_gc_location(ruby_socket);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
VALUE Protocol_QUIC_Dispatcher = Qnil;
|
|
105
|
+
|
|
106
|
+
static void Protocol_QUIC_Dispatcher_mark(void *data) {
|
|
107
|
+
if (data) {
|
|
108
|
+
reinterpret_cast<RubyDispatcher *>(data)->mark();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static void Protocol_QUIC_Dispatcher_compact(void *data) {
|
|
113
|
+
if (data) {
|
|
114
|
+
reinterpret_cast<RubyDispatcher *>(data)->compact();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static void Protocol_QUIC_Dispatcher_free(void *data) {
|
|
119
|
+
if (data) {
|
|
120
|
+
delete reinterpret_cast<Protocol::QUIC::Dispatcher *>(data);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
static size_t Protocol_QUIC_Dispatcher_size(const void *data) {
|
|
125
|
+
return sizeof(RubyDispatcher);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
static const rb_data_type_t Protocol_QUIC_Dispatcher_type = {
|
|
129
|
+
.wrap_struct_name = "Protocol::QUIC::Dispatcher",
|
|
130
|
+
.function = {
|
|
131
|
+
.dmark = Protocol_QUIC_Dispatcher_mark,
|
|
132
|
+
.dfree = Protocol_QUIC_Dispatcher_free,
|
|
133
|
+
.dsize = Protocol_QUIC_Dispatcher_size,
|
|
134
|
+
.dcompact = Protocol_QUIC_Dispatcher_compact,
|
|
135
|
+
},
|
|
136
|
+
.data = NULL,
|
|
137
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
Protocol::QUIC::Dispatcher * Protocol_QUIC_Dispatcher_get(VALUE self)
|
|
141
|
+
{
|
|
142
|
+
Protocol::QUIC::Dispatcher *dispatcher;
|
|
143
|
+
|
|
144
|
+
TypedData_Get_Struct(self, Protocol::QUIC::Dispatcher, &Protocol_QUIC_Dispatcher_type, dispatcher);
|
|
145
|
+
|
|
146
|
+
return dispatcher;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static VALUE Protocol_QUIC_Dispatcher_allocate(VALUE klass) {
|
|
150
|
+
return TypedData_Wrap_Struct(klass, &Protocol_QUIC_Dispatcher_type, NULL);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static VALUE Protocol_QUIC_Dispatcher_initialize(VALUE self, VALUE configuration, VALUE tls_context) {
|
|
154
|
+
auto dispatcher = new RubyDispatcher(self, configuration, tls_context);
|
|
155
|
+
DATA_PTR(self) = dispatcher;
|
|
156
|
+
return self;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static VALUE Protocol_QUIC_Dispatcher_configuration(VALUE self) {
|
|
160
|
+
auto dispatcher = dynamic_cast<RubyDispatcher*>(Protocol_QUIC_Dispatcher_get(self));
|
|
161
|
+
|
|
162
|
+
return dispatcher->ruby_configuration();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
static VALUE Protocol_QUIC_Dispatcher_tls_context(VALUE self) {
|
|
166
|
+
auto dispatcher = dynamic_cast<RubyDispatcher*>(Protocol_QUIC_Dispatcher_get(self));
|
|
167
|
+
|
|
168
|
+
return dispatcher->ruby_tls_context();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static VALUE Protocol_QUIC_Dispatcher_listen(VALUE self, VALUE socket) {
|
|
172
|
+
auto dispatcher = dynamic_cast<RubyDispatcher*>(Protocol_QUIC_Dispatcher_get(self));
|
|
173
|
+
|
|
174
|
+
dispatcher->listen(socket);
|
|
175
|
+
|
|
176
|
+
return Qnil;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
void Init_Protocol_QUIC_Dispatcher(VALUE Protocol_QUIC) {
|
|
180
|
+
Protocol_QUIC_Dispatcher =
|
|
181
|
+
rb_define_class_under(Protocol_QUIC, "Dispatcher", rb_cObject);
|
|
182
|
+
|
|
183
|
+
rb_define_alloc_func(Protocol_QUIC_Dispatcher, Protocol_QUIC_Dispatcher_allocate);
|
|
184
|
+
rb_define_method(Protocol_QUIC_Dispatcher, "initialize", Protocol_QUIC_Dispatcher_initialize, 2);
|
|
185
|
+
|
|
186
|
+
rb_define_method(Protocol_QUIC_Dispatcher, "configuration", Protocol_QUIC_Dispatcher_configuration, 0);
|
|
187
|
+
rb_define_method(Protocol_QUIC_Dispatcher, "tls_context", Protocol_QUIC_Dispatcher_tls_context, 0);
|
|
188
|
+
|
|
189
|
+
rb_define_method(Protocol_QUIC_Dispatcher, "listen", Protocol_QUIC_Dispatcher_listen, 1);
|
|
190
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Dispatcher.h
|
|
3
|
+
// This file is part of the "Protocol::QUIC" project and released under the MIT License.
|
|
4
|
+
//
|
|
5
|
+
// Created by Samuel Williams on 27/4/2023.
|
|
6
|
+
// Copyright, 2023, by Samuel Williams. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include <ruby.h>
|
|
12
|
+
|
|
13
|
+
#include <Protocol/QUIC/Dispatcher.hpp>
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
extern VALUE Protocol_QUIC_Dispatcher;
|
|
20
|
+
|
|
21
|
+
void Init_Protocol_QUIC_Dispatcher(VALUE Protocol_QUIC);
|
|
22
|
+
|
|
23
|
+
Protocol::QUIC::Dispatcher * Protocol_QUIC_Dispatcher_get(VALUE self);
|
|
24
|
+
|
|
25
|
+
#ifdef __cplusplus
|
|
26
|
+
}
|
|
27
|
+
#endif
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PacketHeader.cpp
|
|
3
|
+
// This file is part of the "Protocol::QUIC" project and released under the MIT License.
|
|
4
|
+
//
|
|
5
|
+
// Created by Samuel Williams on 27/4/2023.
|
|
6
|
+
// Copyright, 2023, by Samuel Williams. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#include "PacketHeader.hpp"
|
|
10
|
+
|
|
11
|
+
VALUE Protocol_QUIC_PacketHeader = Qnil;
|
|
12
|
+
|
|
13
|
+
static void Protocol_QUIC_PacketHeader_free(void *data) {
|
|
14
|
+
if (data) {
|
|
15
|
+
delete reinterpret_cast<ngtcp2_pkt_hd *>(data);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static size_t Protocol_QUIC_PacketHeader_size(const void *data) {
|
|
20
|
+
return sizeof(ngtcp2_pkt_hd);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const rb_data_type_t Protocol_QUIC_PacketHeader_type = {
|
|
24
|
+
.wrap_struct_name = "Protocol::QUIC::PacketHeader",
|
|
25
|
+
.function = {
|
|
26
|
+
.dmark = NULL,
|
|
27
|
+
.dfree = Protocol_QUIC_PacketHeader_free,
|
|
28
|
+
.dsize = Protocol_QUIC_PacketHeader_size,
|
|
29
|
+
},
|
|
30
|
+
.data = NULL,
|
|
31
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
ngtcp2_pkt_hd * Protocol_QUIC_PacketHeader_get(VALUE self)
|
|
35
|
+
{
|
|
36
|
+
ngtcp2_pkt_hd *address;
|
|
37
|
+
|
|
38
|
+
TypedData_Get_Struct(self, ngtcp2_pkt_hd, &Protocol_QUIC_PacketHeader_type, address);
|
|
39
|
+
|
|
40
|
+
return address;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
VALUE Protocol_QUIC_PacketHeader_allocate(VALUE klass) {
|
|
44
|
+
return TypedData_Wrap_Struct(klass, &Protocol_QUIC_PacketHeader_type, NULL);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static VALUE Protocol_QUIC_PacketHeader_initialize(VALUE self) {
|
|
48
|
+
DATA_PTR(self) = new ngtcp2_pkt_hd();
|
|
49
|
+
|
|
50
|
+
return self;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
void Init_Protocol_QUIC_PacketHeader(VALUE Protocol_QUIC) {
|
|
54
|
+
Protocol_QUIC_PacketHeader =
|
|
55
|
+
rb_define_class_under(Protocol_QUIC, "PacketHeader", rb_cObject);
|
|
56
|
+
|
|
57
|
+
rb_define_alloc_func(Protocol_QUIC_PacketHeader, Protocol_QUIC_PacketHeader_allocate);
|
|
58
|
+
rb_define_method(Protocol_QUIC_PacketHeader, "initialize", Protocol_QUIC_PacketHeader_initialize, 0);
|
|
59
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// PacketHeader.hpp
|
|
3
|
+
// This file is part of the "Protocol::QUIC" project and released under the MIT License.
|
|
4
|
+
//
|
|
5
|
+
// Created by Samuel Williams on 27/4/2023.
|
|
6
|
+
// Copyright, 2023, by Samuel Williams. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include <ruby.h>
|
|
12
|
+
|
|
13
|
+
#include <ngtcp2/ngtcp2.h>
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
extern VALUE Protocol_QUIC_PacketHeader;
|
|
20
|
+
|
|
21
|
+
void Init_Protocol_QUIC_PacketHeader(VALUE Protocol_QUIC);
|
|
22
|
+
|
|
23
|
+
ngtcp2_pkt_hd * Protocol_QUIC_PacketHeader_get(VALUE self);
|
|
24
|
+
|
|
25
|
+
VALUE Protocol_QUIC_PacketHeader_allocate(VALUE klass);
|
|
26
|
+
|
|
27
|
+
#ifdef __cplusplus
|
|
28
|
+
}
|
|
29
|
+
#endif
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Reference.hpp
|
|
3
|
+
// This file is part of the "Protocol::QUIC" project and released under the MIT License.
|
|
4
|
+
//
|
|
5
|
+
// Created by Samuel Williams on 27/4/2023.
|
|
6
|
+
// Copyright, 2023, by Samuel Williams. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include <ruby.h>
|
|
12
|
+
|
|
13
|
+
struct ValueReference {
|
|
14
|
+
VALUE _value;
|
|
15
|
+
|
|
16
|
+
template <typename ReferenceType>
|
|
17
|
+
ValueReference(VALUE value, ReferenceType & reference) : _value(value)
|
|
18
|
+
{
|
|
19
|
+
DATA_PTR(value) = reinterpret_cast<void*>(&reference);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
template <typename ReferenceType>
|
|
23
|
+
ValueReference(VALUE value, const ReferenceType & reference) : ValueReference(value, const_cast<ReferenceType&>(reference))
|
|
24
|
+
{
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
~ValueReference()
|
|
28
|
+
{
|
|
29
|
+
DATA_PTR(_value) = NULL;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
|
|
2
|
+
#include "Server.hpp"
|
|
3
|
+
|
|
4
|
+
#include "Dispatcher.hpp"
|
|
5
|
+
#include "Configuration.hpp"
|
|
6
|
+
#include "Connection.hpp"
|
|
7
|
+
#include "TLS/ServerContext.hpp"
|
|
8
|
+
#include "Socket.hpp"
|
|
9
|
+
#include "Address.hpp"
|
|
10
|
+
#include "PacketHeader.hpp"
|
|
11
|
+
|
|
12
|
+
#include "Stream.hpp"
|
|
13
|
+
|
|
14
|
+
#include <unordered_map>
|
|
15
|
+
|
|
16
|
+
VALUE Protocol_QUIC_Server = Qnil;
|
|
17
|
+
|
|
18
|
+
class RubyServer : public Protocol::QUIC::Server {
|
|
19
|
+
public:
|
|
20
|
+
VALUE self;
|
|
21
|
+
|
|
22
|
+
private:
|
|
23
|
+
VALUE _dispatcher;
|
|
24
|
+
VALUE _configuration;
|
|
25
|
+
VALUE _tls_context;
|
|
26
|
+
VALUE _socket;
|
|
27
|
+
VALUE _remote_address;
|
|
28
|
+
std::unordered_map<Protocol::QUIC::StreamID, VALUE> _ruby_streams;
|
|
29
|
+
|
|
30
|
+
public:
|
|
31
|
+
RubyServer(VALUE self, VALUE dispatcher, VALUE configuration, VALUE tls_context, VALUE socket, VALUE remote_address, VALUE packet_header, VALUE ocid) : Protocol::QUIC::Server(*Protocol_QUIC_Dispatcher_get(dispatcher), *Protocol_QUIC_Configuration_get(configuration), *Protocol_QUIC_TLS_ServerContext_get(tls_context), *Protocol_QUIC_Socket_get(socket), *Protocol_QUIC_Address_get(remote_address), *Protocol_QUIC_PacketHeader_get(packet_header), nullptr), self(self), _dispatcher(dispatcher), _configuration(configuration), _tls_context(tls_context), _socket(socket), _remote_address(remote_address) {}
|
|
32
|
+
virtual ~RubyServer() {}
|
|
33
|
+
|
|
34
|
+
Protocol::QUIC::Stream * create_stream(Protocol::QUIC::StreamID stream_id) override
|
|
35
|
+
{
|
|
36
|
+
VALUE stream = rb_funcall(self, rb_intern("create_stream"), 1, RB_LL2NUM(stream_id));
|
|
37
|
+
_ruby_streams[stream_id] = stream;
|
|
38
|
+
|
|
39
|
+
return Protocol_QUIC_Stream_get(stream);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void disconnect() override
|
|
43
|
+
{
|
|
44
|
+
Protocol::QUIC::Server::disconnect();
|
|
45
|
+
_ruby_streams.clear();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
void stream_close(Protocol::QUIC::Stream * stream, std::int32_t flags, std::uint64_t error_code) override
|
|
49
|
+
{
|
|
50
|
+
auto stream_id = stream->stream_id();
|
|
51
|
+
Protocol::QUIC::Server::stream_close(stream, flags, error_code);
|
|
52
|
+
_ruby_streams.erase(stream_id);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
void stream_reset(Protocol::QUIC::Stream * stream, std::size_t final_size, std::uint64_t error_code) override
|
|
56
|
+
{
|
|
57
|
+
auto stream_id = stream->stream_id();
|
|
58
|
+
Protocol::QUIC::Server::stream_reset(stream, final_size, error_code);
|
|
59
|
+
_ruby_streams.erase(stream_id);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
void mark() {
|
|
63
|
+
rb_gc_mark_movable(self);
|
|
64
|
+
rb_gc_mark_movable(_dispatcher);
|
|
65
|
+
rb_gc_mark_movable(_configuration);
|
|
66
|
+
rb_gc_mark_movable(_tls_context);
|
|
67
|
+
rb_gc_mark_movable(_socket);
|
|
68
|
+
rb_gc_mark_movable(_remote_address);
|
|
69
|
+
|
|
70
|
+
for (auto & [stream_id, ruby_stream] : _ruby_streams) {
|
|
71
|
+
rb_gc_mark_movable(ruby_stream);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void compact() {
|
|
76
|
+
self = rb_gc_location(self);
|
|
77
|
+
_dispatcher = rb_gc_location(_dispatcher);
|
|
78
|
+
_configuration = rb_gc_location(_configuration);
|
|
79
|
+
_tls_context = rb_gc_location(_tls_context);
|
|
80
|
+
_socket = rb_gc_location(_socket);
|
|
81
|
+
_remote_address = rb_gc_location(_remote_address);
|
|
82
|
+
|
|
83
|
+
for (auto & [stream_id, ruby_stream] : _ruby_streams) {
|
|
84
|
+
ruby_stream = rb_gc_location(ruby_stream);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
static void Protocol_QUIC_Server_mark(void *data)
|
|
90
|
+
{
|
|
91
|
+
if (data) {
|
|
92
|
+
reinterpret_cast<RubyServer *>(data)->mark();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static void Protocol_QUIC_Server_compact(void *data)
|
|
97
|
+
{
|
|
98
|
+
if (data) {
|
|
99
|
+
reinterpret_cast<RubyServer *>(data)->compact();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static void Protocol_QUIC_Server_free(void *data)
|
|
104
|
+
{
|
|
105
|
+
if (data) {
|
|
106
|
+
delete reinterpret_cast<Protocol::QUIC::Server *>(data);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static size_t Protocol_QUIC_Server_size(const void *data) {
|
|
111
|
+
return sizeof(RubyServer);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static const rb_data_type_t Protocol_QUIC_Server_type = {
|
|
115
|
+
.wrap_struct_name = "Protocol::QUIC::Server",
|
|
116
|
+
.function = {
|
|
117
|
+
.dmark = Protocol_QUIC_Server_mark,
|
|
118
|
+
.dfree = Protocol_QUIC_Server_free,
|
|
119
|
+
.dsize = Protocol_QUIC_Server_size,
|
|
120
|
+
.dcompact = Protocol_QUIC_Server_compact,
|
|
121
|
+
},
|
|
122
|
+
.parent = &Protocol_QUIC_Connection_type,
|
|
123
|
+
.data = NULL,
|
|
124
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
Protocol::QUIC::Server * Protocol_QUIC_Server_get(VALUE self)
|
|
128
|
+
{
|
|
129
|
+
Protocol::QUIC::Server *server;
|
|
130
|
+
|
|
131
|
+
TypedData_Get_Struct(self, Protocol::QUIC::Server, &Protocol_QUIC_Server_type, server);
|
|
132
|
+
|
|
133
|
+
return server;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static VALUE Protocol_QUIC_Server_allocate(VALUE klass) {
|
|
137
|
+
return TypedData_Wrap_Struct(klass, &Protocol_QUIC_Server_type, NULL);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Dispatcher & dispatcher, Configuration & configuration, TLS::ServerContext & tls_context, Socket & socket, const Address & remote_address, const ngtcp2_pkt_hd & packet_header, ngtcp2_cid *ocid = nullptr
|
|
141
|
+
static VALUE Protocol_QUIC_Server_initialize(VALUE self, VALUE dispatcher, VALUE configuration, VALUE tls_context, VALUE socket, VALUE remote_address, VALUE packet_header, VALUE ocid) {
|
|
142
|
+
Protocol::QUIC::Server *server = new RubyServer(self, dispatcher, configuration, tls_context, socket, remote_address, packet_header, ocid);
|
|
143
|
+
|
|
144
|
+
DATA_PTR(self) = server;
|
|
145
|
+
|
|
146
|
+
return self;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static VALUE Protocol_QUIC_Server_send_packets(VALUE self) {
|
|
150
|
+
Protocol::QUIC::Server *server = Protocol_QUIC_Server_get(self);
|
|
151
|
+
|
|
152
|
+
server->send_packets();
|
|
153
|
+
|
|
154
|
+
return Qnil;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
void Init_Protocol_QUIC_Server(VALUE Protocol_QUIC) {
|
|
158
|
+
Protocol_QUIC_Server =
|
|
159
|
+
rb_define_class_under(Protocol_QUIC, "Server", rb_cObject);
|
|
160
|
+
|
|
161
|
+
rb_define_alloc_func(Protocol_QUIC_Server, Protocol_QUIC_Server_allocate);
|
|
162
|
+
rb_define_method(Protocol_QUIC_Server, "initialize", Protocol_QUIC_Server_initialize, 7);
|
|
163
|
+
|
|
164
|
+
rb_define_method(Protocol_QUIC_Server, "send_packets", Protocol_QUIC_Server_send_packets, 0);
|
|
165
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Server.h
|
|
3
|
+
// This file is part of the "Protocol::QUIC" project and released under the MIT License.
|
|
4
|
+
//
|
|
5
|
+
// Created by Samuel Williams on 27/4/2023.
|
|
6
|
+
// Copyright, 2023, by Samuel Williams. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include <ruby.h>
|
|
12
|
+
|
|
13
|
+
#include <Protocol/QUIC/Server.hpp>
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
extern VALUE Protocol_QUIC_Server;
|
|
20
|
+
|
|
21
|
+
void Init_Protocol_QUIC_Server(VALUE Protocol_QUIC);
|
|
22
|
+
|
|
23
|
+
Protocol::QUIC::Server * Protocol_QUIC_Server_get(VALUE self);
|
|
24
|
+
|
|
25
|
+
#ifdef __cplusplus
|
|
26
|
+
}
|
|
27
|
+
#endif
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Socket.cpp
|
|
3
|
+
// This file is part of the "Protocol::QUIC" project and released under the MIT License.
|
|
4
|
+
//
|
|
5
|
+
// Created by Samuel Williams on 27/4/2023.
|
|
6
|
+
// Copyright, 2023, by Samuel Williams. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#include "Socket.hpp"
|
|
10
|
+
#include "Address.hpp"
|
|
11
|
+
|
|
12
|
+
VALUE Protocol_QUIC_Socket = Qnil;
|
|
13
|
+
|
|
14
|
+
static void Protocol_QUIC_Socket_free(void *data) {
|
|
15
|
+
if (data) {
|
|
16
|
+
delete reinterpret_cast<Protocol::QUIC::Socket *>(data);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static size_t Protocol_QUIC_Socket_size(const void *data) {
|
|
21
|
+
return sizeof(Protocol::QUIC::Socket);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const rb_data_type_t Protocol_QUIC_Socket_type = {
|
|
25
|
+
.wrap_struct_name = "Protocol::QUIC::Socket",
|
|
26
|
+
.function = {
|
|
27
|
+
.dmark = NULL,
|
|
28
|
+
.dfree = Protocol_QUIC_Socket_free,
|
|
29
|
+
.dsize = Protocol_QUIC_Socket_size,
|
|
30
|
+
},
|
|
31
|
+
.data = NULL,
|
|
32
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
Protocol::QUIC::Socket * Protocol_QUIC_Socket_get(VALUE self)
|
|
36
|
+
{
|
|
37
|
+
Protocol::QUIC::Socket *socket;
|
|
38
|
+
|
|
39
|
+
TypedData_Get_Struct(self, Protocol::QUIC::Socket, &Protocol_QUIC_Socket_type, socket);
|
|
40
|
+
|
|
41
|
+
return socket;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
VALUE Protocol_QUIC_Socket_allocate(VALUE klass) {
|
|
45
|
+
return TypedData_Wrap_Struct(klass, &Protocol_QUIC_Socket_type, NULL);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static VALUE Protocol_QUIC_Socket_initialize(VALUE self, VALUE domain, VALUE type, VALUE protocol) {
|
|
49
|
+
DATA_PTR(self) = new Protocol::QUIC::Socket(RB_NUM2INT(domain), RB_NUM2INT(type), RB_NUM2INT(protocol));
|
|
50
|
+
|
|
51
|
+
return self;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static VALUE Protocol_QUIC_Socket_local_address(VALUE self) {
|
|
55
|
+
auto socket = Protocol_QUIC_Socket_get(self);
|
|
56
|
+
auto &address = socket->local_address();
|
|
57
|
+
|
|
58
|
+
if (address) {
|
|
59
|
+
return Protocol_QUIC_Address_wrap(Protocol_QUIC_Address, address);
|
|
60
|
+
} else {
|
|
61
|
+
return Qnil;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static VALUE Protocol_QUIC_Socket_remote_address(VALUE self) {
|
|
66
|
+
auto socket = Protocol_QUIC_Socket_get(self);
|
|
67
|
+
auto &address = socket->remote_address();
|
|
68
|
+
|
|
69
|
+
if (address) {
|
|
70
|
+
return Protocol_QUIC_Address_wrap(Protocol_QUIC_Address, address);
|
|
71
|
+
} else {
|
|
72
|
+
return Qnil;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static VALUE Protocol_QUIC_Socket_bind(VALUE self, VALUE address) {
|
|
77
|
+
auto socket = Protocol_QUIC_Socket_get(self);
|
|
78
|
+
|
|
79
|
+
return RTEST(
|
|
80
|
+
socket->bind(*Protocol_QUIC_Address_get(address))
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static VALUE Protocol_QUIC_Socket_connect(VALUE self, VALUE address) {
|
|
85
|
+
auto socket = Protocol_QUIC_Socket_get(self);
|
|
86
|
+
|
|
87
|
+
return RTEST(
|
|
88
|
+
socket->connect(*Protocol_QUIC_Address_get(address))
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
void Init_Protocol_QUIC_Socket(VALUE Protocol_QUIC) {
|
|
93
|
+
Protocol_QUIC_Socket = rb_define_class_under(Protocol_QUIC, "Socket", rb_cObject);
|
|
94
|
+
|
|
95
|
+
rb_define_alloc_func(Protocol_QUIC_Socket, Protocol_QUIC_Socket_allocate);
|
|
96
|
+
rb_define_method(Protocol_QUIC_Socket, "initialize", Protocol_QUIC_Socket_initialize, 3);
|
|
97
|
+
|
|
98
|
+
rb_define_method(Protocol_QUIC_Socket, "local_address", Protocol_QUIC_Socket_local_address, 0);
|
|
99
|
+
rb_define_method(Protocol_QUIC_Socket, "remote_address", Protocol_QUIC_Socket_remote_address, 0);
|
|
100
|
+
|
|
101
|
+
rb_define_method(Protocol_QUIC_Socket, "bind", Protocol_QUIC_Socket_bind, 1);
|
|
102
|
+
rb_define_method(Protocol_QUIC_Socket, "connect", Protocol_QUIC_Socket_connect, 1);
|
|
103
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Socket.hpp
|
|
3
|
+
// This file is part of the "Protocol::QUIC" project and released under the MIT License.
|
|
4
|
+
//
|
|
5
|
+
// Created by Samuel Williams on 27/4/2023.
|
|
6
|
+
// Copyright, 2023, by Samuel Williams. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include <ruby.h>
|
|
12
|
+
|
|
13
|
+
#include <Protocol/QUIC/Socket.hpp>
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
extern VALUE Protocol_QUIC_Socket;
|
|
20
|
+
|
|
21
|
+
void Init_Protocol_QUIC_Socket(VALUE Protocol_QUIC);
|
|
22
|
+
|
|
23
|
+
Protocol::QUIC::Socket * Protocol_QUIC_Socket_get(VALUE self);
|
|
24
|
+
|
|
25
|
+
VALUE Protocol_QUIC_Socket_allocate(VALUE klass);
|
|
26
|
+
|
|
27
|
+
#ifdef __cplusplus
|
|
28
|
+
}
|
|
29
|
+
#endif
|