mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-11-04 10:01:05 +01:00 
			
		
		
		
	Merge local DERP server region with other configured DERP sources
This commit is contained in:
		
							parent
							
								
									e78c002f5a
								
							
						
					
					
						commit
						54c3e00a1f
					
				
							
								
								
									
										60
									
								
								app.go
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								app.go
									
									
									
									
									
								
							@ -13,7 +13,6 @@ import (
 | 
				
			|||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/signal"
 | 
						"os/signal"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
@ -247,48 +246,6 @@ func NewHeadscale(cfg Config) (*Headscale, error) {
 | 
				
			|||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		app.DERPServer = embeddedDERPServer
 | 
							app.DERPServer = embeddedDERPServer
 | 
				
			||||||
 | 
					 | 
				
			||||||
		serverURL, err := url.Parse(app.cfg.ServerURL)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		var host string
 | 
					 | 
				
			||||||
		var port int
 | 
					 | 
				
			||||||
		host, portStr, err := net.SplitHostPort(serverURL.Host)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			if serverURL.Scheme == "https" {
 | 
					 | 
				
			||||||
				host = serverURL.Host
 | 
					 | 
				
			||||||
				port = 443
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				host = serverURL.Host
 | 
					 | 
				
			||||||
				port = 80
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			port, err = strconv.Atoi(portStr)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		app.DERPMap = &tailcfg.DERPMap{
 | 
					 | 
				
			||||||
			Regions: map[int]*tailcfg.DERPRegion{
 | 
					 | 
				
			||||||
				999: {
 | 
					 | 
				
			||||||
					RegionID:   999,
 | 
					 | 
				
			||||||
					RegionCode: "headscale",
 | 
					 | 
				
			||||||
					RegionName: "Headscale Embedded DERP",
 | 
					 | 
				
			||||||
					Avoid:      false,
 | 
					 | 
				
			||||||
					Nodes: []*tailcfg.DERPNode{
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							Name:     "999a",
 | 
					 | 
				
			||||||
							RegionID: 999,
 | 
					 | 
				
			||||||
							HostName: host,
 | 
					 | 
				
			||||||
							DERPPort: port,
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			OmitDefaultRegions: false,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &app, nil
 | 
						return &app, nil
 | 
				
			||||||
@ -536,17 +493,18 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *gin.Engine {
 | 
				
			|||||||
func (h *Headscale) Serve() error {
 | 
					func (h *Headscale) Serve() error {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Fetch an initial DERP Map before we start serving
 | 
				
			||||||
 | 
						h.DERPMap = GetDERPMap(h.cfg.DERP)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if h.cfg.DERP.ServerEnabled {
 | 
						if h.cfg.DERP.ServerEnabled {
 | 
				
			||||||
		go h.ServeSTUN()
 | 
							go h.ServeSTUN()
 | 
				
			||||||
	} else {
 | 
							h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
 | 
				
			||||||
		// Fetch an initial DERP Map before we start serving
 | 
						}
 | 
				
			||||||
		h.DERPMap = GetDERPMap(h.cfg.DERP)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if h.cfg.DERP.AutoUpdate {
 | 
						if h.cfg.DERP.AutoUpdate {
 | 
				
			||||||
			derpMapCancelChannel := make(chan struct{})
 | 
							derpMapCancelChannel := make(chan struct{})
 | 
				
			||||||
			defer func() { derpMapCancelChannel <- struct{}{} }()
 | 
							defer func() { derpMapCancelChannel <- struct{}{} }()
 | 
				
			||||||
			go h.scheduledDERPMapUpdateWorker(derpMapCancelChannel)
 | 
							go h.scheduledDERPMapUpdateWorker(derpMapCancelChannel)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go h.expireEphemeralNodes(updateInterval)
 | 
						go h.expireEphemeralNodes(updateInterval)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								derp.go
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								derp.go
									
									
									
									
									
								
							@ -148,6 +148,7 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
 | 
				
			|||||||
		case <-ticker.C:
 | 
							case <-ticker.C:
 | 
				
			||||||
			log.Info().Msg("Fetching DERPMap updates")
 | 
								log.Info().Msg("Fetching DERPMap updates")
 | 
				
			||||||
			h.DERPMap = GetDERPMap(h.cfg.DERP)
 | 
								h.DERPMap = GetDERPMap(h.cfg.DERP)
 | 
				
			||||||
 | 
								h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			namespaces, err := h.ListNamespaces()
 | 
								namespaces, err := h.ListNamespaces()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,8 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@ -14,6 +16,7 @@ import (
 | 
				
			|||||||
	"github.com/rs/zerolog/log"
 | 
						"github.com/rs/zerolog/log"
 | 
				
			||||||
	"tailscale.com/derp"
 | 
						"tailscale.com/derp"
 | 
				
			||||||
	"tailscale.com/net/stun"
 | 
						"tailscale.com/net/stun"
 | 
				
			||||||
 | 
						"tailscale.com/tailcfg"
 | 
				
			||||||
	"tailscale.com/types/key"
 | 
						"tailscale.com/types/key"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -30,12 +33,56 @@ var (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type DERPServer struct {
 | 
					type DERPServer struct {
 | 
				
			||||||
	tailscaleDERP *derp.Server
 | 
						tailscaleDERP *derp.Server
 | 
				
			||||||
 | 
						region        tailcfg.DERPRegion
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Headscale) NewDERPServer() (*DERPServer, error) {
 | 
					func (h *Headscale) NewDERPServer() (*DERPServer, error) {
 | 
				
			||||||
	s := derp.NewServer(key.NodePrivate(*h.privateKey), log.Info().Msgf)
 | 
						s := derp.NewServer(key.NodePrivate(*h.privateKey), log.Info().Msgf)
 | 
				
			||||||
	return &DERPServer{s}, nil
 | 
						region, err := h.generateRegionLocalDERP()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &DERPServer{s, region}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Headscale) generateRegionLocalDERP() (tailcfg.DERPRegion, error) {
 | 
				
			||||||
 | 
						serverURL, err := url.Parse(h.cfg.ServerURL)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return tailcfg.DERPRegion{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var host string
 | 
				
			||||||
 | 
						var port int
 | 
				
			||||||
 | 
						host, portStr, err := net.SplitHostPort(serverURL.Host)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if serverURL.Scheme == "https" {
 | 
				
			||||||
 | 
								host = serverURL.Host
 | 
				
			||||||
 | 
								port = 443
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								host = serverURL.Host
 | 
				
			||||||
 | 
								port = 80
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							port, err = strconv.Atoi(portStr)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return tailcfg.DERPRegion{}, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						localDERPregion := tailcfg.DERPRegion{
 | 
				
			||||||
 | 
							RegionID:   999,
 | 
				
			||||||
 | 
							RegionCode: "headscale",
 | 
				
			||||||
 | 
							RegionName: "Headscale Embedded DERP",
 | 
				
			||||||
 | 
							Avoid:      false,
 | 
				
			||||||
 | 
							Nodes: []*tailcfg.DERPNode{
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Name:     "999a",
 | 
				
			||||||
 | 
									RegionID: 999,
 | 
				
			||||||
 | 
									HostName: host,
 | 
				
			||||||
 | 
									DERPPort: port,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return localDERPregion, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Headscale) DERPHandler(ctx *gin.Context) {
 | 
					func (h *Headscale) DERPHandler(ctx *gin.Context) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user