Skip to content

Commit ca7c5f0

Browse files
committed
multi: initial limited split tunnel for trafffic that fails security policy
1 parent fdd313f commit ca7c5f0

2 files changed

Lines changed: 70 additions & 30 deletions

File tree

ip.go

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,33 +2668,46 @@ type RemoteUserNatClient struct {
26682668
pathTable *pathTable
26692669
// the provide mode of the source packets
26702670
// for locally generated packets this is `ProvideMode_Network`
2671-
provideMode protocol.ProvideMode
2672-
clientUnsub func()
2671+
provideMode protocol.ProvideMode
2672+
closeCallback func()
2673+
clientUnsub func()
26732674
}
26742675

26752676
func NewRemoteUserNatClient(
26762677
client *Client,
26772678
receivePacketCallback ReceivePacketFunction,
26782679
destinations []MultiHopId,
26792680
provideMode protocol.ProvideMode,
2680-
) (*RemoteUserNatClient, error) {
2681-
pathTable, err := newPathTable(destinations)
2682-
if err != nil {
2683-
return nil, err
2684-
}
2681+
) *RemoteUserNatClient {
2682+
return NewRemoteUserNatClientWithClose(client, receivePacketCallback, destinations, provideMode, nil)
2683+
}
2684+
2685+
func NewRemoteUserNatClientWithClose(
2686+
client *Client,
2687+
receivePacketCallback ReceivePacketFunction,
2688+
destinations []MultiHopId,
2689+
provideMode protocol.ProvideMode,
2690+
closeCallback func(),
2691+
) *RemoteUserNatClient {
2692+
pathTable := newPathTable(destinations)
26852693

26862694
userNatClient := &RemoteUserNatClient{
26872695
client: client,
26882696
receivePacketCallback: receivePacketCallback,
26892697
securityPolicy: DefaultEgressSecurityPolicy(),
26902698
pathTable: pathTable,
26912699
provideMode: provideMode,
2700+
closeCallback: closeCallback,
26922701
}
26932702

26942703
clientUnsub := client.AddReceiveCallback(userNatClient.ClientReceive)
26952704
userNatClient.clientUnsub = clientUnsub
26962705

2697-
return userNatClient, nil
2706+
return userNatClient
2707+
}
2708+
2709+
func (self *RemoteUserNatClient) DestinationCount() int {
2710+
return self.pathTable.DestinationCount()
26982711
}
26992712

27002713
func (self *RemoteUserNatClient) SecurityPolicyStats(reset bool) SecurityPolicyStats {
@@ -2787,6 +2800,9 @@ func (self *RemoteUserNatClient) Shuffle() {
27872800
func (self *RemoteUserNatClient) Close() {
27882801
// self.client.RemoveReceiveCallback(self.clientCallbackId)
27892802
self.clientUnsub()
2803+
if self.closeCallback != nil {
2804+
self.closeCallback()
2805+
}
27902806
}
27912807

27922808
type pathTable struct {
@@ -2797,18 +2813,22 @@ type pathTable struct {
27972813
paths6 map[Ip6Path]MultiHopId
27982814
}
27992815

2800-
func newPathTable(destinations []MultiHopId) (*pathTable, error) {
2801-
if len(destinations) == 0 {
2802-
return nil, errors.New("No destinations.")
2803-
}
2816+
func newPathTable(destinations []MultiHopId) *pathTable {
28042817
return &pathTable{
28052818
destinations: destinations,
28062819
paths4: map[Ip4Path]MultiHopId{},
28072820
paths6: map[Ip6Path]MultiHopId{},
2808-
}, nil
2821+
}
2822+
}
2823+
2824+
func (self *pathTable) DestinationCount() int {
2825+
return len(self.destinations)
28092826
}
28102827

28112828
func (self *pathTable) SelectDestination(packet []byte) (MultiHopId, error) {
2829+
if len(self.destinations) == 0 {
2830+
return MultiHopId{}, fmt.Errorf("No destinations")
2831+
}
28122832
if len(self.destinations) == 1 {
28132833
return self.destinations[0], nil
28142834
}

ip_remote_multi_client.go

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,9 @@ type RemoteUserNatMultiClient struct {
375375
clientUpdates map[*multiClientChannel]map[*multiClientChannelUpdate]bool
376376

377377
performanceProfile *PerformanceProfile
378+
379+
localUserNat *LocalUserNat
380+
localUserNatSub func()
378381
}
379382

380383
func NewRemoteUserNatMultiClientWithDefaults(
@@ -403,6 +406,8 @@ func NewRemoteUserNatMultiClient(
403406

404407
securityPolicyStats := DefaultSecurityPolicyStatsCollector()
405408

409+
localUserNat := NewLocalUserNatWithDefaults(cancelCtx, "multi local")
410+
406411
multiClient := &RemoteUserNatMultiClient{
407412
ctx: cancelCtx,
408413
cancel: cancel,
@@ -420,6 +425,7 @@ func NewRemoteUserNatMultiClient(
420425
affinityIp6Paths: map[Ip6Path]map[Ip6Path]time.Time{},
421426
clientUpdates: map[*multiClientChannel]map[*multiClientChannelUpdate]bool{},
422427
performanceProfile: settings.DefaultPerformanceProfile,
428+
localUserNat: localUserNat,
423429
}
424430

425431
multiClient.windows[WindowTypeQuality] = newMultiClientWindow(
@@ -446,6 +452,8 @@ func NewRemoteUserNatMultiClient(
446452
}
447453
// else only keep the quality window for fixed destination
448454

455+
multiClient.localUserNatSub = localUserNat.AddReceivePacketCallback(receivePacketCallback)
456+
449457
monitors := []MultiClientMonitor{}
450458
for _, window := range multiClient.windows {
451459
monitors = append(monitors, window.monitor)
@@ -912,18 +920,23 @@ func (self *RemoteUserNatMultiClient) SendPacket(
912920
glog.Infof("[multi]send bad packet = %s\n", err)
913921
return false
914922
}
915-
switch r {
916-
case SecurityPolicyResultAllow:
923+
if r == SecurityPolicyResultAllow {
917924
parsedPacket := &parsedPacket{
918925
packet: packet,
919926
ipPath: ipPath,
920927
payload: payload,
921928
}
922929
return self.sendPacket(source, provideMode, parsedPacket, timeout)
923-
default:
924-
// TODO upgrade port 53 and port 80 here with protocol specific conversions
925-
glog.V(1).Infof("[multi]drop packet ipv%d p%v -> %s:%d\n", ipPath.Version, ipPath.Protocol, ipPath.DestinationIp, ipPath.DestinationPort)
926-
return false
930+
} else {
931+
// FIXME allow local defaults to true but can be set
932+
allowLocal := true
933+
if allowLocal {
934+
return self.localUserNat.SendPacket(source, provideMode, packet, timeout)
935+
} else {
936+
// TODO upgrade port 53 and port 80 here with protocol specific conversions
937+
glog.V(1).Infof("[multi]drop packet ipv%d p%v -> %s:%d\n", ipPath.Version, ipPath.Protocol, ipPath.DestinationIp, ipPath.DestinationPort)
938+
return false
939+
}
927940
}
928941
}
929942

@@ -1254,11 +1267,13 @@ func (self *RemoteUserNatMultiClient) clientReceivePacket(
12541267
ipPath *IpPath,
12551268
packet []byte,
12561269
) {
1257-
// ipPath, err := ParseIpPath(packet)
1258-
// if err != nil {
1259-
// // bad ip packet, drop
1260-
// return
1261-
// }
1270+
r, err := self.ingressSecurityPolicy.Inspect(provideMode, ipPath)
1271+
if err != nil {
1272+
return
1273+
}
1274+
if r != SecurityPolicyResultAllow {
1275+
return
1276+
}
12621277

12631278
ipPath = ipPath.Reverse()
12641279

@@ -1464,10 +1479,12 @@ func (self *RemoteUserNatMultiClient) Close() {
14641479
window.Close()
14651480
}
14661481

1467-
removedUpdates := []*multiClientChannelUpdate{}
14681482
func() {
14691483
self.stateLock.Lock()
14701484
defer self.stateLock.Unlock()
1485+
1486+
removedUpdates := []*multiClientChannelUpdate{}
1487+
14711488
for _, update := range self.ip4PathUpdates {
14721489
removedUpdates = append(removedUpdates, update)
14731490
// update.Close()
@@ -1483,10 +1500,14 @@ func (self *RemoteUserNatMultiClient) Close() {
14831500
// clear(self.updateIp4Paths)
14841501
// clear(self.updateIp6Paths)
14851502
// clear(clientUpdates)
1503+
1504+
for _, update := range removedUpdates {
1505+
update.Close()
1506+
}
14861507
}()
1487-
for _, update := range removedUpdates {
1488-
update.Close()
1489-
}
1508+
1509+
self.localUserNat.Close()
1510+
self.localUserNatSub()
14901511
}
14911512

14921513
type multiClientChannelUpdate struct {
@@ -3280,8 +3301,7 @@ func (self *multiClientChannel) clientReceive(source TransferPath, frames []*pro
32803301
self.addReceiveAck(ByteCount(len(packet)))
32813302

32823303
ipPath, err := ParseIpPath(packet)
3283-
r, err := self.ingressSecurityPolicy.Inspect(provideMode, ipPath)
3284-
if err == nil && r == SecurityPolicyResultAllow {
3304+
if err == nil {
32853305
self.clientReceivePacketCallback(self, source, provideMode, ipPath, packet)
32863306
}
32873307
// else not an ip packet, drop

0 commit comments

Comments
 (0)