Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set a net.Conn with the correct addresses on the tls.ClientHelloInfo #4001

Merged
merged 1 commit into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ var newConnection = func(
}
cs := handshake.NewCryptoSetupServer(
clientDestConnID,
conn.LocalAddr(),
conn.RemoteAddr(),
params,
tlsConf,
conf.Allow0RTT,
Expand Down
3 changes: 3 additions & 0 deletions fuzzing/handshake/cmd/corpus.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"crypto/tls"
"log"
"net"

fuzzhandshake "github.com/quic-go/quic-go/fuzzing/handshake"
"github.com/quic-go/quic-go/fuzzing/internal/helper"
Expand Down Expand Up @@ -37,6 +38,8 @@ func main() {
config.NextProtos = []string{alpn}
server := handshake.NewCryptoSetupServer(
protocol.ConnectionID{},
&net.UDPAddr{IP: net.IPv6loopback, Port: 1234},
&net.UDPAddr{IP: net.IPv6loopback, Port: 4321},
&wire.TransportParameters{ActiveConnectionIDLimit: 2},
config,
false,
Expand Down
3 changes: 3 additions & 0 deletions fuzzing/handshake/fuzz.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"log"
"math"
mrand "math/rand"
"net"
"time"

"github.com/quic-go/quic-go/fuzzing/internal/helper"
Expand Down Expand Up @@ -304,6 +305,8 @@ func runHandshake(runConfig [confLen]byte, messageConfig uint8, clientConf *tls.

server := handshake.NewCryptoSetupServer(
protocol.ConnectionID{},
&net.UDPAddr{IP: net.IPv6loopback, Port: 1234},
&net.UDPAddr{IP: net.IPv6loopback, Port: 4321},
serverTP,
serverConf,
enable0RTTServer,
Expand Down
24 changes: 24 additions & 0 deletions integrationtests/self/handshake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,30 @@ var _ = Describe("Handshake tests", func() {
Expect(err).ToNot(HaveOccurred())
})

It("has the right local and remote address on the ClientHelloInfo.Conn", func() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now including an end-to-end test to make sure this API never accidentally breaks again.

var local, remote net.Addr
done := make(chan struct{})
tlsConf := &tls.Config{
GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) {
defer close(done)
local = info.Conn.LocalAddr()
remote = info.Conn.RemoteAddr()
return getTLSConfig(), nil
},
}
runServer(tlsConf)
conn, err := quic.DialAddr(
context.Background(),
fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
getTLSClientConfig(),
getQuicConfig(nil),
)
Expect(err).ToNot(HaveOccurred())
Eventually(done).Should(BeClosed())
Expect(server.Addr()).To(Equal(local))
Expect(conn.LocalAddr().(*net.UDPAddr).Port).To(Equal(remote.(*net.UDPAddr).Port))
})

It("works with a long certificate chain", func() {
runServer(getTLSConfigWithLongCertChain())
_, err := quic.DialAddr(
Expand Down
21 changes: 21 additions & 0 deletions internal/handshake/conn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package handshake

import (
"net"
"time"
)

type conn struct {
localAddr, remoteAddr net.Addr
}

var _ net.Conn = &conn{}

func (c *conn) Read([]byte) (int, error) { return 0, nil }
func (c *conn) Write([]byte) (int, error) { return 0, nil }
func (c *conn) Close() error { return nil }
func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr }
func (c *conn) LocalAddr() net.Addr { return c.localAddr }
func (c *conn) SetReadDeadline(time.Time) error { return nil }
func (c *conn) SetWriteDeadline(time.Time) error { return nil }
func (c *conn) SetDeadline(time.Time) error { return nil }
9 changes: 9 additions & 0 deletions internal/handshake/crypto_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"net"
"sync"
"sync/atomic"
"time"
Expand Down Expand Up @@ -104,6 +105,7 @@ func NewCryptoSetupClient(
// NewCryptoSetupServer creates a new crypto setup for the server
func NewCryptoSetupServer(
connID protocol.ConnectionID,
localAddr, remoteAddr net.Addr,
tp *wire.TransportParameters,
tlsConf *tls.Config,
allow0RTT bool,
Expand All @@ -125,6 +127,13 @@ func NewCryptoSetupServer(

quicConf := &qtls.QUICConfig{TLSConfig: tlsConf}
qtls.SetupConfigForServer(quicConf, cs.allow0RTT, cs.getDataForSessionTicket, cs.accept0RTT)
if quicConf.TLSConfig.GetConfigForClient != nil {
gcfc := quicConf.TLSConfig.GetConfigForClient
quicConf.TLSConfig.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) {
info.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr}
return gcfc(info)
}
}

cs.tlsConf = quicConf.TLSConfig
cs.conn = qtls.QUICServer(quicConf)
Expand Down
7 changes: 7 additions & 0 deletions internal/handshake/crypto_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"net"
"time"

mocktls "github.com/quic-go/quic-go/internal/mocks/tls"
Expand Down Expand Up @@ -65,6 +66,8 @@ var _ = Describe("Crypto Setup TLS", func() {
var token protocol.StatelessResetToken
server := NewCryptoSetupServer(
protocol.ConnectionID{},
&net.UDPAddr{IP: net.IPv6loopback, Port: 1234},
&net.UDPAddr{IP: net.IPv6loopback, Port: 4321},
&wire.TransportParameters{StatelessResetToken: &token},
testdata.GetTLSConfig(),
false,
Expand Down Expand Up @@ -204,6 +207,8 @@ var _ = Describe("Crypto Setup TLS", func() {
}
server := NewCryptoSetupServer(
protocol.ConnectionID{},
&net.UDPAddr{IP: net.IPv6loopback, Port: 1234},
&net.UDPAddr{IP: net.IPv6loopback, Port: 4321},
serverTransportParameters,
serverConf,
enable0RTT,
Expand Down Expand Up @@ -273,6 +278,8 @@ var _ = Describe("Crypto Setup TLS", func() {
}
server := NewCryptoSetupServer(
protocol.ConnectionID{},
&net.UDPAddr{IP: net.IPv6loopback, Port: 1234},
&net.UDPAddr{IP: net.IPv6loopback, Port: 4321},
sTransportParameters,
serverConf,
false,
Expand Down