This commit is contained in:
Ken McMillan 2018-11-20 14:24:46 -08:00
Родитель fe24006a75
Коммит aeb30056bc
10 изменённых файлов: 658 добавлений и 118 удалений

Просмотреть файл

@ -1,99 +1,192 @@
Ivy specification of QUIC
-------------------------
Mechanized specification of QUIC
--------------------------------
This directory contains work on specifying the QUIC protocol in Ivy.
The currently targeted version is 9, as described in [this
document](https://tools.ietf.org/html/draft-ietf-quic-transport-09).
This directory contains work on a mechanized specification of the QUIC
protocol in the Ivy language. The currently targeted version is IETF
draft 15, as described in
[this document](https://tools.ietf.org/html/draft-ietf-quic-transport-15).
The specification is written in a way that allows monitoring of
packets on the wire, and will eventually allow for modular testing of
implementations and possibly a fully verified implementation.
packets on the wire, as well as modular testing of implementations.
That is, from the specification we can produce an automated tester
that takes one role in the protocol. The tester uses a technique
called symbolic execution to randomly generate protocol traffic that
complies with the specification. For example, if the tester is taking
the client role, it generates packets that are legal for the client to
send, and these are transmitted to the server being tested. The
responses sent by the server are then checked for compliance with the
specification.
This approach has certain advantages when compared to interoperablilty
testing. First, the specification-based tester can generate stimulus
that can't be produced by any current implementation and perhaps would
only be produced by attackers. Because it is randomized, it tends to
generate the unusual cases that specifiers may not have
considered. Second, it checks for actual specification compliance and
not just for correct interopation. Ensuring compliance to the
specification can be helpful for future protocol developers who have
deal with compatibility with legacy implementations.
In addition, the mechanized specification can be seen as
documentation, since it gives an unambiguous interpretation of
statements made in natural language in the IETF specification
documents.
A guide to the specification
============================
The mechanized specification is given in terms of a set of protocol
events or "actions" in the Ivy language. These events abstractly
represent occurrences at various layers of the protocol stack, for
example, the transmission of a QUIC packet from one endpoint to
another, or the transfer of data to or from an application. To each of
these events are attached *monitors*. The monitors assert requirements
on the events that determine protocol compliance and also record
history information by updating shared variables. This information
makes it possible to specify legal sequences of events, and also to
specify the required relationships between events occurring at
different protocol layers.
A good place to start in reading the specification is the file
`quic_connection.ivy`, which contains the monitors for the various
protocol events and the declarations of all of the relevant state
variables. These specifications use structured representions of data
such as packets or frames rather than byte-level encodings. The
corresponding data types are described in the file `quic_types.ivy`,
`quic_frame.ivy` and `quic_packet.ivy`.
The Ivy language used to express the specification is described
[here](http://microsoft.github.io/ivy/language.html). An example of
using Ivy for specification-based tesing can be found
[here](http://microsoft.github.io/ivy/examples/testing/intro.html).
The specification is intended to be a "literate" document, containing
a natural language description of the protocol, interleaved with the
formal description. This is somewhat a work in progress, however, with
some aspects more clearly documented than others.
The specification as it stands has a number of limitations. First, it
covers only a subset of features of QUIC. Currently, enough features
are covered for the test client to have a successful dialog with
server implementations, but much work remains to be done in specifying
all of the protocol features. Second, the specification does not deal
with quantitative time, meaning certain aspects of the QUIC
specification relating to transmission rates and timeouts can't be
stated.
The remainder of this document describes how to use the mechanized
specification to test implementations.
The Ivy spec is being developed from the informal IETF draft cited
above. Ambiguities are resolved by observing the behavior of existing
implementations. In particular, we use the evolving specification to
monitor packet traces captured from implementations. This allows us
to check consistency and possibly discover incompatibilities between
implementations.
Installation steps
==================
First, Ivy must be installed, as described
[here](http://microsoft.github.io/ivy/install.html). It must be
installed from source, using the git branch `quic15_merge_temp`.
Do these steps just once on a given machine.
### Virtual networking and packet capture
To monitor implementations of the protocol, it is useful to run them
in a virtual network environment. For this we use the [CORE virtual
networking
environment](https://www.nrl.navy.mil/itd/ncs/products/core), the
`tcpdump` command and the `pcap` library. To install these on an Ubuntu
system with version 14.04 or higher, do the following:
Optionally, to monitor implementations of the protocol, it is useful
to run them in a virtual network environment. For this we use the
[CORE virtual networking environment](https://www.nrl.navy.mil/itd/ncs/products/core),
the `tcpdump` command and the `pcap` library. To install these on an
Ubuntu system with version 14.04 or higher, do the following:
sudo apt-get install core-network tcpdump libpcap-dev
On Ubuntu 18.04 you have to install from source. Get the source from
the link above and follow the README.
### Botan
### Picotls
For test generation, the Botan implementation of TLS is used. Install
version 2.6.0 from [here](https://botan.randombit.net/releases/). Instructions
are [here](https://botan.randombit.net/).
The testers make use of the `picotls` implementation of TLS. Install it
according to the instructions [here](https://github.com/h2o/picotls).
Install Botan like this (from the Botan source directory):
Then you need to tell the Ivy compiler where to find the `picotls`
library and headers (unless you copy them to standard locations). Use
this commands, where `PICOTLS_DIR` is the directory in which `picotls`
was built:
./configure.py
make
sudo make install
sudo ln -s /usr/local/include/botan-2/botan /usr/local/include/botan
cp src/lib/tls/tls_reader.h /usr/local/include/botan
The last two commands are needed because Botan installs itself in a
way that it can't find its own header files, and it forgets a header
file (at least in 2.6.0).
$ ivy_libs add picotls $PICOTLS_DIR .
Notice the dot in the above, which is essential.
### Ivy packet monitor
To build the Ivy monitor, change to this directory (the one this README file
is in) and compile `quic_monitor.ivy` like this:
ivyc quic_monitor.ivy
This should create a binary file `quic_monitor`. Copy `mycap.pcap` into this directory and then do:
./quic_monitor mycap.pcap > log.iev
The file `log.iev` should have lines like this:
< show_packet({protocol:udp,addr:0xa000002,port:0x869b},{protocol:udp,addr:0xa000001,port:0x1151},{hdr_long:0x1,hdr_type:0x7f,hdr_cid:0x7c74846907e4ce90,hdr_version:0xff000009,hdr_pkt_num:0x3dee3059,payload:[{frame.stream:{off:0x1,len:0x1,fin:0,id:0,offset:0,length:0x282,data:[0x16,0x3,0x3,...]}}]})
These are decoded packets. Each line consists of a source endpoint, a
destination endpoint and a packet. The structure of packets is
described in [quic_packet.ivy](quic_packet.md).
If the specification is violated by the packet trace, the file will
end with an error message indicating the requirement that was
violated.
#### Build the server tester
There are various testers available that generate different sorts of
traffic for the server. The most basic one is
`quic_server_test_stream.ivy`, in this directory. Build it like this
ivyc target=test quic_server_test_stream.ivy
If successful, this will produce a binary file
`quic_server_test_stream`.
Implementations of QUIC
-----------------------
### Google QUIC
### picoquic
The Google implementation of QUIC is supposed to be IEFT compatible if
you used version 99. It is part of Chromium code base.
Source code and build instructions:
Some instructions to install it are here:
https://github.com/private-octopus/picoquic
Run a server:
http://www.chromium.org/quic/playing-with-quic
./picoquicdemo
Run a client
Before, compiling, you need to patch it to disable packet protection.
A patch against commit `1720d2a` can be found in `chromium_diffs.txt`.
./picoquicdemo localhost
### quant
After compiling and certificate creation, to run the test server, from
the `src` directory of Chromium:
./out/Debug/quic_server \
--quic_response_cache_dir=/tmp/quic-data/www.example.org \
--certificate_file=net/tools/quic/certs/out/leaf_cert.pem \
--key_file=net/tools/quic/certs/out/leaf_cert.pkcs8 --quic-enable-version-99
To run the test client:
out/Default/quick_client --host=127.0.0.1 --port=6121 --disable-certificate-verification https://www.example.org/ --quic-enable-version-99
Source code and build instructions:
https://github.com/NTAP/quant
To run the quant server in this directory:
$QUANT_DIR/Debug/bin/server -d . -c leaf_cert.pem -k leaf_cert.key -p 4443
### MinQUIC
This implementation of version 9 in the go language is available [on
github](https://github.com/ekr/minq). However, for Ivy you should use
the fork [here](https://github.com/kenmcmil/minq) which has been
modified to disable crypto.
This implementation does not support IETF version 15 as of this writing.
When it does, ese these isntructions to run it.
#### Steps to get started with MinQUIC and Ivy
#### Steps to get started with MinQUIC
- Install the [go language](https://golang.org/doc/install) on your platform.
- Follow the instructions [here](https://github.com/kenmcmil/minq) to install MinQUIC.
- Follow the instructions [here](https://github.com/ekr/minq) to install MinQUIC.
##### Go installation notes:
@ -113,48 +206,56 @@ To get MinQUIC running, this command may be helpful:
cd $GOPATH/src
go get github.com/cloudflare/cfssl/helpers
### picoquic
### Google QUIC
Source code and build instructions:
The Google implementation of QUIC is part of Chromium code base, and
is supposed to be IEFT compatible if you used version 99. However,
this in itself seems to be non-standard behavior, and it has not yet
proved possible to interoperate with Google QUIC. For anyone willing
to attempt to rectify this, some instructions to install it are here:
https://github.com/private-octopus/picoquic
Run a server:
http://www.chromium.org/quic/playing-with-quic
./picoquicdemo
Run a client
After compiling and certificate creation, to run the test server, from
the `src` directory of Chromium:
./picoquicdemo localhost
### quant
./out/Debug/quic_server \
--quic_response_cache_dir=/tmp/quic-data/www.example.org \
--certificate_file=net/tools/quic/certs/out/leaf_cert.pem \
--key_file=net/tools/quic/certs/out/leaf_cert.pkcs8 --quic-enable-version-99
To run the quant server in this directory:
To run the test client:
~/projects/quant/Debug/bin/server -d . -c leaf_cert.pem -k leaf_cert.key
out/Default/quick_client --host=127.0.0.1 --port=6121 --disable-certificate-verification https://www.example.org/ --quic-enable-version-99
Virtual network startup
=======================
This step should be performed once, and then redone after each reboot
of the machine (or after you shut down the virtual network
If you want to use virtual networking on linux to isolate QUIC, this
step should be performed once, and then redone after each reboot of
the machine (or after you shut down the virtual network
configuration).
Use the following command in this directory (the one containing this
file!) to set up a suitable virtual network on your system:
file) to set up a suitable virtual network on your system:
sudo ./vnet_setup.sh
Running QUIC and capturing packets
==================================
Running MinQUIC and capturing packets
=====================================
*Note: the packet monitor doesn't currently work because it needs a
way to get the negotiated secrets from TLS. When does does again work,
the following instructions can be used.*
If you haven't done the above virtual network startup step since the
last reboot of your machine, do it now.
We will use MinQUIC as an example, here, but the commands can be
monitored to run different implementations (or mix implementations).
Change to the directory containing MinQUIC:
cd $GOPATH/src/github.com/kenmcmil/minq
@ -183,14 +284,15 @@ To run the server with logging, do this:
MINQ_LOG='*' MINT_LOG='*' go run bin/server/main.go
Build and run the Ivy monitor
=============================
Running the Ivy monitor
=======================
To build the Ivy monitor, change to this directory and compile `quic_monitor.ivy` like this:
*Note: the packet monitor doesn't currently work because it needs a
way to get the negotiated secrets from TLS. When does does again work,
the following instructions can be used.*
ivyc quic_monitor.ivy
This should create a binary file `quic_monitor`. Copy `mycap.pcap` into this directory and then do:
To run the Ivy monitor, change to this directory. Copy your packet
capture file `mycap.pcap` into this directory and then do:
./quic_monitor mycap.pcap > log.iev
@ -204,13 +306,19 @@ described in [quic_packet.ivy](quic_packet.md).
If the specification is violated by the packet trace, the file will
end with an error message indicating the requirement that was
violated.
violated.
Build and run the server tester
===============================
Run the server tester
=====================
ivyc target=test quic_server_test.ivy
In this directory, start the server using the instructions for that
server implementation. Use port number 4443 on the loopack
interface. Then use this command:
./quic_server_test_stream > log.iev
See above for description of the output file log.iev. You can used the
command line option `seed=<int>` to set the random seed.
View the log
============

Просмотреть файл

@ -141,6 +141,25 @@ say it must start *immediately*. It seems reasonable to assume the
some previously queued packets can still be sent to the old address.
Event files: anomaly11.iev
Quant log file: anomaly11.log
QUIC version: draft 15
Ivy commit: ???????
Implementation:
quant, commit: ???????
Issue:
After an http parse error, Quant sends an application close frame
inside an intial packet, which appears not to be allowed in the
spec. The spec says:
The payload of an Initial packet includes a CRYPTO frame (or frames)
containing a cryptographic handshake message, ACK frames, or both.
PADDING and CONNECTION_CLOSE frames are also permitted. An endpoint
that receives an Initial packet containing other frames can either
discard the packet as spurious or treat it as a connection error.
This appears to imply the other frames, such as APPLICATION_CLOSE, are
not allowed in initial packets.

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -0,0 +1,153 @@
$ server -d . -c leaf_cert.pem -k leaf_cert.key -p 4443
0.032 q_init quic.c:498 quant/socket 0.0.16/dd567715 with libev 4.22 ready
q_init quic.c:499 submit bug reports at https://github.com/NTAP/quant/issues
0.034 q_init quic.c:521 debug build, storing fuzzer corpus data
q_bind quic.c:368 binding serv socket on port 4443
init_rec recovery.c:527 in_flight=0, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
new_conn conn.c:1265 serv conn ? on port 4443 created
new_conn conn.c:1267 conn ? state conn_clsd -> conn_idle
q_bind quic.c:370 bound serv socket on port 4443
main server.c:239 server waiting on lo port 4443
427.512 rx_pkts conn.c:885 new serv conn on port 4443 from 127.0.0.1:4988 w/cid=0:000000000000000b
init_rec recovery.c:527 in_flight=0, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
new_conn conn.c:1265 serv conn 0:000000000000000b on port 4443 created
new_conn conn.c:1267 conn 0:000000000000000b state conn_clsd -> conn_idle
427.513 log_pkt pkt.c:116 RX len=1216 0xff=Initial vers=0xff00000f dcid=000000000000000b scid=000000000000000d tok= len=1207 nr=0
rx_pkt conn.c:642 supporting clnt-requested vers 0xff00000f
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=243 [seq]
dec_frames frame.c:891 PADDING len=939
rx_pkt conn.c:668 conn 0:000000000000000b state conn_idle -> conn_opng
update_act_scid conn.c:465 hshk switch to scid 0:fa15135b1bb7c15d for serv conn (was 0:000000000000000b)
on_ch tls.c:310 SNI =
on_ch tls.c:313 ALPN =
427.514 chk_tp tls.c:473 initial_max_stream_data_bidi_local = 8192
chk_tp tls.c:485 initial_max_data = 16384
chk_tp tls.c:502 idle_timeout = 60
chk_tp tls.c:480 initial_max_stream_data_bidi_remote = 8192
chk_tp tls.c:467 initial_max_stream_data_uni = 8192
427.522 rx_crypto conn.c:545 conn 0:fa15135b1bb7c15d state conn_opng -> conn_estb
tx conn.c:420 data TX on serv conn 0:fa15135b1bb7c15d strm -4 w/1 pkt in queue
enc_pkt pkt.c:386 hshk switch to scid 0:88a5f94c9e7a3a74 for serv conn (was 0:fa15135b1bb7c15d)
update_act_scid conn.c:465 hshk switch to scid 0:88a5f94c9e7a3a74 for serv conn (was 0:fa15135b1bb7c15d)
427.522 log_pkt pkt.c:169 TX 0xff=Initial vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 tok=feeab57c9b1bc644a6564dacc67ae0e1a50eabe8345b68934aef3b9b0d6163d2fa15135b1bb7c15d len=0 nr=0
enc_ack_frame frame.c:1167 ACK lg=0 delay=0 (0 usec) cnt=0 block=0 [0]
enc_padding_frame frame.c:1095 PADDING len=97
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=155
on_pkt_sent recovery.c:285 in_flight=299, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
log_sent_pkts conn.c:227 epoch 0 unacked: *0
tx conn.c:420 data TX on serv conn 0:88a5f94c9e7a3a74 strm -2 w/2 pkts in queue
427.522 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=0 nr=0
enc_padding_frame frame.c:1095 PADDING len=103
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=1108
on_pkt_sent recovery.c:285 in_flight=1551, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
427.523 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=0 nr=1
enc_padding_frame frame.c:1095 PADDING len=103
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=1108 len=292
on_pkt_sent recovery.c:285 in_flight=1987, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
log_sent_pkts conn.c:227 epoch 0 unacked: *0
log_sent_pkts conn.c:227 epoch 2 unacked: *0 *1
coalesce pkt.c:218 coalescing 0xfd len 436 behind 0xff len 299
427.712 on_ld_alarm recovery.c:201 handshake RTX #1 on serv conn 0:88a5f94c9e7a3a74
detect_lost_pkts recovery.c:155 pkt 0 considered lost
detect_lost_pkts recovery.c:162 in_flight=1688, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
detect_lost_pkts recovery.c:155 pkt 0 considered lost
detect_lost_pkts recovery.c:162 in_flight=436, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
detect_lost_pkts recovery.c:155 pkt 1 considered lost
detect_lost_pkts recovery.c:162 in_flight=0, cwnd=12000, ssthresh=0, srtt=0.000000, rttvar=0.000000
detect_lost_pkts recovery.c:185 in_flight=0, cwnd=6000, ssthresh=6000, srtt=0.000000, rttvar=0.000000
tx conn.c:420 data TX on serv conn 0:88a5f94c9e7a3a74 strm -4 w/1 pkt in queue
427.713 log_pkt pkt.c:169 TX 0xff=Initial vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 tok=feeab57c9b1bc644a6564dacc67ae0e1a50eabe8345b68934aef3b9b0d6163d2fa15135b1bb7c15d len=274 nr=1
enc_ack_frame frame.c:1167 ACK lg=0 delay=25037 (200296 usec) cnt=0 block=0 [0]
enc_padding_frame frame.c:1095 PADDING len=90
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=155 [RTX]
on_pkt_sent recovery.c:285 in_flight=299, cwnd=6000, ssthresh=6000, srtt=0.000000, rttvar=0.000000
log_sent_pkts conn.c:227 epoch 0 unacked: *0 *1
log_sent_pkts conn.c:227 epoch 2 unacked: *0 *1
tx conn.c:420 data TX on serv conn 0:88a5f94c9e7a3a74 strm -2 w/2 pkts in queue
427.713 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=1228 nr=2
enc_padding_frame frame.c:1095 PADDING len=99
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=1108 [RTX]
on_pkt_sent recovery.c:285 in_flight=1551, cwnd=6000, ssthresh=6000, srtt=0.000000, rttvar=0.000000
427.713 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=412 nr=3
enc_padding_frame frame.c:1095 PADDING len=98
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=1108 len=292 [RTX]
on_pkt_sent recovery.c:285 in_flight=1987, cwnd=6000, ssthresh=6000, srtt=0.000000, rttvar=0.000000
log_sent_pkts conn.c:227 epoch 0 unacked: *0 *1
log_sent_pkts conn.c:227 epoch 2 unacked: *0 *1 *2 *3
coalesce pkt.c:218 coalescing 0xfd len 436 behind 0xff len 299
428.113 on_ld_alarm recovery.c:201 handshake RTX #2 on serv conn 0:88a5f94c9e7a3a74
tx conn.c:420 data TX on serv conn 0:88a5f94c9e7a3a74 strm -4 w/1 pkt in queue
428.113 log_pkt pkt.c:169 TX 0xff=Initial vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 tok=feeab57c9b1bc644a6564dacc67ae0e1a50eabe8345b68934aef3b9b0d6163d2fa15135b1bb7c15d len=274 nr=2
enc_ack_frame frame.c:1167 ACK lg=0 delay=75114 (600912 usec) cnt=0 block=0 [0]
enc_padding_frame frame.c:1095 PADDING len=90
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=155 [RTX]
on_pkt_sent recovery.c:285 in_flight=2286, cwnd=6000, ssthresh=6000, srtt=0.000000, rttvar=0.000000
log_sent_pkts conn.c:227 epoch 0 unacked: *0 *1 *2
log_sent_pkts conn.c:227 epoch 2 unacked: *0 *1 *2 *3
tx conn.c:420 data TX on serv conn 0:88a5f94c9e7a3a74 strm -2 w/2 pkts in queue
428.113 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=1228 nr=4
enc_padding_frame frame.c:1095 PADDING len=99
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=1108 [RTX]
on_pkt_sent recovery.c:285 in_flight=3538, cwnd=6000, ssthresh=6000, srtt=0.000000, rttvar=0.000000
428.113 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=412 nr=5
enc_padding_frame frame.c:1095 PADDING len=98
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=1108 len=292 [RTX]
on_pkt_sent recovery.c:285 in_flight=3974, cwnd=6000, ssthresh=6000, srtt=0.000000, rttvar=0.000000
log_sent_pkts conn.c:227 epoch 0 unacked: *0 *1 *2
log_sent_pkts conn.c:227 epoch 2 unacked: *0 *1 *2 *3 *4 *5
coalesce pkt.c:218 coalescing 0xfd len 436 behind 0xff len 299
428.390 log_pkt pkt.c:126 RX len=104 0xfd=Handshake vers=0xff00000f dcid=88a5f94c9e7a3a74 scid=000000000000000d len=96 nr=0
log_stream_or_crypto_frame frame.c:116 CRYPTO 0x18 off=0 len=52 [seq]
dec_ack_frame frame.c:388 ACK lg=0 delay=0 (0 usec) cnt=0 block=0 [0]
update_rtt recovery.c:319 in_flight=3974, cwnd=6000, ssthresh=6000, srtt=0.878110, rttvar=0.439055
on_pkt_acked recovery.c:461 0 was RTX'ed as 4
dec_frames frame.c:891 PADDING len=15
428.416 ack_alarm pn.c:56 ACK timer fired on serv conn 0:88a5f94c9e7a3a74 epoch 2
428.416 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=0 nr=6
enc_ack_frame frame.c:1167 ACK lg=0 delay=3203 (25624 usec) cnt=0 block=0 [0]
428.604 log_pkt pkt.c:134 RX len=44 0x30=Short kyph=0 dcid=88a5f94c9e7a3a74 nr=0
new_stream stream.c:101 conn 0:88a5f94c9e7a3a74 strm 4 (bidir, clnt) state strm_idle -> strm_open
log_stream_or_crypto_frame frame.c:111 STREAM 0x16=LEN|OFF id=4/4 off=0/16384 len=1 coff=1/32768 [seq]
dec_frames frame.c:903 addtl stream or crypto frame at pos 18, copy
log_stream_or_crypto_frame frame.c:111 STREAM 0x16=LEN|OFF id=4/4 off=1/16384 len=1 coff=2/32768 [seq]
dec_frames frame.c:903 addtl stream or crypto frame at pos 23, copy
log_stream_or_crypto_frame frame.c:111 STREAM 0x16=LEN|OFF id=4/4 off=2/16384 len=1 coff=3/32768 [seq]
dec_frames frame.c:891 PADDING len=15
rx conn.c:1023 q_rx_ready(0, 0) done, exiting event loop
q_rx_ready quic.c:657 serv conn 0:88a5f94c9e7a3a74 ready to rx
q_read quic.c:318 non-blocking read on serv conn 0:88a5f94c9e7a3a74
q_read quic.c:342 read 3 bytes on serv conn 0:88a5f94c9e7a3a74 strm 4
main server.c:281 HTTP parser error: -
q_read quic.c:318 non-blocking read on serv conn 0:88a5f94c9e7a3a74
q_close quic.c:548 closing serv conn 0:88a5f94c9e7a3a74 on port 4443
q_close quic.c:556 conn 0:88a5f94c9e7a3a74 state conn_estb -> conn_qlse
enter_closing conn.c:1133 closing/draining alarm in 4.390550 sec on serv conn 0:88a5f94c9e7a3a74
enter_closing conn.c:1139 conn 0:88a5f94c9e7a3a74 state conn_qlse -> conn_clsg
tx conn.c:420 data TX on serv conn 0:88a5f94c9e7a3a74 strm -4 w/1 pkt in queue
428.605 log_pkt pkt.c:169 TX 0xff=Initial vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 tok=feeab57c9b1bc644a6564dacc67ae0e1a50eabe8345b68934aef3b9b0d6163d2fa15135b1bb7c15d len=274 nr=3
enc_ack_frame frame.c:1167 ACK lg=0 delay=136602 (1092816 usec) cnt=0 block=0 [0]
enc_close_frame frame.c:1280 APPLICATION_CLOSE err=0x0000 rlen=0 reason=
on_pkt_sent recovery.c:285 in_flight=4028, cwnd=6000, ssthresh=6000, srtt=0.878110, rttvar=0.439055
tx_stream_data conn.c:312 cwnd limit 4028 reached (2020 + 6000 > 511163881)
log_sent_pkts conn.c:227 epoch 0 unacked: *0 *1 *2 *3
log_sent_pkts conn.c:227 epoch 2 unacked: *1 *2 *3 *4 *5 (6)
tx conn.c:420 data TX on serv conn 0:88a5f94c9e7a3a74 strm -2 w/2 pkts in queue
428.605 log_pkt pkt.c:179 TX 0xfd=Handshake vers=0xff00000f dcid=000000000000000d scid=88a5f94c9e7a3a74 len=1228 nr=7
enc_ack_frame frame.c:1167 ACK lg=0 delay=26839 (214712 usec) cnt=0 block=0 [0]
enc_close_frame frame.c:1280 APPLICATION_CLOSE err=0x0000 rlen=0 reason=
on_pkt_sent recovery.c:285 in_flight=4081, cwnd=6000, ssthresh=6000, srtt=0.878110, rttvar=0.439055
tx_stream_data conn.c:312 cwnd limit 4081 reached (2020 + 6000 > 511163881)
log_sent_pkts conn.c:227 epoch 0 unacked: *0 *1 *2 *3
log_sent_pkts conn.c:227 epoch 2 unacked: *1 *2 *3 *4 *5 (6) *7
428.605 log_pkt pkt.c:187 TX 0x32=Short kyph=0 dcid=000000000000000d nr=0
enc_ack_frame frame.c:1167 ACK lg=0 delay=79 (632 usec) cnt=0 block=0 [0]
enc_close_frame frame.c:1280 APPLICATION_CLOSE err=0x0000 rlen=0 reason=
on_pkt_sent recovery.c:285 in_flight=4117, cwnd=6000, ssthresh=6000, srtt=0.878110, rttvar=0.439055
coalesce pkt.c:218 coalescing 0xfd len 53 behind 0xff len 54
coalesce pkt.c:218 coalescing 0x32 len 36 behind 0xfd len 107
432.998 enter_closed conn.c:1080 conn 0:88a5f94c9e7a3a74 state conn_clsg -> conn_clsd
enter_closed conn.c:1083 <any>(c, 0) done, exiting event loop
free_stream stream.c:132 freeing strm 4 on serv conn 0:88a5f94c9e7a3a74
443.008 cancel_api_call quic.c:380 canceling API call
cancel_api_call quic.c:383 q_rx_ready(0, 0) done, exiting event loop
443.026 main server.c:294 server exiting

Просмотреть файл

@ -1254,6 +1254,23 @@ object frame = { ...
}
}
# New token frames are sent by the server to provide the client a
# token for establishing a new connection.
object frame = { ...
object new_token = { ...
action handle(f:frame.new_token,src:ip.endpoint,dst:ip.endpoint,scid:cid,dcid:cid,e:encryption_level)
around handle {
require cid_dst_to_src_set(dcid) & cid_dst_to_src(dcid) = scid;
require e = encryption_level.other & established_1rtt_keys(scid);
require num_queued_frames(scid) > 0 -> e = queued_level(scid);
require ~is_client(scid);
...
call enqueue_frame(dst,dcid,f,e,false);
}
}
}
# ### Packet number decoding
# The packet number is decoded from the packet header fields as follows.

Просмотреть файл

@ -414,6 +414,10 @@ object quic_deser = {}
state = quic_path_challenge_data;
return 12;
}
if (frame_type == 0x19) { // new token frame
state = quic_crypto_length; // new token equivalent to this
return 13;
}
std::cerr << "saw tag " << ft << std::endl;
}
throw deser_err();

Просмотреть файл

@ -168,6 +168,17 @@ object frame = {
}
}
object new_token = {
# New token frames are a variant of frame.
variant this of frame = struct {
length : stream_pos, # length of the token
data : stream_data # the token
}
}
instance idx : unbounded_sequence
instance arr : array(idx,this)
}

Просмотреть файл

@ -1292,7 +1292,7 @@ def get_mixin_order(iso,mod):
if len(implements) > 1:
raise iu.IvyError(implements[1],'Multiple implementations for {}'.format(action))
mixins = [m for m in mixins if not isinstance(m,ivy_ast.MixinImplementDef)]
mixers = iu.topological_sort(list(set(m.mixer() for m in mixins)),arcs)
mixers = iu.topological_sort(list(iu.unique(m.mixer() for m in mixins)),arcs)
keymap = dict((x,y) for y,x in enumerate(mixers))
key = lambda m: keymap[m.mixer()]
before = sorted([m for m in mixins if isinstance(m,ivy_ast.MixinBeforeDef)],key=key)

Просмотреть файл

@ -6,7 +6,7 @@
# This script allows you to add and remove native libraries to be
# used by the ivy compiler. The command line syntax is:
#
# python ivy_libs.y [add,remove] name [prefix]
# ivy_libs [add,remove] name [prefix] [libdir]
#
# Here, name is the library name and prefix is the path prefix of
# the library. If not present, the prefix defaults to lib/name within
@ -15,7 +15,11 @@
#
# prefix/lib/lib<name>.so -- the library shared object file
# prefix/include/*.h -- the libaray header files
#
#
# However, if the libraries are not found in prefix/lib, the optional
# libdir argument can be given, specifying the path relative to
# prefix of the directory containing the libraries.
#
# Static libraries can also be used.
#
# Information on added libraries is store in lib/specs in the ivy
@ -26,37 +30,41 @@ import sys
import os
import json
if len(sys.argv) < 3 or len(sys.argv) > 4 or sys.argv[1] not in ['add','remove']:
os.stderr.write('syntax: python ivy_libs.y [add,remove] name [prefix]\n')
exit(1)
verb = sys.argv[1]
name = sys.argv[2]
libpath = os.path.join(os.path.dirname(os.path.dirname(__file__)),'lib')
default_prefix = os.path.abspath(os.path.join(libpath,name))
prefix = sys.argv[3] if len(sys.argv) >= 4 else default_prefix
print 'Adding library {} at prefix {}.'.format(name,prefix)
specfilename = os.path.join(libpath,'specs')
if os.path.isfile(specfilename):
try:
with open(specfilename) as inp:
libs = json.load(inp)
except:
sys.stderr.write('bad format in {}\n'.format(specfilename))
def main():
if len(sys.argv) < 3 or len(sys.argv) > 5 or sys.argv[1] not in ['add','remove']:
sys.stderr.write('syntax: python ivy_libs.y [add,remove] name [prefix] [libdir]\n')
exit(1)
else:
libs = []
libs = [x for x in libs if x[0] != name]
if verb == 'add':
libs.append([name,prefix])
verb = sys.argv[1]
name = sys.argv[2]
with open(specfilename,"w") as out:
json.dump(libs,out)
libpath = os.path.join(os.path.dirname(os.path.dirname(__file__)),'lib')
default_prefix = os.path.abspath(os.path.join(libpath,name))
prefix = sys.argv[3] if len(sys.argv) >= 4 else default_prefix
libdir = [os.path.join(prefix,sys.argv[4])] if len(sys.argv) >= 5 else []
print 'Adding library {} at prefix {}.'.format(name,prefix)
specfilename = os.path.join(libpath,'specs')
if os.path.isfile(specfilename):
try:
with open(specfilename) as inp:
libs = json.load(inp)
except:
sys.stderr.write('bad format in {}\n'.format(specfilename))
exit(1)
else:
libs = []
libs = [x for x in libs if x[0] != name]
if verb == 'add':
libs.append([name,prefix] + libdir)
with open(specfilename,"w") as out:
json.dump(libs,out)
if __name__ == "__main__":
main()

Просмотреть файл

@ -14,7 +14,7 @@ setup(name='ms_ivy',
'tarjan'
],
entry_points = {
'console_scripts': ['ivy=ivy.ivy:main','ivy_check=ivy.ivy_check:main','ivy_to_cpp=ivy.ivy_to_cpp:main','ivy_show=ivy.ivy_show:main','ivy_ev_viewer=ivy.ivy_ev_viewer:main','ivyc=ivy.ivy_to_cpp:ivyc','ivy_to_md=ivy.ivy_to_md:main'],
'console_scripts': ['ivy=ivy.ivy:main','ivy_check=ivy.ivy_check:main','ivy_to_cpp=ivy.ivy_to_cpp:main','ivy_show=ivy.ivy_show:main','ivy_ev_viewer=ivy.ivy_ev_viewer:main','ivyc=ivy.ivy_to_cpp:ivyc','ivy_to_md=ivy.ivy_to_md:main','ivy_libs=ivy.ivy_libs:main'],
},
zip_safe=False)