mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
http3: send SETTINGS_ENABLE_CONNECT_PROTOCOL (for Extended CONNECT) (#4341)
This commit is contained in:
parent
0405634108
commit
9813766373
3 changed files with 83 additions and 12 deletions
|
@ -88,10 +88,17 @@ func (f *headersFrame) Append(b []byte) []byte {
|
|||
return quicvarint.Append(b, f.Length)
|
||||
}
|
||||
|
||||
const settingDatagram = 0x33
|
||||
const (
|
||||
// Extended CONNECT, RFC 9220
|
||||
settingExtendedConnect = 0x8
|
||||
// HTTP Datagrams, RFC 9297
|
||||
settingDatagram = 0x33
|
||||
)
|
||||
|
||||
type settingsFrame struct {
|
||||
Datagram bool
|
||||
Datagram bool // HTTP Datagrams, RFC 9297
|
||||
ExtendedConnect bool // Extended CONNECT, RFC 9220
|
||||
|
||||
Other map[uint64]uint64 // all settings that we don't explicitly recognize
|
||||
}
|
||||
|
||||
|
@ -108,7 +115,7 @@ func parseSettingsFrame(r io.Reader, l uint64) (*settingsFrame, error) {
|
|||
}
|
||||
frame := &settingsFrame{}
|
||||
b := bytes.NewReader(buf)
|
||||
var readDatagram bool
|
||||
var readDatagram, readExtendedConnect bool
|
||||
for b.Len() > 0 {
|
||||
id, err := quicvarint.Read(b)
|
||||
if err != nil { // should not happen. We allocated the whole frame already.
|
||||
|
@ -120,13 +127,22 @@ func parseSettingsFrame(r io.Reader, l uint64) (*settingsFrame, error) {
|
|||
}
|
||||
|
||||
switch id {
|
||||
case settingExtendedConnect:
|
||||
if readExtendedConnect {
|
||||
return nil, fmt.Errorf("duplicate setting: %d", id)
|
||||
}
|
||||
readExtendedConnect = true
|
||||
if val != 0 && val != 1 {
|
||||
return nil, fmt.Errorf("invalid value for SETTINGS_ENABLE_CONNECT_PROTOCOL: %d", val)
|
||||
}
|
||||
frame.ExtendedConnect = val == 1
|
||||
case settingDatagram:
|
||||
if readDatagram {
|
||||
return nil, fmt.Errorf("duplicate setting: %d", id)
|
||||
}
|
||||
readDatagram = true
|
||||
if val != 0 && val != 1 {
|
||||
return nil, fmt.Errorf("invalid value for H3_DATAGRAM: %d", val)
|
||||
return nil, fmt.Errorf("invalid value for SETTINGS_H3_DATAGRAM: %d", val)
|
||||
}
|
||||
frame.Datagram = val == 1
|
||||
default:
|
||||
|
@ -151,11 +167,18 @@ func (f *settingsFrame) Append(b []byte) []byte {
|
|||
if f.Datagram {
|
||||
l += quicvarint.Len(settingDatagram) + quicvarint.Len(1)
|
||||
}
|
||||
if f.ExtendedConnect {
|
||||
l += quicvarint.Len(settingExtendedConnect) + quicvarint.Len(1)
|
||||
}
|
||||
b = quicvarint.Append(b, uint64(l))
|
||||
if f.Datagram {
|
||||
b = quicvarint.Append(b, settingDatagram)
|
||||
b = quicvarint.Append(b, 1)
|
||||
}
|
||||
if f.ExtendedConnect {
|
||||
b = quicvarint.Append(b, settingExtendedConnect)
|
||||
b = quicvarint.Append(b, 1)
|
||||
}
|
||||
for id, val := range f.Other {
|
||||
b = quicvarint.Append(b, id)
|
||||
b = quicvarint.Append(b, val)
|
||||
|
|
|
@ -127,8 +127,8 @@ var _ = Describe("Frames", func() {
|
|||
}
|
||||
})
|
||||
|
||||
Context("H3_DATAGRAM", func() {
|
||||
It("reads the H3_DATAGRAM value", func() {
|
||||
Context("HTTP Datagrams", func() {
|
||||
It("reads the SETTINGS_H3_DATAGRAM value", func() {
|
||||
settings := quicvarint.Append(nil, settingDatagram)
|
||||
settings = quicvarint.Append(settings, 1)
|
||||
data := quicvarint.Append(nil, 4) // type byte
|
||||
|
@ -141,7 +141,7 @@ var _ = Describe("Frames", func() {
|
|||
Expect(sf.Datagram).To(BeTrue())
|
||||
})
|
||||
|
||||
It("rejects duplicate H3_DATAGRAM entries", func() {
|
||||
It("rejects duplicate SETTINGS_H3_DATAGRAM entries", func() {
|
||||
settings := quicvarint.Append(nil, settingDatagram)
|
||||
settings = quicvarint.Append(settings, 1)
|
||||
settings = quicvarint.Append(settings, settingDatagram)
|
||||
|
@ -153,23 +153,67 @@ var _ = Describe("Frames", func() {
|
|||
Expect(err).To(MatchError(fmt.Sprintf("duplicate setting: %d", settingDatagram)))
|
||||
})
|
||||
|
||||
It("rejects invalid values for the H3_DATAGRAM entry", func() {
|
||||
It("rejects invalid values for the SETTINGS_H3_DATAGRAM entry", func() {
|
||||
settings := quicvarint.Append(nil, settingDatagram)
|
||||
settings = quicvarint.Append(settings, 1337)
|
||||
data := quicvarint.Append(nil, 4) // type byte
|
||||
data = quicvarint.Append(data, uint64(len(settings)))
|
||||
data = append(data, settings...)
|
||||
_, err := parseNextFrame(bytes.NewReader(data), nil)
|
||||
Expect(err).To(MatchError("invalid value for H3_DATAGRAM: 1337"))
|
||||
Expect(err).To(MatchError("invalid value for SETTINGS_H3_DATAGRAM: 1337"))
|
||||
})
|
||||
|
||||
It("writes the H3_DATAGRAM setting", func() {
|
||||
It("writes the SETTINGS_H3_DATAGRAM setting", func() {
|
||||
sf := &settingsFrame{Datagram: true}
|
||||
frame, err := parseNextFrame(bytes.NewReader(sf.Append(nil)), nil)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(frame).To(Equal(sf))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Extended Connect", func() {
|
||||
It("reads the SETTINGS_ENABLE_CONNECT_PROTOCOL value", func() {
|
||||
settings := quicvarint.Append(nil, settingExtendedConnect)
|
||||
settings = quicvarint.Append(settings, 1)
|
||||
data := quicvarint.Append(nil, 4) // type byte
|
||||
data = quicvarint.Append(data, uint64(len(settings)))
|
||||
data = append(data, settings...)
|
||||
f, err := parseNextFrame(bytes.NewReader(data), nil)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(f).To(BeAssignableToTypeOf(&settingsFrame{}))
|
||||
sf := f.(*settingsFrame)
|
||||
Expect(sf.ExtendedConnect).To(BeTrue())
|
||||
})
|
||||
|
||||
It("rejects duplicate SETTINGS_ENABLE_CONNECT_PROTOCOL entries", func() {
|
||||
settings := quicvarint.Append(nil, settingExtendedConnect)
|
||||
settings = quicvarint.Append(settings, 1)
|
||||
settings = quicvarint.Append(settings, settingExtendedConnect)
|
||||
settings = quicvarint.Append(settings, 1)
|
||||
data := quicvarint.Append(nil, 4) // type byte
|
||||
data = quicvarint.Append(data, uint64(len(settings)))
|
||||
data = append(data, settings...)
|
||||
_, err := parseNextFrame(bytes.NewReader(data), nil)
|
||||
Expect(err).To(MatchError(fmt.Sprintf("duplicate setting: %d", settingExtendedConnect)))
|
||||
})
|
||||
|
||||
It("rejects invalid values for the SETTINGS_ENABLE_CONNECT_PROTOCOL entry", func() {
|
||||
settings := quicvarint.Append(nil, settingExtendedConnect)
|
||||
settings = quicvarint.Append(settings, 1337)
|
||||
data := quicvarint.Append(nil, 4) // type byte
|
||||
data = quicvarint.Append(data, uint64(len(settings)))
|
||||
data = append(data, settings...)
|
||||
_, err := parseNextFrame(bytes.NewReader(data), nil)
|
||||
Expect(err).To(MatchError("invalid value for SETTINGS_ENABLE_CONNECT_PROTOCOL: 1337"))
|
||||
})
|
||||
|
||||
It("writes the SETTINGS_ENABLE_CONNECT_PROTOCOL setting", func() {
|
||||
sf := &settingsFrame{ExtendedConnect: true}
|
||||
frame, err := parseNextFrame(bytes.NewReader(sf.Append(nil)), nil)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(frame).To(Equal(sf))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("hijacking", func() {
|
||||
|
|
|
@ -451,7 +451,11 @@ func (s *Server) handleConn(conn quic.Connection) error {
|
|||
}
|
||||
b := make([]byte, 0, 64)
|
||||
b = quicvarint.Append(b, streamTypeControlStream) // stream type
|
||||
b = (&settingsFrame{Datagram: s.EnableDatagrams, Other: s.AdditionalSettings}).Append(b)
|
||||
b = (&settingsFrame{
|
||||
Datagram: s.EnableDatagrams,
|
||||
ExtendedConnect: true,
|
||||
Other: s.AdditionalSettings,
|
||||
}).Append(b)
|
||||
str.Write(b)
|
||||
|
||||
go s.handleUnidirectionalStreams(conn)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue