рабочий вариант, но скороть 10 МБит
This commit is contained in:
@@ -14,11 +14,16 @@ type FabricSessionFrameWriter interface {
|
||||
}
|
||||
|
||||
type FabricSessionPacketPeerRegistry struct {
|
||||
mu sync.RWMutex
|
||||
peers map[string]FabricSessionPacketPeer
|
||||
mu sync.RWMutex
|
||||
peers map[string]FabricSessionPacketPeer
|
||||
changed chan struct{}
|
||||
}
|
||||
|
||||
type FabricSessionPacketPeer struct {
|
||||
TunnelID string
|
||||
PoolID string
|
||||
ServiceID string
|
||||
ServiceTunnel FabricServiceTunnel
|
||||
VPNConnectionID string
|
||||
Sender FabricSessionFrameWriter
|
||||
StreamID uint64
|
||||
@@ -30,11 +35,17 @@ type FabricSessionPacketPeer struct {
|
||||
type FabricSessionPacketPeerTransport struct {
|
||||
Registry *FabricSessionPacketPeerRegistry
|
||||
Inbox *FabricPacketInbox
|
||||
TunnelID string
|
||||
PoolID string
|
||||
ServiceID string
|
||||
VPNConnectionID string
|
||||
PeerWaitTimeout time.Duration
|
||||
}
|
||||
|
||||
const defaultFabricSessionPeerWaitTimeout = 500 * time.Millisecond
|
||||
|
||||
func NewFabricSessionPacketPeerRegistry() *FabricSessionPacketPeerRegistry {
|
||||
return &FabricSessionPacketPeerRegistry{peers: map[string]FabricSessionPacketPeer{}}
|
||||
return &FabricSessionPacketPeerRegistry{peers: map[string]FabricSessionPacketPeer{}, changed: make(chan struct{})}
|
||||
}
|
||||
|
||||
func (r *FabricSessionPacketPeerRegistry) RegisterFrame(ctx context.Context, sender FabricSessionFrameWriter, frame fabricproto.Frame) (bool, error) {
|
||||
@@ -53,10 +64,33 @@ func (r *FabricSessionPacketPeerRegistry) RegisterFrame(ctx context.Context, sen
|
||||
if r.peers == nil {
|
||||
r.peers = map[string]FabricSessionPacketPeer{}
|
||||
}
|
||||
if r.changed == nil {
|
||||
r.changed = make(chan struct{})
|
||||
}
|
||||
peer := r.peers[payload.VPNConnectionID]
|
||||
if peer.RegisteredAt.IsZero() {
|
||||
peer.RegisteredAt = now
|
||||
}
|
||||
peer.ServiceTunnel = NormalizeServiceTunnel(FabricServiceTunnel{
|
||||
TunnelID: firstNonEmptyTunnelString(payload.TunnelID, payload.VPNConnectionID),
|
||||
PoolID: payload.PoolID,
|
||||
ServiceID: payload.ServiceID,
|
||||
LocalServiceID: payload.LocalServiceID,
|
||||
RemoteServiceID: payload.RemoteServiceID,
|
||||
ServiceKind: payload.ServiceKind,
|
||||
ServiceClass: payload.ServiceClass,
|
||||
ServiceRole: payload.ServiceRole,
|
||||
RouteLeaseID: payload.RouteLeaseID,
|
||||
RouteGeneration: payload.RouteGeneration,
|
||||
DataPlane: payload.DataPlane,
|
||||
TransportOwner: payload.TransportOwner,
|
||||
RouteVisibility: payload.RouteVisibility,
|
||||
TrafficClasses: payload.TrafficClasses,
|
||||
StreamShards: payload.StreamShards,
|
||||
}, payload.VPNConnectionID)
|
||||
peer.TunnelID = peer.ServiceTunnel.TunnelID
|
||||
peer.PoolID = peer.ServiceTunnel.PoolID
|
||||
peer.ServiceID = peer.ServiceTunnel.ServiceID
|
||||
peer.VPNConnectionID = payload.VPNConnectionID
|
||||
peer.Sender = sender
|
||||
peer.StreamID = frame.StreamID
|
||||
@@ -69,6 +103,7 @@ func (r *FabricSessionPacketPeerRegistry) RegisterFrame(ctx context.Context, sen
|
||||
peer.StreamIDsByTrafficClass[trafficClass] = append(peer.StreamIDsByTrafficClass[trafficClass], frame.StreamID)
|
||||
}
|
||||
r.peers[payload.VPNConnectionID] = peer
|
||||
r.signalLocked()
|
||||
r.mu.Unlock()
|
||||
return true, nil
|
||||
}
|
||||
@@ -84,25 +119,93 @@ func (r *FabricSessionPacketPeerRegistry) TransportFor(vpnConnectionID string, i
|
||||
return nil
|
||||
}
|
||||
return &FabricSessionPacketTransport{
|
||||
Sender: fabricSessionFrameWriterAdapter{writer: peer.Sender},
|
||||
Inbox: inbox,
|
||||
StreamID: peer.StreamID,
|
||||
StreamIDsByTrafficClass: copyStreamIDsByClass(peer.StreamIDsByTrafficClass),
|
||||
VPNConnectionID: vpnConnectionID,
|
||||
SendDirection: FabricDirectionGatewayToClient,
|
||||
ReceiveDirection: FabricDirectionClientToGateway,
|
||||
Sender: fabricSessionFrameWriterAdapter{writer: peer.Sender},
|
||||
Inbox: inbox,
|
||||
StreamID: peer.StreamID,
|
||||
ServiceTunnel: peer.ServiceTunnel,
|
||||
TunnelID: vpnConnectionID,
|
||||
PoolID: peer.PoolID,
|
||||
ServiceID: peer.ServiceID,
|
||||
VPNConnectionID: vpnConnectionID,
|
||||
SendDirection: FabricDirectionGatewayToClient,
|
||||
ReceiveDirection: FabricDirectionClientToGateway,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *FabricSessionPacketPeerRegistry) WaitTransportFor(ctx context.Context, vpnConnectionID string, inbox *FabricPacketInbox, timeout time.Duration) PacketTransport {
|
||||
if timeout <= 0 {
|
||||
return r.TransportFor(vpnConnectionID, inbox)
|
||||
}
|
||||
timer := time.NewTimer(timeout)
|
||||
defer timer.Stop()
|
||||
for {
|
||||
if transport := r.TransportFor(vpnConnectionID, inbox); transport != nil {
|
||||
return transport
|
||||
}
|
||||
changed := r.changedChannel()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-timer.C:
|
||||
return nil
|
||||
case <-changed:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *FabricSessionPacketPeerRegistry) Forget(vpnConnectionID string) {
|
||||
if r == nil || vpnConnectionID == "" {
|
||||
return
|
||||
}
|
||||
r.mu.Lock()
|
||||
if r.changed == nil {
|
||||
r.changed = make(chan struct{})
|
||||
}
|
||||
delete(r.peers, vpnConnectionID)
|
||||
r.signalLocked()
|
||||
r.mu.Unlock()
|
||||
}
|
||||
|
||||
func (r *FabricSessionPacketPeerRegistry) changedChannel() <-chan struct{} {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if r.changed == nil {
|
||||
r.changed = make(chan struct{})
|
||||
}
|
||||
return r.changed
|
||||
}
|
||||
|
||||
func (r *FabricSessionPacketPeerRegistry) signalLocked() {
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
if r.changed == nil {
|
||||
r.changed = make(chan struct{})
|
||||
}
|
||||
close(r.changed)
|
||||
r.changed = make(chan struct{})
|
||||
}
|
||||
|
||||
func (t *FabricSessionPacketPeerTransport) SendGatewayPacketBatch(ctx context.Context, packets [][]byte) error {
|
||||
if t == nil || t.Registry == nil || t.Inbox == nil || t.VPNConnectionID == "" {
|
||||
return mesh.ErrForwardRuntimeUnavailable
|
||||
}
|
||||
transport := t.Registry.TransportFor(t.VPNConnectionID, t.Inbox)
|
||||
waitTimeout := t.PeerWaitTimeout
|
||||
if waitTimeout <= 0 {
|
||||
waitTimeout = defaultFabricSessionPeerWaitTimeout
|
||||
}
|
||||
transport := t.Registry.WaitTransportFor(ctx, t.VPNConnectionID, t.Inbox, waitTimeout)
|
||||
if transport == nil {
|
||||
return mesh.ErrForwardRuntimeUnavailable
|
||||
}
|
||||
return transport.SendGatewayPacketBatch(ctx, packets)
|
||||
if err := transport.SendGatewayPacketBatch(ctx, packets); err != nil {
|
||||
t.Registry.Forget(t.VPNConnectionID)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *FabricSessionPacketPeerTransport) ReceiveGatewayPacketBatch(ctx context.Context, timeout time.Duration) ([][]byte, error) {
|
||||
@@ -126,9 +229,12 @@ func (t *FabricSessionPacketPeerTransport) Snapshot() map[string]any {
|
||||
}
|
||||
}
|
||||
return map[string]any{
|
||||
"transport": "fabric_session_peer_dynamic",
|
||||
"vpn_connection_id": t.VPNConnectionID,
|
||||
"peer_ready": ready == 1,
|
||||
"transport": "fabric_session_peer_dynamic",
|
||||
"tunnel_id": firstNonEmptyTunnelString(t.TunnelID, t.VPNConnectionID),
|
||||
"pool_id": t.PoolID,
|
||||
"service_id": t.ServiceID,
|
||||
"vpn_connection_id_alias": t.VPNConnectionID,
|
||||
"peer_ready": ready == 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +248,12 @@ func (r *FabricSessionPacketPeerRegistry) Snapshot() map[string]any {
|
||||
items := make([]map[string]any, 0, len(r.peers))
|
||||
for _, peer := range r.peers {
|
||||
item := map[string]any{
|
||||
"vpn_connection_id": peer.VPNConnectionID,
|
||||
"stream_id": peer.StreamID,
|
||||
"tunnel_id": firstNonEmptyTunnelString(peer.TunnelID, peer.VPNConnectionID),
|
||||
"pool_id": peer.PoolID,
|
||||
"service_id": peer.ServiceID,
|
||||
"vpn_connection_id_alias": peer.VPNConnectionID,
|
||||
"service_tunnel": peer.ServiceTunnel.Snapshot(),
|
||||
"stream_id": peer.StreamID,
|
||||
}
|
||||
if !peer.RegisteredAt.IsZero() {
|
||||
item["registered_at"] = peer.RegisteredAt.Format(time.RFC3339Nano)
|
||||
|
||||
Reference in New Issue
Block a user