📄 blcksock.pas
字号:
{:Return value of protocol type for socket creation.}
function GetSocketProtocol: integer; Virtual;
{:WSA structure with information about socket provider. On linux is this
structure simulated!}
property WSAData: TWSADATA read GetWsaData;
{:Structure describing local socket side.}
property LocalSin: TVarSin read FLocalSin write FLocalSin;
{:Structure describing remote socket side.}
property RemoteSin: TVarSin read FRemoteSin write FRemoteSin;
{:Socket handler. Suitable for "manual" calls to socket API or manual
connection of socket to a previously created socket (i.e by Accept method
on TCP socket)}
property Socket: TSocket read FSocket write SetSocket;
{:Last socket operation error code. Error codes are described in socket
documentation. Human readable error description is stored in
@link(LastErrorDesc) property.}
property LastError: Integer read FLastError;
{:Human readable error description of @link(LastError) code.}
property LastErrorDesc: string read FLastErrorDesc;
{:Buffer used by all high-level receiving functions. This buffer is used for
optimized reading of data from socket. In normal cases you not need access
to this buffer directly!}
property LineBuffer: string read FBuffer write FBuffer;
{:Size of Winsock receive buffer. If it is not supported by socket provider,
it return as size one kilobyte.}
property SizeRecvBuffer: Integer read GetSizeRecvBuffer write SetSizeRecvBuffer;
{:Size of Winsock send buffer. If it is not supported by socket provider, it
return as size one kilobyte.}
property SizeSendBuffer: Integer read GetSizeSendBuffer write SetSizeSendBuffer;
{:If @True, turn class to non-blocking mode. Not all functions are working
properly in this mode, you must know exactly what you are doing! However
when you have big experience with non-blocking programming, then you can
optimise your program by non-block mode!}
property NonBlockMode: Boolean read FNonBlockMode Write SetNonBlockMode;
{:Set Time-to-live value. (if system supporting it!)}
property TTL: Integer read GetTTL Write SetTTL;
{:If is @true, then class in in IPv6 mode.}
property IP6used: Boolean read FIP6used;
{:Return count of received bytes on this socket from begin of current
connection.}
property RecvCounter: Integer read FRecvCounter;
{:Return count of sended bytes on this socket from begin of current
connection.}
property SendCounter: Integer read FSendCounter;
published
{:Return descriptive string for given error code. This is class function.
You may call it without created object!}
class function GetErrorDesc(ErrorCode: Integer): string;
{:this value is for free use.}
property Tag: Integer read FTag write FTag;
{:If @true, winsock errors raises exception. Otherwise is setted
@link(LastError) value only and you must check it from your program! Default
value is @false.}
property RaiseExcept: Boolean read FRaiseExcept write FRaiseExcept;
{:Define maximum length in bytes of @link(LineBuffer) for high-level
receiving functions. If this functions try to read more data then this
limit, error is returned! If value is 0 (default), no limitation is used.
This is very good protection for stupid attacks to your server by sending
lot of data without proper terminator... until all your memory is allocated
by LineBuffer!
Note: This maximum length is checked only in functions, what read unknown
number of bytes! (like @link(RecvString) or @link(RecvTerminated))}
property MaxLineLength: Integer read FMaxLineLength Write FMaxLineLength;
{:Define maximal bandwidth for all sending operations in bytes per second.
If value is 0 (default), bandwidth limitation is not used.}
property MaxSendBandwidth: Integer read FMaxSendBandwidth Write FMaxSendBandwidth;
{:Define maximal bandwidth for all receiving operations in bytes per second.
If value is 0 (default), bandwidth limitation is not used.}
property MaxRecvBandwidth: Integer read FMaxRecvBandwidth Write FMaxRecvBandwidth;
{:Define maximal bandwidth for all sending and receiving operations in bytes
per second. If value is 0 (default), bandwidth limitation is not used.}
property MaxBandwidth: Integer Write SetBandwidth;
{:Do a conversion of non-standard line terminators to CRLF. (Off by default)
If @True, then terminators like sigle CR, single LF or LFCR are converted
to CRLF internally. This have effect only in @link(RecvString) method!}
property ConvertLineEnd: Boolean read FConvertLineEnd Write FConvertLineEnd;
{:Specified Family of this socket. When you are using Windows preliminary
support for IPv6, then I recommend to set this property!}
property Family: TSocketFamily read FFamily Write SetFamily;
{:When resolving of domain name return both IPv4 and IPv6 addresses, then
specify if is used IPv4 (dafault - @true) or IPv6.}
property PreferIP4: Boolean read FPreferIP4 Write FPreferIP4;
{:By dafault (@false) is all timeouts used as timeout between two packets in
reading operations. If you set this to @true, then Timeouts is for overall
reading operation!}
property InterPacketTimeout: Boolean read FInterPacketTimeout Write FInterPacketTimeout;
{:All sended datas was splitted by this value.}
property SendMaxChunk: Integer read FSendMaxChunk Write FSendMaxChunk;
{:By setting this property to @true you can stop any communication. You can
use this property for soft abort of communication.}
property StopFlag: Boolean read FStopFlag Write FStopFlag;
{:This event is called by various reasons. It is good for monitoring socket,
create gauges for data transfers, etc.}
property OnStatus: THookSocketStatus read FOnStatus write FOnStatus;
{:this event is good for some internal thinks about filtering readed datas.
It is used by telnet client by example.}
property OnReadFilter: THookDataFilter read FOnReadFilter write FOnReadFilter;
{:This event is good for some internal thinks about filtering writed datas.}
property OnWriteFilter: THookDataFilter read FOnWriteFilter write FOnWriteFilter;
{:This event is called after real socket creation for setting special socket
options, because you not know when socket is created. (it is depended on
Ipv4, IPv6 or automatic mode)}
property OnCreateSocket: THookCreateSocket read FOnCreateSocket write FOnCreateSocket;
end;
{:@abstract(Support for SOCKS4 and SOCKS5 proxy)
Layer with definition all necessary properties and functions for
implementation SOCKS proxy client. Do not use this class directly.}
TSocksBlockSocket = class(TBlockSocket)
protected
FSocksIP: string;
FSocksPort: string;
FSocksTimeout: integer;
FSocksUsername: string;
FSocksPassword: string;
FUsingSocks: Boolean;
FSocksResolver: Boolean;
FSocksLastError: integer;
FSocksResponseIP: string;
FSocksResponsePort: string;
FSocksLocalIP: string;
FSocksLocalPort: string;
FSocksRemoteIP: string;
FSocksRemotePort: string;
FBypassFlag: Boolean;
FSocksType: TSocksType;
function SocksCode(IP, Port: string): string;
function SocksDecode(Value: string): integer;
public
constructor Create;
{:Open connection to SOCKS proxy and if @link(SocksUsername) is set, do
authorisation to proxy. This is needed only in special cases! (it is called
internally!)}
function SocksOpen: Boolean;
{:Send specified request to SOCKS proxy. This is needed only in special
cases! (it is called internally!)}
function SocksRequest(Cmd: Byte; const IP, Port: string): Boolean;
{:Receive response to previosly sended request. This is needed only in
special cases! (it is called internally!)}
function SocksResponse: Boolean;
{:Is @True when class is using SOCKS proxy.}
property UsingSocks: Boolean read FUsingSocks;
{:If SOCKS proxy failed, here is error code returned from SOCKS proxy.}
property SocksLastError: integer read FSocksLastError;
published
{:Address of SOCKS server. If value is empty string, SOCKS support is
disabled. Assingning any value to this property enable SOCKS mode.
Warning: You cannot combine this mode with HTTP-tunneling mode!}
property SocksIP: string read FSocksIP write FSocksIP;
{:Port of SOCKS server. Default value is '1080'.}
property SocksPort: string read FSocksPort write FSocksPort;
{:If you need authorisation on SOCKS server, set username here.}
property SocksUsername: string read FSocksUsername write FSocksUsername;
{:If you need authorisation on SOCKS server, set password here.}
property SocksPassword: string read FSocksPassword write FSocksPassword;
{:Specify timeout for communicatin with SOCKS server. Default is one minute.}
property SocksTimeout: integer read FSocksTimeout write FSocksTimeout;
{:If @True, all symbolic names of target hosts is not translated to IP's
locally, but resolving is by SOCKS proxy. Default is @True.}
property SocksResolver: Boolean read FSocksResolver write FSocksResolver;
{:Specify SOCKS type. By default is used SOCKS5, but you can use SOCKS4 too.
When you select SOCKS4, then if @link(SOCKSResolver) is enabled, then is
used SOCKS4a. Othervise is used pure SOCKS4.}
property SocksType: TSocksType read FSocksType write FSocksType;
end;
{:@abstract(Implementation of TCP socket.)
Supported features: IPv4, IPv6, SSL/TLS (SSL2, SSL3 and TLS), SOCKS5 proxy
(outgoing connections and limited incomming), SOCKS4/4a proxy (outgoing
connections and limited incomming), TCP through HTTP proxy tunnel.}
TTCPBlockSocket = class(TSocksBlockSocket)
protected
FSslEnabled: Boolean;
FSslBypass: Boolean;
FSsl: PSSL;
Fctx: PSSL_CTX;
FSSLPassword: string;
FSSLCiphers: string;
FSSLCertificateFile: string;
FSSLPrivateKeyFile: string;
FSSLCertCAFile: string;
FSSLLastError: integer;
FSSLLastErrorDesc: string;
FSSLverifyCert: Boolean;
FSSLType: TSSLType;
FHTTPTunnelIP: string;
FHTTPTunnelPort: string;
FHTTPTunnel: Boolean;
FHTTPTunnelRemoteIP: string;
FHTTPTunnelRemotePort: string;
FHTTPTunnelUser: string;
FHTTPTunnelPass: string;
FHTTPTunnelTimeout: integer;
procedure SetSslEnabled(Value: Boolean);
function SetSslKeys: boolean;
function GetSSLLoaded: Boolean;
procedure SocksDoConnect(IP, Port: string);
procedure HTTPTunnelDoConnect(IP, Port: string);
public
constructor Create;
{:See @link(TBlockSocket.CloseSocket)}
procedure CloseSocket; override;
{:See @link(TBlockSocket.WaitingData)}
function WaitingData: Integer; override;
{:Sets socket to receive mode for new incoming connections. It is necessary
to use @link(TBlockSocket.BIND) function call before this method to select
receiving port!
If you use SOCKS, activate incoming TCP connection by this proxy. (By BIND
method of SOCKS.)}
procedure Listen; virtual;
{:Waits until new incoming connection comes. After it comes a new socket is
automatically created (socket handler is returned by this function as
result).
If you use SOCKS, new socket is not created! In this case is used same
socket as socket for listening! So, you can accept only one connection in
SOCKS mode.}
function Accept: TSocket;
{:Connects socket to remote IP address and PORT. The same rules as with
@link(TBlockSocket.BIND) method are valid. The only exception is that PORT
with 0 value will not be connected. After call to this method
a communication channel between local and remote socket is created. Local
socket is assigned automatically if not controlled by previous call to
@link(TBlockSocket.BIND) method. Structures @link(TBlockSocket.LocalSin)
and @link(TBlockSocket.RemoteSin) will be filled with valid values.
If you use SOCKS, activate outgoing TCP connection by SOCKS proxy specified
in @link(TSocksBlockSocket.SocksIP). (By CONNECT method of SOCKS.)
If you use HTTP-tunnel mode, activate outgoing TCP connection by HTTP
tunnel specified in @link(HTTPTunnelIP). (By CONNECT method of HTTP
protocol.)
If you additionally use SSL mode, then SSL/TLS session was started.
Note: If you call this on non-created socket, then socket is created
automaticly.}
procedure Connect(IP, Port: string); override;
{:If you need upgrade existing TCP connection to SSL/TLS mode, then call
this method. This method switch this class to SSL mode and do SSL/TSL
handshake.}
procedure SSLDoConnect;
{:By this method you can downgrade existing SSL/TLS connection to normal TCP
connection.}
procedure SSLDoShutdown;
{:If you need use this component as SSL/TLS TCP server, then after accepting
of inbound connection you need start SSL/TLS session by this method. Before
call this function, you must have assigned all neeeded certificates and
keys!}
function SSLAcceptConnection: Boolean;
{:See @link(TBlockSocket.GetLocalSinIP)}
function GetLocalSinIP: string; override;
{:See @link(TBlockSocket.GetRemoteSinIP)}
function GetRemoteSinIP: string; override;
{:See @link(TBlockSocket.GetLocalSinPort)}
function GetLocalSinPort: Integer; override;
{:See @link(TBlockSocket.GetRemoteSinPort)}
function GetRemoteSinPort: Integer; override;
{:See @link(TBlockSocket.SendBuffer)}
function SendBuffer(Buffer: TMemory; Length: Integer): Integer; override;
{:See @link(TBlockSocket.RecvBuffer)}
function RecvBuffer(Buffer: TMemory; Len: Integer): Integer; override;
{:Return string with identificator of SSL/TLS version of existing
connection.}
function SSLGetSSLVersion: string;
{:Return subject of remote SSL peer.}
function SSLGetPeerSubject: string;
{:Return issuer certificate of remote SSL peer.}
function SSLGetPeerIssuer: string;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -