Πληροφορίες δικτύου

gethostbyaddr#

Αναζητά μια εγγραφή host με βάση την πακεταρισμένη διεύθυνση IP του.

Η gethostbyaddr εκτελεί αντίστροφη αναζήτηση DNS: δοθείσας μιας πακεταρισμένης δυαδικής διεύθυνσης (τέσσερα bytes για IPv4, δεκαέξι για IPv6) και της αντίστοιχης οικογένειας διευθύνσεων, καλεί τη ρουτίνα C gethostbyaddr(3) του συστήματος και επιστρέφει την εγγραφή host. Η τυπική περίπτωση χρήσης - «από ποιανού μηχάνημα είναι αυτό το πακέτο;» - θέλει τη μορφή βαθμωτού περιβάλλοντος: ένα μοναδικό όνομα host. Η μορφή περιβάλλοντος λίστας εκθέτει την πλήρη struct hostent: κανονικό όνομα, ψευδώνυμα, οικογένεια διευθύνσεων, μήκος διεύθυνσης και κάθε διεύθυνση που γνωρίζει ο resolver για αυτόν τον host.

Σύνοψη#

my $name = gethostbyaddr $packed_addr, $addrtype;
my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr $packed_addr, $addrtype;

Τι επιστρέφεται#

Βαθμωτό περιβάλλον - το κανονικό όνομα host ως απλή συμβολοσειρά, ή undef αν αποτύχει η αντίστροφη αναζήτηση.

Περιβάλλον λίστας - λίστα πέντε στοιχείων που αντικατοπτρίζει τη struct hostent της C:

  • $name - το κανονικό όνομα host στο οποίο αντιστοίχισε τη διεύθυνση ο resolver.

  • $aliases - συμβολοσειρά εναλλακτικών ονομάτων διαχωρισμένη με κενά. Ένα βαθμωτό, όχι λίστα.

  • $addrtype - η οικογένεια διευθύνσεων των επιστρεφόμενων διευθύνσεων, τυπικά AF_INET (2) ή AF_INET6 (10).

  • $length - το μήκος κάθε διεύθυνσης σε bytes (4 για IPv4, 16 για IPv6).

  • @addrs - κάθε διεύθυνση που επιστρέφεται για τον host, καθεμία πακεταρισμένη δυαδική συμβολοσειρά μήκους $length bytes. Συχνά μόνο μία, αλλά πολυσυνδεδεμένοι hosts μπορούν να αποδώσουν περισσότερες.

Σε αποτυχία αναζήτησης σε περιβάλλον λίστας, η επιστροφή είναι η κενή λίστα.

Καθολική κατάσταση που επηρεάζει#

  • $? - τίθεται στην τιμή h_errno της C σε αποτυχία, όταν η πλατφόρμα την εκθέτει. Ελέγξτε με $? != 0 για να διακρίνετε το HOST_NOT_FOUND από το TRY_AGAIN και παρόμοια παροδικά σφάλματα.

  • $! - δεν τίθεται με ουσιαστικό τρόπο από αποτυχίες DNS. Οι αντίστροφες αναζητήσεις αποτυγχάνουν μέσω h_errno, όχι errno· μην ελέγχετε το $! μετά από αποτυχημένη κλήση.

  • Ο δρομέας επανάληψης της βάσης δεδομένων host που μοιράζεται με τις gethostent, sethostent και endhostent. Μια κλήση της gethostbyaddr μπορεί να επαναφέρει έναν δρομέα που άφησε ανοιχτό η gethostent.

Παραδείγματα#

Βαθμωτή μορφή - αντιστοίχιση μιας τετράδας με τελείες σε όνομα host:

use Socket;
my $packed = inet_aton("127.0.0.1");
my $name   = gethostbyaddr($packed, AF_INET);
print defined $name ? "$name\n" : "no PTR record\n";

Πλήρης κύκλος - μπροστινή αναζήτηση, και μετά αντιστροφή της πρώτης διεύθυνσης:

use Socket;
my $packed = gethostbyname("www.perl.org");
my $name   = gethostbyaddr($packed, AF_INET);
print "$name\n";

Αναγνωρίστε τον ομότιμο σε αποδεκτή σύνδεση υποδοχής:

use Socket;
my $peer = getpeername($sock);
my ($port, $iaddr) = sockaddr_in($peer);
my $host = gethostbyaddr($iaddr, AF_INET);
printf "connection from %s:%d\n", $host // inet_ntoa($iaddr), $port;

Μορφή λίστας - κάθε όνομα και διεύθυνση που γνωρίζει ο resolver για τον host:

use Socket;
my $packed = inet_aton("8.8.8.8");
my ($name, $aliases, $type, $len, @addrs) = gethostbyaddr($packed, AF_INET);
print "canonical: $name\n";
print "aliases:   $_\n" for split ' ', $aliases;
print "address:   ", inet_ntoa($_), "\n" for @addrs;

Διεπαφή ανά όνομα μέσω της υπερκάλυψης Net::hostent - μέθοδοι προσπέλασης αντί για αποπακετάρισμα κατά θέση:

use Net::hostent;
use Socket;
my $h = gethostbyaddr(inet_aton("127.0.0.1"), AF_INET);
print $h->name, "\n" if $h;

Οριακές περιπτώσεις#

  • Η ADDR είναι πακεταρισμένη δυαδική συμβολοσειρά, όχι τετράδα με τελείες. Το άμεσο πέρασμα "127.0.0.1" δεν λειτουργεί - η Perl θα καλέσει τον resolver με εννέα ακατέργαστα bytes και δεν θα λάβει τίποτα χρήσιμο. Περάστε πάντοτε πρώτα από τις Socket::inet_aton, Socket::inet_pton, ή ισοδύναμο packer.

  • Το ADDRTYPE πρέπει να ταιριάζει με το πλάτος της διεύθυνσης. Η AF_INET θέλει ADDR τεσσάρων bytes· η AF_INET6 δεκαέξι. Μια αναντιστοιχία είτε επιστρέφει undef, είτε σε ορισμένες πλατφόρμες διαβάζει πέρα από τον ενταμιευτή. Χρησιμοποιήστε τη σταθερά από το Socket, όχι έναν χειρωνακτικά γραμμένο ακέραιο.

  • Ελέγξτε για undef στη βαθμωτή μορφή. Μια εγγραφή PTR που λείπει επιστρέφει undef, όχι κενή συμβολοσειρά. Πολλές διευθύνσεις στο δημόσιο internet δεν έχουν καθόλου αντίστροφη αντιστοίχιση.

  • Ο @addrs μπορεί να μην περιλαμβάνει τη διεύθυνση που ρωτήσατε. Ο resolver επιστρέφει την πλήρη εγγραφή για τον κανονικό host, που μπορεί να περιέχει επιπλέον διευθύνσεις που τυχαίνει να μοιράζονται το όνομα host.

  • Το βαθμωτό περιβάλλον εκτελεί ούτως ή άλλως την πλήρη κλήση resolver. Η ρουτίνα C πάντα συμπληρώνει ολόκληρη την hostent· η Perl απλώς απορρίπτει τη λίστα. Δεν υπάρχει πλεονέκτημα απόδοσης στη βαθμωτή μορφή πέραν από τον σαφέστερο κώδικα.

  • Η αντιστροφή μιας μπροστινής αναζήτησης δεν εγγυάται πλήρη κύκλο. Η gethostbyaddr(gethostbyname($h), AF_INET) μπορεί να επιστρέψει διαφορετικό όνομα από το $h - το αντίστροφο DNS αντιστοιχίζει στο κανονικό όνομα host, που συχνά διαφέρει από το ψευδώνυμο που χρησιμοποίησε η μπροστινή ερώτηση.

  • Η υποστήριξη IPv6 εξαρτάται από την πλατφόρμα. Δεν χειρίζεται κάθε gethostbyaddr(3) της libc την AF_INET6 καθαρά. Για φορητή αντίστροφη επίλυση διπλής στοίβας χρησιμοποιήστε την Socket::getnameinfo.

  • Ασφάλεια threads. Η υποκείμενη ρουτίνα C διατηρεί στατική κατάσταση ανά διεργασία για τον δρομέα του host. Ταυτόχρονες κλήσεις από πολλαπλά threads μπορεί να αναμείξουν αποτελέσματα. Σενάρια που χρειάζονται thread-safe αντίστροφη επίλυση πρέπει να χρησιμοποιούν την Socket::getnameinfo.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • gethostbyname - η μπροστινή αναζήτηση: όνομα host → πακεταρισμένη διεύθυνση

  • gethostent - επαναλάβετε κάθε εγγραφή στη βάση δεδομένων host αντί να αναζητήσετε μία διεύθυνση

  • sethostent - επαναφέρετε στην αρχή τον επαναλήπτη host και ελέγξτε αν το αρχείο παραμένει ανοιχτό μεταξύ αναζητήσεων

  • Socket::inet_aton - δημιουργήστε το πακεταρισμένο όρισμα ADDR από συμβολοσειρά τετράδας με τελείες

  • Socket::inet_ntoa - αποδώστε μια πακεταρισμένη διεύθυνση από τον @addrs πίσω σε μορφή τετράδας με τελείες

  • Socket::getnameinfo - σύγχρονος, ανεξάρτητος πρωτοκόλλου αντίστροφος resolver που χειρίζεται IPv6 και είναι thread-safe