IdStackDnsHostCache.pas 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. unit IdStackDnsHostCache;
  2. interface
  3. uses
  4. IdGlobal;
  5. var
  6. GIdDnsHostCacheExpiryMinutes: UInt32 = 10;
  7. function GetCachedDnsHostAddress(const AHostName: String; const AIPVersion: TIdIPVersion): String;
  8. procedure AddHostAddressToDnsCache(const AHostName; String; const AIPVersion: TIdIPVersion; const AIP: String);
  9. implementation
  10. {$I IdCompilerDefines.inc}
  11. uses
  12. SysUtils, IdThreadSafe;
  13. type
  14. TIdCachedHostAddress = class
  15. public
  16. When: TDateTime;
  17. Host: String;
  18. IP: String;
  19. IPVersion: TIdIPVersion;
  20. end;
  21. TIdCacheThreadList = TIdThreadSafeObjectList{$IFDEF HAS_GENERICS_TObjectList}<TIdCachedHostAddress>{$ENDIF};
  22. var
  23. GIdHostNames: TIdCacheThreadList = nil;
  24. // TODO: add a background thread to keep the cache purged periodically...
  25. function GetCachedDnsHostAddress(const AHostName: String; const AIPVersion: TIdIPVersion): String;
  26. var
  27. LExpire: TDateTime;
  28. LItem: TIdCachedHostAddress;
  29. LList: TList;
  30. I: Integer;
  31. begin
  32. Result := '';
  33. LExpire := Now - (GIdDnsHostCacheExpiryMinutes / MinsPerDay);
  34. LList := GIdHostNames.LockList;
  35. try
  36. for I := LList.Count - 1 downto 0 do
  37. begin
  38. LItem := {$IFDEF HAS_GENERICS_TObjectList}LList.Items[i]{$ELSE}TIdCachedHostAddress(LList.Items[i]){$ENDIF};
  39. if (GIdDnsHostCacheExpiryMinutes <> 0) and (LItem.When < LExpire) then begin
  40. LList.Delete(I);
  41. end
  42. else if (LItem.IPVersion = AIPVersion) and TextIsSame(LItem.Host, AHostName) then
  43. begin
  44. Result := LItem.IP;
  45. Exit;
  46. end;
  47. end;
  48. finally
  49. GIdHostNames.UnlockList;
  50. end;
  51. end;
  52. procedure AddHostAddressToDnsCache(const AHostName; String; const AIPVersion: TIdIPVersion; const AIP: String);
  53. var
  54. LItem: TIdCachedHostAddress;
  55. LList: TList;
  56. I: Integer;
  57. begin
  58. LList := GIdHostNames.LockList;
  59. try
  60. for I := 0 to LList.Count - 1 do
  61. begin
  62. LItem := {$IFDEF HAS_GENERICS_TObjectList}LList.Items[i]{$ELSE}TIdCachedHostAddress(LList.Items[i]){$ENDIF};
  63. if (LItem.IPVersion = AIPVersion) and TextIsSame(LItem.Host, AHostName) then
  64. begin
  65. LList.IP := AIP;
  66. LList.When := Now;
  67. Exit;
  68. end;
  69. end;
  70. LItem := TIdCachedHostAddress.Create;
  71. try
  72. LItem.Host := AHostName;
  73. LItem.IP := AIP;
  74. LItem.IPVersion := AIPVersion;
  75. LItem.When := Now;
  76. LList.Add(LList);
  77. except
  78. LItem.Free;
  79. raise;
  80. end;
  81. finally
  82. GIdHostNames.UnlockList;
  83. end;
  84. end;
  85. initialization
  86. GIdHostNames := TIdCacheThreadList.Create;
  87. finalization
  88. FreeAndNil(GIdHostNames);
  89. end.