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)
| 380 | // disabled, and only addr:port's set via [Server.SetStaticAddrPorts] will be |
| 381 | // used. Metrics must be non-nil. knobs may be nil. |
| 382 | func 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 | |
| 439 | func (s *Server) startPacketReaders() { |
searching dependent graphs…