Commit Graph

54 Commits

Author SHA1 Message Date
Paul Lorenz 647c4daa1e Serialize router control-channel connect/disconnect. Fixes #4196
The controller decided which of two racing connections for a router was current
by comparing router instances, but loaded one per connect by evicting the router
cache and reading back through it. Two connects could both evict, and whichever
read second was handed the instance the first had just published. A shared
instance makes the two connections indistinguishable: the connect path cannot
reject the second into an occupied slot, and when either channel dies the
disconnect path finds itself current and tears down the registration the other is
still using. The surviving channel is never re-bound, so the router stays
connected at the transport layer while absent from the model, unable to recover.

Connect and disconnect were also unserialized, so a stale or superseded
disconnect could interleave with a live connection and take its links with it.

- serializes a router's connect and disconnect with a per-router striped lock
- keeps at most one connection per router: a connect into an occupied slot is
  rejected via an error from ConnectRouter, so the bind fails and NewChannel
  closes it without starting rx or registering it, and the occupant is displaced;
  the router redials into the freed slot
- displaces an occupant by closing its channel and also invoking the teardown
  directly, since a channel that is already closed never fires its close handler
  again; without this a dead but still registered connection holds the slot
  forever and every redial is rejected against a slot nothing can free
- refuses a connect whose control channel is already closed rather than
  registering it, so a connection no disconnect could ever remove is never
  published
- gives every connection its own router instance via RouterManager.NewCtrlChanRouter,
  read through readUncached so the cache neither supplies nor receives it, which
  is what makes comparing instances meaningful
- moves recording the channel and connect time out of the accept path, so a
  caller cannot attach the wrong channel or forget to attach one
- serializes link publication with that teardown on the same per-router stripe.
  Validating currency and then publishing without it is a check-then-act: a
  report can find the connection current and, by the time it reaches the link
  manager, the teardown has already snapshotted and cleared the router's links,
  so the link is recreated after everything that would have removed it. It is
  then absent from the router's own index while still in the link table with a
  disconnected source, and a reconnect reporting the same iteration can adopt
  that stale source instead of rebuilding the link
- guards the entire DisconnectRouter teardown by connection currency, all or
  nothing, and clears the connected flag and link index only when the
  registration was actually given up, with the flag cleared under the same shard
  lock as the map removal so the two cannot be observed disagreeing; the connected flag decides whether the
  controller accepts a router's link reports, so clearing it for the wrong
  connection silences a router that is up and reporting
- reduces MarkConnected to publishing the connection; the takeover-close moves
  into ConnectRouter's reject path
- makes the per-router unlock idempotent so callers can defer it as a leak-safety
  net and still unlock early before closing a channel outside the lock
- stops the replaced RouterSender in routerTxMap.Add so a takeover does not leak
  the old sender's goroutine when the broker's asynchronous RouterDisconnected
  loses the race to the redial's RouterConnected
- discards pending peer state changes for a router whose channel has closed,
  since sending on one fails immediately and the failed send is retried as soon
  as the event loop turns, spinning the loop and flooding the log
- queues the peer-state send-done event on every path, so a missing channel can
  no longer leave sendInProgress set and stall that router's updates permanently
- resolves a router's version from its connected instance when validating link
  conn info, since the version arrives in the hello and so is absent from an
  instance loaded from the database
- normalizes both endpoints to the connected instance in shortestPath, which is
  keyed and compared by pointer and so treated an endpoint held as any other
  instance of the same router as absent from the graph, reporting a router as
  unroutable from itself. That worked before only because the connect path
  published its instance into the router cache, so a cache read and the connected
  map returned the same object; nothing stated the requirement
- configures test logging once per package in TestMain, so a test no longer
  writes global logger state while a previous test's shutdown logging reads it
2026-08-13 23:54:40 -04:00
Paul Lorenz 48e4d4a224 Manage router link configuration via the controller. Fixes #4004
- adds a link ConfigHandler (router/link FactoryRegistry) that applies router.link.v1 config: Apply rebuilds the listener/dialer set wholesale, and established Xlinks survive because Listener.Close() only closes the accept loop
- translates local link: YAML into router.link.v1 JSON and pushes it through the managed-config registry at startup
- adds the UpdateLinkListeners ctrl message so the router republishes its listener set to the controller on change; the controller re-fans via the existing PeerStateChange path
- re-evaluates dialers on link group and listener changes via RescanForDialOpportunities

For #3743.
2026-08-13 15:37:24 -04:00
Paul Lorenz a003f18792 Remove unused link costTags support
- removes the costTags option from router link listeners, which was parsed
  from config, advertised to the controller, and stored on the router model
  but never used for path selection or any other behavior
- drops GetLinkCostTags from the xlink.Listener interface and its transport
  implementation
- reserves the corresponding ctrl_pb.Listener.costTags and
  RouterLinks.RouterLink.linkCostTags protobuf fields and regenerates ctrl.pb.go
- documents the removal in the changelog
2026-08-03 18:03:26 -04:00
Andrew Martinez 45b5046f52 fixes openziti/ziti#4071 unify router capabilities into one shared namespace (#4073)
- keys router capability bits off the sdk-golang RouterCapability enum
- adds a generic capabilities.Mask[T ~int] bitmask, centralizing capability
  set/check behind one value-to-bit translation
- adds capabilities.RouterCapability and ControllerCapability types, with
  RouterCapabilityMask/ControllerCapabilityMask aliases, so masks and checks are
  typed per namespace
- supports control-plane-only router capabilities as negative values that index
  down from the top of the mask, collision-free with the SDK's upward-numbered
  bits and invisible to the SDK and edge-api
- references the sdk-golang RouterCapability enum as the source of truth for
  shared router capability bits
- holds the router's advertised capability mask as an instance on the router env
  rather than a global, so in-process test routers do not share state
- advertises PostureChecks and BindSuccess as capability bits on both channels
  while still sending the legacy boolean edge headers for backwards compatibility
- routes GetCapabilities/IsCapable and the controller's Router.Capabilities field
  through the typed mask
- adds a provenance test that verifies, via go/packages, that every positive
  router capability is SDK-sourced, every negative is control-plane-only, and no
  two resolve to the same bit
- update sdk to v2.0.0-pre2
2026-07-02 17:02:34 -04:00
Paul Lorenz 2dc4075446 Make listener ctrl channels multi-underlay-capable. For #3983
- gives ListenerCtrlChannel Min: 0 constraints per underlay type plus
  MinTotalUnderlays: 1 in its configs, so the controller accepts the
  high/low-priority grouped underlays the router dials while still closing the
  channel only when its last underlay is lost
- restores the multi-underlay behavior the v4 listener-side SetMinTotal(1)
  provided, which the channel/v5 migration dropped
- works around channel/v5 not yet treating MinTotalUnderlays alone as a
  multi-underlay signal
2026-06-22 14:53:47 -04:00
Paul Lorenz 1c877e2501 Migrate to channel/v5 deferred-ack accept API. For #3983
- switches the xlink transport and router ctrl listeners to NewClassicListenerWithAcceptor, passing the MultiListener as a HelloAcceptor
- replaces the controller ctrl channel's NewClassicListener/UnderlayDispatcher wiring with NewClassicListenerWithAcceptor and a TypeRoutingAcceptor, adapting the mesh acceptor via AsHelloAcceptor
- removes the multiListenerAcceptor wrapper now that MultiListener implements HelloAcceptor directly
- removes the xgress_edge Acceptor.Run Create-loop, handing underlays to the MultiListener through the acceptor-based listener
- moves the controller ctrl connect handler into ListenerConfig.ConnectionHandlers
- updates ctrlchan channel tests to the new constructor
2026-06-18 12:51:02 -04:00
Paul Lorenz d481224c9b Decompose multi-underlay channels onto the channel/v5 API. Fixes #3983
- decomposes the ctrlchan, xlink and edge-listener channels onto the v5 Senders, MessageSourceProvider and UnderlayEventListener interfaces, replacing the v4 UnderlayHandler god-interface
- replaces the hand-rolled dial/grouping/backoff machinery with channel.BackoffDialPolicy and declarative Constraints; ctrl keeps survive-to-zero (Min: 0) with MinStableDuration: 0 for prompt reconnect, while xlink and edge default underlays keep Min: 1 so loss closes the channel
- builds grouped channels via channel.NewChannel(*Config) and moves handler retrieval to GetSenders()
- records the channel via InitChannel from each bind handler, before underlay events fire, so handlers registered during bind do not dereference a nil channel
- generates a group secret for ungrouped inbound ctrl underlays on the router accept path, matching the controller, since NewChannel requires one
- preserves link-id-as-channel-id (the link dial policy wraps the cloned link-id identity dialer) and adds a test asserting dialed underlays present the link id
- registers the latency handler explicitly, as it is no longer a self-describing receiver in v5
2026-06-18 12:51:02 -04:00
Paul Lorenz ee8ad78e3b Rename MultiChannel to the unified Channel for channel/v5. For #3983
- channel.MultiChannel -> channel.Channel
- channel.MultiChannelConfig -> channel.Config
- channel.NewMultiChannel(...) -> channel.NewChannel(...)

channel/v5 unifies Channel and MultiChannel into a single Channel abstraction. This is the
mechanical token rename; the Config field changes and handler retrieval that the unification
requires land in the following commit. The two channel.go files that are fully rewritten for
v5 (common/ctrlchan, router/xlink_transport) are excluded here and rewritten in that commit.
Does not build on its own.
2026-06-18 12:51:02 -04:00
Paul Lorenz 1c122af490 Rewrite channel/v4 imports to channel/v5. For #3983
- moves the channel dependency to channel/v5 v5.0.10 and sdk-golang to v1.9.0 in the root and zititest modules
- mechanically rewrites every channel/v4 import path to channel/v5

This is the import-path-only step; the API-level changes the switch requires land in the following commit. This commit does not build on its own.
2026-06-18 12:51:02 -04:00
Paul Lorenz b5eaeefdb3 Prep for channel v5: bind handler invocation, send priorities. Fixes #3942
- invokes bind handlers via h.BindChannel(binding) instead of binding.Bind(h), which channel v5 removes from the Binding interface
- removes WithPriority from edge dial and state message sends; priority was already a no-op on grouped channels and channel v5 removes the priority API
2026-06-05 15:24:45 -04:00
Paul Lorenz 6b869cea9d Add support for ctrlChanListener on router to the model. Fixes #3635 2026-03-07 00:00:51 -05:00
Paul Lorenz 8acf90cdf6 Multi-underlay control channel doesn't correctly handle lack of group secret on non-grouped underlays. Fixes #3624 2026-03-02 13:52:11 -05:00
Paul Lorenz ab51fa8217 Fix the control channel header conflicts with channel headers. Use single strategy for sharing capabilities with bit mask. 2026-02-24 15:50:05 -05:00
Paul Lorenz 90112219a3 Support multi-underlay control channels. Fixes #3550 2026-02-11 14:20:29 -05:00
Paul Lorenz da9ef76d19 Optimize imports 2026-01-28 15:01:35 -05:00
Paul Lorenz 2ffc6e1151 Update ziti version to 2.0 2026-01-28 12:34:10 -05:00
Paul Lorenz e647d67325 Update to channel/v4 2025-04-02 15:28:59 -04:00
Paul Lorenz cccf0c06af Update to channel/v3. Fixes #2390 2024-09-09 12:23:25 -04:00
Paul Lorenz 70b32603ad Start on chaos testing 2024-01-19 17:34:15 -05:00
Paul Lorenz c4abcae949 Link management fixes. Fixes #1692 Fixes #1693 2024-01-19 17:33:21 -05:00
Paul Lorenz b270d18faf Add additional logging. Remove unnecessary router lookups. May address #1460 2023-10-31 14:57:06 -04:00
Paul Lorenz 3523b34b2c Fix panic when router version info isn't set by ensuring it is set and making sure we get the right version. Fixes #1423 2023-10-11 13:55:50 -04:00
Paul Lorenz f3d67b7f49 Update fabric imports 2023-09-28 23:34:28 -04:00
Paul Lorenz cdfd037da9 Move protobuf definitions to common 2023-08-10 19:38:48 -04:00
Paul Lorenz f15b8bef23 Add some more config value validation and guardrails 2023-08-03 17:07:49 -04:00
Paul Lorenz 2ee9539f9c Move link calculation to routers. Fixes #692, fixes #749, fixes openziti/fabric#343 2023-08-03 17:07:48 -04:00
Paul Lorenz bc9bac6f0d Add config support for link groups. Doesn't use group config yet. 2023-05-11 09:34:33 -04:00
Paul Lorenz 820e6391a4 Add heartbeat config and controller peer heartbeats. Fixes openziti/fabric#507
Adds config to controller for heartbeat config
Add config to routers for heartbeat config
Adds configurable heartbeats to controller <-> controller connections
2023-02-28 09:47:53 -05:00
Paul Lorenz ec885daed5 Always use a new router instance for connected routers so we can ensure
disconnect handling applies to the right instance
2022-10-24 14:44:27 -04:00
Paul Lorenz 519574497e Update to channel v2 2022-09-26 17:00:34 -04:00
Paul Lorenz e0f5092a08 Use one port for ctrl channel to router and controllers. Allow syncing existing DB to raft. Fixes #471. Fixes openziti/fabric#479. 2022-08-22 12:09:07 -04:00
Paul Lorenz b26fcf8909 Fix copyright 2022-06-29 16:59:46 -04:00
Paul Lorenz 8dfdce7fab Update to current protobuf library 2022-05-10 14:54:00 -04:00
Paul Lorenz 69bc2fb0cc Update to transport/v2 2022-05-10 11:58:41 -04:00
Paul Lorenz 1874ab5f27 Allow a new control channel to takeover even if the router is already connected
Add churn limiter so it can only happen so often
2022-04-28 14:55:14 -04:00
Paul Lorenz 9a344da855 Update to use transport library 2022-03-31 10:36:28 -04:00
tburtchell 2f8a608c4c Replacing link 'type' with 'protocol' and 'costTags' (#336)
* Replacing link 'type' with 'protocol' and 'costTags'
2022-03-22 09:06:02 -04:00
Paul Lorenz 2b7db10913 Allow routers more control over link management (#318)
* Allow routers more control over link management
2022-03-07 12:22:17 -05:00
Paul Lorenz 675b16ef98 Don't call message sends in control channel bind 2022-02-10 09:20:23 -05:00
Paul Lorenz 3cfea85bf7 Update links to use channel library 2022-01-31 15:52:10 -05:00
Paul Lorenz 84ae5576e1 Update to use channel library 2022-01-27 16:46:21 -05:00
Paul Lorenz e781e3c713 Update control channel to new channel API 2022-01-19 08:15:33 -05:00
Paul Lorenz add3ae6f13 If accept fails, ch will be nil 2021-03-18 13:54:14 -04:00
Paul Lorenz 402dcb1f60 Don't allow routers to connect with no version info. They're too old to work correctly anyway for other reasons 2021-03-18 11:38:42 -04:00
Andrew Martinez a1df84e913 fixes openziti/fabric#133
- Adds version header to outgoing controller hellos and incomming router
  hellos
2020-10-06 09:41:36 -04:00
Michael Quigley 10e6a7ef93 netfoundry/ziti-fabric -> openziti/fabric 2020-05-26 17:14:16 -04:00
Paul Lorenz df0d35e576 Sync terminators when routers connect so invalid terminators can be r… (#86)
* Sync terminators when routers connect so invalid terminators can be removed
2020-04-27 15:56:54 -04:00
Michael Quigley a3838ed857 Controller changes to support non 'transport.Address' addresses (string). Enough 'xlink_transwarp' to minimally establish a connection. (#44) 2020-03-24 16:00:36 -04:00
Michael Quigley a09a608449 HelloRouterAdvertisementsHeader. (#54) 2020-03-24 11:10:01 -04:00
Michael Quigley 2902c4942b Move the X... frameworks underneath controller/ or router/. 2020-03-20 13:57:59 -04:00