mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
remove support for quic-trace
This commit is contained in:
parent
6148ea9a46
commit
02b700804f
21 changed files with 19 additions and 2372 deletions
2
.github/workflows/go-generate.sh
vendored
2
.github/workflows/go-generate.sh
vendored
|
@ -4,7 +4,7 @@ set -e
|
|||
|
||||
find . -type f -name "*.go" -exec shasum {} \; > checksums_before.txt
|
||||
# delete all go-generated files generated (that adhere to the comment convention)
|
||||
grep --include \*.go --exclude-dir quictrace/ -lrIZ "^// Code generated .* DO NOT EDIT\.$" . | xargs --null rm
|
||||
grep --include \*.go -lrIZ "^// Code generated .* DO NOT EDIT\.$" . | xargs --null rm
|
||||
# delete all files generated by Genny
|
||||
grep --include \*.go -lrIZ "This file was automatically generated by genny." . | xargs --null rm
|
||||
# first generate Genny files to make the code compile
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
|
||||
|
@ -457,7 +456,6 @@ var _ = Describe("Client", func() {
|
|||
|
||||
Context("quic.Config", func() {
|
||||
It("setups with the right values", func() {
|
||||
tracer := quictrace.NewTracer()
|
||||
tokenStore := NewLRUTokenStore(10, 4)
|
||||
config := &Config{
|
||||
HandshakeTimeout: 1337 * time.Minute,
|
||||
|
@ -466,7 +464,6 @@ var _ = Describe("Client", func() {
|
|||
MaxIncomingUniStreams: 4321,
|
||||
ConnectionIDLength: 13,
|
||||
StatelessResetKey: []byte("foobar"),
|
||||
QuicTracer: tracer,
|
||||
TokenStore: tokenStore,
|
||||
}
|
||||
c := populateClientConfig(config, false)
|
||||
|
@ -476,7 +473,6 @@ var _ = Describe("Client", func() {
|
|||
Expect(c.MaxIncomingUniStreams).To(BeEquivalentTo(4321))
|
||||
Expect(c.ConnectionIDLength).To(Equal(13))
|
||||
Expect(c.StatelessResetKey).To(Equal([]byte("foobar")))
|
||||
Expect(c.QuicTracer).To(Equal(tracer))
|
||||
Expect(c.TokenStore).To(Equal(tokenStore))
|
||||
})
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ coverage:
|
|||
- internal/utils/newconnectionid_linkedlist.go
|
||||
- internal/utils/packetinterval_linkedlist.go
|
||||
- internal/utils/linkedlist/linkedlist.go
|
||||
- quictrace/
|
||||
- fuzzing/
|
||||
- metrics/
|
||||
status:
|
||||
|
|
|
@ -98,7 +98,6 @@ func populateConfig(config *Config) *Config {
|
|||
ConnectionIDLength: config.ConnectionIDLength,
|
||||
StatelessResetKey: config.StatelessResetKey,
|
||||
TokenStore: config.TokenStore,
|
||||
QuicTracer: config.QuicTracer,
|
||||
Tracer: config.Tracer,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
|
||||
mocklogging "github.com/lucas-clemente/quic-go/internal/mocks/logging"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
@ -70,8 +69,6 @@ var _ = Describe("Config", func() {
|
|||
f.Set(reflect.ValueOf([]byte{1, 2, 3, 4}))
|
||||
case "KeepAlive":
|
||||
f.Set(reflect.ValueOf(true))
|
||||
case "QuicTracer":
|
||||
f.Set(reflect.ValueOf(quictrace.NewTracer()))
|
||||
case "Tracer":
|
||||
f.Set(reflect.ValueOf(mocklogging.NewMockTracer(mockCtrl)))
|
||||
default:
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
"github.com/lucas-clemente/quic-go/qlog"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
)
|
||||
|
||||
type binds []string
|
||||
|
@ -54,45 +53,7 @@ func generatePRData(l int) []byte {
|
|||
return res
|
||||
}
|
||||
|
||||
var tracer quictrace.Tracer
|
||||
|
||||
func init() {
|
||||
tracer = quictrace.NewTracer()
|
||||
}
|
||||
|
||||
func exportTraces() error {
|
||||
traces := tracer.GetAllTraces()
|
||||
if len(traces) != 1 {
|
||||
return errors.New("expected exactly one trace")
|
||||
}
|
||||
for _, trace := range traces {
|
||||
f, err := os.Create("trace.qtr")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write(trace); err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
fmt.Println("Wrote trace to", f.Name())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type tracingHandler struct {
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
var _ http.Handler = &tracingHandler{}
|
||||
|
||||
func (h *tracingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
h.handler.ServeHTTP(w, r)
|
||||
if err := exportTraces(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func setupHandler(www string, trace bool) http.Handler {
|
||||
func setupHandler(www string) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
if len(www) > 0 {
|
||||
|
@ -170,11 +131,8 @@ func setupHandler(www string, trace bool) http.Handler {
|
|||
</form></body></html>`)
|
||||
})
|
||||
|
||||
if !trace {
|
||||
return mux
|
||||
}
|
||||
return &tracingHandler{handler: mux}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// defer profile.Start().Stop()
|
||||
|
@ -188,7 +146,6 @@ func main() {
|
|||
flag.Var(&bs, "bind", "bind to")
|
||||
www := flag.String("www", "", "www data")
|
||||
tcp := flag.Bool("tcp", false, "also listen on TCP")
|
||||
trace := flag.Bool("trace", false, "enable quic-trace")
|
||||
enableQlog := flag.Bool("qlog", false, "output a qlog (in the same directory)")
|
||||
flag.Parse()
|
||||
|
||||
|
@ -205,11 +162,8 @@ func main() {
|
|||
bs = binds{"localhost:6121"}
|
||||
}
|
||||
|
||||
handler := setupHandler(*www, *trace)
|
||||
handler := setupHandler(*www)
|
||||
quicConf := &quic.Config{}
|
||||
if *trace {
|
||||
quicConf.QuicTracer = tracer
|
||||
}
|
||||
if *enableQlog {
|
||||
quicConf.Tracer = qlog.NewTracer(func(_ logging.Perspective, connID []byte) io.WriteCloser {
|
||||
filename := fmt.Sprintf("server_%x.qlog", connID)
|
||||
|
|
2
go.mod
2
go.mod
|
@ -7,7 +7,6 @@ require (
|
|||
github.com/francoispqt/gojay v1.2.13
|
||||
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/marten-seemann/qpack v0.2.1
|
||||
github.com/marten-seemann/qtls v0.10.0
|
||||
github.com/marten-seemann/qtls-go1-15 v0.1.1
|
||||
|
@ -18,6 +17,5 @@ require (
|
|||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299
|
||||
google.golang.org/protobuf v1.23.0
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
)
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/handshake"
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
)
|
||||
|
||||
// RetireBugBackwardsCompatibilityMode controls a backwards compatibility mode, necessary due to a bug in
|
||||
|
@ -262,10 +261,6 @@ type Config struct {
|
|||
StatelessResetKey []byte
|
||||
// KeepAlive defines whether this peer will periodically send a packet to keep the connection alive.
|
||||
KeepAlive bool
|
||||
// QUIC Event Tracer (see https://github.com/google/quic-trace).
|
||||
// Warning: Support for quic-trace will soon be dropped in favor of qlog.
|
||||
// It is disabled by default. Use the "quictrace" build tag to enable (e.g. go build -tags quictrace).
|
||||
QuicTracer quictrace.Tracer
|
||||
Tracer logging.Tracer
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
)
|
||||
|
||||
// NewAckHandler creates a new SentPacketHandler and a new ReceivedPacketHandler
|
||||
|
@ -12,11 +11,10 @@ func NewAckHandler(
|
|||
initialPacketNumber protocol.PacketNumber,
|
||||
rttStats *utils.RTTStats,
|
||||
pers protocol.Perspective,
|
||||
traceCallback func(quictrace.Event),
|
||||
tracer logging.ConnectionTracer,
|
||||
logger utils.Logger,
|
||||
version protocol.VersionNumber,
|
||||
) (SentPacketHandler, ReceivedPacketHandler) {
|
||||
sph := newSentPacketHandler(initialPacketNumber, rttStats, pers, traceCallback, tracer, logger)
|
||||
sph := newSentPacketHandler(initialPacketNumber, rttStats, pers, tracer, logger)
|
||||
return sph, newReceivedPacketHandler(sph, rttStats, logger, version)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
)
|
||||
|
||||
// A Packet is a packet
|
||||
|
@ -48,9 +47,6 @@ type SentPacketHandler interface {
|
|||
|
||||
GetLossDetectionTimeout() time.Time
|
||||
OnLossDetectionTimeout() error
|
||||
|
||||
// report some congestion statistics. For tracing only.
|
||||
GetStats() *quictrace.TransportState
|
||||
}
|
||||
|
||||
type sentPacketTracker interface {
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -85,7 +84,6 @@ type sentPacketHandler struct {
|
|||
|
||||
perspective protocol.Perspective
|
||||
|
||||
traceCallback func(quictrace.Event)
|
||||
tracer logging.ConnectionTracer
|
||||
logger utils.Logger
|
||||
}
|
||||
|
@ -99,7 +97,6 @@ func newSentPacketHandler(
|
|||
initialPacketNumber protocol.PacketNumber,
|
||||
rttStats *utils.RTTStats,
|
||||
pers protocol.Perspective,
|
||||
traceCallback func(quictrace.Event),
|
||||
tracer logging.ConnectionTracer,
|
||||
logger utils.Logger,
|
||||
) *sentPacketHandler {
|
||||
|
@ -119,7 +116,6 @@ func newSentPacketHandler(
|
|||
rttStats: rttStats,
|
||||
congestion: congestion,
|
||||
perspective: pers,
|
||||
traceCallback: traceCallback,
|
||||
tracer: tracer,
|
||||
logger: logger,
|
||||
}
|
||||
|
@ -559,21 +555,6 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
|
|||
h.queueFramesForRetransmission(p)
|
||||
// the bytes in flight need to be reduced no matter if this packet will be retransmitted
|
||||
h.removeFromBytesInFlight(p)
|
||||
if h.traceCallback != nil {
|
||||
frames := make([]wire.Frame, 0, len(p.Frames))
|
||||
for _, f := range p.Frames {
|
||||
frames = append(frames, f.Frame)
|
||||
}
|
||||
h.traceCallback(quictrace.Event{
|
||||
Time: now,
|
||||
EventType: quictrace.PacketLost,
|
||||
EncryptionLevel: p.EncryptionLevel,
|
||||
PacketNumber: p.PacketNumber,
|
||||
PacketSize: p.Length,
|
||||
Frames: frames,
|
||||
TransportState: h.GetStats(),
|
||||
})
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
@ -804,15 +785,3 @@ func (h *sentPacketHandler) SetHandshakeConfirmed() {
|
|||
// Make sure the timer is armed now, if necessary.
|
||||
h.setLossDetectionTimer()
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) GetStats() *quictrace.TransportState {
|
||||
return &quictrace.TransportState{
|
||||
MinRTT: h.rttStats.MinRTT(),
|
||||
SmoothedRTT: h.rttStats.SmoothedRTT(),
|
||||
LatestRTT: h.rttStats.LatestRTT(),
|
||||
BytesInFlight: h.bytesInFlight,
|
||||
CongestionWindow: h.congestion.GetCongestionWindow(),
|
||||
InSlowStart: h.congestion.InSlowStart(),
|
||||
InRecovery: h.congestion.InRecovery(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
JustBeforeEach(func() {
|
||||
lostPackets = nil
|
||||
rttStats := utils.NewRTTStats()
|
||||
handler = newSentPacketHandler(42, rttStats, perspective, nil, nil, utils.DefaultLogger)
|
||||
handler = newSentPacketHandler(42, rttStats, perspective, nil, utils.DefaultLogger)
|
||||
streamFrame = wire.StreamFrame{
|
||||
StreamID: 5,
|
||||
Data: []byte{0x13, 0x37},
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
ackhandler "github.com/lucas-clemente/quic-go/internal/ackhandler"
|
||||
protocol "github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
wire "github.com/lucas-clemente/quic-go/internal/wire"
|
||||
quictrace "github.com/lucas-clemente/quic-go/quictrace"
|
||||
)
|
||||
|
||||
// MockSentPacketHandler is a mock of SentPacketHandler interface
|
||||
|
@ -64,20 +63,6 @@ func (mr *MockSentPacketHandlerMockRecorder) GetLossDetectionTimeout() *gomock.C
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLossDetectionTimeout", reflect.TypeOf((*MockSentPacketHandler)(nil).GetLossDetectionTimeout))
|
||||
}
|
||||
|
||||
// GetStats mocks base method
|
||||
func (m *MockSentPacketHandler) GetStats() *quictrace.TransportState {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetStats")
|
||||
ret0, _ := ret[0].(*quictrace.TransportState)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetStats indicates an expected call of GetStats
|
||||
func (mr *MockSentPacketHandlerMockRecorder) GetStats() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStats", reflect.TypeOf((*MockSentPacketHandler)(nil).GetStats))
|
||||
}
|
||||
|
||||
// HasPacingBudget mocks base method
|
||||
func (m *MockSentPacketHandler) HasPacingBudget() bool {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
# quic-trace Adapter
|
||||
|
||||
This is an experimental implementation of the log format consumed by [quic-trace](https://github.com/google/quic-trace).
|
||||
|
||||
At this moment, this package comes with no API stability whatsoever.
|
|
@ -1,50 +0,0 @@
|
|||
package quictrace
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
// A Tracer traces a QUIC connection
|
||||
type Tracer interface {
|
||||
Trace(protocol.ConnectionID, Event)
|
||||
GetAllTraces() map[string][]byte
|
||||
}
|
||||
|
||||
// EventType is the type of an event
|
||||
type EventType uint8
|
||||
|
||||
const (
|
||||
// PacketSent means that a packet was sent
|
||||
PacketSent EventType = 1 + iota
|
||||
// PacketReceived means that a packet was received
|
||||
PacketReceived
|
||||
// PacketLost means that a packet was lost
|
||||
PacketLost
|
||||
)
|
||||
|
||||
// Event is a quic-traceable event
|
||||
type Event struct {
|
||||
Time time.Time
|
||||
EventType EventType
|
||||
|
||||
TransportState *TransportState
|
||||
EncryptionLevel protocol.EncryptionLevel
|
||||
PacketNumber protocol.PacketNumber
|
||||
PacketSize protocol.ByteCount
|
||||
Frames []wire.Frame
|
||||
}
|
||||
|
||||
// TransportState contains some transport and congestion statistics
|
||||
type TransportState struct {
|
||||
MinRTT time.Duration
|
||||
SmoothedRTT time.Duration
|
||||
LatestRTT time.Duration
|
||||
|
||||
BytesInFlight protocol.ByteCount
|
||||
CongestionWindow protocol.ByteCount
|
||||
InSlowStart bool
|
||||
InRecovery bool
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// +build !quictrace
|
||||
|
||||
package quictrace
|
||||
|
||||
import "github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
|
||||
// NewTracer returns a new Tracer that doesn't do anything.
|
||||
func NewTracer() Tracer {
|
||||
return &nullTracer{}
|
||||
}
|
||||
|
||||
type nullTracer struct{}
|
||||
|
||||
var _ Tracer = &nullTracer{}
|
||||
|
||||
func (t *nullTracer) Trace(protocol.ConnectionID, Event) {}
|
||||
func (t *nullTracer) GetAllTraces() map[string][]byte { return make(map[string][]byte) }
|
File diff suppressed because it is too large
Load diff
|
@ -1,206 +0,0 @@
|
|||
// copied from https://github.com/google/quic-trace/
|
||||
// Only changed the package name.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package pb;
|
||||
|
||||
option go_package = ".;pb";
|
||||
|
||||
enum FrameType {
|
||||
UNKNOWN_FRAME = 0;
|
||||
|
||||
STREAM = 1;
|
||||
ACK = 2;
|
||||
RESET_STREAM = 3;
|
||||
CONNECTION_CLOSE = 4;
|
||||
MAX_DATA = 5;
|
||||
MAX_STREAM_DATA = 6;
|
||||
PING = 7;
|
||||
BLOCKED = 8;
|
||||
STREAM_BLOCKED = 9;
|
||||
PADDING = 10;
|
||||
CRYPTO = 11;
|
||||
};
|
||||
|
||||
// Metadata for STREAM frames.
|
||||
message StreamFrameInfo {
|
||||
optional uint64 stream_id = 1;
|
||||
optional bool fin = 2;
|
||||
optional uint64 length = 3;
|
||||
optional uint64 offset = 4;
|
||||
};
|
||||
|
||||
// Metadata for CRYPTO frames.
|
||||
message CryptoFrameInfo {
|
||||
optional uint64 length = 1;
|
||||
optional uint64 offset = 2;
|
||||
}
|
||||
|
||||
// The intervals are closed, i.e. the interval represented here is
|
||||
// [first_packet, last_packet].
|
||||
message AckBlock {
|
||||
optional uint64 first_packet = 1;
|
||||
optional uint64 last_packet = 2;
|
||||
};
|
||||
|
||||
// Metadata for ACK frames.
|
||||
message AckInfo {
|
||||
repeated AckBlock acked_packets = 1;
|
||||
optional uint64 ack_delay_us = 2;
|
||||
};
|
||||
|
||||
// Metadata for RST_STREAM frames.
|
||||
message ResetStreamInfo {
|
||||
optional uint64 stream_id = 1;
|
||||
optional uint32 application_error_code = 2;
|
||||
optional uint64 final_offset = 3;
|
||||
};
|
||||
|
||||
// Metadata for CONNECTION_CLOSE frames.
|
||||
// Close_type will indicate whether the close is a Google QUIC close,
|
||||
// IETF QUIC Transport CONNECTION CLOSE, or IETF QUIC Application
|
||||
// Connection Close, frame.
|
||||
enum CloseType {
|
||||
GOOGLE_QUIC_CONNECTION_CLOSE = 0;
|
||||
IETF_QUIC_TRANSPORT_CONNECTION_CLOSE = 1;
|
||||
IETF_QUIC_APPLICATION_CONNECTION_CLOSE = 2;
|
||||
};
|
||||
|
||||
// Metadata for CONNECTION_CLOSE/APPLICATION_CLOSE frames.
|
||||
message CloseInfo {
|
||||
optional uint32 error_code = 1;
|
||||
optional string reason_phrase = 2;
|
||||
optional CloseType close_type = 3;
|
||||
optional uint64 transport_close_frame_type = 4;
|
||||
};
|
||||
|
||||
// Metadata for MAX_DATA/MAX_STREAM_DATA frames.
|
||||
message FlowControlInfo {
|
||||
optional uint64 max_data = 1;
|
||||
optional uint64 stream_id = 2;
|
||||
};
|
||||
|
||||
// A message representing a frame, either sent or received.
|
||||
message Frame {
|
||||
optional FrameType frame_type = 1;
|
||||
|
||||
optional StreamFrameInfo stream_frame_info = 2;
|
||||
optional AckInfo ack_info = 3;
|
||||
optional ResetStreamInfo reset_stream_info = 4;
|
||||
optional CloseInfo close_info = 5;
|
||||
optional FlowControlInfo flow_control_info = 6;
|
||||
optional CryptoFrameInfo crypto_frame_info = 7;
|
||||
};
|
||||
|
||||
// Metadata that represents transport stack's understanding of the current state
|
||||
// of the transport channel.
|
||||
message TransportState {
|
||||
optional uint64 min_rtt_us = 1;
|
||||
// Smoothed RTT, usually computed using EWMA.
|
||||
optional uint64 smoothed_rtt_us = 2;
|
||||
// The latest RTT measureent available.
|
||||
optional uint64 last_rtt_us = 3;
|
||||
|
||||
optional uint64 in_flight_bytes = 4;
|
||||
optional uint64 cwnd_bytes = 5;
|
||||
// Pacing rate, in bits per second.
|
||||
optional uint64 pacing_rate_bps = 6;
|
||||
|
||||
// Any arbitrary information about congestion control state that is not
|
||||
// representable via parameters above.
|
||||
optional string congestion_control_state = 7;
|
||||
};
|
||||
|
||||
// Documents external network parameters supplied to the sender. Typically not
|
||||
// all of those would be supplied (e.g. if bandwidth and RTT are supplied, you
|
||||
// can infer the suggested CWND), but there are no restrictions on which fields
|
||||
// may or may not be set.
|
||||
message ExternalNetworkParameters {
|
||||
optional uint64 bandwidth_bps = 1; // in bits per second
|
||||
optional uint64 rtt_us = 2;
|
||||
optional uint64 cwnd_bytes = 3;
|
||||
};
|
||||
|
||||
enum EncryptionLevel {
|
||||
ENCRYPTION_UNKNOWN = 0;
|
||||
|
||||
ENCRYPTION_INITIAL = 1;
|
||||
ENCRYPTION_0RTT = 2;
|
||||
ENCRYPTION_1RTT = 3;
|
||||
ENCRYPTION_HANDSHAKE = 4;
|
||||
};
|
||||
|
||||
enum EventType {
|
||||
UNKNOWN_EVENT = 0;
|
||||
|
||||
PACKET_SENT = 1;
|
||||
PACKET_RECEIVED = 2;
|
||||
PACKET_LOST = 3;
|
||||
|
||||
// An APPLICATION_LIMITED event occurs when the sender is capable of sending
|
||||
// more data and tries to send it, but discovers that it does not have any
|
||||
// outstanding data to send. Such events are important to some congestion
|
||||
// control algorithms (for example, BBR) since they are trying to measure the
|
||||
// largest achievable throughput, but it is impossible to measure it when the
|
||||
// application does not send anything.
|
||||
APPLICATION_LIMITED = 4;
|
||||
|
||||
// Record when external information about expected network conditions
|
||||
// (available bandwidth, RTT, congestion window, etc) is supplied to the
|
||||
// sender.
|
||||
EXTERNAL_PARAMETERS = 5;
|
||||
};
|
||||
|
||||
enum TransmissionReason {
|
||||
// Indicates that there was not any particular special reason the packet was
|
||||
// sent.
|
||||
NORMAL_TRANSMISSION = 0;
|
||||
|
||||
// Indicates that the packet sent is a tail loss probe, cf.
|
||||
// https://tools.ietf.org/html/draft-ietf-quic-recovery-14#section-4.3.2
|
||||
TAIL_LOSS_PROBE = 1;
|
||||
|
||||
// Indicates that the packet is sent due to retransmission timeout, cf
|
||||
// https://tools.ietf.org/html/draft-ietf-quic-recovery-14#section-4.3.3
|
||||
RTO_TRANSMISSION = 2;
|
||||
|
||||
// Indicates that the packet is sent in order to probe whether there is extra
|
||||
// bandwidth available in cases where the sender needs an estimate of
|
||||
// available bandwidth, but the application does not provide enough data for
|
||||
// such estimate to become naturally available. This is usually only used in
|
||||
// real-time protocols.
|
||||
PROBING_TRANSMISSION = 3;
|
||||
};
|
||||
|
||||
// An event that has occurred over duration of the connection.
|
||||
message Event {
|
||||
optional uint64 time_us = 1;
|
||||
optional EventType event_type = 2;
|
||||
|
||||
optional uint64 packet_number = 3;
|
||||
repeated Frame frames = 4;
|
||||
optional uint64 packet_size = 5;
|
||||
optional EncryptionLevel encryption_level = 6;
|
||||
// State of the transport stack after the event has happened.
|
||||
optional TransportState transport_state = 7;
|
||||
// For event_type = EXTERNAL_PARAMETERS, record parameters specified.
|
||||
optional ExternalNetworkParameters external_network_parameters = 8;
|
||||
|
||||
// For sent packets, indicate if there is a special reason for why the packet
|
||||
// in question was transmitted.
|
||||
optional TransmissionReason transmission_reason = 9
|
||||
[default = NORMAL_TRANSMISSION];
|
||||
};
|
||||
|
||||
message Trace {
|
||||
// QUIC version tag, as represented on wire. Should be always 4 bytes long.
|
||||
optional bytes protocol_version = 1;
|
||||
|
||||
// Source and destination connection ID. If multiple connection IDs are used,
|
||||
// record the first one used with short-form header.
|
||||
optional bytes source_connection_id = 2;
|
||||
optional bytes destination_connection_id = 3;
|
||||
|
||||
repeated Event events = 4;
|
||||
};
|
|
@ -1,205 +0,0 @@
|
|||
// +build quictrace
|
||||
|
||||
package quictrace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
"github.com/lucas-clemente/quic-go/quictrace/pb"
|
||||
)
|
||||
|
||||
type traceEvent struct {
|
||||
connID protocol.ConnectionID
|
||||
ev Event
|
||||
}
|
||||
|
||||
// A tracer is used to trace a QUIC connection
|
||||
type tracer struct {
|
||||
eventQueue chan traceEvent
|
||||
|
||||
events map[string] /* conn ID */ []traceEvent
|
||||
}
|
||||
|
||||
var _ Tracer = &tracer{}
|
||||
|
||||
// NewTracer creates a new Tracer
|
||||
func NewTracer() Tracer {
|
||||
qt := &tracer{
|
||||
eventQueue: make(chan traceEvent, 1<<10),
|
||||
events: make(map[string][]traceEvent),
|
||||
}
|
||||
go qt.run()
|
||||
return qt
|
||||
}
|
||||
|
||||
// Trace traces an event
|
||||
func (t *tracer) Trace(connID protocol.ConnectionID, ev Event) {
|
||||
t.eventQueue <- traceEvent{connID: connID, ev: ev}
|
||||
}
|
||||
|
||||
func (t *tracer) run() {
|
||||
for tev := range t.eventQueue {
|
||||
key := string(tev.connID)
|
||||
if _, ok := t.events[key]; !ok {
|
||||
t.events[key] = make([]traceEvent, 0, 10*1<<10)
|
||||
}
|
||||
t.events[key] = append(t.events[key], tev)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tracer) GetAllTraces() map[string][]byte {
|
||||
traces := make(map[string][]byte)
|
||||
for connID := range t.events {
|
||||
data, err := t.emitByConnIDAsString(connID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
traces[connID] = data
|
||||
}
|
||||
return traces
|
||||
}
|
||||
|
||||
// Emit emits the serialized protobuf that will be consumed by quic-trace
|
||||
func (t *tracer) Emit(connID protocol.ConnectionID) ([]byte, error) {
|
||||
return t.emitByConnIDAsString(string(connID))
|
||||
}
|
||||
|
||||
func (t *tracer) emitByConnIDAsString(connID string) ([]byte, error) {
|
||||
events, ok := t.events[connID]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no trace found for connection ID %s", connID)
|
||||
}
|
||||
trace := &pb.Trace{
|
||||
DestinationConnectionId: []byte{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
SourceConnectionId: []byte{1, 2, 3, 4, 5, 6, 7, 8},
|
||||
ProtocolVersion: []byte{0xff, 0, 0, 19},
|
||||
Events: make([]*pb.Event, len(events)),
|
||||
}
|
||||
var startTime time.Time
|
||||
for i, ev := range events {
|
||||
event := ev.ev
|
||||
if i == 0 {
|
||||
startTime = event.Time
|
||||
}
|
||||
|
||||
packetNumber := uint64(event.PacketNumber)
|
||||
packetSize := uint64(event.PacketSize)
|
||||
|
||||
trace.Events[i] = &pb.Event{
|
||||
TimeUs: durationToUs(event.Time.Sub(startTime)),
|
||||
EventType: getEventType(event.EventType),
|
||||
PacketSize: &packetSize,
|
||||
PacketNumber: &packetNumber,
|
||||
TransportState: getTransportState(event.TransportState),
|
||||
EncryptionLevel: getEncryptionLevel(event.EncryptionLevel),
|
||||
Frames: getFrames(event.Frames),
|
||||
}
|
||||
}
|
||||
delete(t.events, connID)
|
||||
return proto.Marshal(trace)
|
||||
}
|
||||
|
||||
func getEventType(evType EventType) *pb.EventType {
|
||||
var t pb.EventType
|
||||
switch evType {
|
||||
case PacketSent:
|
||||
t = pb.EventType_PACKET_SENT
|
||||
case PacketReceived:
|
||||
t = pb.EventType_PACKET_RECEIVED
|
||||
case PacketLost:
|
||||
t = pb.EventType_PACKET_LOST
|
||||
default:
|
||||
panic("unknown event type")
|
||||
}
|
||||
return &t
|
||||
}
|
||||
|
||||
func getEncryptionLevel(encLevel protocol.EncryptionLevel) *pb.EncryptionLevel {
|
||||
enc := pb.EncryptionLevel_ENCRYPTION_UNKNOWN
|
||||
switch encLevel {
|
||||
case protocol.EncryptionInitial:
|
||||
enc = pb.EncryptionLevel_ENCRYPTION_INITIAL
|
||||
case protocol.EncryptionHandshake:
|
||||
enc = pb.EncryptionLevel_ENCRYPTION_HANDSHAKE
|
||||
case protocol.Encryption0RTT:
|
||||
enc = pb.EncryptionLevel_ENCRYPTION_0RTT
|
||||
case protocol.Encryption1RTT:
|
||||
enc = pb.EncryptionLevel_ENCRYPTION_1RTT
|
||||
}
|
||||
return &enc
|
||||
}
|
||||
|
||||
func getFrames(wframes []wire.Frame) []*pb.Frame {
|
||||
streamFrameType := pb.FrameType_STREAM
|
||||
cryptoFrameType := pb.FrameType_CRYPTO
|
||||
ackFrameType := pb.FrameType_ACK
|
||||
var frames []*pb.Frame
|
||||
for _, frame := range wframes {
|
||||
switch f := frame.(type) {
|
||||
case *wire.CryptoFrame:
|
||||
offset := uint64(f.Offset)
|
||||
length := uint64(len(f.Data))
|
||||
frames = append(frames, &pb.Frame{
|
||||
FrameType: &cryptoFrameType,
|
||||
CryptoFrameInfo: &pb.CryptoFrameInfo{
|
||||
Offset: &offset,
|
||||
Length: &length,
|
||||
},
|
||||
})
|
||||
case *wire.StreamFrame:
|
||||
streamID := uint64(f.StreamID)
|
||||
offset := uint64(f.Offset)
|
||||
length := uint64(f.DataLen())
|
||||
frames = append(frames, &pb.Frame{
|
||||
FrameType: &streamFrameType,
|
||||
StreamFrameInfo: &pb.StreamFrameInfo{
|
||||
StreamId: &streamID,
|
||||
Offset: &offset,
|
||||
Length: &length,
|
||||
},
|
||||
})
|
||||
case *wire.AckFrame:
|
||||
var ackedPackets []*pb.AckBlock
|
||||
for _, ackBlock := range f.AckRanges {
|
||||
firstPacket := uint64(ackBlock.Smallest)
|
||||
lastPacket := uint64(ackBlock.Largest)
|
||||
ackedPackets = append(ackedPackets, &pb.AckBlock{
|
||||
FirstPacket: &firstPacket,
|
||||
LastPacket: &lastPacket,
|
||||
})
|
||||
}
|
||||
frames = append(frames, &pb.Frame{
|
||||
FrameType: &ackFrameType,
|
||||
AckInfo: &pb.AckInfo{
|
||||
AckDelayUs: durationToUs(f.DelayTime),
|
||||
AckedPackets: ackedPackets,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
return frames
|
||||
}
|
||||
|
||||
func getTransportState(state *TransportState) *pb.TransportState {
|
||||
bytesInFlight := uint64(state.BytesInFlight)
|
||||
congestionWindow := uint64(state.CongestionWindow)
|
||||
ccs := fmt.Sprintf("InSlowStart: %t, InRecovery: %t", state.InSlowStart, state.InRecovery)
|
||||
return &pb.TransportState{
|
||||
MinRttUs: durationToUs(state.MinRTT),
|
||||
SmoothedRttUs: durationToUs(state.SmoothedRTT),
|
||||
LastRttUs: durationToUs(state.LatestRTT),
|
||||
InFlightBytes: &bytesInFlight,
|
||||
CwndBytes: &congestionWindow,
|
||||
CongestionControlState: &ccs,
|
||||
}
|
||||
}
|
||||
|
||||
func durationToUs(d time.Duration) *uint64 {
|
||||
dur := uint64(d / 1000)
|
||||
return &dur
|
||||
}
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
|
||||
|
@ -136,7 +135,6 @@ var _ = Describe("Server", func() {
|
|||
It("setups with the right values", func() {
|
||||
supportedVersions := []protocol.VersionNumber{protocol.VersionTLS}
|
||||
acceptToken := func(_ net.Addr, _ *Token) bool { return true }
|
||||
tracer := quictrace.NewTracer()
|
||||
config := Config{
|
||||
Versions: supportedVersions,
|
||||
AcceptToken: acceptToken,
|
||||
|
@ -144,7 +142,6 @@ var _ = Describe("Server", func() {
|
|||
MaxIdleTimeout: 42 * time.Minute,
|
||||
KeepAlive: true,
|
||||
StatelessResetKey: []byte("foobar"),
|
||||
QuicTracer: tracer,
|
||||
}
|
||||
ln, err := Listen(conn, tlsConf, &config)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -156,7 +153,6 @@ var _ = Describe("Server", func() {
|
|||
Expect(reflect.ValueOf(server.config.AcceptToken)).To(Equal(reflect.ValueOf(acceptToken)))
|
||||
Expect(server.config.KeepAlive).To(BeTrue())
|
||||
Expect(server.config.StatelessResetKey).To(Equal([]byte("foobar")))
|
||||
Expect(server.config.QuicTracer).To(Equal(tracer))
|
||||
// stop the listener
|
||||
Expect(ln.Close()).To(Succeed())
|
||||
})
|
||||
|
|
63
session.go
63
session.go
|
@ -21,7 +21,6 @@ import (
|
|||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
"github.com/lucas-clemente/quic-go/logging"
|
||||
"github.com/lucas-clemente/quic-go/quictrace"
|
||||
)
|
||||
|
||||
type unpacker interface {
|
||||
|
@ -205,8 +204,6 @@ type session struct {
|
|||
keepAlivePingSent bool
|
||||
keepAliveInterval time.Duration
|
||||
|
||||
traceCallback func(quictrace.Event)
|
||||
|
||||
logID string
|
||||
tracer logging.ConnectionTracer
|
||||
logger utils.Logger
|
||||
|
@ -275,7 +272,6 @@ var newSession = func(
|
|||
0,
|
||||
s.rttStats,
|
||||
s.perspective,
|
||||
s.traceCallback,
|
||||
s.tracer,
|
||||
s.logger,
|
||||
s.version,
|
||||
|
@ -398,7 +394,6 @@ var newClientSession = func(
|
|||
initialPacketNumber,
|
||||
s.rttStats,
|
||||
s.perspective,
|
||||
s.traceCallback,
|
||||
s.tracer,
|
||||
s.logger,
|
||||
s.version,
|
||||
|
@ -507,12 +502,6 @@ func (s *session) preSetup() {
|
|||
s.sessionCreationTime = now
|
||||
|
||||
s.windowUpdateQueue = newWindowUpdateQueue(s.streamsMap, s.connFlowController, s.framer.QueueControlFrame)
|
||||
|
||||
if s.config.QuicTracer != nil {
|
||||
s.traceCallback = func(ev quictrace.Event) {
|
||||
s.config.QuicTracer.Trace(s.origDestConnID, ev)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// run the session main loop
|
||||
|
@ -1030,8 +1019,6 @@ func (s *session) handleUnpackedPacket(
|
|||
// Only used for tracing.
|
||||
// If we're not tracing, this slice will always remain empty.
|
||||
var frames []wire.Frame
|
||||
var transportState *quictrace.TransportState
|
||||
|
||||
r := bytes.NewReader(packet.data)
|
||||
var isAckEliciting bool
|
||||
for {
|
||||
|
@ -1045,30 +1032,17 @@ func (s *session) handleUnpackedPacket(
|
|||
if ackhandler.IsFrameAckEliciting(frame) {
|
||||
isAckEliciting = true
|
||||
}
|
||||
if s.traceCallback != nil || s.tracer != nil {
|
||||
frames = append(frames, frame)
|
||||
}
|
||||
// Only process frames now if we're not logging.
|
||||
// If we're logging, we need to make sure that the packet_received event is logged first.
|
||||
if s.tracer == nil {
|
||||
if err := s.handleFrame(frame, packet.encryptionLevel, packet.hdr.DestConnectionID); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
frames = append(frames, frame)
|
||||
}
|
||||
}
|
||||
|
||||
if s.traceCallback != nil {
|
||||
transportState = s.sentPacketHandler.GetStats()
|
||||
s.traceCallback(quictrace.Event{
|
||||
Time: rcvTime,
|
||||
EventType: quictrace.PacketReceived,
|
||||
TransportState: transportState,
|
||||
EncryptionLevel: packet.encryptionLevel,
|
||||
PacketNumber: packet.packetNumber,
|
||||
PacketSize: protocol.ByteCount(len(packet.data)),
|
||||
Frames: frames,
|
||||
})
|
||||
}
|
||||
if s.tracer != nil {
|
||||
fs := make([]logging.Frame, len(frames))
|
||||
for i, frame := range frames {
|
||||
|
@ -1556,7 +1530,7 @@ func (s *session) sendPacket() (bool, error) {
|
|||
if err != nil || packet == nil {
|
||||
return false, err
|
||||
}
|
||||
s.logCoalescedPacket(now, packet)
|
||||
s.logCoalescedPacket(packet)
|
||||
for _, p := range packet.packets {
|
||||
if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {
|
||||
s.firstAckElicitingPacketAfterIdleSentTime = now
|
||||
|
@ -1580,7 +1554,7 @@ func (s *session) sendPackedPacket(packet *packedPacket) {
|
|||
if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && packet.IsAckEliciting() {
|
||||
s.firstAckElicitingPacketAfterIdleSentTime = now
|
||||
}
|
||||
s.logPacket(now, packet)
|
||||
s.logPacket(packet)
|
||||
s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket(time.Now(), s.retransmissionQueue))
|
||||
s.connIDManager.SentPacket()
|
||||
s.sendQueue.Send(packet.buffer)
|
||||
|
@ -1591,11 +1565,11 @@ func (s *session) sendConnectionClose(quicErr *qerr.QuicError) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.logCoalescedPacket(time.Now(), packet)
|
||||
s.logCoalescedPacket(packet)
|
||||
return packet.buffer.Data, s.conn.Write(packet.buffer.Data)
|
||||
}
|
||||
|
||||
func (s *session) logPacketContents(now time.Time, p *packetContents) {
|
||||
func (s *session) logPacketContents(p *packetContents) {
|
||||
// tracing
|
||||
if s.tracer != nil {
|
||||
frames := make([]logging.Frame, 0, len(p.frames))
|
||||
|
@ -1605,23 +1579,6 @@ func (s *session) logPacketContents(now time.Time, p *packetContents) {
|
|||
s.tracer.SentPacket(p.header, p.length, p.ack, frames)
|
||||
}
|
||||
|
||||
// quic-trace
|
||||
if s.traceCallback != nil {
|
||||
frames := make([]wire.Frame, 0, len(p.frames))
|
||||
for _, f := range p.frames {
|
||||
frames = append(frames, f.Frame)
|
||||
}
|
||||
s.traceCallback(quictrace.Event{
|
||||
Time: now,
|
||||
EventType: quictrace.PacketSent,
|
||||
TransportState: s.sentPacketHandler.GetStats(),
|
||||
EncryptionLevel: p.EncryptionLevel(),
|
||||
PacketNumber: p.header.PacketNumber,
|
||||
PacketSize: p.length,
|
||||
Frames: frames,
|
||||
})
|
||||
}
|
||||
|
||||
// quic-go logging
|
||||
if !s.logger.Debug() {
|
||||
return
|
||||
|
@ -1635,7 +1592,7 @@ func (s *session) logPacketContents(now time.Time, p *packetContents) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *session) logCoalescedPacket(now time.Time, packet *coalescedPacket) {
|
||||
func (s *session) logCoalescedPacket(packet *coalescedPacket) {
|
||||
if s.logger.Debug() {
|
||||
if len(packet.packets) > 1 {
|
||||
s.logger.Debugf("-> Sending coalesced packet (%d parts, %d bytes) for connection %s", len(packet.packets), packet.buffer.Len(), s.logID)
|
||||
|
@ -1644,15 +1601,15 @@ func (s *session) logCoalescedPacket(now time.Time, packet *coalescedPacket) {
|
|||
}
|
||||
}
|
||||
for _, p := range packet.packets {
|
||||
s.logPacketContents(now, p)
|
||||
s.logPacketContents(p)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *session) logPacket(now time.Time, packet *packedPacket) {
|
||||
func (s *session) logPacket(packet *packedPacket) {
|
||||
if s.logger.Debug() {
|
||||
s.logger.Debugf("-> Sending packet %d (%d bytes) for connection %s, %s", packet.header.PacketNumber, packet.buffer.Len(), s.logID, packet.EncryptionLevel())
|
||||
}
|
||||
s.logPacketContents(now, packet.packetContents)
|
||||
s.logPacketContents(packet.packetContents)
|
||||
}
|
||||
|
||||
// AcceptStream returns the next stream openend by the peer
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue