MCPcopy
hub / github.com/tailscale/tailscale / NewServer

Function NewServer

net/udprelay/server.go:382–437  ·  view source on GitHub ↗

NewServer constructs a [Server] listening on port. If port is zero, then port selection is left up to the host networking stack. If onlyStaticAddrPorts is true, then dynamic addr:port discovery will be disabled, and only addr:port's set via [Server.SetStaticAddrPorts] will be used. Metrics must be n

(logf logger.Logf, port uint16, onlyStaticAddrPorts bool, metrics *usermetric.Registry, knobs *controlknobs.Knobs)

Source from the content-addressed store, hash-verified

380// disabled, and only addr:port's set via [Server.SetStaticAddrPorts] will be
381// used. Metrics must be non-nil. knobs may be nil.
382func NewServer(logf logger.Logf, port uint16, onlyStaticAddrPorts bool, metrics *usermetric.Registry, knobs *controlknobs.Knobs) (s *Server, err error) {
383 s = &Server{
384 logf: logf,
385 disco: key.NewDisco(),
386 bindLifetime: defaultBindLifetime,
387 steadyStateLifetime: defaultSteadyStateLifetime,
388 closeCh: make(chan struct{}),
389 onlyStaticAddrPorts: onlyStaticAddrPorts,
390 serverEndpointByDisco: make(map[key.SortedPairOfDiscoPublic]*serverEndpoint),
391 nextVNI: minVNI,
392 cloudInfo: cloudinfo.New(logf),
393 controlKnobs: knobs,
394 }
395 s.discoPublic = s.disco.Public()
396 s.metrics = registerMetrics(metrics)
397
398 // TODO(creachadair): Find a way to plumb this in during initialization.
399 // As-written, messages published here will not be seen by other components
400 // in a running client.
401 bus := eventbus.New()
402 s.bus = bus
403 netMon, err := netmon.New(s.bus, logf)
404 if err != nil {
405 return nil, err
406 }
407 s.netMon = netMon
408 s.netChecker = &netcheck.Client{
409 NetMon: netMon,
410 Logf: logger.WithPrefix(logf, "netcheck: "),
411 SendPacket: func(b []byte, addrPort netip.AddrPort) (int, error) {
412 if addrPort.Addr().Is4() {
413 return s.uc4[0].WriteToUDPAddrPort(b, addrPort)
414 } else if len(s.uc6) > 0 {
415 return s.uc6[0].WriteToUDPAddrPort(b, addrPort)
416 } else {
417 return 0, errors.New("IPv6 socket is not bound")
418 }
419 },
420 }
421
422 err = s.bindSockets(port)
423 if err != nil {
424 return nil, err
425 }
426 s.startPacketReaders()
427
428 if !s.onlyStaticAddrPorts {
429 s.wg.Add(1)
430 go s.addrDiscoveryLoop()
431 }
432
433 s.wg.Add(1)
434 go s.endpointGCLoop()
435
436 return s, nil
437}
438
439func (s *Server) startPacketReaders() {

Callers 2

newExtensionFunction · 0.92
TestServerFunction · 0.70

Calls 15

NewDiscoFunction · 0.92
NewFunction · 0.92
NewFunction · 0.92
NewFunction · 0.92
WithPrefixFunction · 0.92
bindSocketsMethod · 0.80
startPacketReadersMethod · 0.80
addrDiscoveryLoopMethod · 0.80
endpointGCLoopMethod · 0.80
registerMetricsFunction · 0.70
WriteToUDPAddrPortMethod · 0.65
AddMethod · 0.65

Tested by 1

TestServerFunction · 0.56

Used in the wild real call sites across dependent graphs

searching dependent graphs…