Skip to content

Commit

Permalink
Encryption levels can be dropped
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiraux committed Mar 11, 2020
1 parent 74b37a1 commit ed24fc5
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 51 deletions.
5 changes: 3 additions & 2 deletions agents/buffer_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func (a *BufferAgent) Run(conn *Connection) {
a.Init("BufferAgent", conn.OriginalDestinationCID)

uPChan := conn.UnprocessedPayloads.RegisterNewChan(1000)
eLChan := conn.EncryptionLevelsAvailable.RegisterNewChan(1000)
eLChan := conn.EncryptionLevels.RegisterNewChan(1000)

unprocessedPayloads := make(map[EncryptionLevel][]IncomingPayload)
encryptionLevelsAvailable := make(map[EncryptionLevel]bool)
Expand All @@ -31,7 +31,7 @@ func (a *BufferAgent) Run(conn *Connection) {
}
case i := <-eLChan:
dEL := i.(DirectionalEncryptionLevel)
if dEL.Read {
if dEL.Available && dEL.Read {
eL := dEL.EncryptionLevel
encryptionLevelsAvailable[eL] = true
if len(unprocessedPayloads[eL]) > 0 {
Expand All @@ -40,6 +40,7 @@ func (a *BufferAgent) Run(conn *Connection) {
for _, uP := range unprocessedPayloads[eL] {
conn.IncomingPayloads.Submit(uP)
}
unprocessedPayloads[eL] = nil
}
case <-a.close:
return
Expand Down
2 changes: 2 additions & 0 deletions agents/handshake_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ func (a *HandshakeAgent) Run(conn *Connection) {
a.HandshakeStatus.Submit(HandshakeStatus{true, tlsPacket, nil})
conn.IncomingPackets.Unregister(incPackets)
if !a.DontDropKeys {
conn.EncryptionLevels.Submit(DirectionalEncryptionLevel{EncryptionLevel: EncryptionLevelInitial, Available: false})
conn.EncryptionLevels.Submit(DirectionalEncryptionLevel{EncryptionLevel: EncryptionLevelHandshake, Available: false})
// TODO: Drop crypto contexts accordingly
}
}
Expand Down
12 changes: 10 additions & 2 deletions agents/recovery_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (a *RecoveryAgent) Run(conn *Connection) {

incomingPackets := conn.IncomingPackets.RegisterNewChan(1000)
outgoingPackets := conn.OutgoingPackets.RegisterNewChan(1000)
eLAvailable := conn.EncryptionLevelsAvailable.RegisterNewChan(10)
eLAvailable := conn.EncryptionLevels.RegisterNewChan(10)

go func() {
defer a.Logger.Println("Agent terminated")
Expand Down Expand Up @@ -103,11 +103,19 @@ func (a *RecoveryAgent) Run(conn *Connection) {
}
case i := <-eLAvailable:
eL := i.(DirectionalEncryptionLevel)
if eL.EncryptionLevel == EncryptionLevel1RTT { // Handshake has completed, empty the retransmission buffers
if eL.Available && eL.EncryptionLevel == EncryptionLevel1RTT { // Handshake has completed, empty the retransmission buffers
a.Logger.Println("Handshake has completed, emptying the two retransmission buffers")
a.retransmissionBuffer[PNSpaceInitial] = make(map[PacketNumber]RetransmittableFrames)
a.retransmissionBuffer[PNSpaceHandshake] = make(map[PacketNumber]RetransmittableFrames)
}
if !eL.Available && eL.EncryptionLevel == EncryptionLevelInitial {
a.Logger.Println("Dropping Initial encryption level, emptying the retransmission buffer")
a.retransmissionBuffer[PNSpaceInitial] = make(map[PacketNumber]RetransmittableFrames)
}
if !eL.Available && eL.EncryptionLevel == EncryptionLevelHandshake {
a.Logger.Println("Dropping Handshake encryption level, emptying the retransmission buffer")
a.retransmissionBuffer[PNSpaceHandshake] = make(map[PacketNumber]RetransmittableFrames)
}
case <-a.conn.ConnectionClosed:
if len(a.retransmissionBuffer[PNSpaceInitial]) > 0 || len(a.retransmissionBuffer[PNSpaceHandshake]) > 0 || len(a.retransmissionBuffer[PNSpaceAppData]) > 0 {
a.Logger.Println("Connection is closing, emptying retransmit buffers")
Expand Down
73 changes: 44 additions & 29 deletions agents/send_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,39 @@ import (
// It also merge the ACK frames inside a given packet before sending.
type SendingAgent struct {
BaseAgent
MTU uint16
FrameProducer []FrameProducer
DontCoalesceZeroRTT bool
MTU uint16
FrameProducer []FrameProducer
DontCoalesceZeroRTT bool
KeepDroppedEncryptionLevels bool
}

func (a *SendingAgent) Run(conn *Connection) {
a.Init("SendingAgent", conn.OriginalDestinationCID)

preparePacket := conn.PreparePacket.RegisterNewChan(100)
sendPacket := conn.SendPacket.RegisterNewChan(100)
newEncryptionLevelAvailable := conn.EncryptionLevelsAvailable.RegisterNewChan(10)
elChan := conn.EncryptionLevels.RegisterNewChan(10)

encryptionLevels := []EncryptionLevel{EncryptionLevelInitial, EncryptionLevel0RTT, EncryptionLevelHandshake, EncryptionLevel1RTT}
encryptionLevelsAvailable := map[DirectionalEncryptionLevel]bool{
{EncryptionLevelNone, false}: true,
{EncryptionLevelInitial, false}: true,
encryptionLevels := map[DirectionalEncryptionLevel]bool{
{EncryptionLevel: EncryptionLevelInitial, Available: true}: true,
{EncryptionLevel: EncryptionLevelNone, Available: true}: true,
{EncryptionLevel: EncryptionLevel0RTT, Available: false}: true,
{EncryptionLevel: EncryptionLevelHandshake, Available: false}: true,
{EncryptionLevel: EncryptionLevel1RTT, Available: false}: true,
}
bestEncryptionLevels := map[EncryptionLevel]EncryptionLevel {
bestEncryptionLevels := map[EncryptionLevel]EncryptionLevel{
EncryptionLevelBest: EncryptionLevelInitial,
}
timers := make(map[EncryptionLevel]*time.Timer)
timersArmed := make(map[EncryptionLevel]bool)
for _, el := range encryptionLevels {
timers[el] = time.NewTimer(0)
timersArmed[el] = false
if !timers[el].Stop() {
<-timers[el].C
for dEL := range encryptionLevels {
el := dEL.EncryptionLevel
if dEL.EncryptionLevel != EncryptionLevelNone {
timers[el] = time.NewTimer(0)
timersArmed[el] = false
if !timers[el].Stop() {
<-timers[el].C
}
}
}

Expand Down Expand Up @@ -84,16 +90,16 @@ func (a *SendingAgent) Run(conn *Connection) {
defer close(a.closed)
for {
select {
case i :=<-preparePacket:
case i := <-preparePacket:
eL := i.(EncryptionLevel)

if eL == EncryptionLevelBest || eL == EncryptionLevelBestAppData {
nEL := chooseBestEncryptionLevel(encryptionLevelsAvailable, eL == EncryptionLevelBestAppData)
nEL := chooseBestEncryptionLevel(encryptionLevels, eL == EncryptionLevelBestAppData)
bestEncryptionLevels[eL] = nEL
a.Logger.Printf("Chose %s as new encryption level for %s\n", nEL, eL)
eL = nEL
}
if encryptionLevelsAvailable[DirectionalEncryptionLevel{eL, false}] && !timersArmed[eL] {
if encryptionLevels[DirectionalEncryptionLevel{EncryptionLevel: eL, Read: false, Available: true}] && !timersArmed[eL] {
timers[eL].Reset(2 * time.Millisecond)
timersArmed[eL] = true
}
Expand Down Expand Up @@ -124,16 +130,25 @@ func (a *SendingAgent) Run(conn *Connection) {
conn.DoSendPacket(p, EncryptionLevel1RTT)
}
timersArmed[EncryptionLevel1RTT] = false
case i := <-newEncryptionLevelAvailable:
case i := <-elChan:
dEL := i.(DirectionalEncryptionLevel)
if dEL.Read {
continue
}
eL := dEL.EncryptionLevel
encryptionLevelsAvailable[dEL] = true
bestEncryptionLevels[EncryptionLevelBest] = chooseBestEncryptionLevel(encryptionLevelsAvailable, false)
bestEncryptionLevels[EncryptionLevelBestAppData] = chooseBestEncryptionLevel(encryptionLevelsAvailable, true)
timers[eL].Reset(2 * time.Millisecond)
t := timers[eL]
if !dEL.Available && !a.KeepDroppedEncryptionLevels {
a.Logger.Println("Dropping encryption level", eL.String())
encryptionLevels[dEL] = true
t.Stop()
} else if dEL.Available {
encryptionLevels[dEL] = true
dEL.Available = false
delete(encryptionLevels, dEL)
bestEncryptionLevels[EncryptionLevelBest] = chooseBestEncryptionLevel(encryptionLevels, false)
bestEncryptionLevels[EncryptionLevelBestAppData] = chooseBestEncryptionLevel(encryptionLevels, true)
t.Reset(2 * time.Millisecond)
}
case i := <-sendPacket:
p := i.(PacketToSend)
if p.EncryptionLevel == EncryptionLevelInitial && p.Packet.Header().PacketType() == Initial {
Expand Down Expand Up @@ -170,21 +185,21 @@ func (a *SendingAgent) Run(conn *Connection) {
}()
}

var elOrder = []DirectionalEncryptionLevel{{EncryptionLevel1RTT, false}, {EncryptionLevelHandshake, false}, {EncryptionLevelInitial, false}}
var elAppDataOrder = []DirectionalEncryptionLevel{{EncryptionLevel1RTT, false}, {EncryptionLevel0RTT, false}}
var elOrder = []EncryptionLevel{EncryptionLevel1RTT, EncryptionLevelHandshake, EncryptionLevelInitial}
var elAppDataOrder = []EncryptionLevel{EncryptionLevel1RTT, EncryptionLevel0RTT}

func chooseBestEncryptionLevel(elAvailable map[DirectionalEncryptionLevel]bool, restrictAppData bool) EncryptionLevel {
func chooseBestEncryptionLevel(eLs map[DirectionalEncryptionLevel]bool, restrictAppData bool) EncryptionLevel {
order := elOrder
if restrictAppData {
order = elAppDataOrder
}
for _, dEL := range order {
if elAvailable[dEL] {
return dEL.EncryptionLevel
for _, eL := range order {
if eLs[DirectionalEncryptionLevel{EncryptionLevel: eL, Available: true}] {
return eL
}
}
if restrictAppData {
return EncryptionLevel1RTT
}
return order[len(order)-1].EncryptionLevel
return order[len(order)-1]
}
14 changes: 9 additions & 5 deletions agents/tls_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ func (a *TLSAgent) Run(conn *Connection) {
a.TLSStatus = NewBroadcaster(10)
a.ResumptionTicket = NewBroadcaster(10)

encryptionLevels := []DirectionalEncryptionLevel{{EncryptionLevelHandshake, false}, {EncryptionLevelHandshake, true}, {EncryptionLevel1RTT, false}, {EncryptionLevel1RTT, true}}
encryptionLevelsAvailable := make(map[DirectionalEncryptionLevel]bool)
encryptionLevels := []*DirectionalEncryptionLevel{
{EncryptionLevel: EncryptionLevelHandshake},
{EncryptionLevel: EncryptionLevelHandshake, Read: true},
{EncryptionLevel: EncryptionLevel1RTT},
{EncryptionLevel: EncryptionLevel1RTT, Read: true},
}

incomingPackets := conn.IncomingPackets.RegisterNewChan(1000)

Expand Down Expand Up @@ -117,9 +121,9 @@ func (a *TLSAgent) Run(conn *Connection) {
}

for _, e := range encryptionLevels {
if !encryptionLevelsAvailable[e] && conn.CryptoStates[e.EncryptionLevel] != nil && ((e.Read && conn.CryptoStates[e.EncryptionLevel].HeaderRead != nil) || (!e.Read && conn.CryptoStates[e.EncryptionLevel].HeaderWrite != nil)) {
encryptionLevelsAvailable[e] = true
conn.EncryptionLevelsAvailable.Submit(e)
if !e.Available && conn.CryptoStates[e.EncryptionLevel] != nil && ((e.Read && conn.CryptoStates[e.EncryptionLevel].HeaderRead != nil) || (!e.Read && conn.CryptoStates[e.EncryptionLevel].HeaderWrite != nil)) {
e.Available = true
conn.EncryptionLevels.Submit(*e)
}
}

Expand Down
18 changes: 9 additions & 9 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ type Connection struct {
CryptoStreams CryptoStreams // TODO: It should be a parent class without closing states
Streams Streams

IncomingPackets Broadcaster //type: Packet
OutgoingPackets Broadcaster //type: Packet
IncomingPayloads Broadcaster //type: IncomingPayload
UnprocessedPayloads Broadcaster //type: UnprocessedPayload
EncryptionLevelsAvailable Broadcaster //type: DirectionalEncryptionLevel
FrameQueue Broadcaster //type: QueuedFrame
TransportParameters Broadcaster //type: QuicTransportParameters
IncomingPackets Broadcaster //type: Packet
OutgoingPackets Broadcaster //type: Packet
IncomingPayloads Broadcaster //type: IncomingPayload
UnprocessedPayloads Broadcaster //type: UnprocessedPayload
EncryptionLevels Broadcaster //type: DirectionalEncryptionLevel
FrameQueue Broadcaster //type: QueuedFrame
TransportParameters Broadcaster //type: QuicTransportParameters

PreparePacket Broadcaster //type: EncryptionLevel
SendPacket Broadcaster //type: PacketToSend
Expand Down Expand Up @@ -152,7 +152,7 @@ func (c *Connection) GetInitialPacket() *InitialPacket {
if len(c.Tls.ZeroRTTSecret()) > 0 {
c.Logger.Printf("0-RTT secret is available, installing crypto state")
c.CryptoStates[EncryptionLevel0RTT] = NewProtectedCryptoState(c.Tls, nil, c.Tls.ZeroRTTSecret())
c.EncryptionLevelsAvailable.Submit(DirectionalEncryptionLevel{EncryptionLevel0RTT, false})
c.EncryptionLevels.Submit(DirectionalEncryptionLevel{EncryptionLevel: EncryptionLevel0RTT, Read: false, Available: true})
}

var initialLength int
Expand Down Expand Up @@ -345,7 +345,7 @@ func NewConnection(serverName string, version uint32, ALPN string, SCID []byte,
c.OutgoingPackets = NewBroadcaster(1000)
c.IncomingPayloads = NewBroadcaster(1000)
c.UnprocessedPayloads = NewBroadcaster(1000)
c.EncryptionLevelsAvailable = NewBroadcaster(10)
c.EncryptionLevels = NewBroadcaster(10)
c.FrameQueue = NewBroadcaster(1000)
c.TransportParameters = NewBroadcaster(10)
c.ConnectionClosed = make(chan bool, 1)
Expand Down
3 changes: 2 additions & 1 deletion crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ var EpochToEncryptionLevel = map[pigotls.Epoch]EncryptionLevel {
}

type DirectionalEncryptionLevel struct {
EncryptionLevel
EncryptionLevel EncryptionLevel
Read bool
Available bool
}

type CryptoState struct {
Expand Down
2 changes: 1 addition & 1 deletion scenarii/connection_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ 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.EncryptionLevel1RTT, false})
conn.EncryptionLevels.Submit(qt.DirectionalEncryptionLevel{EncryptionLevel: qt.EncryptionLevel1RTT, Available: true})

incPackets := conn.IncomingPackets.RegisterNewChan(1000)

Expand Down
2 changes: 1 addition & 1 deletion scenarii/connection_migration_v4_v6.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ firstFlight:

connAgents.Get("SocketAgent").Run(conn)
connAgents.Get("SendingAgent").Run(conn)
conn.EncryptionLevelsAvailable.Submit(qt.DirectionalEncryptionLevel{qt.EncryptionLevel1RTT, false})
conn.EncryptionLevels.Submit(qt.DirectionalEncryptionLevel{EncryptionLevel: qt.EncryptionLevel1RTT, Available: true})

incPackets = conn.IncomingPackets.RegisterNewChan(1000)

Expand Down
2 changes: 1 addition & 1 deletion scenarii/zero_rtt.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (s *ZeroRTTScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredPat
defer trace.Complete(conn)

incPackets = conn.IncomingPackets.RegisterNewChan(1000)
encryptionLevelsAvailable := conn.EncryptionLevelsAvailable.RegisterNewChan(10)
encryptionLevelsAvailable := conn.EncryptionLevels.RegisterNewChan(10)

responseChan := connAgents.AddHTTPAgent().SendRequest(preferredPath, "GET", trace.Host, nil) // TODO: Verify that this get effectively sent in a 0-RTT packet
handshakeAgent.InitiateHandshake() // TODO: Handle stateless connection
Expand Down

0 comments on commit ed24fc5

Please sign in to comment.