mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
109 lines
3.6 KiB
Go
109 lines
3.6 KiB
Go
package handshake
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"time"
|
|
|
|
"github.com/lucas-clemente/quic-go/internal/protocol"
|
|
"github.com/lucas-clemente/quic-go/internal/utils"
|
|
)
|
|
|
|
type paramsNegotiator struct {
|
|
paramsNegotiatorBase
|
|
}
|
|
|
|
var _ ParamsNegotiator = ¶msNegotiator{}
|
|
|
|
// newParamsNegotiator creates a new connection parameters manager
|
|
func newParamsNegotiator(pers protocol.Perspective, v protocol.VersionNumber, params *TransportParameters) *paramsNegotiator {
|
|
h := ¶msNegotiator{}
|
|
h.perspective = pers
|
|
h.version = v
|
|
h.init(params)
|
|
return h
|
|
}
|
|
|
|
func (h *paramsNegotiator) SetFromTransportParameters(params []transportParameter) error {
|
|
h.mutex.Lock()
|
|
defer h.mutex.Unlock()
|
|
|
|
var foundInitialMaxStreamData bool
|
|
var foundInitialMaxData bool
|
|
var foundInitialMaxStreamID bool
|
|
var foundIdleTimeout bool
|
|
|
|
for _, p := range params {
|
|
switch p.Parameter {
|
|
case initialMaxStreamDataParameterID:
|
|
foundInitialMaxStreamData = true
|
|
if len(p.Value) != 4 {
|
|
return fmt.Errorf("wrong length for initial_max_stream_data: %d (expected 4)", len(p.Value))
|
|
}
|
|
h.sendStreamFlowControlWindow = protocol.ByteCount(binary.BigEndian.Uint32(p.Value))
|
|
utils.Debugf("h.sendStreamFlowControlWindow: %#x", h.sendStreamFlowControlWindow)
|
|
case initialMaxDataParameterID:
|
|
foundInitialMaxData = true
|
|
if len(p.Value) != 4 {
|
|
return fmt.Errorf("wrong length for initial_max_data: %d (expected 4)", len(p.Value))
|
|
}
|
|
h.sendConnectionFlowControlWindow = protocol.ByteCount(binary.BigEndian.Uint32(p.Value))
|
|
utils.Debugf("h.sendConnectionFlowControlWindow: %#x", h.sendConnectionFlowControlWindow)
|
|
case initialMaxStreamIDParameterID:
|
|
foundInitialMaxStreamID = true
|
|
if len(p.Value) != 4 {
|
|
return fmt.Errorf("wrong length for initial_max_stream_id: %d (expected 4)", len(p.Value))
|
|
}
|
|
// TODO: handle this value
|
|
case idleTimeoutParameterID:
|
|
foundIdleTimeout = true
|
|
if len(p.Value) != 2 {
|
|
return fmt.Errorf("wrong length for idle_timeout: %d (expected 2)", len(p.Value))
|
|
}
|
|
val := time.Duration(binary.BigEndian.Uint16(p.Value)) * time.Second
|
|
h.idleConnectionStateLifetime = h.negotiateIdleConnectionStateLifetime(val)
|
|
case omitConnectionIDParameterID:
|
|
if len(p.Value) != 0 {
|
|
return fmt.Errorf("wrong length for omit_connection_id: %d (expected empty)", len(p.Value))
|
|
}
|
|
h.omitConnectionID = true
|
|
}
|
|
}
|
|
|
|
if !(foundInitialMaxStreamData && foundInitialMaxData && foundInitialMaxStreamID && foundIdleTimeout) {
|
|
return errors.New("missing parameter")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (h *paramsNegotiator) GetTransportParameters() []transportParameter {
|
|
initialMaxStreamData := make([]byte, 4)
|
|
binary.BigEndian.PutUint32(initialMaxStreamData, uint32(h.GetReceiveStreamFlowControlWindow()))
|
|
initialMaxData := make([]byte, 4)
|
|
binary.BigEndian.PutUint32(initialMaxData, uint32(h.GetReceiveConnectionFlowControlWindow()))
|
|
initialMaxStreamID := make([]byte, 4)
|
|
// TODO: use a reasonable value here
|
|
binary.BigEndian.PutUint32(initialMaxStreamID, math.MaxUint32)
|
|
idleTimeout := make([]byte, 2)
|
|
binary.BigEndian.PutUint16(idleTimeout, uint16(h.GetIdleConnectionStateLifetime().Seconds()))
|
|
params := []transportParameter{
|
|
{initialMaxStreamDataParameterID, initialMaxStreamData},
|
|
{initialMaxDataParameterID, initialMaxData},
|
|
{initialMaxStreamIDParameterID, initialMaxStreamID},
|
|
{idleTimeoutParameterID, idleTimeout},
|
|
}
|
|
h.mutex.RLock()
|
|
defer h.mutex.RUnlock()
|
|
if h.omitConnectionID {
|
|
params = append(params, transportParameter{omitConnectionIDParameterID, []byte{}})
|
|
}
|
|
return params
|
|
}
|
|
|
|
func (h *paramsNegotiator) OmitConnectionID() bool {
|
|
h.mutex.RLock()
|
|
defer h.mutex.RUnlock()
|
|
return h.omitConnectionID
|
|
}
|