public bool Equals(IpTablesChain other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } return(string.Equals(_name, other._name) && string.Equals(_table, other._table) && Equals(_system, other._system) && _ipVersion == other._ipVersion); }
public bool CompareRules(IpTablesChain ipTablesChain, IEqualityComparer <IpTablesRule> eqc = null) { eqc = eqc ?? new IpTablesRule.ValueComparison(); return(Enumerable.SequenceEqual(_rules, ipTablesChain._rules, eqc)); }
/// <summary> /// Add an IPTables rule to the set /// </summary> /// <param name="rule"></param> public void AddRule(IpTablesRule rule) { IpTablesChain ipchain = _chains.GetChainOrAdd(rule.Chain); ipchain.Rules.Add(rule); }
/// <summary> /// Create a new (empty) IPTables Rule /// </summary> /// <param name="system"></param> /// <param name="chain"></param> public IpTablesRule(NetfilterSystem system, IpTablesChain chain) { _system = system; _chain = chain; }
/// <summary> /// Sync with an IPTables system /// </summary> /// <param name="sync"></param> /// <param name="canDeleteChain"></param> /// <param name="maxRetries"></param> public void Sync(INetfilterSync <IpTablesRule> sync, Func <IpTablesChain, bool> canDeleteChain = null, int maxRetries = 10) { var tableAdapter = _system.GetTableAdapter(_ipVersion); List <IpTablesChain> chainsToAdd = new List <IpTablesChain>(); bool needed; int retries = maxRetries; do { try { //Start transaction tableAdapter.StartTransaction(); //Load all chains, figure out what to add var tableChains = new Dictionary <string, List <IpTablesChain> >(); foreach (IpTablesChain chain in Chains) { if (!tableChains.ContainsKey(chain.Table)) { var chains = _system.GetChains(chain.Table, _ipVersion).ToList(); tableChains.Add(chain.Table, chains); } if ( tableChains[chain.Table].FirstOrDefault(a => a.Name == chain.Name && a.Table == chain.Table) == null) { //Chain doesnt exist, to create chainsToAdd.Add(chain); } } //Add the new chains / rules foreach (var chain in chainsToAdd) { tableChains[chain.Table].Add(_system.AddChain(chain)); } chainsToAdd.Clear(); //Special case if (tableAdapter is IPTablesLibAdapterClient) { //Sync chain adds before starting rule adds tableAdapter.EndTransactionCommit(); tableAdapter.StartTransaction(); } //Update chains with differing rules foreach (IpTablesChain chain in Chains) { IpTablesChain realChain = tableChains[chain.Table].First(a => a.Name == chain.Name && a.Table == chain.Table); if (realChain != null) { //Update chain realChain.SyncInternal(chain.Rules, sync); } } //End Transaction: COMMIT tableAdapter.EndTransactionCommit(); if (canDeleteChain != null) { //Start transaction //Needs new transaction, bug in libiptc? tableAdapter.StartTransaction(); foreach (string table in Chains.Select(a => a.Table).Distinct()) { foreach (IpTablesChain chain in _system.GetChains(table, _ipVersion)) { if (!_chains.HasChain(chain.Name, chain.Table) && canDeleteChain(chain)) { chain.Delete(); } } } //End Transaction: COMMIT tableAdapter.EndTransactionCommit(); } needed = false; } catch (IpTablesNetExceptionErrno ex) { if (ex.Errno == 11 && retries != 0)//Resource Temporarily unavailable { Thread.Sleep(100 * (maxRetries - retries)); retries--; needed = true; } else { throw; } } } while (needed); }