Greetings. I had been using version 2.0.2 (under Linux, if it matters) and noticed a problem with the THostResolver component. It was giving incorrect (reversed) addresses for anything that had to come from DNS. Entries out of /etc/hosts would work fine, though. After fixing the problem here locally, I figured I ought to share.
In the process of getting ready to do that, I wound up upgrading to the latest stable version (2.0.4) and was happy to see that some attempt had already been made to fix that bug. Unfortunately, it appears that the problem has been reversed instead of fixed. Now lookups that come through DNS are showing up properly but the ones from /etc/hosts are not. The fix is further down, but for reference here is a test program which will show the problem in action. The original purpose of this test program was to develop/test a generic Lookup() function that would deal with short and full host names, which it does. Feel free to use it, if it's helpful to you. :) program resolver_test; uses SysUtils, resolve, netdb; function Lookup (WhatHost: String): String; var TheHost: THostResolver; begin Result := ''; TheHost := THostResolver.Create(nil); try // First, attempt lookup using the name as given to us if TheHost.NameLookup(WhatHost) then Result := TheHost.AddressAsString; // If not found, and no dot in the name, tack on default domain if (Result = '') and (pos('.', WhatHost) = 0) then if TheHost.NameLookup(WhatHost + '.' + DefaultDomainList) then Result := TheHost.AddressAsString; finally TheHost.free; end; end; procedure testlookup (What, Where, Expected: String); var Res : String; begin Res := Lookup (What); Write (Format('Lookup %-19s from %-10s : %-15s ', [What, Where, Res])); if Res = Expected then writeln ('Success!') else writeln ('Failure!'); end; begin Writeln ('default domain is ', DefaultDomainList); testlookup ('localhost', '/etc/hosts', '127.0.0.1'); testlookup ('host85', 'dns', '192.168.1.85'); testlookup ('delenn', '/etc/hosts', '192.168.1.92'); testlookup ('www.freepascal.org', 'dns', '62.166.198.202'); end. The "expected" values were all determined by "getent hosts" as follows: for a in localhost host85 delenn www.freepascal.org ; do getent hosts $a; done The "where" part comes from me knowing that there are only two non-comment lines in my /etc/hosts file. :) The incorrect results, as given by the above program compiled with the 2.0.4 binary distribution: default domain is sbcglobal.net Lookup localhost from /etc/hosts : 1.0.0.127 Failure! Lookup host85 from dns : 192.168.1.85 Success! Lookup delenn from /etc/hosts : 92.1.168.192 Failure! Lookup www.freepascal.org from dns : 62.166.198.202 Success! As you can see, the addresses that came from /etc/hosts are in the wrong order. The problem is in the routines THostResolver.NameLookup and THostResolver.SaveHostEntry in resolve.pp. In THostResolver.SaveHostEntry there are several calls of NetToHost(), as follows: Procedure THostResolver.SaveHostEntry(Entry : Pointer); Var PH : ^THostEntry; I : Integer; begin PH:=ENtry; FName:=PH^.Name; FHostAddress:=NetToHost(PH^.Addr); FAddressCount:=1; GetMem(FAddresses,SizeOf(THostAddr)); FAddresses[0]:=NetToHost(PH^.Addr); FAliases.CommaText:=PH^.Aliases; end; This is incorrect behavior, as some of the addresses passed to SaveHostEntry may already be in host order. The two NetToHost() calls should be removed from this function, and instead, one should be added to the THostResolver.Namelookup function immediately after the ResolveHostByName() call, which returns addresses in network order. Like so: {$ifdef usenetdb} Function THostResolver.NameLookup (Const S : String) : Boolean; Var H : THostEntry; begin Result:=Inherited NameLookup(S); If Result then begin Result:=GetHostByName(S,H); if not Result then begin Result:=ResolveHostByName(S,H); if Result then H.Addr:=NetToHost(H.Addr); end; If Result then SaveHostEntry(@H); end; end; ... and the other fix, further down ... Procedure THostResolver.SaveHostEntry(Entry : Pointer); Var PH : ^THostEntry; I : Integer; begin PH:=ENtry; FName:=PH^.Name; FHostAddress:=PH^.Addr; FAddressCount:=1; GetMem(FAddresses,SizeOf(THostAddr)); FAddresses[0]:=PH^.Addr; FAliases.CommaText:=PH^.Aliases; end; After this change, the proper results are obtained: ~/devel/temp $./resolver_test default domain is sbcglobal.net Lookup localhost from /etc/hosts : 127.0.0.1 Success! Lookup host85 from dns : 192.168.1.85 Success! Lookup delenn from /etc/hosts : 192.168.1.92 Success! Lookup www.freepascal.org from dns : 62.166.198.202 Success! I have not looked at any of the other T{foo}Resolver classes at all, since I don't use them, and do not know if they need similar changes. In any event, I hope this proves helpful to the person maintaining this module. Best regards, Pete C. _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel