getaddrinfo
« | 28 May 2023 | »Die Funktion getaddrinfo()
löst Funktionen wie gethostbyname()
oder gethostbyaddr()
ab und ist quasi “die” Schnittstelle zur DNS
Auflösung eines Systems im Netzwerk.
Blöd nur, dass Windows 95 davon nichts wusste…
Fehlkonstruktion gethostbyname
gethostbyname()
ist auch eine von diesen dummen Funktionen, die C
Programmen ihren schlechten Ruf beschert hat.
Hier wird nämlich das Ergebnis in einen Puffer im Hintergrund geschrieben,
den man nicht unter Kontrolle hat.
Im schlimmsten Fall ist es ein globaler Puffer, was bedeutet, dass nicht
zwei Threads die Funktion nicht gleichzeitig benutzen dürfen.
Das kann man jetzt gerne über einen Mutex lösen, durch niemand weiß, ob nicht eine Fremdbibliothek ebenso die Funktion aufruft und dort ohne Mutex den Puffer bearbeitet.
getaddrinfo()
ist die flexibler Nachfolger-Funktion und allokiert
separaten Speicher für jeden Aufruf. Außerdem erlaubt sie wesentlich
mehr Optionen für die Hostnamen-Auflösung.
Warum als nicht immer getaddrinfo?
Tja, heute kein Thema. Jedes OS hat die Funktion integriert. Doch meine
(Support-)Welt beginnt in den 90ern, wo getaddrinfo
weder in Windows
noch in den damaligen Unix-Derivaten garantiert vorhanden war.
Aus diesem Grund findet man in meinen älteren Projekten nur Mutex-geschützte
gethostbyname
Aufrufe.
Unter Windows wurde getaddrinfo()
mit Windows XP in die ws2_32.dll
integriert.
Windows 2000 und ältere Vertreter meldeten somit immer einen fehlenden
Einsprungpunkt, wenn man sein Projekt gegen die Funktion linken ließ.
Es gibt zwar den dokumentierten Verweis zur inline Funktion WspiapiGetAddrInfo
,
die getaddrinfo
dann über andere DLLs zu laden versucht, doch auch die sind
nur unter Windows 2000 mit bestimmten Preview-Updates vorhanden und nicht in
Standard-Installationen.
Windows 9x fällt übrigens generell flach bei dem Thema.
Fazit
Heute baue ich in der Regel auf ein dynamisch geladenes getaddrinfo()
.
Ist die Funktion im OS enthalten (also LoadLibrary("ws2_32")
oder
dlopen(NULL, RTLD_GLOBAL)
), wird sie benutzt.
Wenn nicht, dann implementiere ich sie mit gethostbyname
provisorisch
inklusive Mutex nach.
Auf diese Weise kommen Binaries heraus, die überall gestartet werden können und dann eben das heranziehen, was vorhanden ist.