Add fabric session packet transport
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package vpnruntime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/example/remote-access-platform/agents/rap-node-agent/internal/fabricproto"
|
||||
"github.com/example/remote-access-platform/agents/rap-node-agent/internal/mesh"
|
||||
)
|
||||
|
||||
type FabricSessionFrameSender interface {
|
||||
Send(context.Context, fabricproto.Frame) error
|
||||
}
|
||||
|
||||
type FabricSessionFrameReceiver interface {
|
||||
Frames() <-chan fabricproto.Frame
|
||||
Errors() <-chan error
|
||||
}
|
||||
|
||||
type FabricSessionPacketTransport struct {
|
||||
Sender FabricSessionFrameSender
|
||||
Receiver FabricSessionFrameReceiver
|
||||
Inbox *FabricPacketInbox
|
||||
|
||||
StreamID uint64
|
||||
VPNConnectionID string
|
||||
SendDirection string
|
||||
ReceiveDirection string
|
||||
TrafficClass string
|
||||
|
||||
sequence uint64
|
||||
}
|
||||
|
||||
func (t *FabricSessionPacketTransport) SendGatewayPacketBatch(ctx context.Context, packets [][]byte) error {
|
||||
packets = cleanPacketBatch(packets)
|
||||
if len(packets) == 0 {
|
||||
return nil
|
||||
}
|
||||
if t == nil || t.Sender == nil {
|
||||
return mesh.ErrForwardRuntimeUnavailable
|
||||
}
|
||||
if t.StreamID == 0 || t.VPNConnectionID == "" {
|
||||
return errors.New("fabric session packet transport identity is incomplete")
|
||||
}
|
||||
direction := t.SendDirection
|
||||
if direction == "" {
|
||||
direction = FabricDirectionGatewayToClient
|
||||
}
|
||||
frame, err := NewFabricVPNPacketDataFrame(FabricVPNPacketFrameInput{
|
||||
StreamID: t.StreamID,
|
||||
Sequence: atomic.AddUint64(&t.sequence, 1),
|
||||
VPNConnectionID: t.VPNConnectionID,
|
||||
Direction: direction,
|
||||
TrafficClass: t.TrafficClass,
|
||||
Packets: packets,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.Sender.Send(ctx, frame)
|
||||
}
|
||||
|
||||
func (t *FabricSessionPacketTransport) ReceiveGatewayPacketBatch(ctx context.Context, timeout time.Duration) ([][]byte, error) {
|
||||
if t == nil || t.Inbox == nil {
|
||||
return nil, mesh.ErrForwardRuntimeUnavailable
|
||||
}
|
||||
direction := t.ReceiveDirection
|
||||
if direction == "" {
|
||||
direction = FabricDirectionClientToGateway
|
||||
}
|
||||
return t.Inbox.Receive(ctx, t.VPNConnectionID, direction, timeout)
|
||||
}
|
||||
|
||||
func (t *FabricSessionPacketTransport) RunFrameIngress(ctx context.Context) error {
|
||||
if t == nil || t.Receiver == nil || t.Inbox == nil {
|
||||
return mesh.ErrForwardRuntimeUnavailable
|
||||
}
|
||||
frames := t.Receiver.Frames()
|
||||
errorsCh := t.Receiver.Errors()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case err, ok := <-errorsCh:
|
||||
if !ok {
|
||||
errorsCh = nil
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case frame, ok := <-frames:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if frame.Type != fabricproto.FrameData {
|
||||
continue
|
||||
}
|
||||
if t.StreamID != 0 && frame.StreamID != t.StreamID {
|
||||
continue
|
||||
}
|
||||
if err := t.Inbox.DeliverFabricSessionFrame(ctx, frame); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user