mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 21:15:39 +00:00
e415991256
* advertise server's DERP public key following its ServerHello * have client look for that DEPR public key in the response PeerCertificates * let client advertise it's going into a "fast start" mode if it finds it * modify server to support that fast start mode, just not sending the HTTP response header Cuts down another round trip, bringing the latency of being able to write our first DERP frame from SF to Bangalore from ~725ms (3 RTT) to ~481ms (2 RTT: TCP and TLS). Fixes #693 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package derphttp
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
|
|
"tailscale.com/derp"
|
|
)
|
|
|
|
// fastStartHeader is the header (with value "1") that signals to the HTTP
|
|
// server that the DERP HTTP client does not want the HTTP 101 response
|
|
// headers and it will begin writing & reading the DERP protocol immediately
|
|
// following its HTTP request.
|
|
const fastStartHeader = "Derp-Fast-Start"
|
|
|
|
func Handler(s *derp.Server) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if p := r.Header.Get("Upgrade"); p != "WebSocket" && p != "DERP" {
|
|
http.Error(w, "DERP requires connection upgrade", http.StatusUpgradeRequired)
|
|
return
|
|
}
|
|
fastStart := r.Header.Get(fastStartHeader) == "1"
|
|
|
|
h, ok := w.(http.Hijacker)
|
|
if !ok {
|
|
http.Error(w, "HTTP does not support general TCP support", 500)
|
|
return
|
|
}
|
|
|
|
netConn, conn, err := h.Hijack()
|
|
if err != nil {
|
|
log.Printf("Hijack failed: %v", err)
|
|
http.Error(w, "HTTP does not support general TCP support", 500)
|
|
return
|
|
}
|
|
|
|
if !fastStart {
|
|
pubKey := s.PublicKey()
|
|
fmt.Fprintf(conn, "HTTP/1.1 101 Switching Protocols\r\n"+
|
|
"Upgrade: DERP\r\n"+
|
|
"Connection: Upgrade\r\n"+
|
|
"Derp-Version: %v\r\n"+
|
|
"Derp-Public-Key: %x\r\n\r\n",
|
|
derp.ProtocolVersion,
|
|
pubKey[:])
|
|
}
|
|
|
|
s.Accept(netConn, conn, netConn.RemoteAddr().String())
|
|
})
|
|
}
|