📄 sslinux.pas
字号:
Hints.ai_flags := AI_PASSIVE;
Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
end
else
if (IP = cLocalhost) or (IP = c6Localhost) then
begin
Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
end
else
begin
Result := synsock.GetAddrInfo(PChar(IP), PChar(Port), @Hints, Addr);
end;
end;
if Result = 0 then
if (Addr <> nil) then
Move(Addr^.ai_addr^, Sin, Addr^.ai_addrlen);
finally
if Assigned(Addr) then
synsock.FreeAddrInfo(Addr);
end;
end;
begin
Result := 0;
FillChar(Sin, Sizeof(Sin), 0);
if not IsNewApi(family) then
begin
SynSockCS.Enter;
try
Sin.sin_family := AF_INET;
ProtoEnt := synsock.GetProtoByNumber(SockProtocol);
ServEnt := nil;
if ProtoEnt <> nil then
ServEnt := synsock.GetServByName(PChar(Port), ProtoEnt^.p_name);
if ServEnt = nil then
Sin.sin_port := synsock.htons(StrToIntDef(Port, 0))
else
Sin.sin_port := ServEnt^.s_port;
if IP = cBroadcast then
Sin.sin_addr.s_addr := u_long(INADDR_BROADCAST)
else
begin
Sin.sin_addr.s_addr := synsock.inet_addr(PChar(IP));
if Sin.sin_addr.s_addr = u_long(INADDR_NONE) then
begin
HostEnt := synsock.GetHostByName(PChar(IP));
Result := synsock.WSAGetLastError;
if HostEnt <> nil then
Sin.sin_addr.S_addr := u_long(Pu_long(HostEnt^.h_addr_list^)^);
end;
end;
finally
SynSockCS.Leave;
end;
end
else
begin
FillChar(Hints1, Sizeof(Hints1), 0);
FillChar(Hints2, Sizeof(Hints2), 0);
TwoPass := False;
if Family = AF_UNSPEC then
begin
if PreferIP4 then
begin
Hints1.ai_family := AF_INET;
Hints2.ai_family := AF_INET6;
TwoPass := True;
end
else
begin
Hints2.ai_family := AF_INET;
Hints1.ai_family := AF_INET6;
TwoPass := True;
end;
end
else
Hints1.ai_family := Family;
Hints1.ai_socktype := SockType;
Hints1.ai_protocol := SockProtocol;
Hints2.ai_socktype := Hints1.ai_socktype;
Hints2.ai_protocol := Hints1.ai_protocol;
r := GetAddr(IP, Port, Hints1, Sin1);
Result := r;
sin := sin1;
if r <> 0 then
if TwoPass then
begin
r := GetAddr(IP, Port, Hints2, Sin2);
Result := r;
if r = 0 then
sin := sin2;
end;
end;
end;
function GetSinIP(Sin: TVarSin): string;
var
p: PChar;
host, serv: string;
hostlen, servlen: integer;
r: integer;
begin
Result := '';
if not IsNewApi(Sin.AddressFamily) then
begin
p := synsock.inet_ntoa(Sin.sin_addr);
if p <> nil then
Result := p;
end
else
begin
hostlen := NI_MAXHOST;
servlen := NI_MAXSERV;
setlength(host, hostlen);
setlength(serv, servlen);
r := getnameinfo(@sin, SizeOfVarSin(sin), PChar(host), hostlen,
PChar(serv), servlen, NI_NUMERICHOST + NI_NUMERICSERV);
if r = 0 then
Result := PChar(host);
end;
end;
function GetSinPort(Sin: TVarSin): Integer;
begin
if (Sin.sin_family = AF_INET6) then
Result := synsock.ntohs(Sin.sin6_port)
else
Result := synsock.ntohs(Sin.sin_port);
end;
procedure ResolveNameToIP(Name: string; Family, SockProtocol, SockType: integer; const IPList: TStrings);
type
TaPInAddr = array[0..250] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
Hints: TAddrInfo;
Addr: PAddrInfo;
AddrNext: PAddrInfo;
r: integer;
host, serv: string;
hostlen, servlen: integer;
RemoteHost: PHostEnt;
IP: u_long;
PAdrPtr: PaPInAddr;
i: Integer;
s: string;
InAddr: TInAddr;
begin
IPList.Clear;
if not IsNewApi(Family) then
begin
IP := synsock.inet_addr(PChar(Name));
if IP = u_long(INADDR_NONE) then
begin
SynSockCS.Enter;
try
RemoteHost := synsock.GetHostByName(PChar(Name));
if RemoteHost <> nil then
begin
PAdrPtr := PAPInAddr(RemoteHost^.h_addr_list);
i := 0;
while PAdrPtr^[i] <> nil do
begin
InAddr := PAdrPtr^[i]^;
s := Format('%d.%d.%d.%d', [InAddr.S_bytes[0], InAddr.S_bytes[1],
InAddr.S_bytes[2], InAddr.S_bytes[3]]);
IPList.Add(s);
Inc(i);
end;
end;
finally
SynSockCS.Leave;
end;
end
else
IPList.Add(Name);
end
else
begin
Addr := nil;
try
FillChar(Hints, Sizeof(Hints), 0);
Hints.ai_family := AF_UNSPEC;
Hints.ai_socktype := SockType;
Hints.ai_protocol := SockProtocol;
Hints.ai_flags := 0;
r := synsock.GetAddrInfo(PChar(Name), nil, @Hints, Addr);
if r = 0 then
begin
AddrNext := Addr;
while not(AddrNext = nil) do
begin
if not(((Family = AF_INET6) and (AddrNext^.ai_family = AF_INET))
or ((Family = AF_INET) and (AddrNext^.ai_family = AF_INET6))) then
begin
hostlen := NI_MAXHOST;
servlen := NI_MAXSERV;
setlength(host, hostlen);
setlength(serv, servlen);
r := getnameinfo(AddrNext^.ai_addr, AddrNext^.ai_addrlen,
PChar(host), hostlen, PChar(serv), servlen,
NI_NUMERICHOST + NI_NUMERICSERV);
if r = 0 then
begin
host := PChar(host);
IPList.Add(host);
end;
end;
AddrNext := AddrNext^.ai_next;
end;
end;
finally
if Assigned(Addr) then
synsock.FreeAddrInfo(Addr);
end;
end;
if IPList.Count = 0 then
IPList.Add(cAnyHost);
end;
function ResolvePort(Port: string; Family, SockProtocol, SockType: integer): Word;
var
ProtoEnt: PProtoEnt;
ServEnt: PServEnt;
Hints: TAddrInfo;
Addr: PAddrInfo;
r: integer;
begin
Result := 0;
if not IsNewApi(Family) then
begin
SynSockCS.Enter;
try
ProtoEnt := synsock.GetProtoByNumber(SockProtocol);
ServEnt := nil;
if ProtoEnt <> nil then
ServEnt := synsock.GetServByName(PChar(Port), ProtoEnt^.p_name);
if ServEnt = nil then
Result := StrToIntDef(Port, 0)
else
Result := synsock.htons(ServEnt^.s_port);
finally
SynSockCS.Leave;
end;
end
else
begin
Addr := nil;
try
FillChar(Hints, Sizeof(Hints), 0);
Hints.ai_family := AF_UNSPEC;
Hints.ai_socktype := SockType;
Hints.ai_protocol := Sockprotocol;
Hints.ai_flags := AI_PASSIVE;
r := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
if (r = 0) and Assigned(Addr) then
begin
if Addr^.ai_family = AF_INET then
Result := synsock.htons(Addr^.ai_addr^.sin_port);
if Addr^.ai_family = AF_INET6 then
Result := synsock.htons(PSockAddrIn6(Addr^.ai_addr)^.sin6_port);
end;
finally
if Assigned(Addr) then
synsock.FreeAddrInfo(Addr);
end;
end;
end;
function ResolveIPToName(IP: string; Family, SockProtocol, SockType: integer): string;
var
Hints: TAddrInfo;
Addr: PAddrInfo;
r: integer;
host, serv: string;
hostlen, servlen: integer;
RemoteHost: PHostEnt;
IPn: u_long;
begin
Result := IP;
if not IsNewApi(Family) then
begin
IPn := synsock.inet_addr(PChar(IP));
if IPn <> u_long(INADDR_NONE) then
begin
SynSockCS.Enter;
try
RemoteHost := GetHostByAddr(@IPn, SizeOf(IPn), AF_INET);
if RemoteHost <> nil then
Result := RemoteHost^.h_name;
finally
SynSockCS.Leave;
end;
end;
end
else
begin
Addr := nil;
try
FillChar(Hints, Sizeof(Hints), 0);
Hints.ai_family := AF_UNSPEC;
Hints.ai_socktype := SockType;
Hints.ai_protocol := SockProtocol;
Hints.ai_flags := 0;
r := synsock.GetAddrInfo(PChar(IP), nil, @Hints, Addr);
if (r = 0) and Assigned(Addr)then
begin
hostlen := NI_MAXHOST;
servlen := NI_MAXSERV;
setlength(host, hostlen);
setlength(serv, servlen);
r := getnameinfo(Addr^.ai_addr, Addr^.ai_addrlen,
PChar(host), hostlen, PChar(serv), servlen,
NI_NUMERICSERV);
if r = 0 then
Result := PChar(host);
end;
finally
if Assigned(Addr) then
synsock.FreeAddrInfo(Addr);
end;
end;
end;
{=============================================================================}
function InitSocketInterface(stack: string): Boolean;
begin
Result := False;
SockEnhancedApi := False;
if stack = '' then
stack := DLLStackName;
SynSockCS.Enter;
try
if SynSockCount = 0 then
begin
SockEnhancedApi := False;
SockWship6Api := False;
Libc.Signal(Libc.SIGPIPE, TSignalHandler(Libc.SIG_IGN));
LibHandle := LoadLibrary(PChar(Stack));
if LibHandle <> 0 then
begin
errno_loc := GetProcAddress(LibHandle, PChar('__errno_location'));
CloseSocket := GetProcAddress(LibHandle, PChar('close'));
IoctlSocket := GetProcAddress(LibHandle, PChar('ioctl'));
WSAGetLastError := LSWSAGetLastError;
WSAStartup := LSWSAStartup;
WSACleanup := LSWSACleanup;
ssAccept := GetProcAddress(LibHandle, PChar('accept'));
ssBind := GetProcAddress(LibHandle, PChar('bind'));
ssConnect := GetProcAddress(LibHandle, PChar('connect'));
ssGetPeerName := GetProcAddress(LibHandle, PChar('getpeername'));
ssGetSockName := GetProcAddress(LibHandle, PChar('getsockname'));
GetSockOpt := GetProcAddress(LibHandle, PChar('getsockopt'));
Htonl := GetProcAddress(LibHandle, PChar('htonl'));
Htons := GetProcAddress(LibHandle, PChar('htons'));
Inet_Addr := GetProcAddress(LibHandle, PChar('inet_addr'));
Inet_Ntoa := GetProcAddress(LibHandle, PChar('inet_ntoa'));
Listen := GetProcAddress(LibHandle, PChar('listen'));
Ntohl := GetProcAddress(LibHandle, PChar('ntohl'));
Ntohs := GetProcAddress(LibHandle, PChar('ntohs'));
ssRecv := GetProcAddress(LibHandle, PChar('recv'));
ssRecvFrom := GetProcAddress(LibHandle, PChar('recvfrom'));
Select := GetProcAddress(LibHandle, PChar('select'));
ssSend := GetProcAddress(LibHandle, PChar('send'));
ssSendTo := GetProcAddress(LibHandle, PChar('sendto'));
SetSockOpt := GetProcAddress(LibHandle, PChar('setsockopt'));
ShutDown := GetProcAddress(LibHandle, PChar('shutdown'));
Socket := GetProcAddress(LibHandle, PChar('socket'));
GetHostByAddr := GetProcAddress(LibHandle, PChar('gethostbyaddr'));
GetHostByName := GetProcAddress(LibHandle, PChar('gethostbyname'));
GetProtoByName := GetProcAddress(LibHandle, PChar('getprotobyname'));
GetProtoByNumber := GetProcAddress(LibHandle, PChar('getprotobynumber'));
GetServByName := GetProcAddress(LibHandle, PChar('getservbyname'));
GetServByPort := GetProcAddress(LibHandle, PChar('getservbyport'));
ssGetHostName := GetProcAddress(LibHandle, PChar('gethostname'));
{$IFNDEF FORCEOLDAPI}
GetAddrInfo := GetProcAddress(LibHandle, PChar('getaddrinfo'));
FreeAddrInfo := GetProcAddress(LibHandle, PChar('freeaddrinfo'));
GetNameInfo := GetProcAddress(LibHandle, PChar('getnameinfo'));
SockEnhancedApi := Assigned(GetAddrInfo) and Assigned(FreeAddrInfo)
and Assigned(GetNameInfo);
{$ENDIF}
Result := True;
end;
end
else Result := True;
if Result then
Inc(SynSockCount);
finally
SynSockCS.Leave;
end;
end;
function DestroySocketInterface: Boolean;
begin
SynSockCS.Enter;
try
Dec(SynSockCount);
if SynSockCount < 0 then
SynSockCount := 0;
if SynSockCount = 0 then
begin
if LibHandle <> 0 then
begin
FreeLibrary(libHandle);
LibHandle := 0;
end;
if LibWship6Handle <> 0 then
begin
FreeLibrary(LibWship6Handle);
LibWship6Handle := 0;
end;
end;
finally
SynSockCS.Leave;
end;
Result := True;
end;
initialization
begin
SynSockCS := SyncObjs.TCriticalSection.Create;
SET_IN6_IF_ADDR_ANY (@in6addr_any);
SET_LOOPBACK_ADDR6 (@in6addr_loopback);
end;
finalization
begin
SynSockCS.Free;
end;
{$ENDIF}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -