📄 blcksock.pas
字号:
Result := 'Protocol family not supported';
WSAEAFNOSUPPORT: {10047}
Result := 'Address family not supported';
WSAEADDRINUSE: {10048}
Result := 'Address already in use';
WSAEADDRNOTAVAIL: {10049}
Result := 'Can''t assign requested address';
WSAENETDOWN: {10050}
Result := 'Network is down';
WSAENETUNREACH: {10051}
Result := 'Network is unreachable';
WSAENETRESET: {10052}
Result := 'Network dropped connection on reset';
WSAECONNABORTED: {10053}
Result := 'Software caused connection abort';
WSAECONNRESET: {10054}
Result := 'Connection reset by peer';
WSAENOBUFS: {10055}
Result := 'No Buffer space available';
WSAEISCONN: {10056}
Result := 'Socket is already connected';
WSAENOTCONN: {10057}
Result := 'Socket is not connected';
WSAESHUTDOWN: {10058}
Result := 'Can''t send after Socket shutdown';
WSAETOOMANYREFS: {10059}
Result := 'Too many references:can''t splice';
WSAETIMEDOUT: {10060}
Result := 'Connection timed out';
WSAECONNREFUSED: {10061}
Result := 'Connection refused';
WSAELOOP: {10062}
Result := 'Too many levels of symbolic links';
WSAENAMETOOLONG: {10063}
Result := 'File name is too long';
WSAEHOSTDOWN: {10064}
Result := 'Host is down';
WSAEHOSTUNREACH: {10065}
Result := 'No route to host';
WSAENOTEMPTY: {10066}
Result := 'Directory is not empty';
WSAEPROCLIM: {10067}
Result := 'Too many processes';
WSAEUSERS: {10068}
Result := 'Too many users';
WSAEDQUOT: {10069}
Result := 'Disk quota exceeded';
WSAESTALE: {10070}
Result := 'Stale NFS file handle';
WSAEREMOTE: {10071}
Result := 'Too many levels of remote in path';
WSASYSNOTREADY: {10091}
Result := 'Network subsystem is unusable';
WSAVERNOTSUPPORTED: {10092}
Result := 'Winsock DLL cannot support this application';
WSANOTINITIALISED: {10093}
Result := 'Winsock not initialized';
WSAEDISCON: {10101}
Result := 'WSAEDISCON-10101';
WSAHOST_NOT_FOUND: {11001}
Result := 'Host not found';
WSATRY_AGAIN: {11002}
Result := 'Non authoritative - host not found';
WSANO_RECOVERY: {11003}
Result := 'Non recoverable error';
WSANO_DATA: {11004}
Result := 'Valid name, no data record of requested type'
else
Result := 'Not a Winsock error (' + IntToStr(ErrorCode) + ')';
end;
end;
{======================================================================}
constructor TSocksBlockSocket.Create;
begin
inherited Create;
FSocksIP:= '';
FSocksPort:= '1080';
FSocksTimeout:= 300000;
FSocksUsername:= '';
FSocksPassword:= '';
FUsingSocks := False;
FSocksResolver := True;
FSocksLastError := 0;
FSocksResponseIP := '';
FSocksResponsePort := '';
FSocksLocalIP := '';
FSocksLocalPort := '';
FSocksRemoteIP := '';
FSocksRemotePort := '';
end;
function TSocksBlockSocket.SocksOpen: boolean;
var
Buf: string;
n: integer;
begin
Result := False;
FUsingSocks := False;
if FSocksUsername = '' then
Buf := #5 + #1 + #0
else
Buf := #5 + #2 + #2 +#0;
SendString(Buf);
Buf := RecvPacket(FSocksTimeout);
FBuffer := Copy(Buf, 3, Length(buf) - 2);
if Length(Buf) < 2 then
Exit;
if Buf[1] <> #5 then
Exit;
n := Ord(Buf[2]);
case n of
0: //not need authorisation
;
2:
begin
Buf := #1 + char(Length(FSocksUsername)) + FSocksUsername
+ char(Length(FSocksPassword)) + FSocksPassword;
SendString(Buf);
Buf := RecvPacket(FSocksTimeout);
FBuffer := Copy(Buf, 3, Length(buf) - 2);
if Length(Buf) < 2 then
Exit;
if Buf[2] <> #0 then
Exit;
end;
else
Exit;
end;
FUsingSocks := True;
Result := True;
end;
function TSocksBlockSocket.SocksRequest(Cmd: Byte;
const IP, Port: string): Boolean;
var
Buf: string;
begin
Result := False;
Buf := #5 + char(Cmd) + #0 + SocksCode(IP, Port);
SendString(Buf);
Result := FLastError = 0;
end;
function TSocksBlockSocket.SocksResponse: Boolean;
var
Buf: string;
x: integer;
begin
Result := False;
FSocksResponseIP := '';
FSocksResponsePort := '';
Buf := RecvPacket(FSocksTimeout);
if FLastError <> 0 then
Exit;
if Length(Buf) < 5 then
Exit;
if Buf[1] <> #5 then
Exit;
FSocksLastError := Ord(Buf[2]);
if FSocksLastError <> 0 then
Exit;
x := SocksDecode(Buf);
FBuffer := Copy(Buf, x, Length(buf) - x + 1);
Result := True;
end;
function TSocksBlockSocket.SocksCode(IP, Port: string): string;
begin
if IsIP(IP) then
Result := #1 + IPToID(IP)
else
if FSocksResolver then
Result := #3 + char(Length(IP)) + IP
else
Result := #1 + IPToID(ResolveName(IP));
Result := Result + CodeInt(synsock.htons(ResolvePort(Port)));
end;
function TSocksBlockSocket.SocksDecode(Value: string): integer;
var
Atyp: Byte;
y, n: integer;
w: Word;
begin
FSocksResponsePort := '0';
Atyp := Ord(Value[4]);
Result := 5;
case Atyp of
1:
begin
if Length(Value) < 10 then
Exit;
FSocksResponseIP := Format('%d.%d.%d.%d',
[Ord(Value[5]), Ord(Value[6]), Ord(Value[7]), Ord(Value[8])]);
Result := 9;
end;
3:
begin
y := Ord(Value[5]);
if Length(Value) < (5 + y + 2) then
Exit;
for n := 6 to 6 + y do
FSocksResponseIP := FSocksResponseIP + Value[n];
Result := 5 + y +1;
end;
else
Exit;
end;
w := DecodeInt(Value, Result);
FSocksResponsePort := IntToStr(w);
Result := Result + 2;
end;
{======================================================================}
destructor TUDPBlockSocket.Destroy;
begin
if Assigned(FSocksControlSock) then
FSocksControlSock.Free;
inherited;
end;
procedure TUDPBlockSocket.CreateSocket;
begin
FSocket := synsock.Socket(PF_INET, Integer(SOCK_DGRAM), IPPROTO_UDP);
FProtocol := IPPROTO_UDP;
inherited CreateSocket;
end;
function TUDPBlockSocket.EnableBroadcast(Value: Boolean): Boolean;
var
Opt: Integer;
Res: Integer;
begin
opt := Ord(Value);
Res := synsock.SetSockOpt(FSocket, SOL_SOCKET, SO_BROADCAST, @Opt, SizeOf(opt));
SockCheck(Res);
Result := res = 0;
ExceptCheck;
end;
procedure TUDPBlockSocket.Connect(IP, Port: string);
begin
SetRemoteSin(IP, Port);
FBuffer := '';
DoStatus(HR_Connect, IP + ':' + Port);
end;
function TUDPBlockSocket.RecvBuffer(Buffer: Pointer; Length: Integer): Integer;
begin
Result := RecvBufferFrom(Buffer, Length);
end;
function TUDPBlockSocket.SendBuffer(Buffer: Pointer; Length: Integer): Integer;
begin
Result := SendBufferTo(Buffer, Length);
end;
function TUDPBlockSocket.UdpAssociation: Boolean;
var
b: Boolean;
begin
Result := True;
FUsingSocks := False;
if FSocksIP <> '' then
begin
Result := False;
if not Assigned(FSocksControlSock) then
FSocksControlSock := TTCPBlockSocket.Create;
FSocksControlSock.CloseSocket;
FSocksControlSock.CreateSocket;
FSocksControlSock.Connect(FSocksIP, FSocksPort);
if FSocksControlSock.LastError <> 0 then
Exit;
// if not assigned local port, assign it!
if GetLocalSinPort = 0 then
Bind(GetLocalSinIP, '0');
GetSins;
//open control TCP connection to SOCKS
b := FSocksControlSock.SocksOpen;
if b then
b := FSocksControlSock.SocksRequest(3, GetLocalSinIP,
IntToStr(GetLocalSinPort));
if b then
b := FSocksControlSock.SocksResponse;
if not b and (FLastError = 0) then
FLastError := WSANO_RECOVERY;
FUsingSocks :=FSocksControlSock.UsingSocks;
FSocksRemoteIP := FSocksControlSock.FSocksResponseIP;
FSocksRemotePort := FSocksControlSock.FSocksResponsePort;
Result := True;
end;
end;
function TUDPBlockSocket.SendBufferTo(Buffer: Pointer; Length: Integer): Integer;
var
SIp: string;
SPort: integer;
Buf: string;
begin
UdpAssociation;
if FUsingSocks then
begin
Sip := GetRemoteSinIp;
SPort := GetRemoteSinPort;
SetRemoteSin(FSocksRemoteIP, FSocksRemotePort);
SetLength(Buf,Length);
Move(Buffer^, PChar(Buf)^, Length);
Buf := #0 + #0 + #0 + SocksCode(Sip, IntToStr(SPort)) + Buf;
Result := inherited SendBufferTo(PChar(Buf), System.Length(buf));
SetRemoteSin(Sip, IntToStr(SPort));
end
else
begin
Result := inherited SendBufferTo(Buffer, Length);
GetSins;
end;
end;
function TUDPBlockSocket.RecvBufferFrom(Buffer: Pointer; Length: Integer): Integer;
var
Buf: string;
x: integer;
begin
Result := inherited RecvBufferFrom(Buffer, Length);
if FUsingSocks then
begin
SetLength(Buf, Result);
Move(Buffer^, PChar(Buf)^, Result);
x := SocksDecode(Buf);
Result := Result - x + 1;
Buf := Copy(Buf, x, Result);
Move(PChar(Buf)^, Buffer^, Result);
SetRemoteSin(FSocksResponseIP, FSocksResponsePort);
end;
end;
{======================================================================}
procedure TTCPBlockSocket.CreateSocket;
begin
FSocket := synsock.Socket(PF_INET, Integer(SOCK_STREAM), IPPROTO_TCP);
FProtocol := IPPROTO_TCP;
inherited CreateSocket;
end;
procedure TTCPBlockSocket.CloseSocket;
begin
synsock.Shutdown(FSocket, 1);
inherited CloseSocket;
end;
procedure TTCPBlockSocket.Listen;
var
b: Boolean;
Sip,SPort: string;
begin
if FSocksIP = '' then
begin
SockCheck(synsock.Listen(FSocket, SOMAXCONN));
GetSins;
end
else
begin
Sip := GetLocalSinIP;
if Sip = '0.0.0.0' then
Sip := LocalName;
SPort := IntToStr(GetLocalSinPort);
Connect(FSocksIP, FSocksPort);
b := SocksOpen;
if b then
b := SocksRequest(2, Sip, SPort);
if b then
b := SocksResponse;
if not b and (FLastError = 0) then
FLastError := WSANO_RECOVERY;
FSocksLocalIP := FSocksResponseIP;
if FSocksLocalIP = '0.0.0.0' then
FSocksLocalIP := FSocksIP;
FSocksLocalPort := FSocksResponsePort;
FSocksRemoteIP := '';
FSocksRemotePort := '';
end;
ExceptCheck;
DoStatus(HR_Listen, '');
end;
function TTCPBlockSocket.Accept: TSocket;
var
Len: Integer;
begin
if FUsingSocks then
begin
if not SocksResponse and (FLastError = 0) then
FLastError := WSANO_RECOVERY;
FSocksRemoteIP := FSocksResponseIP;
FSocksRemotePort := FSocksResponsePort;
Result := FSocket;
end
else
begin
Len := SizeOf(FRemoteSin);
Result := synsock.Accept(FSocket, @FRemoteSin, @Len);
SockCheck(Result);
end;
ExceptCheck;
DoStatus(HR_Accept, '');
end;
procedure TTCPBlockSocket.Connect(IP, Port: string);
var
b: Boolean;
begin
if FSocksIP = '' then
inherited Connect(IP, Port)
else
begin
inherited Connect(FSocksIP, FSocksPort);
b := SocksOpen;
if b then
b := SocksRequest(1, IP, Port);
if b then
b := SocksResponse;
if not b and (FLastError = 0) then
FLastError := WSANO_RECOVERY;
FSocksLocalIP := FSocksResponseIP;
FSocksLocalPort := FSocksResponsePort;
FSocksRemoteIP := IP;
FSocksRemotePort := Port;
ExceptCheck;
DoStatus(HR_Connect, IP + ':' + Port);
end;
end;
function TTCPBlockSocket.GetLocalSinIP: string;
begin
if FUsingSocks then
Result := FSocksLocalIP
else
Result := inherited GetLocalSinIP;
end;
function TTCPBlockSocket.GetRemoteSinIP: string;
begin
if FUsingSocks then
Result := FSocksRemoteIP
else
Result := inherited GetRemoteSinIP;
end;
function TTCPBlockSocket.GetLocalSinPort: Integer;
begin
if FUsingSocks then
Result := StrToIntDef(FSocksLocalPort, 0)
else
Result := inherited GetLocalSinPort;
end;
function TTCPBlockSocket.GetRemoteSinPort: Integer;
begin
if FUsingSocks then
Result := StrToIntDef(FSocksRemotePort, 0)
else
Result := inherited GetRemoteSinPort;
end;
{======================================================================}
//See 'winsock2.txt' file in distribute package!
procedure TICMPBlockSocket.CreateSocket;
begin
FSocket := synsock.Socket(PF_INET, Integer(SOCK_RAW), IPPROTO_ICMP);
FProtocol := IPPROTO_ICMP;
inherited CreateSocket;
end;
{======================================================================}
//See 'winsock2.txt' file in distribute package!
procedure TRAWBlockSocket.CreateSocket;
begin
FSocket := synsock.Socket(PF_INET, Integer(SOCK_RAW), IPPROTO_RAW);
FProtocol := IPPROTO_RAW;
inherited CreateSocket;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -