package mesh import ( "fmt" "time" ) func ValidateProductionEnvelopeRouteConfig(local PeerIdentity, envelope ProductionEnvelope, routes []SyntheticRoute, now time.Time) error { if len(routes) == 0 { return nil } route, ok := productionRouteByID(routes, envelope.RouteID) if !ok { return ErrRouteNotFound } if route.ClusterID != envelope.ClusterID || route.ClusterID != local.ClusterID { return ErrClusterMismatch } if route.SourceNodeID != envelope.SourceNodeID || route.DestinationNodeID != envelope.DestinationNodeID { return ErrInvalidRoutePath } if route.ExpiresAt.IsZero() || !route.ExpiresAt.After(now.UTC()) || envelope.ExpiresAt.After(route.ExpiresAt) { return ErrRouteExpired } if !contains(route.AllowedChannels, envelope.ChannelClass) { return ErrUnauthorizedChannel } path := routePath(route) if len(path) < 2 || path[0] != route.SourceNodeID || path[len(path)-1] != route.DestinationNodeID { return ErrInvalidRoutePath } if len(envelope.RoutePath) > 0 && !sameNodePath(envelope.RoutePath, path) { return ErrInvalidRoutePath } if len(path) > 2 && len(envelope.RoutePath) == 0 { return ErrInvalidRoutePath } currentIndex := indexOf(path, local.NodeID) if currentIndex < 0 || envelope.CurrentHopNodeID != local.NodeID { return ErrNodeMismatch } expectedNextHop := local.NodeID if local.NodeID != envelope.DestinationNodeID { if currentIndex >= len(path)-1 { return ErrInvalidRoutePath } expectedNextHop = path[currentIndex+1] } if envelope.NextHopNodeID != expectedNextHop { return ErrInvalidRoutePath } if route.MaxTTL > 0 && envelope.TTL > route.MaxTTL { return fmt.Errorf("%w: ttl exceeds configured route max_ttl", ErrForwardEnvelopeInvalid) } if route.MaxHops > 0 && envelope.HopCount > route.MaxHops { return fmt.Errorf("%w: hop_count exceeds configured route max_hops", ErrForwardEnvelopeInvalid) } return nil } func productionRouteByID(routes []SyntheticRoute, routeID string) (SyntheticRoute, bool) { for _, route := range routes { if route.RouteID == routeID { return route, true } } return SyntheticRoute{}, false } func sameNodePath(a []string, b []string) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true }