IdSSLOpenSSLHeaders.pas
defines
SSLDLLVers : array [0..7] of string = ('.10','.1.0.2','.1.0.1','.1.0.0','0.9.9','.0.9.8','.0.9.7','0.9.6');
Note: I think '0.9.9' should probably have been '.0.9.9' in the above, but that is a lesser... bug?
Fixed.
IdGlobal
On non-Windows HackLoad is used to load ssl (which iterates through SSLDLLVers list) while On Windows HackLoad is not used since the dll is not versioned in filename.
Correct.
IdSSLOpenSSLHeaders.pas
routine LoadSSLCyrptography
- on windows loads the nonversioned lib file directly
- else if symbolic links supported uses HackLoad - but passes en empty versions array (This does nothing? since HackLoad only does any actions on passed array items)
- else if above fails it expands SSLDLLVers with letters (a,b,c etc.) then uses HackLoad
This means on Mac - Indy never reads the non-versioned file name - i.e. libsll.dylib
That is not correct. Look again at Indy's code more carefully. By default, Indy first loads the non-versioned files, in case symlinks are present. If that fails, then Indy resorts to loading individual versioned files (from newer to older):
var
GIdLoadSymLinksFirst: Boolean = True;
...
if GIdLoadSymLinksFirst then begin
Result := {$IFNDEF KYLIXCOMPAT}HMODULE({$ENDIF}
HackLoad(GIdOpenSSLPath + SSLCLIB_DLL_name, [])
{$IFNDEF KYLIXCOMPAT}){$ENDIF};
end;
if Result = 0 then begin
for i := Low(SSLDLLVers) to High(SSLDLLVers) do begin
for j := Low(SSLDLLVersChar) to High(SSLDLLVersChar) do begin
LLibVersions[j] := SSLDLLVers[i] + SSLDLLVersChar[j];
end;
Result := {$IFNDEF KYLIXCOMPAT}HMODULE({$ENDIF}
HackLoad(GIdOpenSSLPath + SSLCLIB_DLL_name, LLibVersions)
{$IFNDEF KYLIXCOMPAT}){$ENDIF};
if Result <> 0 then begin
Break;
end;
end;
end;
if (Result = 0) and (not GIdLoadSymLinksFirst) then begin
Result := {$IFNDEF KYLIXCOMPAT}HMODULE({$ENDIF}
HackLoad(GIdOpenSSLPath + SSLCLIB_DLL_name, [])
{$IFNDEF KYLIXCOMPAT}){$ENDIF};
end;
As you can see, an empty array is passed to HackLoad() only when loading non-versioned files. Whether Indy loads symlinks first, or versioned files first, is controlled by the GIdLoadSymLinksFirst variable, which is True by default (and can be changed at runtime by calling IdOpenSSLSetLoadSymLinksFirst() before OpenSSL is loaded).
Indy also seems grab pointers to all routines in the lib - and not as needed. I saw this by checking the source code TODO comments.)
Yes, I've been wanting to change that for a long time. For other external libraries that Indy uses, it loads functions on an as-needed basis. But for OpenSSL, because of the sheer number of functions being imported, it probably made more sense to load them all up front (I didn't write that code, I only maintain it).
I will try test the LibreSSL binaries shipped with Mac OS now by inserting their file name versions in the SSLDLLVers const.
You should not need to do that, since Indy should be loading the non-versioned symlinks first, which would map to LibreSSL. Make sure you are using an up-to-date snapshot of Indy.