forked from quic-go/quic-go
@@ -25,7 +25,8 @@ func (u *packetUnpacker) Unpack(publicHeaderBinary []byte, publicHeader *PublicH
|
|||||||
ciphertext, _ := ioutil.ReadAll(r)
|
ciphertext, _ := ioutil.ReadAll(r)
|
||||||
plaintext, err := u.aead.Open(publicHeader.PacketNumber, publicHeaderBinary, ciphertext)
|
plaintext, err := u.aead.Open(publicHeader.PacketNumber, publicHeaderBinary, ciphertext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
// Wrap err in quicError so that public reset is sent by session
|
||||||
|
return nil, protocol.NewQuicError(errorcodes.QUIC_DECRYPTION_FAILURE, err.Error())
|
||||||
}
|
}
|
||||||
r = bytes.NewReader(plaintext)
|
r = bytes.NewReader(plaintext)
|
||||||
|
|
||||||
|
|||||||
20
session.go
20
session.go
@@ -51,7 +51,8 @@ type Session struct {
|
|||||||
closeChan chan struct{}
|
closeChan chan struct{}
|
||||||
closed bool
|
closed bool
|
||||||
|
|
||||||
// Used to calculate the next packet number from the truncated wire representation
|
// Used to calculate the next packet number from the truncated wire
|
||||||
|
// representation, and sent back in public reset packets
|
||||||
lastRcvdPacketNumber protocol.PacketNumber
|
lastRcvdPacketNumber protocol.PacketNumber
|
||||||
|
|
||||||
rttStats congestion.RTTStats
|
rttStats congestion.RTTStats
|
||||||
@@ -232,6 +233,11 @@ func (s *Session) Close(e error) error {
|
|||||||
errorCode = quicError.ErrorCode
|
errorCode = quicError.ErrorCode
|
||||||
}
|
}
|
||||||
s.closeStreamsWithError(e)
|
s.closeStreamsWithError(e)
|
||||||
|
|
||||||
|
if errorCode == errorcodes.QUIC_DECRYPTION_FAILURE {
|
||||||
|
return s.sendPublicReset(s.lastRcvdPacketNumber)
|
||||||
|
}
|
||||||
|
|
||||||
packet, err := s.packer.PackPacket(nil, []frames.Frame{
|
packet, err := s.packer.PackPacket(nil, []frames.Frame{
|
||||||
&frames.ConnectionCloseFrame{ErrorCode: errorCode, ReasonPhrase: reasonPhrase},
|
&frames.ConnectionCloseFrame{ErrorCode: errorCode, ReasonPhrase: reasonPhrase},
|
||||||
}, false)
|
}, false)
|
||||||
@@ -339,3 +345,15 @@ func (s *Session) garbageCollectStreams() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Session) sendPublicReset(rejectedPacketNumber protocol.PacketNumber) error {
|
||||||
|
fmt.Printf("Sending public reset for connection %d, packet number %d\n", s.connectionID, rejectedPacketNumber)
|
||||||
|
packet := &publicResetPacket{
|
||||||
|
connectionID: s.connectionID,
|
||||||
|
rejectedPacketNumber: rejectedPacketNumber,
|
||||||
|
nonceProof: 0, // TODO: Currently ignored by chrome.
|
||||||
|
}
|
||||||
|
var b bytes.Buffer
|
||||||
|
packet.Write(&b)
|
||||||
|
return s.conn.write(b.Bytes())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package quic
|
package quic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@@ -243,6 +244,13 @@ var _ = Describe("Session", func() {
|
|||||||
Expect(conn.written[0]).To(ContainSubstring(string([]byte{0x4c, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0})))
|
Expect(conn.written[0]).To(ContainSubstring(string([]byte{0x4c, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0})))
|
||||||
Expect(conn.written[0]).To(ContainSubstring(string("foobar")))
|
Expect(conn.written[0]).To(ContainSubstring(string("foobar")))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("sends public reset", func() {
|
||||||
|
err := session.sendPublicReset(1)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(conn.written).To(HaveLen(1))
|
||||||
|
Expect(conn.written[0]).To(ContainSubstring(string([]byte("PRST"))))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("closes when crypto stream errors", func() {
|
It("closes when crypto stream errors", func() {
|
||||||
@@ -263,4 +271,23 @@ var _ = Describe("Session", func() {
|
|||||||
_, err = s.Write([]byte{})
|
_, err = s.Write([]byte{})
|
||||||
Expect(err).To(MatchError("CryptoSetup: expected CHLO"))
|
Expect(err).To(MatchError("CryptoSetup: expected CHLO"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("sends public reset when receiving invalid message", func() {
|
||||||
|
path := os.Getenv("GOPATH") + "/src/github.com/lucas-clemente/quic-go/example/"
|
||||||
|
signer, err := crypto.NewRSASigner(path+"cert.der", path+"key.der")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
scfg := handshake.NewServerConfig(crypto.NewCurve25519KEX(), signer)
|
||||||
|
session = NewSession(conn, 0, 0, scfg, nil).(*Session)
|
||||||
|
hdr := &PublicHeader{
|
||||||
|
PacketNumber: 42,
|
||||||
|
}
|
||||||
|
r := bytes.NewReader([]byte("foo"))
|
||||||
|
err = session.handlePacket(nil, hdr, r)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
// Close() should send public reset
|
||||||
|
err = session.Close(err)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(conn.written).To(HaveLen(1))
|
||||||
|
Expect(conn.written[0]).To(ContainSubstring(string([]byte("PRST"))))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user