Skip to content

Commit

Permalink
Adds a new virtual encryption level for best app data encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiraux committed Jan 21, 2019
1 parent ff6f1af commit acd73d2
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 19 deletions.
6 changes: 3 additions & 3 deletions agents/http_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (a *HTTPAgent) Run(conn *Connection) {
a.peerControlStreamID = HTTPNoStream
peerControlStream := make(chan interface{}, 1000)
peerControlStreamBuffer := new(bytes.Buffer)
a.conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.controlStreamID, conn.Streams.Get(a.controlStreamID), []byte{'C'}, false), EncryptionLevelBest})
a.conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.controlStreamID, conn.Streams.Get(a.controlStreamID), []byte{'C'}, false), EncryptionLevelBestAppData})
a.sendFrameOnStream(http3.NewSETTINGS(nil), a.controlStreamID, false)

a.streamData = make(chan streamData)
Expand Down Expand Up @@ -160,7 +160,7 @@ func (a *HTTPAgent) Run(conn *Connection) {
settingsQPACKBlockedStreams = s.Value.Value
}
}
a.QPACK.InitEncoder(uint(settingsHeaderTableSize), uint(settingsHeaderTableSize / 4), uint(settingsQPACKBlockedStreams), a.QPACKEncoderOpts)
a.QPACK.InitEncoder(uint(settingsHeaderTableSize), uint(settingsHeaderTableSize), uint(settingsQPACKBlockedStreams), a.QPACKEncoderOpts)
default:
spew.Dump(fr)
}
Expand Down Expand Up @@ -188,7 +188,7 @@ func (a *HTTPAgent) Run(conn *Connection) {
func (a *HTTPAgent) sendFrameOnStream(frame http3.HTTPFrame, streamID uint64, fin bool) {
buf := new(bytes.Buffer)
frame.WriteTo(buf)
a.conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(streamID, a.conn.Streams.Get(streamID), buf.Bytes(), fin), EncryptionLevelBest})
a.conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(streamID, a.conn.Streams.Get(streamID), buf.Bytes(), fin), EncryptionLevelBestAppData})
}
func (a *HTTPAgent) attemptDecoding(streamID uint64, buffer *bytes.Buffer) {
var l VarInt
Expand Down
8 changes: 4 additions & 4 deletions agents/qpack_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (a *QPACKAgent) Run(conn *Connection) {
}
a.DecodedHeaders.Submit(DecodedHeaders{dhb.StreamID, headers})
if len(dhb.DecoderStream()) > 0 {
conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.DecoderStreamID, conn.Streams.Get(a.DecoderStreamID), dhb.DecoderStream(), false), EncryptionLevelBest})
conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.DecoderStreamID, conn.Streams.Get(a.DecoderStreamID), dhb.DecoderStream(), false), EncryptionLevelBestAppData})
}
a.Logger.Printf("Submitted %d decoded headers on stream %d\n", len(headers), dhb.StreamID)
}
Expand Down Expand Up @@ -142,7 +142,7 @@ func (a *QPACKAgent) Run(conn *Connection) {
a.EncodedHeaders.Submit(EncodedHeaders{e.StreamID, payload})
a.Logger.Printf("Encoded %d headers in %d bytes, with %d additional bytes on the encoder stream\n", len(e.Headers), len(payload), len(encStream))
if len(encStream) > 0 {
conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.EncoderStreamID, conn.Streams.Get(a.EncoderStreamID), encStream, false), EncryptionLevelBest})
conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.EncoderStreamID, conn.Streams.Get(a.EncoderStreamID), encStream, false), EncryptionLevelBestAppData})
a.Logger.Printf("Enqueued %d bytes on the encoder stream\n", len(encStream))
}
case d := <-a.DecodeHeaders:
Expand All @@ -157,8 +157,8 @@ func (a *QPACKAgent) Run(conn *Connection) {
}
}()

conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.EncoderStreamID, conn.Streams.Get(a.EncoderStreamID), []byte{'H'}, false), EncryptionLevelBest})
conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.DecoderStreamID, conn.Streams.Get(a.DecoderStreamID), []byte{'h'}, false), EncryptionLevelBest})
conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.EncoderStreamID, conn.Streams.Get(a.EncoderStreamID), []byte{'H'}, false), EncryptionLevelBestAppData})
conn.FrameQueue.Submit(QueuedFrame{NewStreamFrame(a.DecoderStreamID, conn.Streams.Get(a.DecoderStreamID), []byte{'h'}, false), EncryptionLevelBestAppData})
}
func (a *QPACKAgent) InitEncoder(headerTableSize uint, dynamicTablesize uint, maxRiskedStreams uint, opts uint32) {
a.encoder.Init(headerTableSize, dynamicTablesize, maxRiskedStreams, opts)
Expand Down
38 changes: 29 additions & 9 deletions agents/send_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (a *SendingAgent) Run(conn *Connection) {
newEncryptionLevelAvailable := make(chan interface{}, 10)
conn.EncryptionLevelsAvailable.Register(newEncryptionLevelAvailable)

encryptionLevels := []EncryptionLevel{EncryptionLevelInitial, EncryptionLevel0RTT, EncryptionLevelHandshake, EncryptionLevel1RTT, EncryptionLevelBest}
encryptionLevels := []EncryptionLevel{EncryptionLevelInitial, EncryptionLevel0RTT, EncryptionLevelHandshake, EncryptionLevel1RTT, EncryptionLevelBest, EncryptionLevelBestAppData}
encryptionLevelsAvailable := map[DirectionalEncryptionLevel]bool {
{EncryptionLevelNone, false}: true,
{EncryptionLevelInitial, false}: true,
Expand Down Expand Up @@ -64,7 +64,7 @@ func (a *SendingAgent) Run(conn *Connection) {
}

fillAndSendPacket := func(packet Framer, level EncryptionLevel) {
if len(frameBuffer[level]) > 0 {
if len(frameBuffer[level]) > 0 && encryptionLevelsAvailable[DirectionalEncryptionLevel{level, false}] {
a.Logger.Printf("Timer for encryption level %s fired, scheduling the sending of %d bytes in %d frames\n", level.String(), frameBufferLength[level], len(frameBuffer[level]))

fillWithLevel(packet, level)
Expand All @@ -83,8 +83,8 @@ func (a *SendingAgent) Run(conn *Connection) {
if frameBufferLength[qf.EncryptionLevel]+qf.FrameLength() > a.MTU {
a.Logger.Printf("Scheduling the sending of %d bytes in %d frames in the buffer\n", frameBufferLength[qf.EncryptionLevel], len(frameBuffer[qf.EncryptionLevel]))

if qf.EncryptionLevel == EncryptionLevelBest {
qf.EncryptionLevel = chooseBestEncryptionLevel(encryptionLevelsAvailable)
if qf.EncryptionLevel == EncryptionLevelBest || qf.EncryptionLevel == EncryptionLevelBestAppData {
qf.EncryptionLevel = chooseBestEncryptionLevel(encryptionLevelsAvailable, qf.EncryptionLevel == EncryptionLevelBestAppData)
a.Logger.Printf("Chose %s as best encryption level\n", qf.EncryptionLevel.String())
}

Expand Down Expand Up @@ -117,7 +117,7 @@ func (a *SendingAgent) Run(conn *Connection) {
} else {
frameBuffer[qf.EncryptionLevel] = append(frameBuffer[qf.EncryptionLevel], qf.Frame)
frameBufferLength[qf.EncryptionLevel] += qf.FrameLength()
if encryptionLevelsAvailable[DirectionalEncryptionLevel{qf.EncryptionLevel, false}] || qf.EncryptionLevel == EncryptionLevelBest {
if encryptionLevelsAvailable[DirectionalEncryptionLevel{qf.EncryptionLevel, false}] || qf.EncryptionLevel == EncryptionLevelBest || qf.EncryptionLevel == EncryptionLevelBestAppData {
timers[qf.EncryptionLevel].Reset(5 * time.Millisecond)
}
}
Expand All @@ -130,7 +130,7 @@ func (a *SendingAgent) Run(conn *Connection) {
case <-timers[EncryptionLevel1RTT].C:
fillAndSendPacket(NewProtectedPacket(conn), EncryptionLevel1RTT)
case <-timers[EncryptionLevelBest].C:
eL := chooseBestEncryptionLevel(encryptionLevelsAvailable)
eL := chooseBestEncryptionLevel(encryptionLevelsAvailable, false)
a.Logger.Printf("Timer for encryption level %s fired, chose %s as new encryption level\n", EncryptionLevelBest.String(), eL.String())

for _, f := range frameBuffer[EncryptionLevelBest] {
Expand All @@ -140,6 +140,18 @@ func (a *SendingAgent) Run(conn *Connection) {
frameBuffer[EncryptionLevelBest] = nil
frameBufferLength[EncryptionLevelBest] = 0

timers[eL].Reset(0)
case <-timers[EncryptionLevelBestAppData].C:
eL := chooseBestEncryptionLevel(encryptionLevelsAvailable, true)
a.Logger.Printf("Timer for encryption level %s fired, chose %s as new encryption level\n", EncryptionLevelBestAppData.String(), eL.String())

for _, f := range frameBuffer[EncryptionLevelBestAppData] {
frameBuffer[eL] = append(frameBuffer[eL], f)
frameBufferLength[eL] += f.FrameLength()
}
frameBuffer[EncryptionLevelBestAppData] = nil
frameBufferLength[EncryptionLevelBestAppData] = 0

timers[eL].Reset(0)
case i := <- newEncryptionLevelAvailable:
dEL := i.(DirectionalEncryptionLevel)
Expand All @@ -166,14 +178,22 @@ func (a *SendingAgent) Run(conn *Connection) {
}

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

func chooseBestEncryptionLevel(elAvailable map[DirectionalEncryptionLevel]bool) EncryptionLevel {
for _, dEL := range elOrder {
func chooseBestEncryptionLevel(elAvailable map[DirectionalEncryptionLevel]bool, restrictAppData bool) EncryptionLevel {
order := elOrder
if restrictAppData {
order = elAppDataOrder
}
for _, dEL := range order {
if elAvailable[dEL] {
return dEL.EncryptionLevel
}
}
return elOrder[len(elOrder) - 1].EncryptionLevel
if restrictAppData {
return EncryptionLevel1RTT
}
return order[len(order) - 1].EncryptionLevel
}

func mergeAckFrames(frames []*AckFrame) *AckFrame {
Expand Down
2 changes: 1 addition & 1 deletion connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func (c *Connection) CloseConnection(quicLayer bool, errCode uint16, reasonPhras
}
}
func (c *Connection) SendHTTPGETRequest(path string, streamID uint64) {
c.FrameQueue.Submit(QueuedFrame{NewStreamFrame(streamID, c.Streams.Get(streamID), []byte(fmt.Sprintf("GET %s\r\n", path)), true), EncryptionLevelBest})
c.FrameQueue.Submit(QueuedFrame{NewStreamFrame(streamID, c.Streams.Get(streamID), []byte(fmt.Sprintf("GET %s\r\n", path)), true), EncryptionLevelBestAppData})
}
func (c *Connection) Close() {
c.Tls.Close()
Expand Down
4 changes: 3 additions & 1 deletion crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ const (
EncryptionLevel0RTT
EncryptionLevelHandshake
EncryptionLevel1RTT
EncryptionLevelBest // A special flag to indicate that the best encryption level available should be used
EncryptionLevelBest // A special flag to indicate that the best encryption level available should be used
EncryptionLevelBestAppData // A special flag to indicate that the best app data encryption level available should be used
)

func (eL EncryptionLevel) String() string {
Expand All @@ -37,6 +38,7 @@ var encryptionLevelToString = map[EncryptionLevel]string {
EncryptionLevel0RTT: "0RTT",
EncryptionLevel1RTT: "1RTT",
EncryptionLevelBest: "Best",
EncryptionLevelBestAppData: "BestAppData",
}

var packetTypeToEncryptionLevel = map[PacketType]EncryptionLevel{
Expand Down
2 changes: 1 addition & 1 deletion scenarii/scenario.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (s *AbstractScenario) Timeout() *time.Timer {
// Useful helper for scenarii that requires the handshake to complete before executing their test and don't want to
// discern the cause of its failure.
func (s *AbstractScenario) CompleteHandshake(conn *qt.Connection, trace *qt.Trace, handshakeErrorCode uint8, additionalAgents ...agents.Agent) *agents.ConnectionAgents {
connAgents := agents.AttachAgentsToConnection(conn, agents.GetDefaultAgents()...)
connAgents := agents.AttachAgentsToConnection(conn, append(agents.GetDefaultAgents(), additionalAgents...)...)
handshakeAgent := &agents.HandshakeAgent{TLSAgent: connAgents.Get("TLSAgent").(*agents.TLSAgent), SocketAgent: connAgents.Get("SocketAgent").(*agents.SocketAgent)}
connAgents.Add(handshakeAgent)

Expand Down

0 comments on commit acd73d2

Please sign in to comment.