Skip to content

Commit

Permalink
Initial draft-28 support
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiraux committed May 29, 2020
1 parent bde58c3 commit e83805b
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 54 deletions.
24 changes: 20 additions & 4 deletions agents/handshake_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type HandshakeAgent struct {
DontDropKeys bool
sendInitial chan bool
receivedRetry bool
retrySource ConnectionID
}

func (a *HandshakeAgent) Run(conn *Connection) {
Expand Down Expand Up @@ -72,6 +73,7 @@ func (a *HandshakeAgent) Run(conn *Connection) {
a.Logger.Println("A Retry packet was received, restarting the connection")
a.receivedRetry = true
conn.DestinationCID = p.Header().(*LongHeader).SourceCID
a.retrySource = p.Header().(*LongHeader).SourceCID
tlsTP, alpn := conn.TLSTPHandler, conn.ALPN
conn.TransitionTo(QuicVersion, alpn)
conn.TLSTPHandler = tlsTP
Expand Down Expand Up @@ -121,10 +123,24 @@ func (a *HandshakeAgent) Run(conn *Connection) {
case i := <-tlsStatus:
s := i.(TLSStatus)
if s.Error != nil {
if s.Completed && a.receivedRetry && !bytes.Equal(conn.TLSTPHandler.ReceivedParameters.OriginalConnectionId, conn.OriginalDestinationCID){
a.Logger.Println("The server include an invalid original_connection_id after sending a Retry")
s.Completed = false
s.Error = errors.New(fmt.Sprint("invalid original_connection_id"))
if s.Completed {
if !bytes.Equal(conn.TLSTPHandler.ReceivedParameters.OriginalDestinationConnectionId, conn.OriginalDestinationCID) {
a.Logger.Println("The server included an invalid original_destination_connection_id")
s.Completed = false
s.Error = errors.New(fmt.Sprint("invalid original_destination_connection_id"))
} else if a.receivedRetry {
if !bytes.Equal(conn.TLSTPHandler.ReceivedParameters.RetrySourceConnectionId, a.retrySource) {
a.Logger.Println("The server include an invalid retry_source_connection_id after sending a Retry")
s.Completed = false
s.Error = errors.New(fmt.Sprint("invalid retry_source_connection_id"))
}
} else {
if conn.TLSTPHandler.ReceivedParameters.RetrySourceConnectionId != nil {
a.Logger.Println("The server included a retry_source_connection_id but did not send a Retry")
s.Completed = false
s.Error = errors.New(fmt.Sprint("invalid retry_source_connection_id"))
}
}
}
a.HandshakeStatus.Submit(HandshakeStatus{s.Completed, s.Packet, s.Error})
}
Expand Down
2 changes: 1 addition & 1 deletion agents/socket_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (a *SocketAgent) Run(conn *Connection) {

go func() {
for {
recBuf := make([]byte, MaxUDPPayloadSize)
recBuf := make([]byte, MaxTheoreticUDPPayloadSize)
oob := make([]byte, 128) // Find a reasonable upper-bound
i, oobn, _, addr, err := conn.UdpConnection.ReadMsgUDP(recBuf, oob)

Expand Down
16 changes: 8 additions & 8 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ import (
)

// TODO: Reconsider the use of global variables
var QuicVersion uint32 = 0xff00001b // See https://tools.ietf.org/html/draft-ietf-quic-transport-08#section-4
var QuicALPNToken = "hq-27" // See https://www.ietf.org/mail-archive/web/quic/current/msg01882.html
var QuicH3ALPNToken = "h3-27" // See https://tools.ietf.org/html/draft-ietf-quic-http-17#section-2.1
var QuicVersion uint32 = 0xff00001c // See https://tools.ietf.org/html/draft-ietf-quic-transport-08#section-4
var QuicALPNToken = "hq-28" // See https://www.ietf.org/mail-archive/web/quic/current/msg01882.html
var QuicH3ALPNToken = "h3-28" // See https://tools.ietf.org/html/draft-ietf-quic-http-17#section-2.1

const (
MinimumInitialLength = 1252
MinimumInitialLengthv6 = 1232
MaxUDPPayloadSize = 65507
MaximumVersion = 0xff00001b
MinimumVersion = 0xff00001b
MinimumInitialLength = 1252
MinimumInitialLengthv6 = 1232
MaxTheoreticUDPPayloadSize = 65507
MaximumVersion = 0xff00001c
MinimumVersion = 0xff00001c
)

// errors
Expand Down
2 changes: 1 addition & 1 deletion connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func (c *Connection) GetAckFrame(space PNSpace) *AckFrame { // Returns an ack fr
return frame
}
func (c *Connection) TransitionTo(version uint32, ALPN string) {
c.TLSTPHandler = NewTLSTransportParameterHandler()
c.TLSTPHandler = NewTLSTransportParameterHandler(c.SourceCID)
c.Version = version
c.ALPN = ALPN
c.Tls = pigotls.NewConnection(c.ServerName, c.ALPN, c.ResumptionTicket)
Expand Down
1 change: 1 addition & 0 deletions scenarii/zero_length_cid.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func NewZeroLengthCID() *ZeroLengthCID {

func (s *ZeroLengthCID) Run(conn *qt.Connection, trace *qt.Trace, preferredPath string, debug bool) {
conn.SourceCID = nil
conn.TLSTPHandler.InitialSourceConnectionId = nil
connAgents := s.CompleteHandshake(conn, trace, ZLCID_TLSHandshakeFailed)
if connAgents == nil {
return
Expand Down
93 changes: 53 additions & 40 deletions transport_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,45 @@ import (
type TransportParametersType uint64

const (
OriginalConnectionId TransportParametersType = 0x00
IdleTimeout = 0x01
StatelessResetToken = 0x02
MaxPacketSize = 0x03
InitialMaxData = 0x04
InitialMaxStreamDataBidiLocal = 0x05
InitialMaxStreamDataBidiRemote = 0x06
InitialMaxStreamDataUni = 0x07
InitialMaxStreamsBidi = 0x08
InitialMaxStreamsUni = 0x09
AckDelayExponent = 0x0a
MaxAckDelay = 0x0b
DisableMigration = 0x0c
PreferredAddress = 0x0d // TODO: Handle this parameter
ActiveConnectionIdLimit = 0x0e
OriginalDestinationConnectionId TransportParametersType = 0x00
IdleTimeout = 0x01
StatelessResetToken = 0x02
MaxUDPPacketSize = 0x03
InitialMaxData = 0x04
InitialMaxStreamDataBidiLocal = 0x05
InitialMaxStreamDataBidiRemote = 0x06
InitialMaxStreamDataUni = 0x07
InitialMaxStreamsBidi = 0x08
InitialMaxStreamsUni = 0x09
AckDelayExponent = 0x0a
MaxAckDelay = 0x0b
DisableMigration = 0x0c
PreferredAddress = 0x0d // TODO: Handle this parameter
ActiveConnectionIdLimit = 0x0e
InitialSourceConnectionId = 0x0f
RetrySourceConnectionId = 0x10
)

type QuicTransportParameters struct { // A set of QUIC transport parameters value
OriginalConnectionId ConnectionID
IdleTimeout uint64
StatelessResetToken []byte
MaxPacketSize uint64
MaxData uint64
MaxStreamDataBidiLocal uint64
MaxStreamDataBidiRemote uint64
MaxStreamDataUni uint64
MaxBidiStreams uint64
MaxUniStreams uint64
AckDelayExponent uint64
MaxAckDelay uint64
DisableMigration bool
PreferredAddress []byte
ActiveConnectionIdLimit uint64
AdditionalParameters TransportParameterList
ToJSON map[string]interface{}
OriginalDestinationConnectionId ConnectionID
IdleTimeout uint64
StatelessResetToken []byte
MaxPacketSize uint64
MaxData uint64
MaxStreamDataBidiLocal uint64
MaxStreamDataBidiRemote uint64
MaxStreamDataUni uint64
MaxBidiStreams uint64
MaxUniStreams uint64
AckDelayExponent uint64
MaxAckDelay uint64
DisableMigration bool
PreferredAddress []byte
ActiveConnectionIdLimit uint64
InitialSourceConnectionId ConnectionID
RetrySourceConnectionId ConnectionID
AdditionalParameters TransportParameterList
ToJSON map[string]interface{}
}

type TransportParameter struct {
Expand Down Expand Up @@ -77,8 +81,8 @@ type TLSTransportParameterHandler struct {
ReceivedParameters *QuicTransportParameters
}

func NewTLSTransportParameterHandler() *TLSTransportParameterHandler {
return &TLSTransportParameterHandler{QuicTransportParameters: QuicTransportParameters{MaxStreamDataBidiLocal: 16 * 1024, MaxStreamDataUni: 16 * 1024, MaxData: 32 * 1024, MaxBidiStreams: 1, MaxUniStreams: 3, IdleTimeout: 10000, AckDelayExponent: 3, ActiveConnectionIdLimit: 4}}
func NewTLSTransportParameterHandler(scid ConnectionID) *TLSTransportParameterHandler {
return &TLSTransportParameterHandler{QuicTransportParameters: QuicTransportParameters{MaxStreamDataBidiLocal: 16 * 1024, MaxStreamDataUni: 16 * 1024, MaxData: 32 * 1024, MaxBidiStreams: 1, MaxUniStreams: 3, IdleTimeout: 10000, AckDelayExponent: 3, ActiveConnectionIdLimit: 4, InitialSourceConnectionId: scid}}
}
func (h *TLSTransportParameterHandler) GetExtensionData() ([]byte, error) {
var parameters []TransportParameter
Expand All @@ -103,13 +107,15 @@ func (h *TLSTransportParameterHandler) GetExtensionData() ([]byte, error) {
parameters = append(parameters, TransportParameter{parametersType, []byte{val}})
case []byte:
parameters = append(parameters, TransportParameter{parametersType, val})
case ConnectionID:
parameters = append(parameters, TransportParameter{parametersType, []byte(val)})
case bool:
if !val {
return
}
parameters = append(parameters, TransportParameter{parametersType, []byte{}})
default:
panic("the parameter value should be uint32, uint16, byte, bool or []byte")
panic("the parameter value should be uint32, uint16, byte, bool, []byte or ConnectionID")
}
}

Expand All @@ -123,8 +129,9 @@ func (h *TLSTransportParameterHandler) GetExtensionData() ([]byte, error) {
addParameter(ActiveConnectionIdLimit, h.QuicTransportParameters.ActiveConnectionIdLimit)
}
if h.QuicTransportParameters.MaxPacketSize > 0 {
addParameter(MaxPacketSize, h.QuicTransportParameters.MaxPacketSize)
addParameter(MaxUDPPacketSize, h.QuicTransportParameters.MaxPacketSize)
}
addParameter(InitialSourceConnectionId, h.QuicTransportParameters.InitialSourceConnectionId)
for _, p := range h.QuicTransportParameters.AdditionalParameters {
parameters = append(parameters, p)
}
Expand Down Expand Up @@ -177,16 +184,16 @@ func (h *TLSTransportParameterHandler) ReceiveExtensionData(data []byte) error {
}
pDataBuf := bytes.NewBuffer(pData)
switch TransportParametersType(pType.Value) {
case OriginalConnectionId:
receivedParameters.OriginalConnectionId = ConnectionID(pDataBuf.Bytes())
receivedParameters.ToJSON["original_connection_id"] = ConnectionID(pData)
case OriginalDestinationConnectionId:
receivedParameters.OriginalDestinationConnectionId = ConnectionID(pDataBuf.Bytes())
receivedParameters.ToJSON["original_destination_connection_id"] = ConnectionID(pData)
case IdleTimeout:
receivedParameters.IdleTimeout, _, err = lib.ReadVarIntValue(pDataBuf)
receivedParameters.ToJSON["idle_timeout"] = receivedParameters.IdleTimeout
case StatelessResetToken:
receivedParameters.StatelessResetToken = pDataBuf.Bytes()
receivedParameters.ToJSON["stateless_reset_token"] = receivedParameters.StatelessResetToken
case MaxPacketSize:
case MaxUDPPacketSize:
receivedParameters.MaxPacketSize, _, err = lib.ReadVarIntValue(pDataBuf)
receivedParameters.ToJSON["max_packet_size"] = receivedParameters.MaxPacketSize
case InitialMaxData:
Expand Down Expand Up @@ -222,6 +229,12 @@ func (h *TLSTransportParameterHandler) ReceiveExtensionData(data []byte) error {
case ActiveConnectionIdLimit:
receivedParameters.ActiveConnectionIdLimit, _, err = lib.ReadVarIntValue(pDataBuf)
receivedParameters.ToJSON["active_connection_id_limit"] = receivedParameters.ActiveConnectionIdLimit
case InitialSourceConnectionId:
receivedParameters.InitialSourceConnectionId = ConnectionID(pDataBuf.Bytes())
receivedParameters.ToJSON["initial_source_connection_id"] = ConnectionID(pData)
case RetrySourceConnectionId:
receivedParameters.RetrySourceConnectionId = ConnectionID(pDataBuf.Bytes())
receivedParameters.ToJSON["retry_source_connection_id"] = ConnectionID(pData)
default:
p := TransportParameter{ParameterType: TransportParametersType(pType.Value), Value: pDataBuf.Bytes()}
receivedParameters.AdditionalParameters.AddParameter(p)
Expand Down

0 comments on commit e83805b

Please sign in to comment.