Question

Pour mon application de serveur, je dois vérifier si une adresse IP est dans notre liste noire.

Quel est le moyen le plus efficace de comparer les adresses IP? La conversion de l’adresse IP en entier et sa comparaison seraient-elles efficaces?

Était-ce utile?

La solution

Cela dépend de la langue que vous utilisez, mais une adresse IP est généralement stockée sous forme d’entier non signé 32 bits, au moins sur la couche réseau, ce qui facilite les comparaisons. Même si ce n'est pas le cas, à moins que vous ne conceviez une application de commutation de paquets haute performance, cela ne constituera probablement pas un goulot d'étranglement. Évitez l’optimisation prématurée - concevez votre programme pour la testabilité et l’évolutivité. Si vous rencontrez des problèmes de performances, vous pouvez utiliser un profileur pour voir où se trouvent les goulots d’étranglement.

Éditer: pour clarifier, les adresses IPv4 sont stockées sous forme d’entiers 32 bits, plus un masque de réseau (qui n’est pas nécessaire pour les comparaisons d’adresses IP). Si vous utilisez le plus récent et plus rare IPv6, les adresses auront une longueur de 128 bits.

Autres conseils

Les entiers 32 bits sont la voie à suivre - jusqu'à ce que vous commenciez à traiter les adresses IPv6 128 bits.

Vous voulez dire si vous devez le comparer en tant que chaîne de texte ou convertir int en int et le comparer en tant qu'int?

Ce n'est généralement pas le goulot d'étranglement dans ce type de recherche. vous pouvez simplement essayer d'implémenter les deux méthodes et voir laquelle est la plus rapide.

Le vrai problème avec la recherche d'adresse IP consiste généralement à effectuer des requêtes efficaces, en tirant parti du fait que vous avez affaire à des adresses IP et pas uniquement à des nombres aléatoires. Pour ce faire, vous pouvez consulter LC trie et peut-être cet article

Cela ne devrait évidemment vous intéresser que si votre liste noire contient des dizaines de milliers ou des millions d'entrées. Si elle n’a que 10 à 20 entrées, une recherche linéaire devrait être privilégiée et la question la plus intéressante est la comparaison textuelle vs la comparaison d’entiers.

static public bool IsEqual(string ToCompare,
                                      string CompareAgainst)
  {

     return IPAddressToLongBackwards(ToCompare)==IPAddressToLongBackwards(CompareAgainst);
  }

static private uint IPAddressToLongBackwards(string IPAddr)
  {
     System.Net.IPAddress oIP=System.Net.IPAddress.Parse(IPAddr);
     byte[] byteIP=oIP.GetAddressBytes();


     uint ip=(uint)byteIP[0]<<24;
     ip+=(uint)byteIP[1]<<16;
     ip+=(uint)byteIP[2]<<8;
     ip+=(uint)byteIP[3];

     return ip;
  }

Si je vous ai bien compris, il s'agit d'un code permettant de comparer deux adresses IP. Tu veux ça? Vous pouvez également faire des choses telles que:

static public bool IsGreater(string ToCompare,
                               string CompareAgainst)
  {

     return IPAddressToLongBackwards(ToCompare)>
        IPAddressToLongBackwards(CompareAgainst);
  }

parce que vous avez les octets d'adresse.

Oui, j’ai trouvé que pour être efficace, ce serait long, et bien sûr, vous devez indexer les adresses IP de la liste noire sous forme entière.

Utilisez un outil tel que PeerGuardian qui interdit les connexions TCP / IP entrantes au niveau du pilote aux adresses IP figurant sur une liste noire. Très sécurisé, aucun code requis (sans conteste: hautement sécurisé, car aucun code requis).

J'ai fait cela et je l'ai testé, en utilisant un entier non signé (32 bits), c'est le plus rapide. Je suppose que vous comparez cela à la représentation sous forme de chaîne.

Une autre chose qui pourrait vous aider lors de la création de la table, j’avais auparavant 2 colonnes: LowIP et HighIP; De cette façon, j'ai pu mettre en liste noire des plages entières d'IP avec une entrée d'enregistrement et obtenir toujours de bonnes performances en vérifiant l'IP dans la plage.

J'ai une fois hérité du code dans lequel quelqu'un pensait que stocker des adresses IP sous 4 int était vraiment une bonne chose, sauf qu'ils passaient tout leur temps à convertir en int /.

Les conserver sous forme de chaînes dans la base de données était beaucoup plus simple et ne nécessitait qu'un seul index. Vous seriez surpris de voir à quel point SQL Server peut indexer des chaînes plutôt que 4 colonnes d'entiers. Mais cette liste IP n'était pas pour la liste noire. Un aller-retour à la base de données coûte très cher.

Si une base de données est saturée, stockez-la dans un dictionnaire en mémoire, mais ce n’est qu’une hypothèse, car nous n’avons aucune idée du nombre dont vous avez besoin de comparer. Étant donné que la plupart des codes de hachage sont des entiers de 32 bits et que les adresses IPv4 en ont 32, l'adresse IP elle-même pourrait bien être un bon hashcode.

Mais comme d’autres le font remarquer, la meilleure option pourrait être de réduire la charge de votre serveur et d’acheter du matériel spécialisé. Vous pouvez peut-être conserver en mémoire les adresses IP récemment inscrites sur la liste noire et en publier périodiquement de nouvelles sur le routeur.

Si vous êtes l'un de ceux qui essaient de créer un logiciel à l'intérieur d'un routeur, vous devrez alors chercher votre livre de structures de données et créer quelque chose comme un b-tree.

La Radix ou PATRICIA Trie est la structure optimale pour cela.

Recherchez les outils de flux dans la source C: http://www.splintered.net/sw/flow-tools/

J'ai travaillé dessus il y a quelques années.

Avez-vous un problème d'efficacité existant?

Si tel est le cas, alors postez le code (ou pseudo-code) et nous pourrons choisir le cadavre.

Si ce n'est pas le cas, je vous suggérerais d'essayer quelque chose de simple, comme stocker les entrées dans une liste triée et utiliser le Sort () et le Recherche existants de votre environnement.

Les comparaisons entières sont beaucoup plus rapides que les comparaisons de chaînes.

Si vous stockez les entiers dans une liste triée, vous pouvez les trouver plus rapidement que dans une liste non triée.

si vous recevez l'adresse IP sous forme de chaîne, il peut être plus efficace de la comparer à une chaîne que de la convertir en représentation entière

mais je voudrais profiler les deux solutions pour être certain, si quelques millisecondes (nanosecondes!) vont avoir de l'importance pour cette opération; -)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top