Skip to content

Commit

Permalink
Use ConnContext (#57)
Browse files Browse the repository at this point in the history
### Description

Now that `ConnContext` is available in `http3.Server`, we don't need to
create a new `http3.Server` for every new connection.

Depends on quic-go/quic-go#4230

### Type of change

* [ ] New feature
* [x] Feature improvement
* [ ] Bug fix
* [ ] Documentation
* [ ] Cleanup / refactoring
* [ ] Other (please explain)


### How is this change tested ?

* [x] Unit tests
* [ ] Manual tests (explain)
* [ ] Tests are not needed
  • Loading branch information
rthellend committed Jan 18, 2024
1 parent 45ea704 commit 5d6462c
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 18 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# TLSPROXY Release Notes

* Report outbound connections on the metrics page.
* Improve how http3 connections are handled.
* Update go dependencies:
* upgraded github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 => v0.0.0-20240117000934-35fc243c5815
* upgraded github.com/onsi/ginkgo/v2 v2.13.2 => v2.14.0
* upgraded github.com/quic-go/quic-go v0.40.1 => v0.41.0
* upgraded golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc => v0.0.0-20240112132812-db7319d0e0e3
* upgraded golang.org/x/tools v0.16.1 => v0.17.0
* Report outbound connections on the metrics page.

## v0.5.1

Expand Down
2 changes: 1 addition & 1 deletion proxy/backend-http.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (be *Backend) reverseProxy() http.Handler {
}

func (be *Backend) setAltSvc(header http.Header, req *http.Request) {
if be.http3Handler == nil {
if be.http3Server == nil {
return
}
if req.TLS != nil && req.TLS.NegotiatedProtocol == "h3" {
Expand Down
8 changes: 8 additions & 0 deletions proxy/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,21 @@ func (be *Backend) close(ctx context.Context) {
be.httpServer.Close()
close(be.httpConnChan)
be.httpServer = nil
if h3 := be.http3Server; h3 != nil {
be.http3Server = nil
h3.Close()
}
return
}
go be.httpServer.Shutdown(ctx)
be.shutdown = true
if be.inFlight == 0 {
close(be.httpConnChan)
be.httpServer = nil
if h3 := be.http3Server; h3 != nil {
be.http3Server = nil
h3.Close()
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion proxy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ type Backend struct {

httpServer *http.Server
httpConnChan chan net.Conn
http3Handler http.Handler
http3Server io.Closer
localHandlers []localHandler
outConns *connTracker

Expand Down
5 changes: 5 additions & 0 deletions proxy/noquic.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"context"
"crypto/tls"
"errors"
"io"
"net"
"net/http"
)
Expand All @@ -48,3 +49,7 @@ func (be *Backend) dialQUICStream(context.Context, string, *tls.Config) (net.Con
func (be *Backend) http3Transport() http.RoundTripper {
return nil
}

func http3Server(http.Handler) io.Closer {
return nil
}
10 changes: 5 additions & 5 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,22 +684,22 @@ func (p *Proxy) Reconfigure(cfg *Config) error {
be.httpConnChan = make(chan net.Conn)
be.httpServer = startInternalHTTPServer(be.localHandler(), be.httpConnChan)
if *cfg.EnableQUIC && be.ALPNProtos != nil && slices.Contains(*be.ALPNProtos, "h3") {
be.http3Handler = be.localHandler()
be.http3Server = http3Server(be.localHandler())
}

case ModeLocal:
be.httpConnChan = make(chan net.Conn)
be.httpServer = startInternalHTTPServer(be.localHandler(), be.httpConnChan)
if *cfg.EnableQUIC && be.ALPNProtos != nil && slices.Contains(*be.ALPNProtos, "h3") {
be.http3Handler = be.localHandler()
be.http3Server = http3Server(be.localHandler())
}

case ModeHTTPS, ModeHTTP:
if *cfg.EnableQUIC && be.ALPNProtos != nil && slices.Contains(*be.ALPNProtos, "h3") {
be.http3Handler = be.reverseProxy()
}
be.httpConnChan = make(chan net.Conn)
be.httpServer = startInternalHTTPServer(be.reverseProxy(), be.httpConnChan)
if *cfg.EnableQUIC && be.ALPNProtos != nil && slices.Contains(*be.ALPNProtos, "h3") {
be.http3Server = http3Server(be.reverseProxy())
}
}
}

Expand Down
20 changes: 10 additions & 10 deletions proxy/quic.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,7 @@ func (p *Proxy) handleQUICConnection(qc *netw.QUICConn) {
log.Printf("ERR [%s] %s:%s ➔ %s|%s:%s %s: %v", sum, qc.RemoteAddr().Network(), qc.RemoteAddr(), idnaToUnicode(cs.ServerName), be.Mode, cs.NegotiatedProtocol, tag, err)
}

if be.http3Handler != nil && cs.NegotiatedProtocol == "h3" {
// Creating a new http3 server for every request isn't great,
// but it seems to be the only way to pass a context value to
// the request.
serv := &http3.Server{
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
req = req.WithContext(context.WithValue(req.Context(), connCtxKey, qc))
be.http3Handler.ServeHTTP(w, req)
}),
}
if serv, ok := be.http3Server.(*http3.Server); ok && cs.NegotiatedProtocol == "h3" {
if err := serv.ServeQUICConn(qc); err != nil {
reportErr(err, "ServeQUICConn")
}
Expand Down Expand Up @@ -567,3 +558,12 @@ func (be *Backend) http3Transport() http.RoundTripper {
},
}
}

func http3Server(handler http.Handler) *http3.Server {
return &http3.Server{
Handler: handler,
ConnContext: func(ctx context.Context, c quic.Connection) context.Context {
return context.WithValue(ctx, connCtxKey, c)
},
}
}

0 comments on commit 5d6462c

Please sign in to comment.