mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 02:01:14 +01:00 
			
		
		
		
	Change-Id: I6b790e92dcc608515ac8b178f2271adc9fd98f78 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
		
			
				
	
	
		
			79 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			79 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 resolver
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"html"
 | 
						|
	"net/http"
 | 
						|
	"strconv"
 | 
						|
	"sync"
 | 
						|
	"sync/atomic"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"tailscale.com/health"
 | 
						|
)
 | 
						|
 | 
						|
func init() {
 | 
						|
	health.RegisterDebugHandler("dnsfwd", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
						|
		n, _ := strconv.Atoi(r.FormValue("n"))
 | 
						|
		if n <= 0 {
 | 
						|
			n = 100
 | 
						|
		} else if n > 10000 {
 | 
						|
			n = 10000
 | 
						|
		}
 | 
						|
		fl, ok := fwdLogAtomic.Load().(*fwdLog)
 | 
						|
		if !ok || n != len(fl.ent) {
 | 
						|
			fl = &fwdLog{ent: make([]fwdLogEntry, n)}
 | 
						|
			fwdLogAtomic.Store(fl)
 | 
						|
		}
 | 
						|
		fl.ServeHTTP(w, r)
 | 
						|
	}))
 | 
						|
}
 | 
						|
 | 
						|
var fwdLogAtomic atomic.Value // of *fwdLog
 | 
						|
 | 
						|
type fwdLog struct {
 | 
						|
	mu  sync.Mutex
 | 
						|
	pos int // ent[pos] is next entry
 | 
						|
	ent []fwdLogEntry
 | 
						|
}
 | 
						|
 | 
						|
type fwdLogEntry struct {
 | 
						|
	Domain string
 | 
						|
	Time   time.Time
 | 
						|
}
 | 
						|
 | 
						|
func (fl *fwdLog) addName(name string) {
 | 
						|
	if fl == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	fl.mu.Lock()
 | 
						|
	defer fl.mu.Unlock()
 | 
						|
	if len(fl.ent) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	fl.ent[fl.pos] = fwdLogEntry{Domain: name, Time: time.Now()}
 | 
						|
	fl.pos++
 | 
						|
	if fl.pos == len(fl.ent) {
 | 
						|
		fl.pos = 0
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (fl *fwdLog) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
	fl.mu.Lock()
 | 
						|
	defer fl.mu.Unlock()
 | 
						|
 | 
						|
	fmt.Fprintf(w, "<html><h1>DNS forwards</h1>")
 | 
						|
	now := time.Now()
 | 
						|
	for i := 0; i < len(fl.ent); i++ {
 | 
						|
		ent := fl.ent[(i+fl.pos)%len(fl.ent)]
 | 
						|
		if ent.Domain == "" {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		fmt.Fprintf(w, "%v ago: %v<br>\n", now.Sub(ent.Time).Round(time.Second), html.EscapeString(ent.Domain))
 | 
						|
	}
 | 
						|
}
 |