Skip to content

Idea - allow getaddrinfo to select the IP version property #651

@JPeterMugaas

Description

@JPeterMugaas

I noticed that some programs resolve localhost and my computer name to IPv6 addresses while resolving Internet hostnames to IPv4 addresses. Indy does not do this because it passes the IP version directly to the getaddrinfo through the hints property. I would like an option that allows getaddrinfo to return either an IPv4 or IPv6 depending upon the situation.

I wrote a function that does this but using it would probably an ugly workaround but I hope it is integrated into Indy somehow:

procedure ResolveHost(const AHostname : String;
  out VIPAddress : String;
  out VIPVersion : TIdIPVersion);
var
  {$IFDEF UNICODE}
  LAddrInfo: pAddrInfoW;
  Hints: TAddrInfoW;
  {$ELSE}
  LAddrInfo: pAddrInfo;
  Hints: TAddrInfo;
  {$ENDIF}
  RetVal: Integer;
  LHostName: String;
  {$IFDEF STRING_UNICODE_MISMATCH}
  LTemp: TIdPlatformString;
  {$ENDIF}
begin
  ZeroMemory(@Hints, SizeOf(Hints));
  Hints.ai_family := AF_UNSPEC;
  Hints.ai_socktype := SOCK_STREAM;
  LAddrInfo := nil;

  if UseIDNAPI then begin
    LHostName := IDNToPunnyCode(
      {$IFDEF STRING_IS_UNICODE}
      AHostName
      {$ELSE}
      TIdUnicodeString(AHostName) // explicit convert to Unicode
      {$ENDIF}
    );
  end else begin
    LHostName := AHostname;
  end;

  {$IFDEF STRING_UNICODE_MISMATCH}
  LTemp := TIdPlatformString(LHostName); // explicit convert to Ansi/Unicode
  {$ENDIF}
  if Assigned(getaddrinfo) then
  begin
    RetVal := getaddrinfo(
      {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(LHostName){$ENDIF},
      nil, @Hints, @LAddrInfo);
    if RetVal <> 0 then begin
      RaiseSocketError(gaiErrorToWsaError(RetVal));
    end;
  end;

  try
    if not Assigned(LAddrInfo) then
    begin
      case LAddrInfo^.ai_family of
      AF_INET :
        begin
          VIPVersion := Id_IPv4;
          VIPAddress := TranslateTInAddrToString(PSockAddrIn(LAddrInfo^.ai_addr)^.sin_addr, Id_IPv4);
        end;
        AF_INET6 :
        begin
          VIPVersion := Id_IPv6;
          VIPAddress := TranslateTInAddrToString(PSockAddrIn6(LAddrInfo^.ai_addr)^.sin6_addr, Id_IPv6);
        end;
      end;
    end;
  finally
    freeaddrinfo(LAddrInfo);
  end;
end;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Element: Socket StacksIssues related to OS socket APIs, TIdStack and TIdSocketList descedants, etcStatus: ReportedIssue has been reported for reviewType: EnhancementIssue is proposing a new feature/enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions