Skip to content

Commit

Permalink
Adds a parameter to change the idle time of scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiraux committed Feb 21, 2019
1 parent 0df5ced commit e005839
Show file tree
Hide file tree
Showing 27 changed files with 229 additions and 137 deletions.
15 changes: 13 additions & 2 deletions agents/base_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ func (c *ConnectionAgents) Get(name string) Agent {
return c.agents[name]
}

func (c *ConnectionAgents) Has(name string) (Agent, bool) {
a, b := c.agents[name]
return a, b
}

func (c *ConnectionAgents) GetFrameProducingAgents() []FrameProducer {
var agents []FrameProducer
for _, a := range c.agents {
Expand Down Expand Up @@ -144,8 +149,13 @@ func (c *ConnectionAgents) StopAll() {
// This function sends an (CONNECTION|APPLICATION)_CLOSE frame and wait for it to be sent out. Then it stops all the
// agents attached to this connection.
func (c *ConnectionAgents) CloseConnection(quicLayer bool, errorCode uint16, reasonPhrase string) {
a := &ClosingAgent{QuicLayer: quicLayer, ErrorCode: errorCode, ReasonPhrase: reasonPhrase}
c.Add(a)
var a Agent
var present bool
if a, present = c.Has("ClosingAgent"); !present {
a = &ClosingAgent{}
c.Add(a)
}
a.(*ClosingAgent).Close(quicLayer, errorCode, reasonPhrase)
a.Join()
c.StopAll()
}
Expand All @@ -165,5 +175,6 @@ func GetDefaultAgents() []Agent {
&FrameQueueAgent{},
fc,
&StreamAgent{FlowControlAgent: fc},
&ClosingAgent{},
}
}
50 changes: 39 additions & 11 deletions agents/closing_agent.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,60 @@
package agents

import . "github.com/QUIC-Tracker/quic-tracker"
import (
. "github.com/QUIC-Tracker/quic-tracker"
"time"
)

// The ClosingAgent is responsible for queuing an (CONNECTION|APPLICATION)_CLOSE frame and to wait for it to be sent out.
// The ClosingAgent is responsible for keeping track of events that can close the connection, such as the idle timeout.
// It can queue an (CONNECTION|APPLICATION)_CLOSE frame and wait for it to be sent out.
type ClosingAgent struct {
BaseAgent
QuicLayer bool
ErrorCode uint16
ReasonPhrase string
closing bool
conn *Connection
IdleDuration time.Duration
IdleTimeout *time.Timer
}

func (a *ClosingAgent) Run (conn *Connection) {
func (a *ClosingAgent) Run(conn *Connection) {
a.Init("ClosingAgent", conn.OriginalDestinationCID)
a.conn = conn
a.IdleDuration = time.Duration(a.conn.TLSTPHandler.IdleTimeout) * time.Second
a.IdleTimeout = time.NewTimer(a.IdleDuration)

incomingPackets := conn.IncomingPackets.RegisterNewChan(1000)
outgoingPackets := conn.OutgoingPackets.RegisterNewChan(1000)

go func() {
defer a.Logger.Println("Agent terminated")
defer close(a.closed)
defer close(a.conn.ConnectionClosed)

conn.CloseConnection(a.QuicLayer, a.ErrorCode, a.ReasonPhrase)
for {
switch p := (<-outgoingPackets).(type) {
case Framer:
if p.Contains(ConnectionCloseType) || p.Contains(ApplicationCloseType) {
return
select {
case <-incomingPackets:
a.IdleTimeout.Reset(a.IdleDuration)
case i := <-outgoingPackets:
switch p := i.(type) {
case Framer:
if a.closing && (p.Contains(ConnectionCloseType) || p.Contains(ApplicationCloseType)) {
return
}
}
if p := i.(Packet); p.ShouldBeAcknowledged() {
a.IdleTimeout.Reset(a.IdleDuration)
}
case <-a.IdleTimeout.C:
a.closing = true
a.Logger.Printf("Idle timeout of %v reached, closing\n", a.IdleDuration.String())
return
}
}
}()
}

func (a *ClosingAgent) Close(quicLayer bool, errorCode uint16, reasonPhrase string) {
if !a.closing {
a.closing = true
a.conn.CloseConnection(quicLayer, errorCode, reasonPhrase)
}
}
2 changes: 2 additions & 0 deletions bin/test_suite/scenario_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func main() {
outputFile := flag.String("output", "", "The file to write the output to. Output to stdout if not set.")
debug := flag.Bool("debug", false, "Enables debugging information to be printed.")
netInterface := flag.String("interface", "", "The interface to listen to when capturing pcap.")
timeout := flag.Int("timeout", 10, "The amount of time in seconds spent when completing the test. Defaults to 10. When set to 0, the test ends as soon as possible.")
flag.Parse()

if *host == "" || *url == "" || *scenarioName == "" {
Expand All @@ -43,6 +44,7 @@ func main() {
trace.AttachTo(conn)

start := time.Now()
scenario.SetTimer(time.Duration(*timeout) * time.Second)
scenario.Run(conn, trace, *url, *debug)
trace.Duration = uint64(time.Now().Sub(start).Seconds() * 1000)
ip := strings.Replace(conn.ConnectedIp().String(), "[", "", -1)
Expand Down
3 changes: 2 additions & 1 deletion bin/test_suite/test_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func main() {
parallel := flag.Bool("parallel", false, "Runs each scenario against multiple hosts at the same time.")
maxInstances := flag.Int("max-instances", 10, "Limits the number of parallel scenario runs.")
randomise := flag.Bool("randomise", false, "Randomise the execution order of scenarii")
timeout := flag.Int("timeout", 10, "The amount of time in seconds spent when completing a test. Defaults to 10. When set to 0, each test ends as soon as possible.")
debug := flag.Bool("debug", false, "Enables debugging information to be printed.")
flag.Parse()

Expand Down Expand Up @@ -122,7 +123,7 @@ func main() {
crashTrace := GetCrashTrace(scenario, host) // Prepare one just in case
start := time.Now()

args := []string{"run", scenarioRunnerFilename, "-host", host, "-url", url, "-scenario", id, "-interface", *netInterface, "-output", outputFile.Name()}
args := []string{"run", scenarioRunnerFilename, "-host", host, "-url", url, "-scenario", id, "-interface", *netInterface, "-output", outputFile.Name(), "-timeout", string(*timeout)}
if *debug {
args = append(args, "-debug")
}
Expand Down
3 changes: 3 additions & 0 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type Connection struct {
PreparePacket Broadcaster //type: EncryptionLevel
StreamInput Broadcaster //type: StreamInput

ConnectionClosed chan bool

OriginalDestinationCID ConnectionID
SourceCID ConnectionID
DestinationCID ConnectionID
Expand Down Expand Up @@ -287,6 +289,7 @@ func NewConnection(serverName string, version uint32, ALPN string, SCID []byte,
c.EncryptionLevelsAvailable = NewBroadcaster(10)
c.FrameQueue = NewBroadcaster(1000)
c.TransportParameters = NewBroadcaster(10)
c.ConnectionClosed = make(chan bool, 1)
c.PreparePacket = NewBroadcaster(1000)
c.StreamInput = NewBroadcaster(1000)

Expand Down
7 changes: 3 additions & 4 deletions scenarii/ack_ecn.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package scenarii
import (
qt "github.com/QUIC-Tracker/quic-tracker"
"github.com/QUIC-Tracker/quic-tracker/agents"
"time"
)

const (
Expand All @@ -22,8 +21,6 @@ func NewAckECNScenario() *AckECNScenario {
return &AckECNScenario{AbstractScenario{name: "ack_ecn", version: 1}}
}
func (s *AckECNScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)

connAgents := s.CompleteHandshake(conn, trace, AE_TLSHandshakeFailed)
if connAgents == nil {
return
Expand Down Expand Up @@ -68,7 +65,9 @@ func (s *AckECNScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl
trace.ErrorCode = 0
}
}
case <-s.Timeout().C:
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
return
}
}
Expand Down
7 changes: 3 additions & 4 deletions scenarii/ack_only.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package scenarii

import (
qt "github.com/QUIC-Tracker/quic-tracker"

"time"
)

const (
Expand All @@ -19,7 +17,6 @@ func NewAckOnlyScenario() *AckOnlyScenario {
return &AckOnlyScenario{AbstractScenario{name: "ack_only", version: 1}}
}
func (s *AckOnlyScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
connAgents := s.CompleteHandshake(conn, trace, AO_TLSHandshakeFailed)
if connAgents == nil {
return
Expand Down Expand Up @@ -67,7 +64,9 @@ func (s *AckOnlyScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl
return
}
}
case <-s.Timeout().C:
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
return
}
}
Expand Down
6 changes: 3 additions & 3 deletions scenarii/address_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ func NewAddressValidationScenario() *AddressValidationScenario {
return &AddressValidationScenario{AbstractScenario{name: "address_validation", version: 3}}
}
func (s *AddressValidationScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)

connAgents := agents.AttachAgentsToConnection(conn, agents.GetDefaultAgents()...)
defer connAgents.StopAll()

Expand Down Expand Up @@ -93,7 +91,9 @@ forLoop:
defer connAgents.CloseConnection(false, 0, "")
trace.ErrorCode = 0
}
case <-s.Timeout().C:
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
break forLoop
}
}
Expand Down
11 changes: 7 additions & 4 deletions scenarii/connection_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ func NewConnectionMigrationScenario() *ConnectionMigrationScenario {
return &ConnectionMigrationScenario{AbstractScenario{name: "connection_migration", version: 1}}
}
func (s *ConnectionMigrationScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
connAgents := s.CompleteHandshake(conn, trace, CM_TLSHandshakeFailed)
if connAgents == nil {
return
Expand All @@ -43,8 +42,6 @@ func (s *ConnectionMigrationScenario) Run(conn *qt.Connection, trace *qt.Trace,

connAgents.Get("SocketAgent").Run(conn)
connAgents.Get("SendingAgent").Run(conn)

conn.EncryptionLevelsAvailable.Submit(qt.DirectionalEncryptionLevel{qt.EncryptionLevelHandshake, false}) // TODO: Find a way around this
conn.EncryptionLevelsAvailable.Submit(qt.DirectionalEncryptionLevel{qt.EncryptionLevel1RTT, false})

incPackets := conn.IncomingPackets.RegisterNewChan(1000)
Expand All @@ -63,7 +60,13 @@ func (s *ConnectionMigrationScenario) Run(conn *qt.Connection, trace *qt.Trace,
if fp, ok := p.(qt.Framer); ok && fp.Contains(qt.PathChallengeType) {
trace.ErrorCode = 0
}
case <-s.Timeout().C:

if conn.Streams.Get(0).ReadClosed {
s.Finished()
}
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
return
}
}
Expand Down
10 changes: 5 additions & 5 deletions scenarii/flow_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package scenarii
import (
qt "github.com/QUIC-Tracker/quic-tracker"
"github.com/QUIC-Tracker/quic-tracker/agents"

"time"
)

const (
Expand All @@ -24,7 +22,6 @@ func NewFlowControlScenario() *FlowControlScenario {
return &FlowControlScenario{AbstractScenario{name: "flow_control", version: 2}}
}
func (s *FlowControlScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
conn.TLSTPHandler.MaxStreamDataBidiLocal = 80

connAgents := s.CompleteHandshake(conn, trace, FC_TLSHandshakeFailed)
Expand All @@ -51,6 +48,7 @@ forLoop:

if conn.Streams.Get(0).ReadClosed {
conn.IncomingPackets.Unregister(incPackets)
s.Finished()
break
}

Expand All @@ -62,8 +60,10 @@ forLoop:
conn.FrameQueue.Submit(qt.QueuedFrame{qt.MaxStreamDataFrame{0, uint64(conn.TLSTPHandler.MaxStreamDataBidiLocal)}, qt.EncryptionLevel1RTT})
shouldResume = true
}
case <-s.Timeout().C:
break forLoop
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
break forLoop
}
}

Expand Down
6 changes: 3 additions & 3 deletions scenarii/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
qt "github.com/QUIC-Tracker/quic-tracker"

"github.com/QUIC-Tracker/quic-tracker/agents"
"time"
)

const (
Expand All @@ -22,7 +21,6 @@ func NewHandshakeScenario() *HandshakeScenario {
return &HandshakeScenario{AbstractScenario{name: "handshake", version: 2}}
}
func (s *HandshakeScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
connAgents := agents.AttachAgentsToConnection(conn, agents.GetDefaultAgents()...)
handshakeAgent := &agents.HandshakeAgent{TLSAgent: connAgents.Get("TLSAgent").(*agents.TLSAgent), SocketAgent: connAgents.Get("SocketAgent").(*agents.SocketAgent)}
connAgents.Add(handshakeAgent)
Expand All @@ -49,7 +47,9 @@ func (s *HandshakeScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredU
trace.Results["negotiated_version"] = conn.Version
}
handshakeAgent.HandshakeStatus.Unregister(handshakeStatus)
case <-s.Timeout().C:
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
if !status.Completed {
if trace.ErrorCode == 0 {
trace.MarkError(H_Timeout, "", nil)
Expand Down
14 changes: 9 additions & 5 deletions scenarii/http3_encoder_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ func NewHTTP3EncoderStreamScenario() *HTTP3EncoderStreamScenario {
return &HTTP3EncoderStreamScenario{AbstractScenario{name: "http3_encoder_stream", version: 1, http3: true}}
}
func (s *HTTP3EncoderStreamScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
conn.TLSTPHandler.MaxUniStreams = 3

http := agents.HTTPAgent{QPACKEncoderOpts: ls_qpack_go.LSQPackEncOptIxAggr}
Expand Down Expand Up @@ -52,7 +51,9 @@ forLoop:
case *http3.SETTINGS:
break forLoop
}
case <-s.Timeout().C:
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
trace.ErrorCode = H3ES_SETTINGSNotSent
return
}
Expand All @@ -61,12 +62,15 @@ forLoop:
<-time.NewTimer(200 * time.Millisecond).C
http.SendRequest(preferredUrl, "GET", trace.Host, nil)

trace.ErrorCode = H3ES_RequestTimeout
select {
case <-responseReceived:
trace.ErrorCode = 0
<-s.Timeout().C
case <-s.Timeout().C:
trace.ErrorCode = H3ES_RequestTimeout
s.Finished()
<-s.Timeout()
case <-conn.ConnectionClosed:
return
case <-s.Timeout():
return
}
}
Loading

0 comments on commit e005839

Please sign in to comment.