mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-05 23:07:44 +00:00
ipn/ipnserver: only permit the pre-HTTP LocalAPI protocol on Windows
Updates #6417 Change-Id: I1c9dbee3f72969f703b3ff2dbbaa145a17db868b Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
033bd94d4c
commit
250edeb3da
@ -165,11 +165,38 @@ func bufferIsConnect(br *bufio.Reader) bool {
|
||||
return mem.HasPrefix(mem.B(peek), mem.S("CONN"))
|
||||
}
|
||||
|
||||
// permitOldProtocol is whether we permit the old pre-HTTP protocol from the
|
||||
// client (cmd/tailscale or GUI client) to the tailscaled server.
|
||||
//
|
||||
// This is currently (2022-11-24) only permitted on Windows. There is an
|
||||
// outstanding change to the Windows GUI to finish the migration to the
|
||||
// HTTP-based protocol. Once it's in, this constant will go away and the old
|
||||
// protocol will not be permitted for any platform.
|
||||
const permitOldProtocol = runtime.GOOS == "windows"
|
||||
|
||||
// ipnProtoAndMethodSniffTimeout returns the read timeout to try to read a few
|
||||
// bytes from incoming IPN connection to determine whether it's an old-style
|
||||
// IPN bus connection or a new-style HTTP connection. And if an HTTP connection,
|
||||
// what its HTTP method is.
|
||||
func ipnProtoAndMethodSniffTimeout() time.Duration {
|
||||
if permitOldProtocol {
|
||||
// In the old protocol, the client might not be sending anything at all
|
||||
// and only receiving, so keep a short timeout as to not delay
|
||||
// connecting to the IPN bus and getting ipn.Notify messages.
|
||||
return 1 * time.Second
|
||||
}
|
||||
// But in the new protocol, there will always be an HTTP request to start,
|
||||
// so we can take a long time to receive the first few bytes. 30s is
|
||||
// overkill.
|
||||
return 30 * time.Second
|
||||
}
|
||||
|
||||
func (s *Server) serveConn(ctx context.Context, c net.Conn, logf logger.Logf) {
|
||||
// First see if it's an HTTP request.
|
||||
// First sniff a few bytes to see if it's an HTTP request. And if so, which
|
||||
// HTTP method.
|
||||
br := bufio.NewReader(c)
|
||||
c.SetReadDeadline(time.Now().Add(time.Second))
|
||||
br.Peek(4)
|
||||
c.SetReadDeadline(time.Now().Add(ipnProtoAndMethodSniffTimeout()))
|
||||
br.Peek(4) // either 4 bytes old protocol length header, or HTTP "GET " etc.
|
||||
c.SetReadDeadline(time.Time{})
|
||||
|
||||
// Handle logtail CONNECT requests early. (See docs on handleProxyConnectConn)
|
||||
@ -178,7 +205,10 @@ func (s *Server) serveConn(ctx context.Context, c net.Conn, logf logger.Logf) {
|
||||
return
|
||||
}
|
||||
|
||||
isHTTPReq := bufferHasHTTPRequest(br)
|
||||
// If we don't permit the old "IPN bus" JSON bidi stream protocol, then
|
||||
// assume it's HTTP. Otherwise sniff the first few bytes to see if it looks
|
||||
// like HTTP.
|
||||
isHTTPReq := !permitOldProtocol || bufferHasHTTPRequest(br)
|
||||
|
||||
ci, err := s.addConn(c, isHTTPReq)
|
||||
if err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user