forked from quic-go/quic-go
10
session.go
10
session.go
@@ -272,10 +272,14 @@ func (s *Session) handlePacketImpl(p *receivedPacket) error {
|
||||
utils.Debugf("<- Reading packet 0x%x (%d bytes) for connection %x @ %s", hdr.PacketNumber, len(data)+len(hdr.Raw), hdr.ConnectionID, time.Now().Format("15:04:05.000"))
|
||||
}
|
||||
|
||||
// TODO: Only do this after authenticating
|
||||
s.conn.setCurrentRemoteAddr(p.remoteAddr)
|
||||
|
||||
packet, err := s.unpacker.Unpack(hdr.Raw, hdr, data)
|
||||
// if the decryption failed, this might be a packet sent by an attacker
|
||||
// don't update the remote address
|
||||
if quicErr, ok := err.(*qerr.QuicError); ok && quicErr.ErrorCode == qerr.DecryptionFailure {
|
||||
return err
|
||||
}
|
||||
// update the remote address, even if unpacking failed for any other reason than a decryption error
|
||||
s.conn.setCurrentRemoteAddr(p.remoteAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ import (
|
||||
)
|
||||
|
||||
type mockConnection struct {
|
||||
written [][]byte
|
||||
remoteAddr net.IP
|
||||
written [][]byte
|
||||
}
|
||||
|
||||
func (m *mockConnection) write(p []byte) error {
|
||||
@@ -35,12 +36,21 @@ func (m *mockConnection) write(p []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*mockConnection) setCurrentRemoteAddr(addr interface{}) {}
|
||||
func (*mockConnection) RemoteAddr() *net.UDPAddr { return &net.UDPAddr{} }
|
||||
func (m *mockConnection) setCurrentRemoteAddr(addr interface{}) {
|
||||
if ip, ok := addr.(net.IP); ok {
|
||||
m.remoteAddr = ip
|
||||
}
|
||||
}
|
||||
func (*mockConnection) RemoteAddr() *net.UDPAddr { return &net.UDPAddr{} }
|
||||
|
||||
type mockUnpacker struct{}
|
||||
type mockUnpacker struct {
|
||||
unpackErr error
|
||||
}
|
||||
|
||||
func (m *mockUnpacker) Unpack(publicHeaderBinary []byte, hdr *PublicHeader, data []byte) (*unpackedPacket, error) {
|
||||
if m.unpackErr != nil {
|
||||
return nil, m.unpackErr
|
||||
}
|
||||
return &unpackedPacket{
|
||||
frames: nil,
|
||||
}, nil
|
||||
@@ -613,6 +623,51 @@ var _ = Describe("Session", func() {
|
||||
err = session.handlePacketImpl(&receivedPacket{publicHeader: hdr})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("updating the remote address", func() {
|
||||
It("sets the remote address", func() {
|
||||
remoteIP := net.IPv4(192, 168, 0, 100)
|
||||
Expect(session.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
||||
p := receivedPacket{
|
||||
remoteAddr: remoteIP,
|
||||
publicHeader: &PublicHeader{PacketNumber: 1337},
|
||||
}
|
||||
err := session.handlePacketImpl(&p)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(session.conn.(*mockConnection).remoteAddr).To(Equal(remoteIP))
|
||||
})
|
||||
|
||||
It("doesn't change the remote address if authenticating the packet fails", func() {
|
||||
remoteIP := net.IPv4(192, 168, 0, 100)
|
||||
attackerIP := net.IPv4(192, 168, 0, 102)
|
||||
session.conn.(*mockConnection).remoteAddr = remoteIP
|
||||
// use the real packetUnpacker here, to make sure this test fails if the error code for failed decryption changes
|
||||
session.unpacker = &packetUnpacker{}
|
||||
session.unpacker.(*packetUnpacker).aead = &crypto.NullAEAD{}
|
||||
p := receivedPacket{
|
||||
remoteAddr: attackerIP,
|
||||
publicHeader: &PublicHeader{PacketNumber: 1337},
|
||||
}
|
||||
err := session.handlePacketImpl(&p)
|
||||
quicErr := err.(*qerr.QuicError)
|
||||
Expect(quicErr.ErrorCode).To(Equal(qerr.DecryptionFailure))
|
||||
Expect(session.conn.(*mockConnection).remoteAddr).To(Equal(remoteIP))
|
||||
})
|
||||
|
||||
It("sets the remote address, if the packet is authenticated, but unpacking fails for another reason", func() {
|
||||
testErr := errors.New("testErr")
|
||||
remoteIP := net.IPv4(192, 168, 0, 100)
|
||||
Expect(session.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
||||
p := receivedPacket{
|
||||
remoteAddr: remoteIP,
|
||||
publicHeader: &PublicHeader{PacketNumber: 1337},
|
||||
}
|
||||
session.unpacker.(*mockUnpacker).unpackErr = testErr
|
||||
err := session.handlePacketImpl(&p)
|
||||
Expect(err).To(MatchError(testErr))
|
||||
Expect(session.conn.(*mockConnection).remoteAddr).To(Equal(remoteIP))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("sending packets", func() {
|
||||
|
||||
Reference in New Issue
Block a user