github.com/quic-go/quic-go@v0.44.0/qlog/event.go (about) 1 package qlog 2 3 import ( 4 "errors" 5 "fmt" 6 "net" 7 "net/netip" 8 "time" 9 10 "github.com/quic-go/quic-go" 11 "github.com/quic-go/quic-go/internal/protocol" 12 "github.com/quic-go/quic-go/internal/utils" 13 "github.com/quic-go/quic-go/logging" 14 15 "github.com/francoispqt/gojay" 16 ) 17 18 func milliseconds(dur time.Duration) float64 { return float64(dur.Nanoseconds()) / 1e6 } 19 20 type eventDetails interface { 21 Category() category 22 Name() string 23 gojay.MarshalerJSONObject 24 } 25 26 type event struct { 27 RelativeTime time.Duration 28 eventDetails 29 } 30 31 var _ gojay.MarshalerJSONObject = event{} 32 33 func (e event) IsNil() bool { return false } 34 func (e event) MarshalJSONObject(enc *gojay.Encoder) { 35 enc.Float64Key("time", milliseconds(e.RelativeTime)) 36 enc.StringKey("name", e.Category().String()+":"+e.Name()) 37 enc.ObjectKey("data", e.eventDetails) 38 } 39 40 type versions []versionNumber 41 42 func (v versions) IsNil() bool { return false } 43 func (v versions) MarshalJSONArray(enc *gojay.Encoder) { 44 for _, e := range v { 45 enc.AddString(e.String()) 46 } 47 } 48 49 type rawInfo struct { 50 Length logging.ByteCount // full packet length, including header and AEAD authentication tag 51 PayloadLength logging.ByteCount // length of the packet payload, excluding AEAD tag 52 } 53 54 func (i rawInfo) IsNil() bool { return false } 55 func (i rawInfo) MarshalJSONObject(enc *gojay.Encoder) { 56 enc.Uint64Key("length", uint64(i.Length)) 57 enc.Uint64KeyOmitEmpty("payload_length", uint64(i.PayloadLength)) 58 } 59 60 type eventConnectionStarted struct { 61 SrcAddr *net.UDPAddr 62 DestAddr *net.UDPAddr 63 64 SrcConnectionID protocol.ConnectionID 65 DestConnectionID protocol.ConnectionID 66 } 67 68 var _ eventDetails = &eventConnectionStarted{} 69 70 func (e eventConnectionStarted) Category() category { return categoryTransport } 71 func (e eventConnectionStarted) Name() string { return "connection_started" } 72 func (e eventConnectionStarted) IsNil() bool { return false } 73 74 func (e eventConnectionStarted) MarshalJSONObject(enc *gojay.Encoder) { 75 if utils.IsIPv4(e.SrcAddr.IP) { 76 enc.StringKey("ip_version", "ipv4") 77 } else { 78 enc.StringKey("ip_version", "ipv6") 79 } 80 enc.StringKey("src_ip", e.SrcAddr.IP.String()) 81 enc.IntKey("src_port", e.SrcAddr.Port) 82 enc.StringKey("dst_ip", e.DestAddr.IP.String()) 83 enc.IntKey("dst_port", e.DestAddr.Port) 84 enc.StringKey("src_cid", e.SrcConnectionID.String()) 85 enc.StringKey("dst_cid", e.DestConnectionID.String()) 86 } 87 88 type eventVersionNegotiated struct { 89 clientVersions, serverVersions []versionNumber 90 chosenVersion versionNumber 91 } 92 93 func (e eventVersionNegotiated) Category() category { return categoryTransport } 94 func (e eventVersionNegotiated) Name() string { return "version_information" } 95 func (e eventVersionNegotiated) IsNil() bool { return false } 96 97 func (e eventVersionNegotiated) MarshalJSONObject(enc *gojay.Encoder) { 98 if len(e.clientVersions) > 0 { 99 enc.ArrayKey("client_versions", versions(e.clientVersions)) 100 } 101 if len(e.serverVersions) > 0 { 102 enc.ArrayKey("server_versions", versions(e.serverVersions)) 103 } 104 enc.StringKey("chosen_version", e.chosenVersion.String()) 105 } 106 107 type eventConnectionClosed struct { 108 e error 109 } 110 111 func (e eventConnectionClosed) Category() category { return categoryTransport } 112 func (e eventConnectionClosed) Name() string { return "connection_closed" } 113 func (e eventConnectionClosed) IsNil() bool { return false } 114 115 func (e eventConnectionClosed) MarshalJSONObject(enc *gojay.Encoder) { 116 var ( 117 statelessResetErr *quic.StatelessResetError 118 handshakeTimeoutErr *quic.HandshakeTimeoutError 119 idleTimeoutErr *quic.IdleTimeoutError 120 applicationErr *quic.ApplicationError 121 transportErr *quic.TransportError 122 versionNegotiationErr *quic.VersionNegotiationError 123 ) 124 switch { 125 case errors.As(e.e, &statelessResetErr): 126 enc.StringKey("owner", ownerRemote.String()) 127 enc.StringKey("trigger", "stateless_reset") 128 enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", statelessResetErr.Token)) 129 case errors.As(e.e, &handshakeTimeoutErr): 130 enc.StringKey("owner", ownerLocal.String()) 131 enc.StringKey("trigger", "handshake_timeout") 132 case errors.As(e.e, &idleTimeoutErr): 133 enc.StringKey("owner", ownerLocal.String()) 134 enc.StringKey("trigger", "idle_timeout") 135 case errors.As(e.e, &applicationErr): 136 owner := ownerLocal 137 if applicationErr.Remote { 138 owner = ownerRemote 139 } 140 enc.StringKey("owner", owner.String()) 141 enc.Uint64Key("application_code", uint64(applicationErr.ErrorCode)) 142 enc.StringKey("reason", applicationErr.ErrorMessage) 143 case errors.As(e.e, &transportErr): 144 owner := ownerLocal 145 if transportErr.Remote { 146 owner = ownerRemote 147 } 148 enc.StringKey("owner", owner.String()) 149 enc.StringKey("connection_code", transportError(transportErr.ErrorCode).String()) 150 enc.StringKey("reason", transportErr.ErrorMessage) 151 case errors.As(e.e, &versionNegotiationErr): 152 enc.StringKey("trigger", "version_mismatch") 153 } 154 } 155 156 type eventPacketSent struct { 157 Header gojay.MarshalerJSONObject // either a shortHeader or a packetHeader 158 Length logging.ByteCount 159 PayloadLength logging.ByteCount 160 Frames frames 161 IsCoalesced bool 162 ECN logging.ECN 163 Trigger string 164 } 165 166 var _ eventDetails = eventPacketSent{} 167 168 func (e eventPacketSent) Category() category { return categoryTransport } 169 func (e eventPacketSent) Name() string { return "packet_sent" } 170 func (e eventPacketSent) IsNil() bool { return false } 171 172 func (e eventPacketSent) MarshalJSONObject(enc *gojay.Encoder) { 173 enc.ObjectKey("header", e.Header) 174 enc.ObjectKey("raw", rawInfo{Length: e.Length, PayloadLength: e.PayloadLength}) 175 enc.ArrayKeyOmitEmpty("frames", e.Frames) 176 enc.BoolKeyOmitEmpty("is_coalesced", e.IsCoalesced) 177 if e.ECN != logging.ECNUnsupported { 178 enc.StringKey("ecn", ecn(e.ECN).String()) 179 } 180 enc.StringKeyOmitEmpty("trigger", e.Trigger) 181 } 182 183 type eventPacketReceived struct { 184 Header gojay.MarshalerJSONObject // either a shortHeader or a packetHeader 185 Length logging.ByteCount 186 PayloadLength logging.ByteCount 187 Frames frames 188 ECN logging.ECN 189 IsCoalesced bool 190 Trigger string 191 } 192 193 var _ eventDetails = eventPacketReceived{} 194 195 func (e eventPacketReceived) Category() category { return categoryTransport } 196 func (e eventPacketReceived) Name() string { return "packet_received" } 197 func (e eventPacketReceived) IsNil() bool { return false } 198 199 func (e eventPacketReceived) MarshalJSONObject(enc *gojay.Encoder) { 200 enc.ObjectKey("header", e.Header) 201 enc.ObjectKey("raw", rawInfo{Length: e.Length, PayloadLength: e.PayloadLength}) 202 enc.ArrayKeyOmitEmpty("frames", e.Frames) 203 enc.BoolKeyOmitEmpty("is_coalesced", e.IsCoalesced) 204 if e.ECN != logging.ECNUnsupported { 205 enc.StringKey("ecn", ecn(e.ECN).String()) 206 } 207 enc.StringKeyOmitEmpty("trigger", e.Trigger) 208 } 209 210 type eventRetryReceived struct { 211 Header packetHeader 212 } 213 214 func (e eventRetryReceived) Category() category { return categoryTransport } 215 func (e eventRetryReceived) Name() string { return "packet_received" } 216 func (e eventRetryReceived) IsNil() bool { return false } 217 218 func (e eventRetryReceived) MarshalJSONObject(enc *gojay.Encoder) { 219 enc.ObjectKey("header", e.Header) 220 } 221 222 type eventVersionNegotiationReceived struct { 223 Header packetHeaderVersionNegotiation 224 SupportedVersions []versionNumber 225 } 226 227 func (e eventVersionNegotiationReceived) Category() category { return categoryTransport } 228 func (e eventVersionNegotiationReceived) Name() string { return "packet_received" } 229 func (e eventVersionNegotiationReceived) IsNil() bool { return false } 230 231 func (e eventVersionNegotiationReceived) MarshalJSONObject(enc *gojay.Encoder) { 232 enc.ObjectKey("header", e.Header) 233 enc.ArrayKey("supported_versions", versions(e.SupportedVersions)) 234 } 235 236 type eventVersionNegotiationSent struct { 237 Header packetHeaderVersionNegotiation 238 SupportedVersions []versionNumber 239 } 240 241 func (e eventVersionNegotiationSent) Category() category { return categoryTransport } 242 func (e eventVersionNegotiationSent) Name() string { return "packet_sent" } 243 func (e eventVersionNegotiationSent) IsNil() bool { return false } 244 245 func (e eventVersionNegotiationSent) MarshalJSONObject(enc *gojay.Encoder) { 246 enc.ObjectKey("header", e.Header) 247 enc.ArrayKey("supported_versions", versions(e.SupportedVersions)) 248 } 249 250 type eventPacketBuffered struct { 251 PacketType logging.PacketType 252 PacketSize protocol.ByteCount 253 } 254 255 func (e eventPacketBuffered) Category() category { return categoryTransport } 256 func (e eventPacketBuffered) Name() string { return "packet_buffered" } 257 func (e eventPacketBuffered) IsNil() bool { return false } 258 259 func (e eventPacketBuffered) MarshalJSONObject(enc *gojay.Encoder) { 260 //nolint:gosimple 261 enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType, PacketNumber: protocol.InvalidPacketNumber}) 262 enc.ObjectKey("raw", rawInfo{Length: e.PacketSize}) 263 enc.StringKey("trigger", "keys_unavailable") 264 } 265 266 type eventPacketDropped struct { 267 PacketType logging.PacketType 268 PacketSize protocol.ByteCount 269 PacketNumber logging.PacketNumber 270 Trigger packetDropReason 271 } 272 273 func (e eventPacketDropped) Category() category { return categoryTransport } 274 func (e eventPacketDropped) Name() string { return "packet_dropped" } 275 func (e eventPacketDropped) IsNil() bool { return false } 276 277 func (e eventPacketDropped) MarshalJSONObject(enc *gojay.Encoder) { 278 enc.ObjectKey("header", packetHeaderWithType{ 279 PacketType: e.PacketType, 280 PacketNumber: e.PacketNumber, 281 }) 282 enc.ObjectKey("raw", rawInfo{Length: e.PacketSize}) 283 enc.StringKey("trigger", e.Trigger.String()) 284 } 285 286 type metrics struct { 287 MinRTT time.Duration 288 SmoothedRTT time.Duration 289 LatestRTT time.Duration 290 RTTVariance time.Duration 291 292 CongestionWindow protocol.ByteCount 293 BytesInFlight protocol.ByteCount 294 PacketsInFlight int 295 } 296 297 type eventMTUUpdated struct { 298 mtu protocol.ByteCount 299 done bool 300 } 301 302 func (e eventMTUUpdated) Category() category { return categoryRecovery } 303 func (e eventMTUUpdated) Name() string { return "mtu_updated" } 304 func (e eventMTUUpdated) IsNil() bool { return false } 305 306 func (e eventMTUUpdated) MarshalJSONObject(enc *gojay.Encoder) { 307 enc.Uint64Key("mtu", uint64(e.mtu)) 308 enc.BoolKey("done", e.done) 309 } 310 311 type eventMetricsUpdated struct { 312 Last *metrics 313 Current *metrics 314 } 315 316 func (e eventMetricsUpdated) Category() category { return categoryRecovery } 317 func (e eventMetricsUpdated) Name() string { return "metrics_updated" } 318 func (e eventMetricsUpdated) IsNil() bool { return false } 319 320 func (e eventMetricsUpdated) MarshalJSONObject(enc *gojay.Encoder) { 321 if e.Last == nil || e.Last.MinRTT != e.Current.MinRTT { 322 enc.FloatKey("min_rtt", milliseconds(e.Current.MinRTT)) 323 } 324 if e.Last == nil || e.Last.SmoothedRTT != e.Current.SmoothedRTT { 325 enc.FloatKey("smoothed_rtt", milliseconds(e.Current.SmoothedRTT)) 326 } 327 if e.Last == nil || e.Last.LatestRTT != e.Current.LatestRTT { 328 enc.FloatKey("latest_rtt", milliseconds(e.Current.LatestRTT)) 329 } 330 if e.Last == nil || e.Last.RTTVariance != e.Current.RTTVariance { 331 enc.FloatKey("rtt_variance", milliseconds(e.Current.RTTVariance)) 332 } 333 334 if e.Last == nil || e.Last.CongestionWindow != e.Current.CongestionWindow { 335 enc.Uint64Key("congestion_window", uint64(e.Current.CongestionWindow)) 336 } 337 if e.Last == nil || e.Last.BytesInFlight != e.Current.BytesInFlight { 338 enc.Uint64Key("bytes_in_flight", uint64(e.Current.BytesInFlight)) 339 } 340 if e.Last == nil || e.Last.PacketsInFlight != e.Current.PacketsInFlight { 341 enc.Uint64KeyOmitEmpty("packets_in_flight", uint64(e.Current.PacketsInFlight)) 342 } 343 } 344 345 type eventUpdatedPTO struct { 346 Value uint32 347 } 348 349 func (e eventUpdatedPTO) Category() category { return categoryRecovery } 350 func (e eventUpdatedPTO) Name() string { return "metrics_updated" } 351 func (e eventUpdatedPTO) IsNil() bool { return false } 352 353 func (e eventUpdatedPTO) MarshalJSONObject(enc *gojay.Encoder) { 354 enc.Uint32Key("pto_count", e.Value) 355 } 356 357 type eventPacketLost struct { 358 PacketType logging.PacketType 359 PacketNumber protocol.PacketNumber 360 Trigger packetLossReason 361 } 362 363 func (e eventPacketLost) Category() category { return categoryRecovery } 364 func (e eventPacketLost) Name() string { return "packet_lost" } 365 func (e eventPacketLost) IsNil() bool { return false } 366 367 func (e eventPacketLost) MarshalJSONObject(enc *gojay.Encoder) { 368 enc.ObjectKey("header", packetHeaderWithTypeAndPacketNumber{ 369 PacketType: e.PacketType, 370 PacketNumber: e.PacketNumber, 371 }) 372 enc.StringKey("trigger", e.Trigger.String()) 373 } 374 375 type eventKeyUpdated struct { 376 Trigger keyUpdateTrigger 377 KeyType keyType 378 KeyPhase protocol.KeyPhase 379 // we don't log the keys here, so we don't need `old` and `new`. 380 } 381 382 func (e eventKeyUpdated) Category() category { return categorySecurity } 383 func (e eventKeyUpdated) Name() string { return "key_updated" } 384 func (e eventKeyUpdated) IsNil() bool { return false } 385 386 func (e eventKeyUpdated) MarshalJSONObject(enc *gojay.Encoder) { 387 enc.StringKey("trigger", e.Trigger.String()) 388 enc.StringKey("key_type", e.KeyType.String()) 389 if e.KeyType == keyTypeClient1RTT || e.KeyType == keyTypeServer1RTT { 390 enc.Uint64Key("key_phase", uint64(e.KeyPhase)) 391 } 392 } 393 394 type eventKeyDiscarded struct { 395 KeyType keyType 396 KeyPhase protocol.KeyPhase 397 } 398 399 func (e eventKeyDiscarded) Category() category { return categorySecurity } 400 func (e eventKeyDiscarded) Name() string { return "key_discarded" } 401 func (e eventKeyDiscarded) IsNil() bool { return false } 402 403 func (e eventKeyDiscarded) MarshalJSONObject(enc *gojay.Encoder) { 404 if e.KeyType != keyTypeClient1RTT && e.KeyType != keyTypeServer1RTT { 405 enc.StringKey("trigger", "tls") 406 } 407 enc.StringKey("key_type", e.KeyType.String()) 408 if e.KeyType == keyTypeClient1RTT || e.KeyType == keyTypeServer1RTT { 409 enc.Uint64Key("key_phase", uint64(e.KeyPhase)) 410 } 411 } 412 413 type eventTransportParameters struct { 414 Restore bool 415 Owner owner 416 SentBy protocol.Perspective 417 418 OriginalDestinationConnectionID protocol.ConnectionID 419 InitialSourceConnectionID protocol.ConnectionID 420 RetrySourceConnectionID *protocol.ConnectionID 421 422 StatelessResetToken *protocol.StatelessResetToken 423 DisableActiveMigration bool 424 MaxIdleTimeout time.Duration 425 MaxUDPPayloadSize protocol.ByteCount 426 AckDelayExponent uint8 427 MaxAckDelay time.Duration 428 ActiveConnectionIDLimit uint64 429 430 InitialMaxData protocol.ByteCount 431 InitialMaxStreamDataBidiLocal protocol.ByteCount 432 InitialMaxStreamDataBidiRemote protocol.ByteCount 433 InitialMaxStreamDataUni protocol.ByteCount 434 InitialMaxStreamsBidi int64 435 InitialMaxStreamsUni int64 436 437 PreferredAddress *preferredAddress 438 439 MaxDatagramFrameSize protocol.ByteCount 440 } 441 442 func (e eventTransportParameters) Category() category { return categoryTransport } 443 func (e eventTransportParameters) Name() string { 444 if e.Restore { 445 return "parameters_restored" 446 } 447 return "parameters_set" 448 } 449 func (e eventTransportParameters) IsNil() bool { return false } 450 451 func (e eventTransportParameters) MarshalJSONObject(enc *gojay.Encoder) { 452 if !e.Restore { 453 enc.StringKey("owner", e.Owner.String()) 454 if e.SentBy == protocol.PerspectiveServer { 455 enc.StringKey("original_destination_connection_id", e.OriginalDestinationConnectionID.String()) 456 if e.StatelessResetToken != nil { 457 enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", e.StatelessResetToken[:])) 458 } 459 if e.RetrySourceConnectionID != nil { 460 enc.StringKey("retry_source_connection_id", (*e.RetrySourceConnectionID).String()) 461 } 462 } 463 enc.StringKey("initial_source_connection_id", e.InitialSourceConnectionID.String()) 464 } 465 enc.BoolKey("disable_active_migration", e.DisableActiveMigration) 466 enc.FloatKeyOmitEmpty("max_idle_timeout", milliseconds(e.MaxIdleTimeout)) 467 enc.Int64KeyNullEmpty("max_udp_payload_size", int64(e.MaxUDPPayloadSize)) 468 enc.Uint8KeyOmitEmpty("ack_delay_exponent", e.AckDelayExponent) 469 enc.FloatKeyOmitEmpty("max_ack_delay", milliseconds(e.MaxAckDelay)) 470 enc.Uint64KeyOmitEmpty("active_connection_id_limit", e.ActiveConnectionIDLimit) 471 472 enc.Int64KeyOmitEmpty("initial_max_data", int64(e.InitialMaxData)) 473 enc.Int64KeyOmitEmpty("initial_max_stream_data_bidi_local", int64(e.InitialMaxStreamDataBidiLocal)) 474 enc.Int64KeyOmitEmpty("initial_max_stream_data_bidi_remote", int64(e.InitialMaxStreamDataBidiRemote)) 475 enc.Int64KeyOmitEmpty("initial_max_stream_data_uni", int64(e.InitialMaxStreamDataUni)) 476 enc.Int64KeyOmitEmpty("initial_max_streams_bidi", e.InitialMaxStreamsBidi) 477 enc.Int64KeyOmitEmpty("initial_max_streams_uni", e.InitialMaxStreamsUni) 478 479 if e.PreferredAddress != nil { 480 enc.ObjectKey("preferred_address", e.PreferredAddress) 481 } 482 if e.MaxDatagramFrameSize != protocol.InvalidByteCount { 483 enc.Int64Key("max_datagram_frame_size", int64(e.MaxDatagramFrameSize)) 484 } 485 } 486 487 type preferredAddress struct { 488 IPv4, IPv6 netip.AddrPort 489 ConnectionID protocol.ConnectionID 490 StatelessResetToken protocol.StatelessResetToken 491 } 492 493 var _ gojay.MarshalerJSONObject = &preferredAddress{} 494 495 func (a preferredAddress) IsNil() bool { return false } 496 func (a preferredAddress) MarshalJSONObject(enc *gojay.Encoder) { 497 enc.StringKey("ip_v4", a.IPv4.Addr().String()) 498 enc.Uint16Key("port_v4", a.IPv4.Port()) 499 enc.StringKey("ip_v6", a.IPv6.Addr().String()) 500 enc.Uint16Key("port_v6", a.IPv6.Port()) 501 enc.StringKey("connection_id", a.ConnectionID.String()) 502 enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", a.StatelessResetToken)) 503 } 504 505 type eventLossTimerSet struct { 506 TimerType timerType 507 EncLevel protocol.EncryptionLevel 508 Delta time.Duration 509 } 510 511 func (e eventLossTimerSet) Category() category { return categoryRecovery } 512 func (e eventLossTimerSet) Name() string { return "loss_timer_updated" } 513 func (e eventLossTimerSet) IsNil() bool { return false } 514 515 func (e eventLossTimerSet) MarshalJSONObject(enc *gojay.Encoder) { 516 enc.StringKey("event_type", "set") 517 enc.StringKey("timer_type", e.TimerType.String()) 518 enc.StringKey("packet_number_space", encLevelToPacketNumberSpace(e.EncLevel)) 519 enc.Float64Key("delta", milliseconds(e.Delta)) 520 } 521 522 type eventLossTimerExpired struct { 523 TimerType timerType 524 EncLevel protocol.EncryptionLevel 525 } 526 527 func (e eventLossTimerExpired) Category() category { return categoryRecovery } 528 func (e eventLossTimerExpired) Name() string { return "loss_timer_updated" } 529 func (e eventLossTimerExpired) IsNil() bool { return false } 530 531 func (e eventLossTimerExpired) MarshalJSONObject(enc *gojay.Encoder) { 532 enc.StringKey("event_type", "expired") 533 enc.StringKey("timer_type", e.TimerType.String()) 534 enc.StringKey("packet_number_space", encLevelToPacketNumberSpace(e.EncLevel)) 535 } 536 537 type eventLossTimerCanceled struct{} 538 539 func (e eventLossTimerCanceled) Category() category { return categoryRecovery } 540 func (e eventLossTimerCanceled) Name() string { return "loss_timer_updated" } 541 func (e eventLossTimerCanceled) IsNil() bool { return false } 542 543 func (e eventLossTimerCanceled) MarshalJSONObject(enc *gojay.Encoder) { 544 enc.StringKey("event_type", "cancelled") 545 } 546 547 type eventCongestionStateUpdated struct { 548 state congestionState 549 } 550 551 func (e eventCongestionStateUpdated) Category() category { return categoryRecovery } 552 func (e eventCongestionStateUpdated) Name() string { return "congestion_state_updated" } 553 func (e eventCongestionStateUpdated) IsNil() bool { return false } 554 555 func (e eventCongestionStateUpdated) MarshalJSONObject(enc *gojay.Encoder) { 556 enc.StringKey("new", e.state.String()) 557 } 558 559 type eventECNStateUpdated struct { 560 state logging.ECNState 561 trigger logging.ECNStateTrigger 562 } 563 564 func (e eventECNStateUpdated) Category() category { return categoryRecovery } 565 func (e eventECNStateUpdated) Name() string { return "ecn_state_updated" } 566 func (e eventECNStateUpdated) IsNil() bool { return false } 567 568 func (e eventECNStateUpdated) MarshalJSONObject(enc *gojay.Encoder) { 569 enc.StringKey("new", ecnState(e.state).String()) 570 enc.StringKeyOmitEmpty("trigger", ecnStateTrigger(e.trigger).String()) 571 } 572 573 type eventGeneric struct { 574 name string 575 msg string 576 } 577 578 func (e eventGeneric) Category() category { return categoryTransport } 579 func (e eventGeneric) Name() string { return e.name } 580 func (e eventGeneric) IsNil() bool { return false } 581 582 func (e eventGeneric) MarshalJSONObject(enc *gojay.Encoder) { 583 enc.StringKey("details", e.msg) 584 } 585 586 type eventALPNInformation struct { 587 chosenALPN string 588 } 589 590 func (e eventALPNInformation) Category() category { return categoryTransport } 591 func (e eventALPNInformation) Name() string { return "alpn_information" } 592 func (e eventALPNInformation) IsNil() bool { return false } 593 594 func (e eventALPNInformation) MarshalJSONObject(enc *gojay.Encoder) { 595 enc.StringKey("chosen_alpn", e.chosenALPN) 596 }