CIDR's actually working would be nice. That's what I get for assuming the output from a different func would be correct.

When banning checked accounts, it should only tag and comment the checked ones, not all of them in the list.
Optimizing firewall.
This commit is contained in:
asayre 2007-02-10 08:21:13 +00:00
parent 318ad5f08c
commit 75e8798c18
4 changed files with 254 additions and 49 deletions

View file

@ -2,16 +2,168 @@ using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Collections.Generic;
namespace Server
{
public class Firewall
{
private static ArrayList m_Blocked;
#region Firewall Entries
public interface IFirewallEntry
{
bool IsBlocked( IPAddress address );
}
public class IPFirewallEntry : IFirewallEntry
{
IPAddress m_Address;
public IPFirewallEntry( IPAddress address )
{
m_Address = address;
}
public bool IsBlocked( IPAddress address )
{
return m_Address.Equals( address );
}
public override string ToString()
{
return m_Address.ToString();
}
public override bool Equals( object obj )
{
if( obj is IPAddress )
{
return obj.Equals( m_Address );
}
else if( obj is string )
{
IPAddress otherAddress;
if( IPAddress.TryParse( (string)obj, out otherAddress ) )
return otherAddress.Equals( m_Address );
}
else if( obj is IPFirewallEntry )
{
return m_Address.Equals( ((IPFirewallEntry)obj).m_Address );
}
return false;
}
public override int GetHashCode()
{
return m_Address.GetHashCode();
}
}
public class CIDRFirewallEntry : IFirewallEntry
{
IPAddress m_CIDRPrefix;
int m_CIDRLength;
public CIDRFirewallEntry( IPAddress cidrPrefix, int cidrLength )
{
m_CIDRPrefix = cidrPrefix;
m_CIDRLength = cidrLength;
}
public bool IsBlocked( IPAddress address )
{
return Utility.IPMatchCIDR( m_CIDRPrefix, address, m_CIDRLength );
}
public override string ToString()
{
return String.Format( "{0}/{1}", m_CIDRPrefix, m_CIDRLength );
}
public override bool Equals( object obj )
{
if( obj is string )
{
string entry= (string)obj;
string[] str = entry.Split( '/' );
if( str.Length == 2 )
{
IPAddress cidrPrefix;
if( IPAddress.TryParse( str[0], out cidrPrefix ) )
{
int cidrLength;
if( int.TryParse( str[1], out cidrLength ) )
return m_CIDRPrefix.Equals( cidrPrefix ) && m_CIDRLength.Equals( cidrLength );
}
}
}
else if( obj is CIDRFirewallEntry )
{
CIDRFirewallEntry entry = obj as CIDRFirewallEntry;
return m_CIDRPrefix.Equals( entry.m_CIDRPrefix ) && m_CIDRLength.Equals( entry.m_CIDRLength );
}
return false;
}
public override int GetHashCode()
{
return m_CIDRPrefix.GetHashCode() ^ m_CIDRLength.GetHashCode();
}
}
public class WildcardIPFirewallEntry : IFirewallEntry
{
string m_Entry;
bool m_Valid = true;
public WildcardIPFirewallEntry( string entry )
{
m_Entry = entry;
}
public bool IsBlocked( IPAddress address )
{
if( !m_Valid )
return false; //Why process if it's invalid? it'll return false anyway after processing it.
return Utility.IPMatch( m_Entry, address, ref m_Valid );
}
public override string ToString()
{
return m_Entry.ToString();
}
public override bool Equals( object obj )
{
if( obj is string )
return obj.Equals( m_Entry );
else if( obj is WildcardIPFirewallEntry )
m_Entry.Equals( ((WildcardIPFirewallEntry)obj).m_Entry );
return false;
}
public override int GetHashCode()
{
return m_Entry.GetHashCode();
}
}
#endregion
private static List<IFirewallEntry> m_Blocked;
static Firewall()
{
m_Blocked = new ArrayList();
m_Blocked = new List<IFirewallEntry>();
string path = "firewall.cfg";
@ -28,6 +180,9 @@ namespace Server
if ( line.Length == 0 )
continue;
m_Blocked.Add( ToFirewallEntry( line ) );
/*
object toAdd;
IPAddress addr;
@ -37,12 +192,13 @@ namespace Server
toAdd = line;
m_Blocked.Add( toAdd.ToString() );
* */
}
}
}
}
public static ArrayList List
public static List<IFirewallEntry> List
{
get
{
@ -50,47 +206,87 @@ namespace Server
}
}
public static IFirewallEntry ToFirewallEntry( object entry )
{
if( entry is IFirewallEntry )
return (IFirewallEntry)entry;
else if( entry is IPAddress )
return new IPFirewallEntry( (IPAddress)entry );
else if( entry is string )
return ToFirewallEntry( (string)entry );
return null;
}
public static IFirewallEntry ToFirewallEntry( string entry )
{
IPAddress addr;
if( IPAddress.TryParse( entry, out addr ) )
return new IPFirewallEntry( addr );
//Try CIDR parse
string[] str = entry.Split( '/' );
if( str.Length == 2 )
{
IPAddress cidrPrefix;
if( IPAddress.TryParse( str[0], out cidrPrefix ) )
{
int cidrLength;
if( int.TryParse( str[1], out cidrLength ) )
return new CIDRFirewallEntry( cidrPrefix, cidrLength );
}
}
return new WildcardIPFirewallEntry( entry );
}
public static void RemoveAt( int index )
{
m_Blocked.RemoveAt( index );
Save();
}
public static void Remove( string pattern )
public static void Remove( object obj )
{
m_Blocked.Remove( pattern );
Save();
}
IFirewallEntry entry = ToFirewallEntry( obj );
public static void Remove( IPAddress ip )
{
m_Blocked.Remove( ip );
Save();
if( entry != null )
{
m_Blocked.Remove( entry );
Save();
}
}
public static void Add( object obj )
{
if ( !(obj is IPAddress) && !(obj is String) )
return;
if ( !m_Blocked.Contains( obj ) )
m_Blocked.Add( obj );
Save();
if( obj is IPAddress )
Add( (IPAddress)obj );
else if( obj is string )
Add( (string)obj );
}
public static void Add( string pattern )
{
if ( !m_Blocked.Contains( pattern ) )
m_Blocked.Add( pattern );
IFirewallEntry entry = ToFirewallEntry( pattern );
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
public static void Add( IPAddress ip )
{
if ( !m_Blocked.Contains( ip ) )
m_Blocked.Add( ip );
IFirewallEntry entry = new IPFirewallEntry( ip );
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
@ -108,6 +304,14 @@ namespace Server
public static bool IsBlocked( IPAddress ip )
{
for( int i = 0; i < m_Blocked.Count; i++ )
{
if( m_Blocked[i].IsBlocked( ip ) )
return true;
}
return false;
/*
bool contains = false;
for ( int i = 0; !contains && i < m_Blocked.Count; ++i )
@ -126,6 +330,7 @@ namespace Server
}
return contains;
* */
}
}
}

View file

@ -85,9 +85,9 @@ namespace Server.Movement
bool landBlocks = (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Impassable) != 0;
bool considerLand = !landTile.Ignored;
if ( landBlocks && canSwim && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) != 0 )
if ( landBlocks && canSwim && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) != 0 ) //Impassable, Can Swim, and Is water. Don't block it.
landBlocks = false;
else if ( cantWalk && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) == 0 )
else if ( cantWalk && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) == 0 ) //Can't walk and it's not water
landBlocks = true;
int landZ = 0, landCenter = 0, landTop = 0;
@ -101,6 +101,7 @@ namespace Server.Movement
bool ignoreDoors = ( m_AlwaysIgnoreDoors || !m.Alive || m.Body.BodyID == 0x3DB || m.IsDeadBondedPet );
#region Tiles
for ( int i = 0; i < tiles.Length; ++i )
{
Tile tile = tiles[i];
@ -152,7 +153,9 @@ namespace Server.Movement
}
}
}
#endregion
#region Items
for ( int i = 0; i < items.Count; ++i )
{
Item item = items[i];
@ -205,6 +208,8 @@ namespace Server.Movement
}
}
#endregion
if ( considerLand && !landBlocks && stepTop >= landZ )
{
int ourZ = landCenter;

View file

@ -1545,7 +1545,7 @@ namespace Server.Gumps
from.SendGump( new NoticeGump( 1060637, 30720, String.Format( "You have {0} the account{1}.", ban ? "banned" : "deleted", rads.Count == 1 ? "" : "s" ), 0xFFC000, 420, 280, new NoticeGumpCallback( ResendGump_Callback ), new object[]{ list, rads, ban ? page : 0 } ) );
if ( ban )
from.SendGump( new BanDurationGump( list ) );
from.SendGump( new BanDurationGump( rads ) );
}
else
{
@ -2503,8 +2503,7 @@ namespace Server.Gumps
{
CommandLogging.WriteLine( from, "{0} {1} removing {2} from firewall list", from.AccessLevel, CommandLogging.Format( from ), m_State );
Firewall.List.Remove( m_State );
Firewall.Save();
Firewall.Remove( m_State );
from.SendGump( new AdminGump( from, AdminGumpPage.Firewall, 0, null, String.Format( "{0} : Removed from firewall.", m_State ), null ) );
}