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

Allow use of custom port value in Alt-Svc header. #3272

Merged
merged 5 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func main() {
flag.Var(&bs, "bind", "bind to")
www := flag.String("www", "", "www data")
tcp := flag.Bool("tcp", false, "also listen on TCP")
customAltSvcPort := flag.Uint("customAltSvcPort", 0, "use custom Alt-Svc header port value")
enableQlog := flag.Bool("qlog", false, "output a qlog (in the same directory)")
flag.Parse()

Expand Down Expand Up @@ -182,7 +183,12 @@ func main() {
var err error
if *tcp {
certFile, keyFile := testdata.GetCertificatePaths()
err = http3.ListenAndServe(bCap, certFile, keyFile, handler)
if *customAltSvcPort != 0 {
logger.Infof("using customAltSvcPort = %v", *customAltSvcPort)
err = http3.ListenAndServeWithCustomAltSvcPort(bCap, certFile, keyFile, handler, uint32(*customAltSvcPort))
} else {
err = http3.ListenAndServe(bCap, certFile, keyFile, handler)
}
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is important enough to warrant complicating the example.

} else {
server := http3.Server{
Server: &http.Server{Handler: handler, Addr: bCap},
Expand Down
41 changes: 30 additions & 11 deletions http3/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ type Server struct {
// See https://www.ietf.org/archive/id/draft-schinazi-masque-h3-datagram-02.html.
EnableDatagrams bool

port uint32 // used atomically
port uint32 // used atomically
customAltSvcPort uint32 // custom port used for Alt-Svc response header
Copy link
Member

Choose a reason for hiding this comment

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

I think it should be fine just to export port here.


mutex sync.Mutex
listeners map[*quic.EarlyListener]struct{}
Expand Down Expand Up @@ -439,16 +440,22 @@ func (s *Server) SetQuicHeaders(hdr http.Header) error {
port := atomic.LoadUint32(&s.port)

if port == 0 {
// Extract port from s.Server.Addr
_, portStr, err := net.SplitHostPort(s.Server.Addr)
if err != nil {
return err
}
portInt, err := net.LookupPort("tcp", portStr)
if err != nil {
return err
if s.customAltSvcPort != 0 {
// Use customAltSvcPort if set
port = s.customAltSvcPort
} else {
// Extract port from s.Server.Addr
_, portStr, err := net.SplitHostPort(s.Server.Addr)
if err != nil {
return err
}
portInt, err := net.LookupPort("tcp", portStr)
if err != nil {
return err
}
port = uint32(portInt)
}
port = uint32(portInt)

atomic.StoreUint32(&s.port, port)
}

Expand Down Expand Up @@ -486,6 +493,17 @@ func ListenAndServeQUIC(addr, certFile, keyFile string, handler http.Handler) er
// http.DefaultServeMux is used when handler is nil.
// The correct Alt-Svc headers for QUIC are set.
func ListenAndServe(addr, certFile, keyFile string, handler http.Handler) error {
return ListenAndServeWithCustomAltSvcPort(addr, certFile, keyFile, handler, 0)
}

// ListenAndServeWithCustomAltSvcPort listens on the given network address for both, TLS and QUIC
// connetions in parallel. It returns if one of the two returns an error.
// http.DefaultServeMux is used when handler is nil.
// The correct Alt-Svc headers for QUIC are set.
// customAltSvcPort is used to override the default port value in the Alt-Svc response header.
// This is useful when a Layer 4 firewall is redirecting UDP traffic and clients must use
// a port different from the port the QUIC server itself is listening on.
func ListenAndServeWithCustomAltSvcPort(addr, certFile, keyFile string, handler http.Handler, customAltSvcPort uint32) error {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need an extra function here. Users who need to change the port should just initialize an http3.Server..

// Load certs
var err error
certs := make([]tls.Certificate, 1)
Expand Down Expand Up @@ -530,7 +548,8 @@ func ListenAndServe(addr, certFile, keyFile string, handler http.Handler) error
}

quicServer := &Server{
Server: httpServer,
Server: httpServer,
customAltSvcPort: customAltSvcPort,
Copy link
Contributor Author

@aaronriekenberg aaronriekenberg Sep 11, 2021

Choose a reason for hiding this comment

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

Another possible way to do this would be to just set Server.port to customAltSvcPort here, and then SetQuicHeaders would find port is always having a non-zero value. Open to suggestions of what you think is the best way to do this. :)

}

if handler == nil {
Expand Down