@@ -11,6 +11,7 @@ import (
1111 "strconv"
1212 "strings"
1313 "sync"
14+ "sync/atomic"
1415 "time"
1516
1617 "github.com/gaissmai/bart"
@@ -89,6 +90,9 @@ type HandshakeFilter struct {
8990 AllowedCidrs []netip.Prefix
9091 AllowedCANames map [string ]struct {}
9192 AllowedCAShas map [string ]struct {}
93+
94+ IsEmtpy atomic.Bool
95+ IsModifiedSinceLastMashalling atomic.Bool
9296}
9397
9498// FirewallTable is the entry point for a rule, the evaluation order is:
@@ -1039,19 +1043,26 @@ func parsePort(s string) (startPort, endPort int32, err error) {
10391043}
10401044
10411045func NewHandshakeFilter () * HandshakeFilter {
1042- return & HandshakeFilter {
1046+ hf := & HandshakeFilter {
10431047 AllowedHosts : make (map [string ]struct {}),
10441048 AllowedGroups : make (map [string ]struct {}),
10451049 AllowedGroupsCombos : make ([]map [string ]struct {}, 0 ),
10461050 AllowedCidrs : make ([]netip.Prefix , 0 ),
10471051 AllowedCANames : make (map [string ]struct {}),
10481052 AllowedCAShas : make (map [string ]struct {}),
10491053 }
1054+
1055+ hf .IsModifiedSinceLastMashalling .Store (false )
1056+ hf .IsEmtpy .Store (true )
1057+
1058+ return hf
10501059}
10511060
10521061func (hfws * HandshakeFilter ) AddRule (groups []string , host string , localIp netip.Prefix , CAName string , CASha string ) {
1062+ ruleAdded := false
10531063 if host != "" {
10541064 hfws .AllowedHosts [host ] = struct {}{}
1065+ ruleAdded = true
10551066 }
10561067
10571068 if len (groups ) > 1 {
@@ -1066,23 +1077,34 @@ func (hfws *HandshakeFilter) AddRule(groups []string, host string, localIp netip
10661077 gs ,
10671078 )
10681079 }
1080+ ruleAdded = true
10691081 } else if len (groups ) == 1 {
10701082 hfws .AllowedGroups [groups [0 ]] = struct {}{}
1083+ ruleAdded = true
10711084 }
10721085
10731086 if localIp .IsValid () {
10741087 hfws .AllowedCidrs = append (
10751088 hfws .AllowedCidrs ,
10761089 localIp ,
10771090 )
1091+ ruleAdded = true
10781092 }
10791093
10801094 if CAName != "" {
10811095 hfws .AllowedCANames [CAName ] = struct {}{}
1096+ ruleAdded = true
10821097 }
10831098
10841099 if CASha != "" {
10851100 hfws .AllowedCAShas [CASha ] = struct {}{}
1101+ ruleAdded = true
1102+ }
1103+
1104+ hfws .IsModifiedSinceLastMashalling .Store (ruleAdded )
1105+
1106+ if ruleAdded {
1107+ hfws .IsEmtpy .Store (false )
10861108 }
10871109}
10881110
@@ -1134,6 +1156,88 @@ func (hfws *HandshakeFilter) IsHandshakeAllowed(groups []string, host string, vp
11341156 return false
11351157}
11361158
1159+ func (hfws * HandshakeFilter ) MarshalToHfw () * HandshakeFilteringWhitelist {
1160+ hfw := & HandshakeFilteringWhitelist {
1161+ AllowedHosts : make ([]string , len (hfws .AllowedHosts )),
1162+ AllowedGroups : make ([]string , len (hfws .AllowedGroups )),
1163+ AllowedGroupsCombos : make ([]* GroupsCombos , len (hfws .AllowedGroupsCombos )),
1164+ AllowedCidrs : make ([]string , len (hfws .AllowedCidrs )),
1165+ AllowedCANames : make ([]string , len (hfws .AllowedCANames )),
1166+ AllowedCAShas : make ([]string , len (hfws .AllowedCAShas )),
1167+ SetEmpty : hfws .IsEmtpy .Load (),
1168+ }
1169+
1170+ for host := range hfws .AllowedHosts {
1171+ hfw .AllowedHosts = append (hfw .AllowedHosts , host )
1172+ }
1173+
1174+ for group := range hfws .AllowedGroups {
1175+ hfw .AllowedGroups = append (hfw .AllowedGroups , group )
1176+ }
1177+
1178+ for i , groupCombo := range hfws .AllowedGroupsCombos {
1179+ gc := & GroupsCombos {
1180+ Group : make ([]string , len (groupCombo )),
1181+ }
1182+ j := 0
1183+ for group := range groupCombo {
1184+ gc .Group [j ] = group
1185+ j += 1
1186+ }
1187+ hfw .AllowedGroupsCombos [i ] = gc
1188+ }
1189+
1190+ for i , cidr := range hfws .AllowedCidrs {
1191+ hfw .AllowedCidrs [i ] = cidr .String ()
1192+ }
1193+
1194+ for ca := range hfws .AllowedCANames {
1195+ hfw .AllowedCANames = append (hfw .AllowedCANames , ca )
1196+ }
1197+
1198+ for fp := range hfws .AllowedCAShas {
1199+ hfw .AllowedCAShas = append (hfw .AllowedCAShas , fp )
1200+ }
1201+
1202+ hfws .IsModifiedSinceLastMashalling .Store (false )
1203+
1204+ return hfw
1205+ }
1206+
1207+ func (hfws * HandshakeFilter ) UnmarshalFromHfw (hfw * HandshakeFilteringWhitelist ) {
1208+ if hfw == nil {
1209+ return
1210+ }
1211+
1212+ for _ , h := range hfw .AllowedHosts {
1213+ hfws .AddRule (nil , h , netip.Prefix {}, "" , "" )
1214+ }
1215+
1216+ for _ , g := range hfw .AllowedGroups {
1217+ hfws .AddRule ([]string {g }, "" , netip.Prefix {}, "" , "" )
1218+ }
1219+
1220+ for _ , gc := range hfw .AllowedGroupsCombos {
1221+ hfws .AddRule (gc .Group , "" , netip.Prefix {}, "" , "" )
1222+ }
1223+
1224+ for _ , cs := range hfw .AllowedCidrs {
1225+ c , err := netip .ParsePrefix (cs )
1226+ if err != nil {
1227+ continue
1228+ }
1229+ hfws .AddRule (nil , "" , c , "" , "" )
1230+ }
1231+
1232+ for _ , ca := range hfw .AllowedCANames {
1233+ hfws .AddRule (nil , "" , netip.Prefix {}, ca , "" )
1234+ }
1235+
1236+ for _ , sha := range hfw .AllowedCAShas {
1237+ hfws .AddRule (nil , "" , netip.Prefix {}, "" , sha )
1238+ }
1239+ }
1240+
11371241func isSubset (subset map [string ]struct {}, superset []string ) bool {
11381242 ls := len (subset )
11391243 s := make (map [string ]struct {}, ls )
0 commit comments