Mercurial > hg > nginx-tests
annotate lib/Test/Nginx/HTTP3.pm @ 1874:d57a0fd293a3
Tests: basic QUIC support.
- handshake using X25519 TLS secrets
- TLS PSK, session tickets, session resumption, early data, retry support
- packet numbers and packet acknowledgment
- QUIC frames handling
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Tue, 01 Feb 2022 14:54:32 +0300 |
parents | |
children | f50c2a65ccc0 |
rev | line source |
---|---|
1874
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1 package Test::Nginx::HTTP3; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
2 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
3 # (C) Sergey Kandaurov |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
4 # (C) Nginx, Inc. |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
5 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
6 # Module for nginx QUIC tests. |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
7 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
8 ############################################################################### |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
9 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
10 use warnings; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
11 use strict; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
12 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
13 use IO::Socket::INET; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
14 use IO::Select; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
15 use Data::Dumper; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
16 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
17 use Test::Nginx; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
18 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
19 sub new { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
20 my $self = {}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
21 bless $self, shift @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
22 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
23 my ($port, %extra) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
24 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
25 require Crypt::KeyDerivation; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
26 require Crypt::PK::X25519; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
27 require Crypt::PRNG; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
28 require Crypt::AuthEnc::GCM; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
29 require Crypt::Mode::CTR; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
30 require Crypt::Digest; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
31 require Crypt::Mac::HMAC; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
32 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
33 $self->{socket} = IO::Socket::INET->new( |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
34 Proto => "udp", |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
35 PeerAddr => '127.0.0.1:' . port($port || 8980), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
36 ); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
37 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
38 $self->{repeat} = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
39 $self->{token} = ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
40 $self->{psk_list} = $extra{psk_list} || []; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
41 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
42 $self->{sni} = exists $extra{sni} ? $extra{sni} : 'localhost'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
43 $self->{opts} = $extra{opts}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
44 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
45 $self->{zero} = pack("x5"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
46 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
47 $self->{buf} = ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
48 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
49 $self->init(); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
50 $self->init_key_schedule(); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
51 $self->initial(); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
52 $self->handshake() or return; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
53 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
54 return $self; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
55 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
56 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
57 sub init { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
58 my ($self, $early_data) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
59 $self->{keys} = []; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
60 $self->{pn} = [[-1, -1, -1, -1], [-1, -1, -1, -1]]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
61 $self->{crypto_in} = [[],[],[],[]]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
62 $self->{stream_in} = []; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
63 $self->{frames_in} = []; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
64 $self->{tlsm} = (); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
65 $self->{tlsm}{$_} = '' |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
66 for 'ch', 'sh', 'ee', 'cert', 'cv', 'sf', 'cf', 'nst'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
67 $self->{requests} = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
68 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
69 # Initial |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
70 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
71 $self->{odcid} = undef; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
72 $self->{scid} = Crypt::PRNG::random_bytes(17); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
73 $self->{dcid} = Crypt::PRNG::random_bytes(18); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
74 $self->{salt} = "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17" |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
75 . "\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
76 $self->{ncid} = []; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
77 $self->{early_data} = $early_data; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
78 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
79 $self->retry(); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
80 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
81 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
82 sub retry { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
83 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
84 my $prk = Crypt::KeyDerivation::hkdf_extract($self->{dcid}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
85 $self->{salt}, 'SHA256'); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
86 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
87 Test::Nginx::log_core('||', "scid = " . unpack("H*", $self->{scid})); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
88 Test::Nginx::log_core('||', "dcid = " . unpack("H*", $self->{dcid})); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
89 Test::Nginx::log_core('||', "prk = " . unpack("H*", $prk)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
90 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
91 $self->set_traffic_keys('tls13 client in', 0, 'w', $prk); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
92 $self->set_traffic_keys('tls13 server in', 0, 'r', $prk); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
93 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
94 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
95 sub init_key_schedule { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
96 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
97 $self->{psk} = $self->{psk_list}[0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
98 $self->{es_prk} = Crypt::KeyDerivation::hkdf_extract( |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
99 $self->{psk}->{secret} || pack("x32"), pack("x32"), 'SHA256'); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
100 $self->{sk} = Crypt::PK::X25519->new->generate_key; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
101 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
102 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
103 sub initial { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
104 my ($self, $ed) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
105 $self->{tlsm}{ch} = $self->build_tls_client_hello(); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
106 my $ch = $self->{tlsm}{ch}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
107 my $crypto = build_crypto($ch); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
108 my $padding = 1200 - length($crypto); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
109 $padding = 0 if $padding < 0 || $self->{psk}->{ed}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
110 my $payload = $crypto . pack("x$padding"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
111 my $initial = $self->encrypt_aead($payload, 0); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
112 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
113 if ($ed && $self->{psk}->{ed}) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
114 $self->set_traffic_keys('tls13 c e traffic', 1, 'w', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
115 $self->{es_prk}, Crypt::Digest::digest_data('SHA256', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
116 $self->{tlsm}{ch})); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
117 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
118 # my $ed = "\x0a\x02\x08\x00\x04\x02\x06\x1f\x0d\x00\x0a" |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
119 # . $self->build_stream("\x01\x06\x00\x00\xc0"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
120 $payload = $ed; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
121 # $payload = $self->build_stream("GET /\n"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
122 $padding = 1200 - length($crypto) - length($payload); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
123 $payload .= pack("x$padding") if $padding > 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
124 $initial .= $self->encrypt_aead($payload, 1); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
125 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
126 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
127 $self->{socket}->syswrite($initial); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
128 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
129 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
130 sub handshake { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
131 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
132 my $buf = ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
133 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
134 $self->read_tls_message(\$buf, \&parse_tls_server_hello) or return; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
135 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
136 my $sh = $self->{tlsm}{sh}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
137 my $extens_len = unpack("C*", substr($sh, 6 + 32 + 4, 2)) * 8 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
138 + unpack("C*", substr($sh, 6 + 32 + 5, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
139 my $extens = substr($sh, 6 + 32 + 4 + 2, $extens_len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
140 my $pub = key_share($extens); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
141 Test::Nginx::log_core('||', "pub = " . unpack("H*", $pub)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
142 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
143 my $pk = Crypt::PK::X25519->new; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
144 $pk->import_key_raw($pub, "public"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
145 my $shared_secret = $self->{sk}->shared_secret($pk); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
146 Test::Nginx::log_core('||', "shared = " . unpack("H*", $shared_secret)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
147 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
148 # tls13_advance_key_schedule |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
149 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
150 $self->{hs_prk} = hkdf_advance($shared_secret, $self->{es_prk}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
151 Test::Nginx::log_core('||', "hs = " . unpack("H*", $self->{hs_prk})); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
152 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
153 # derive_secret_with_transcript |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
154 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
155 my $digest = Crypt::Digest::digest_data('SHA256', $self->{tlsm}{ch} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
156 . $self->{tlsm}{sh}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
157 $self->set_traffic_keys('tls13 c hs traffic', 2, 'w', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
158 $self->{hs_prk}, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
159 $self->set_traffic_keys('tls13 s hs traffic', 2, 'r', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
160 $self->{hs_prk}, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
161 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
162 $self->read_tls_message(\$buf, \&parse_tls_encrypted_extensions); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
163 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
164 unless (keys %{$self->{psk}}) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
165 $self->read_tls_message(\$buf, \&parse_tls_certificate); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
166 $self->read_tls_message(\$buf, \&parse_tls_certificate_verify); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
167 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
168 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
169 $self->read_tls_message(\$buf, \&parse_tls_finished); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
170 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
171 # tls13_advance_key_schedule(application) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
172 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
173 $self->{ms_prk} = hkdf_advance(pack("x32"), $self->{hs_prk}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
174 Test::Nginx::log_core('||', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
175 "master = " . unpack("H*", $self->{ms_prk})); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
176 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
177 # derive_secret_with_transcript(application) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
178 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
179 $digest = Crypt::Digest::digest_data('SHA256', $self->{tlsm}{ch} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
180 . $self->{tlsm}{sh} . $self->{tlsm}{ee} . $self->{tlsm}{cert} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
181 . $self->{tlsm}{cv} . $self->{tlsm}{sf}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
182 $self->set_traffic_keys('tls13 c ap traffic', 3, 'w', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
183 $self->{ms_prk}, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
184 $self->set_traffic_keys('tls13 s ap traffic', 3, 'r', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
185 $self->{ms_prk}, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
186 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
187 # client finished |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
188 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
189 my $finished = tls13_finished($self->{keys}[2]{w}{prk}, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
190 Test::Nginx::log_core('||', "finished = " . unpack("H*", $finished)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
191 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
192 $self->{tlsm}{cf} = $finished; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
193 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
194 $digest = Crypt::Digest::digest_data('SHA256', $self->{tlsm}{ch} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
195 . $self->{tlsm}{sh} . $self->{tlsm}{ee} . $self->{tlsm}{cert} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
196 . $self->{tlsm}{cv} . $self->{tlsm}{sf} . $self->{tlsm}{cf}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
197 $self->{rms_prk} = hkdf_expand_label("tls13 res master", 32, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
198 $self->{ms_prk}, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
199 Test::Nginx::log_core('||', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
200 "resumption = " . unpack("H*", $self->{rms_prk})); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
201 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
202 my $crypto = build_crypto($finished); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
203 $self->{socket}->syswrite($self->encrypt_aead($crypto, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
204 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
205 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
206 #if (!$psk->{ed}) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
207 # my $r = "\x0a\x02\x08\x00\x04\x02\x06\x1f\x0d\x00\x0a"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
208 # $s->syswrite(encrypt_aead($r, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
209 # $r = "\x01\x06\x00\x00\xc0"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
210 # $s->syswrite(encrypt_aead($self->build_stream($r), 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
211 #} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
212 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
213 sub DESTROY { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
214 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
215 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
216 return unless $self->{socket}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
217 return unless $self->{keys}[3]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
218 my $frame = build_cc(0, "graceful shutdown"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
219 $self->{socket}->syswrite($self->encrypt_aead($frame, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
220 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
221 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
222 sub ping { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
223 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
224 my $frame = "\x01\x00\x00\x00"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
225 $self->{socket}->syswrite($self->encrypt_aead($frame, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
226 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
227 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
228 sub reset_stream { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
229 my ($self, $sid, $code) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
230 my $final_size = $self->{streams}{$sid}{sent}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
231 my $frame = "\x04" . build_int($sid) . build_int($code) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
232 . build_int($final_size); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
233 $self->{socket}->syswrite($self->encrypt_aead($frame, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
234 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
235 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
236 sub stop_sending { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
237 my ($self, $sid, $code) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
238 my $frame = "\x05" . build_int($sid) . build_int($code); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
239 $self->{socket}->syswrite($self->encrypt_aead($frame, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
240 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
241 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
242 sub new_connection_id { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
243 my ($self, $seqno, $ret, $id, $token) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
244 my $frame = "\x18" . build_int($seqno) . build_int($ret) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
245 . pack("C", length($id)) . $id . $token; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
246 $self->{socket}->syswrite($self->encrypt_aead($frame, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
247 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
248 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
249 sub path_challenge { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
250 my ($self, $data) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
251 my $frame = "\x1a" . $data; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
252 $self->{socket}->syswrite($self->encrypt_aead($frame, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
253 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
254 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
255 sub path_response { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
256 my ($self, $data) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
257 my $frame = "\x1b" . $data; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
258 $self->{socket}->syswrite($self->encrypt_aead($frame, 3)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
259 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
260 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
261 ############################################################################### |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
262 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
263 sub parse_frames { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
264 my ($buf) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
265 my @frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
266 my $offset = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
267 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
268 while ($offset < length($buf)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
269 my ($tlen, $type) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
270 $offset += $tlen; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
271 next if $type == 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
272 my $frame = { type => $type }; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
273 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
274 if ($type == 1) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
275 $frame->{type} = 'PING'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
276 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
277 if ($type == 2) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
278 $frame->{type} = 'ACK'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
279 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
280 $frame->{largest} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
281 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
282 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
283 $frame->{delay} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
284 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
285 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
286 $frame->{count} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
287 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
288 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
289 $frame->{first} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
290 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
291 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
292 if ($type == 4) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
293 $frame->{type} = 'RESET_STREAM'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
294 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
295 $frame->{sid} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
296 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
297 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
298 $frame->{code} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
299 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
300 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
301 $frame->{final_size} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
302 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
303 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
304 if ($type == 5) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
305 $frame->{type} = 'STOP_SENDING'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
306 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
307 $frame->{sid} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
308 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
309 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
310 $frame->{code} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
311 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
312 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
313 if ($type == 6) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
314 my ($olen, $off) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
315 $offset += $olen; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
316 my ($llen, $len) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
317 $offset += $llen; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
318 $frame->{type} = 'CRYPTO'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
319 $frame->{length} = $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
320 $frame->{offset} = $off; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
321 $frame->{payload} = substr($buf, $offset, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
322 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
323 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
324 if ($type == 7) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
325 $frame->{type} = 'NEW_TOKEN'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
326 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
327 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
328 $frame->{token} = substr($buf, $offset, $val); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
329 $offset += $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
330 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
331 if (($type & 0xf8) == 0x08) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
332 $frame->{type} = 'STREAM'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
333 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
334 $frame->{id} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
335 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
336 if ($type & 0x4) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
337 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
338 $frame->{offset} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
339 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
340 } else { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
341 $frame->{offset} = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
342 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
343 if ($type & 0x2) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
344 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
345 $frame->{length} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
346 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
347 } else { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
348 $frame->{length} = length($buf) - $offset; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
349 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
350 if ($type & 0x1) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
351 $frame->{fin} = 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
352 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
353 $frame->{payload} = |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
354 substr($buf, $offset, $frame->{length}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
355 $offset += $frame->{length}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
356 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
357 if ($type == 18 || $type == 19) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
358 $frame->{type} = 'MAX_STREAMS'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
359 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
360 $frame->{val} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
361 $frame->{uni} = 1 if $type == 19; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
362 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
363 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
364 if ($type == 24) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
365 $frame->{type} = 'NCID'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
366 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
367 $frame->{seqno} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
368 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
369 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
370 $frame->{rpt} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
371 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
372 $len = unpack("C", substr($buf, $offset, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
373 $frame->{length} = $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
374 $offset += 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
375 $frame->{cid} = substr($buf, $offset, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
376 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
377 $frame->{token} = substr($buf, $offset, 16); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
378 $offset += 16; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
379 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
380 if ($type == 26) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
381 $frame->{type} = 'PATH_CHALLENGE'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
382 $frame->{data} = substr($buf, $offset, 8); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
383 $offset += 8; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
384 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
385 if ($type == 27) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
386 $frame->{type} = 'PATH_RESPONSE'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
387 $frame->{data} = substr($buf, $offset, 8); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
388 $offset += 8; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
389 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
390 if ($type == 28 || $type == 29) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
391 $frame->{type} = 'CONNECTION_CLOSE'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
392 my ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
393 $frame->{error} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
394 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
395 if ($type == 28) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
396 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
397 $frame->{frame_type} = $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
398 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
399 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
400 ($len, $val) = parse_int(substr($buf, $offset)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
401 $offset += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
402 $frame->{phrase} = substr($buf, $offset, $val); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
403 $offset += $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
404 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
405 if ($type == 30) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
406 $frame->{type} = 'HANDSHAKE_DONE'; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
407 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
408 push @frames, $frame; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
409 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
410 return \@frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
411 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
412 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
413 sub handle_frames { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
414 my ($self, $frames, $level) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
415 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
416 my @frames = grep { $_->{type} eq 'CRYPTO' } @$frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
417 while (my $frame = shift @frames) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
418 insert_crypto($self->{crypto_in}[$level], [ |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
419 $frame->{offset}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
420 $frame->{length}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
421 $frame->{payload}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
422 ]); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
423 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
424 $self->parse_tls_nst() if $level == 3; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
425 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
426 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
427 @frames = grep { $_->{type} eq 'STREAM' } @$frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
428 while (my $frame = shift @frames) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
429 $self->{stream_in}[$frame->{id}] ||= { buf => [], pos => 0 }; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
430 insert_crypto($self->{stream_in}[$frame->{id}]->{buf}, [ |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
431 $frame->{offset}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
432 $frame->{length}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
433 $frame->{payload}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
434 $frame->{fin}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
435 ]); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
436 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
437 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
438 @frames = grep { $_->{type} eq 'NCID' } @$frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
439 while (my $frame = shift @frames) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
440 push @{$self->{ncid}}, $frame; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
441 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
442 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
443 my $ack = $self->{ack}[$level]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
444 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
445 # stop tracking acknowledged ACK ranges |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
446 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
447 @frames = grep { $_->{type} eq 'ACK' } @$frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
448 while (my $frame = shift @frames) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
449 my $max = $frame->{largest}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
450 my $min = $max - $frame->{first}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
451 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
452 for my $num ($min .. $max) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
453 for my $pn (keys %$ack) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
454 delete $ack->{$pn} if $ack->{$pn} == $num; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
455 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
456 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
457 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
458 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
459 $self->{socket}->syswrite($self->encrypt_aead(build_ack($ack), $level)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
460 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
461 for my $pn (keys %$ack) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
462 $ack->{$pn} = $self->{pn}[0][$level] if $ack->{$pn} == -1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
463 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
464 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
465 my ($frame) = grep { $_->{type} eq 'NEW_TOKEN' } @$frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
466 $self->{token} = $frame->{token} || ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
467 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
468 push @{$self->{frames_in}}, grep { $_->{type} ne 'CRYPTO' |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
469 && $_->{type} ne 'STREAM' } @$frames; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
470 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
471 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
472 sub insert_crypto { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
473 my ($crypto, $frame) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
474 my $i; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
475 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
476 for ($i = 0; $i < scalar @$crypto; $i++) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
477 # frame][crypto][frame |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
478 my $this = @$crypto[$i]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
479 if (@$frame[0] <= @$this[0] && |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
480 @$frame[0] + @$frame[1] >= @$this[0] + @$this[1]) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
481 { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
482 my $old = substr(@$frame[2], @$this[0] - @$frame[0], |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
483 @$this[1]); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
484 die "bad inner" if $old ne @$this[2]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
485 splice @$crypto, $i, 1; $i--; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
486 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
487 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
488 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
489 return push @$crypto, $frame if !@$crypto; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
490 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
491 for ($i = 0; $i < @$crypto; $i++) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
492 if (@$frame[0] <= @{@$crypto[$i]}[0] + @{@$crypto[$i]}[1]) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
493 last; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
494 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
495 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
496 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
497 return push @$crypto, $frame if $i == @$crypto; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
498 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
499 my $this = @$crypto[$i]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
500 my $next = @$crypto[$i + 1]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
501 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
502 if (@$frame[0] + @$frame[1] == @$this[0]) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
503 # frame][crypto |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
504 @$this[0] = @$frame[0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
505 @$this[1] += @$frame[1]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
506 @$this[2] = @$frame[2] . @$this[2]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
507 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
508 } elsif (@$this[0] + @$this[1] == @$frame[0]) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
509 # crypto][frame |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
510 @$this[1] += @$frame[1]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
511 @$this[2] .= @$frame[2]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
512 @$this[3] = @$frame[3]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
513 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
514 } elsif (@$frame[0] + @$frame[1] < @$this[0]) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
515 # frame..crypto |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
516 return splice @$crypto, $i, 0, $frame; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
517 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
518 } else { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
519 # overlay |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
520 my ($b1, $b2) = @$this[0] < @$frame[0] |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
521 ? ($this, $frame) : ($frame, $this); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
522 my ($o1, $o2) = @$this[0] + @$this[1] < @$frame[0] + @$frame[1] |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
523 ? ($this, $frame) : ($frame, $this); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
524 my $offset = @$b2[0] - @$b1[0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
525 my $length = @$o1[0] + @$o1[1] - @$b2[0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
526 my $old = substr @$b1[2], $offset, $length, @$b2[2]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
527 die "bad repl" if substr(@$b1[2], $offset, $length) ne $old; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
528 @$this = (@$b1[0], @$o2[0] + @$o2[1] - @$b1[0], @$b1[2]); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
529 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
530 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
531 return if !defined $next; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
532 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
533 # combine with next overlay if any |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
534 if (@$this[0] + @$this[1] >= @$next[0]) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
535 my $offset = @$next[0] - @$this[0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
536 my $length = @$this[0] + @$this[1] - @$next[0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
537 my $old = substr @$this[2], $offset, $length, @$next[2]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
538 die "bad repl2" if substr(@$this[2], $offset, $length) ne $old; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
539 @$this[1] = @$next[0] + @$next[1] - @$this[0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
540 splice @$crypto, $i + 1, 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
541 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
542 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
543 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
544 ############################################################################### |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
545 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
546 sub save_session_tickets { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
547 my ($self, $content) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
548 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
549 my $nst_len = unpack("n", substr($content, 2, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
550 my $nst = substr($content, 4, $nst_len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
551 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
552 my $psk = {}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
553 my $lifetime = substr($nst, 0, 4); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
554 $psk->{age_add} = substr($nst, 4, 4); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
555 my $nonce_len = unpack("C", substr($nst, 8, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
556 my $nonce = substr($nst, 9, $nonce_len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
557 my $len = unpack("n", substr($nst, 8 + 1 + $nonce_len, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
558 $psk->{ticket} = substr($nst, 11 + $nonce_len, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
559 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
560 my $extens_len = unpack("n", substr($nst, 11 + $nonce_len + $len, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
561 my $extens = substr($nst, 11 + $nonce_len + $len + 2, $extens_len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
562 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
563 $psk->{ed} = early_data($extens); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
564 $psk->{secret} = hkdf_expand_label("tls13 resumption", 32, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
565 $self->{rms_prk}, $nonce); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
566 push @{$self->{psk_list}}, $psk; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
567 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
568 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
569 sub decode_pn { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
570 my ($self, $pn, $pnl, $level) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
571 my $expected = $self->{pn}[1][$level] + 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
572 my $pn_win = 1 << $pnl * 8; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
573 my $pn_hwin = $pn_win / 2; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
574 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
575 $pn |= $expected & ~($pn_win - 1); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
576 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
577 if ($pn <= $expected - $pn_hwin && $pn < (1 << 62) - $pn_win) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
578 $pn += $pn_win; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
579 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
580 } elsif ($pn > $expected + $pn_hwin && $pn >= $pn_win) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
581 $pn -= $pn_win; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
582 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
583 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
584 return $pn; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
585 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
586 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
587 sub decrypt_aead { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
588 my ($self, $buf) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
589 my $flags = unpack("C", substr($buf, 0, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
590 return 0, $self->decrypt_retry($buf) if ($flags & 0xf0) == 0xf0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
591 my $level = $flags & 0x80 ? $flags - 0xc0 >> 4 : 3; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
592 my $offpn = 1 + length($self->{scid}) if $level == 3; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
593 $offpn = ( |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
594 $offpn = unpack("C", substr($buf, 5, 1)), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
595 $self->{scid} = substr($buf, 6, $offpn), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
596 $offpn = unpack("C", substr($buf, 6 + length($self->{scid}), 1)), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
597 $self->{dcid} = |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
598 substr($buf, 6 + length($self->{scid}) + 1, $offpn), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
599 7 + ($level == 0) + length($self->{scid}) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
600 + length($self->{dcid})) if $level != 3; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
601 my ($len, $val) = $level != 3 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
602 ? parse_int(substr($buf, $offpn)) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
603 : (0, length($buf) - $offpn); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
604 $offpn += $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
605 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
606 my $sample = substr($buf, $offpn + 4, 16); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
607 my ($ad, $pnl, $pn) = $self->decrypt_ad($buf, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
608 $self->{keys}[$level]{r}{hp}, $sample, $offpn, $level == 3); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
609 Test::Nginx::log_core('||', "ad = " . unpack("H*", $ad)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
610 $pn = $self->decode_pn($pn, $pnl, $level); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
611 my $nonce = substr(pack("x12") . pack("N", $pn), -12) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
612 ^ $self->{keys}[$level]{r}{iv}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
613 my $ciphertext = substr($buf, $offpn + $pnl, $val - 16 - $pnl); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
614 my $tag = substr($buf, $offpn + $val - 16, 16); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
615 my $plaintext = Crypt::AuthEnc::GCM::gcm_decrypt_verify('AES', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
616 $self->{keys}[$level]{r}{key}, $nonce, $ad, $ciphertext, $tag); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
617 return if !defined $plaintext; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
618 Test::Nginx::log_core('||', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
619 "pn = $pn, level = $level, length = " . length($plaintext)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
620 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
621 $self->{pn}[1][$level] = $pn; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
622 $self->{ack}[$level]{$pn} = -1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
623 $self->{ack}[$_] = undef for (0 .. $level - 1); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
624 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
625 return ($level, $plaintext, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
626 substr($buf, length($ad . $ciphertext . $tag)), ''); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
627 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
628 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
629 sub decrypt_ad { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
630 my ($self, $buf, $hp, $sample, $offset, $short) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
631 my $m = Crypt::Mode::CTR->new('AES'); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
632 my $mask = $m->encrypt($self->{zero}, $hp, $sample); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
633 substr($buf, 0, 1) ^= substr($mask, 0, 1) & ($short ? "\x1f" : "\x0f"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
634 my $pnl = unpack("C", substr($buf, 0, 1) & "\x03") + 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
635 for (my $i = 0; $i < $pnl; $i++) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
636 substr($buf, $offset + $i, 1) ^= substr($mask, $i + 1, 1); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
637 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
638 my $pn = unpack("C", substr($buf, $offset, $pnl)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
639 my $ad = substr($buf, 0, $offset + $pnl); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
640 return ($ad, $pnl, $pn); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
641 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
642 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
643 sub encrypt_aead { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
644 my ($self, $payload, $level) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
645 my $pn = ++$self->{pn}[0][$level]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
646 my $ad = pack("C", $level == 3 ? 0x40 : 0xc + $level << 4) | "\x03"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
647 $ad .= "\x00\x00\x00\x01" unless $level == 3; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
648 $ad .= $level == 3 ? $self->{dcid} : |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
649 pack("C", length($self->{dcid})) . $self->{dcid} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
650 . pack("C", length($self->{scid})) . $self->{scid}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
651 $ad .= build_int(length($self->{token})) . $self->{token} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
652 if $level == 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
653 $ad .= build_int(length($payload) + 16 + 4) unless $level == 3; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
654 $ad .= pack("N", $pn); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
655 my $nonce = substr(pack("x12") . pack("N", $pn), -12) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
656 ^ $self->{keys}[$level]{w}{iv}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
657 my ($ciphertext, $tag) = Crypt::AuthEnc::GCM::gcm_encrypt_authenticate( |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
658 'AES', $self->{keys}[$level]{w}{key}, $nonce, $ad, $payload); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
659 my $sample = substr($ciphertext . $tag, 0, 16); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
660 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
661 $ad = $self->encrypt_ad($ad, $self->{keys}[$level]{w}{hp}, |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
662 $sample, $level == 3); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
663 return $ad . $ciphertext . $tag; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
664 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
665 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
666 sub encrypt_ad { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
667 my ($self, $ad, $hp, $sample, $short) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
668 my $m = Crypt::Mode::CTR->new('AES'); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
669 my $mask = $m->encrypt($self->{zero}, $hp, $sample); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
670 substr($ad, 0, 1) ^= substr($mask, 0, 1) & ($short ? "\x1f" : "\x0f"); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
671 substr($ad, -4) ^= substr($mask, 1); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
672 return $ad; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
673 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
674 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
675 sub decrypt_retry { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
676 my ($self, $buf) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
677 my $off = unpack("C", substr($buf, 5, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
678 $self->{scid} = substr($buf, 6, $off); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
679 $self->{odcid} = $self->{dcid}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
680 $self->{dcid} = unpack("C", substr($buf, 6 + $off, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
681 $self->{dcid} = substr($buf, 6 + $off + 1, $self->{dcid}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
682 my $token = substr($buf, 6 + $off + 1 + length($self->{dcid}), -16); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
683 my $tag = substr($buf, -16); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
684 my $pseudo = pack("C", length($self->{odcid})) . $self->{odcid} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
685 . substr($buf, 0, -16); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
686 return ($tag, retry_verify_tag($pseudo), $token); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
687 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
688 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
689 sub retry_verify_tag { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
690 my $key = "\xbe\x0c\x69\x0b\x9f\x66\x57\x5a" |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
691 . "\x1d\x76\x6b\x54\xe3\x68\xc8\x4e"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
692 my $nonce = "\x46\x15\x99\xd3\x5d\x63\x2b\xf2\x23\x98\x25\xbb"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
693 my (undef, $tag) = Crypt::AuthEnc::GCM::gcm_encrypt_authenticate('AES', |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
694 $key, $nonce, shift, ''); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
695 return $tag; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
696 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
697 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
698 sub set_traffic_keys { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
699 my ($self, $label, $level, $direction, $secret, $digest) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
700 my $prk = hkdf_expand_label($label, 32, $secret, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
701 my $key = hkdf_expand_label("tls13 quic key", 16, $prk); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
702 my $iv = hkdf_expand_label("tls13 quic iv", 12, $prk); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
703 my $hp = hkdf_expand_label("tls13 quic hp", 16, $prk); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
704 $self->{keys}[$level]{$direction}{prk} = $prk; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
705 $self->{keys}[$level]{$direction}{key} = $key; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
706 $self->{keys}[$level]{$direction}{iv} = $iv; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
707 $self->{keys}[$level]{$direction}{hp} = $hp; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
708 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
709 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
710 sub hmac_finished { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
711 my ($key, $digest) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
712 my $finished_key = hkdf_expand_label("tls13 finished", 32, $key); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
713 Crypt::Mac::HMAC::hmac('SHA256', $finished_key, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
714 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
715 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
716 sub tls13_finished { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
717 my ($key, $digest) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
718 my $hmac = hmac_finished($key, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
719 "\x14\x00" . pack('n', length($hmac)) . $hmac; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
720 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
721 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
722 sub binders { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
723 my ($key, $digest) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
724 my $hmac = hmac_finished($key, $digest); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
725 pack('n', length($hmac) + 1) . pack('C', length($hmac)) . $hmac; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
726 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
727 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
728 sub hkdf_advance { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
729 my ($secret, $prk) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
730 my $digest0 = Crypt::Digest::digest_data('SHA256', ''); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
731 my $expand = hkdf_expand_label("tls13 derived", 32, $prk, $digest0); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
732 Crypt::KeyDerivation::hkdf_extract($secret, $expand, 'SHA256'); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
733 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
734 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
735 sub hkdf_expand_label { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
736 my ($label, $len, $prk, $context) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
737 $context = '' if !defined $context; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
738 my $info = pack("C3", 0, $len, length($label)) . $label |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
739 . pack("C", length($context)) . $context; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
740 return Crypt::KeyDerivation::hkdf_expand($prk, 'SHA256', $len, $info); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
741 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
742 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
743 sub key_share { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
744 my ($extens) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
745 my $offset = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
746 while ($offset < length($extens)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
747 my $ext = substr($extens, $offset, 2); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
748 my $len = unpack("C", substr($extens, $offset + 2, 1)) * 8 + |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
749 unpack("C", substr($extens, $offset + 3, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
750 if ($ext eq "\x00\x33") { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
751 return substr($extens, $offset + 4 + 4, $len - 4); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
752 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
753 $offset += 4 + $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
754 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
755 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
756 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
757 sub early_data { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
758 my ($extens) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
759 my $offset = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
760 while ($offset < length($extens)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
761 my $ext = substr($extens, $offset, 2); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
762 my $len = unpack("C", substr($extens, $offset + 2, 1)) * 8 + |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
763 unpack("C", substr($extens, $offset + 3, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
764 if ($ext eq "\x00\x2a") { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
765 return substr($extens, $offset + 4, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
766 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
767 $offset += 4 + $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
768 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
769 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
770 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
771 ############################################################################### |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
772 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
773 sub build_cc { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
774 my ($code, $reason) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
775 "\x1d" . build_int($code) . build_int(length($reason)) . $reason; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
776 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
777 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
778 sub build_ack { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
779 my ($ack) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
780 my @keys = sort { $b <=> $a } keys %$ack; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
781 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
782 return "\x02" . build_int($keys[0]) . "\x00\x00\x00" if @keys == 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
783 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
784 my $min = my $max = shift @keys; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
785 my @acks = (); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
786 for my $next (@keys) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
787 if ($next == $min - 1) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
788 $min = $next; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
789 next if $next != $keys[-1]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
790 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
791 push @acks, $max, $min; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
792 $min = $max = $next; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
793 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
794 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
795 ($max, $min) = splice @acks, 0, 2; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
796 my $ranges = @acks / 2; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
797 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
798 $ack = "\x02" . build_int($max) . "\x00" . build_int($ranges) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
799 . build_int($max - $min); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
800 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
801 for (my $smallest = $min; $ranges--; ) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
802 my ($max, $min) = splice @acks, 0, 2; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
803 $ack .= build_int($smallest - $max - 2); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
804 $ack .= build_int($max - $min); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
805 $smallest = $min; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
806 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
807 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
808 return $ack; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
809 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
810 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
811 sub build_crypto { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
812 my ($tlsm) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
813 "\x06\x00" . build_int(length($tlsm)) . $tlsm; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
814 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
815 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
816 sub build_stream { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
817 my ($self, $r, %extra) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
818 my $stream = $extra{start} ? 0xe : 0xf; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
819 my $length = $extra{length} ? $extra{length} : build_int(length($r)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
820 my $offset = build_int($extra{offset} ? $extra{offset} : 0); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
821 my $sid = defined $extra{sid} ? $extra{sid} : $self->{requests}++; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
822 pack("CC", $stream, 4 * $sid) . $offset . $length . $r; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
823 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
824 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
825 sub parse_int { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
826 my ($buf) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
827 my $val = unpack("C", substr($buf, 0, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
828 my $len = my $plen = 1 << ($val >> 6); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
829 $val = $val & 0x3f; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
830 while (--$len) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
831 $val = ($val << 8) + unpack("C", substr($buf, $plen - $len, 1)) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
832 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
833 return ($plen, $val); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
834 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
835 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
836 sub build_int { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
837 my ($value) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
838 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
839 my $build_int_set = sub { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
840 my ($value, $len, $bits) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
841 (($value >> ($len * 8)) & 0xff) | ($bits << 6); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
842 }; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
843 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
844 if ($value < 1 << 6) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
845 pack("C", $build_int_set->($value, 0, 0)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
846 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
847 } elsif ($value < 1 << 14) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
848 pack("C*", |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
849 $build_int_set->($value, 1, 1), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
850 $build_int_set->($value, 0, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
851 ); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
852 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
853 } elsif ($value < 1 << 30) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
854 pack("C*", |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
855 $build_int_set->($value, 3, 2), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
856 $build_int_set->($value, 2, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
857 $build_int_set->($value, 1, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
858 $build_int_set->($value, 0, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
859 ); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
860 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
861 } else { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
862 pack("C*", |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
863 build_int_set->($value, 7, 3), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
864 build_int_set->($value, 6, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
865 build_int_set->($value, 5, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
866 build_int_set->($value, 4, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
867 build_int_set->($value, 3, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
868 build_int_set->($value, 2, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
869 build_int_set->($value, 1, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
870 build_int_set->($value, 0, 0), |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
871 ); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
872 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
873 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
874 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
875 ############################################################################### |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
876 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
877 sub read_stream_message { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
878 my ($self, $timo) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
879 my ($level, $plaintext, @data); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
880 my $s = $self->{socket}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
881 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
882 while (1) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
883 @data = $self->parse_stream(); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
884 return @data if $#data; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
885 return if scalar @{$self->{frames_in}}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
886 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
887 my $txt; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
888 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
889 if (!length($self->{buf})) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
890 return unless IO::Select->new($s)->can_read($timo || 3); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
891 $s->sysread($self->{buf}, 65527); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
892 $txt = "recv"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
893 } else { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
894 $txt = "remaining"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
895 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
896 my $len = length $self->{buf}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
897 Test::Nginx::log_core('||', sprintf("$txt = [%d]", $len)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
898 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
899 while ($self->{buf}) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
900 ($level, $plaintext, $self->{buf}, $self->{token}) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
901 = $self->decrypt_aead($self->{buf}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
902 return if !defined $plaintext; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
903 goto retry if $self->{token}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
904 $self->handle_frames(parse_frames($plaintext), $level); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
905 @data = $self->parse_stream(); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
906 return @data if $#data; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
907 return if scalar @{$self->{frames_in}}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
908 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
909 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
910 return; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
911 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
912 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
913 sub parse_stream { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
914 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
915 my $data; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
916 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
917 for my $i (0 .. $#{$self->{stream_in}}) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
918 my $stream = $self->{stream_in}[$i]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
919 next if !defined $stream; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
920 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
921 my $buf = $stream->{buf}[0][2]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
922 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
923 if ($stream->{buf}[0][3]) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
924 $stream->{buf}[0][3] = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
925 $stream->{eof} = 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
926 $data = ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
927 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
928 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
929 if (length($buf) > $stream->{pos}) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
930 $data = substr($buf, $stream->{pos}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
931 $stream->{pos} = length($buf); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
932 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
933 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
934 next if !defined $data; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
935 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
936 return ($i, $data, $stream->{eof} ? 1 : 0); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
937 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
938 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
939 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
940 ############################################################################### |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
941 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
942 sub read_tls_message { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
943 my ($self, $buf, $type) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
944 my $s = $self->{socket}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
945 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
946 while (!$type->($self)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
947 my $txt; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
948 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
949 if (!length($$buf)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
950 return unless IO::Select->new($s)->can_read(3); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
951 $s->sysread($$buf, 65527); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
952 $txt = "recv"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
953 } else { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
954 $txt = "remaining"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
955 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
956 my $len = length $$buf; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
957 Test::Nginx::log_core('||', sprintf("$txt = [%d]", $len)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
958 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
959 while ($$buf) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
960 (my $level, my $plaintext, $$buf, $self->{token}) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
961 = $self->decrypt_aead($$buf); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
962 return if !defined $plaintext; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
963 goto retry if $self->{token}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
964 $self->handle_frames(parse_frames($plaintext), $level); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
965 return 1 if $type->($self); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
966 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
967 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
968 return; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
969 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
970 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
971 sub parse_tls_server_hello { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
972 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
973 my $buf = $self->{crypto_in}[0][0][2] if $self->{crypto_in}[0][0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
974 return 0 if !$buf || length($buf) < 4; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
975 my $type = unpack("C", substr($buf, 0, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
976 my $len = unpack("n", substr($buf, 2, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
977 my $content = substr($buf, 4, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
978 return 0 if length($content) < $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
979 $self->{tlsm}{sh} = substr($buf, 0, 4) . $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
980 return $self->{tlsm}{sh}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
981 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
982 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
983 sub parse_tls_encrypted_extensions { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
984 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
985 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
986 return 0 if !$buf; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
987 my $off = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
988 my $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
989 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
990 while ($off < length($buf)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
991 return 0 if length($buf) < 4; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
992 my $type = unpack("C", substr($buf, $off, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
993 my $len = unpack("n", substr($buf, $off + 2, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
994 $content = substr($buf, $off + 4, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
995 return 0 if length($content) < $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
996 last if $type == 8; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
997 $off += 4 + $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
998 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
999 $self->{tlsm}{ee} = substr($buf, $off, 4) . $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1000 return $self->{tlsm}{ee}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1001 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1002 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1003 sub parse_tls_certificate { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1004 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1005 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1006 return 0 if !$buf; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1007 my $off = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1008 my $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1009 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1010 while ($off < length($buf)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1011 return 0 if length($buf) < 4; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1012 my $type = unpack("C", substr($buf, $off, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1013 my $len = unpack("n", substr($buf, $off + 2, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1014 $content = substr($buf, $off + 4, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1015 return 0 if length($content) < $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1016 last if $type == 11; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1017 $off += 4 + $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1018 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1019 $self->{tlsm}{cert} = substr($buf, $off, 4) . $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1020 return $self->{tlsm}{cert}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1021 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1022 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1023 sub parse_tls_certificate_verify { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1024 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1025 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1026 return 0 if !$buf; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1027 my $off = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1028 my $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1029 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1030 while ($off < length($buf)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1031 return 0 if length($buf) < 4; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1032 my $type = unpack("C", substr($buf, $off, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1033 my $len = unpack("n", substr($buf, $off + 2, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1034 $content = substr($buf, $off + 4, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1035 return 0 if length($content) < $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1036 last if $type == 15; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1037 $off += 4 + $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1038 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1039 $self->{tlsm}{cv} = substr($buf, $off, 4) . $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1040 return $self->{tlsm}{cv}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1041 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1042 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1043 sub parse_tls_finished { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1044 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1045 my $buf = $self->{crypto_in}[2][0][2] if $self->{crypto_in}[2][0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1046 return 0 if !$buf; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1047 my $off = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1048 my $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1049 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1050 while ($off < length($buf)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1051 return 0 if length($buf) < 4; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1052 my $type = unpack("C", substr($buf, $off, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1053 my $len = unpack("n", substr($buf, $off + 2, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1054 $content = substr($buf, $off + 4, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1055 return 0 if length($content) < $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1056 last if $type == 20; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1057 $off += 4 + $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1058 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1059 $self->{tlsm}{sf} = substr($buf, $off, 4) . $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1060 return $self->{tlsm}{sf}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1061 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1062 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1063 sub parse_tls_nst { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1064 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1065 my $buf = $self->{crypto_in}[3][0][2] if $self->{crypto_in}[3][0]; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1066 return 0 if !$buf; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1067 my $off = 0; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1068 my $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1069 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1070 while ($off < length($buf)) { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1071 return 0 if length($buf) < 4; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1072 my $type = unpack("C", substr($buf, $off, 1)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1073 my $len = unpack("n", substr($buf, $off + 2, 2)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1074 $content = substr($buf, $off + 4, $len); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1075 return 0 if length($content) < $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1076 $self->{tlsm}{nst} .= substr($buf, $off, 4) . $content; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1077 $self->save_session_tickets(substr($buf, $off, 4) . $content); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1078 $off += 4 + $len; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1079 substr($self->{crypto_in}[3][0][2], 0, $off) = ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1080 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1081 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1082 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1083 sub build_tls_client_hello { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1084 my ($self) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1085 my $key_share = $self->{sk}->export_key_raw('public'); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1086 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1087 my $version = "\x03\x03"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1088 my $random = Crypt::PRNG::random_bytes(32); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1089 my $session = "\x00"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1090 my $cipher = "\x00\x02\x13\x01"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1091 my $compr = "\x01\x00"; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1092 my $ext = build_tlsext_server_name($self->{sni}) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1093 . build_tlsext_supported_groups(29) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1094 . build_tlsext_alpn("h3", "hq-interop") |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1095 . build_tlsext_sigalgs(0x0804, 0x0805, 0x0806) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1096 . build_tlsext_supported_versions(0x0304) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1097 . build_tlsext_ke_modes(1) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1098 . build_tlsext_key_share(29, $key_share) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1099 . build_tlsext_quic_tp($self->{scid}, $self->{opts}); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1100 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1101 $ext .= build_tlsext_early_data($self->{psk}) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1102 . build_tlsext_psk($self->{psk}) if keys %{$self->{psk}}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1103 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1104 my $len = pack('n', length($ext)); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1105 my $ch = $version . $random . $session . $cipher . $compr . $len . $ext; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1106 $ch = "\x01\x00" . pack('n', length($ch)) . $ch; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1107 $ch = build_tls_ch_with_binder($ch, $self->{es_prk}) |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1108 if keys %{$self->{psk}}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1109 return $ch; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1110 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1111 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1112 sub build_tlsext_server_name { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1113 my ($name) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1114 my $sname = pack('xn', length($name)) . $name; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1115 my $snamelist = pack('n', length($sname)) . $sname; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1116 pack('n2', 0, length($snamelist)) . $snamelist; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1117 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1118 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1119 sub build_tlsext_supported_groups { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1120 my $ngrouplist = pack('n*', @_ * 2, @_); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1121 pack('n2', 10, length($ngrouplist)) . $ngrouplist; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1122 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1123 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1124 sub build_tlsext_alpn { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1125 my $protoname = pack('(C/a*)*', @_); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1126 my $protonamelist = pack('n', length($protoname)) . $protoname; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1127 pack('n2', 16, length($protonamelist)) . $protonamelist; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1128 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1129 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1130 sub build_tlsext_sigalgs { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1131 my $sschemelist = pack('n*', @_ * 2, @_); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1132 pack('n2', 13, length($sschemelist)) . $sschemelist; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1133 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1134 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1135 sub build_tlsext_supported_versions { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1136 my $versions = pack('Cn*', @_ * 2, @_); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1137 pack('n2', 43, length($versions)) . $versions; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1138 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1139 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1140 sub build_tlsext_ke_modes { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1141 my $versions = pack('C*', scalar(@_), @_); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1142 pack('n2', 45, length($versions)) . $versions; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1143 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1144 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1145 sub build_tlsext_key_share { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1146 my ($group, $share) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1147 my $kse = pack("n2", $group, length($share)) . $share; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1148 my $ksch = pack("n", length($kse)) . $kse; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1149 pack('n2', 51, length($ksch)) . $ksch; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1150 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1151 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1152 sub build_tlsext_quic_tp { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1153 my ($scid, $opts) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1154 my $tp = ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1155 my $quic_tp_tlv = sub { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1156 my ($id, $val) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1157 $val = $opts->{$id} // $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1158 $val = build_int($val) unless $id == 15; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1159 $tp .= build_int($id) . pack("C*", length($val)) . $val; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1160 }; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1161 $quic_tp_tlv->(1, 30000); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1162 $quic_tp_tlv->(4, 1048576); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1163 $quic_tp_tlv->(5, 262144); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1164 $quic_tp_tlv->(7, 262144); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1165 $quic_tp_tlv->(9, 100); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1166 $quic_tp_tlv->(15, $scid); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1167 pack('n2', 57, length($tp)) . $tp; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1168 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1169 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1170 sub build_tlsext_early_data { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1171 my ($psk) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1172 $psk->{ed} ? pack('n2', 42, 0) : ''; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1173 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1174 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1175 sub build_tlsext_psk { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1176 my ($psk) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1177 my $identity = pack('n', length($psk->{ticket})) . $psk->{ticket} |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1178 . $psk->{age_add}; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1179 my $identities = pack('n', length($identity)) . $identity; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1180 my $hash = pack('x32'); # SHA256 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1181 my $binder = pack('C', length($hash)) . $hash; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1182 my $binders = pack('n', length($binder)) . $binder; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1183 pack('n2', 41, length($identities . $binders)) . $identities . $binders; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1184 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1185 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1186 sub build_tls_ch_with_binder { |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1187 my ($ch, $prk) = @_; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1188 my $digest0 = Crypt::Digest::digest_data('SHA256', ''); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1189 my $key = hkdf_expand_label("tls13 res binder", 32, $prk, $digest0); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1190 my $truncated = substr($ch, 0, -35); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1191 my $context = Crypt::Digest::digest_data('SHA256', $truncated); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1192 $truncated . binders($key, $context); |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1193 } |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1194 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1195 ############################################################################### |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1196 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1197 1; |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1198 |
d57a0fd293a3
Tests: basic QUIC support.
Sergey Kandaurov <pluknet@nginx.com>
parents:
diff
changeset
|
1199 ############################################################################### |