PageRenderTime 10ms CodeModel.GetById 5ms app.highlight 121ms RepoModel.GetById 28ms app.codeStats 1ms

/DebugHelper.exe_src/synapse/blcksock.pas

https://bitbucket.org/valicek1/little-debug-helper
Pascal | 4352 lines | 2990 code | 440 blank | 922 comment | 245 complexity | 8a8b49582c82ba22459dd7c3711feb1e MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1{==============================================================================|
   2| Project : Ararat Synapse                                       | 009.009.000 |
   3|==============================================================================|
   4| Content: Library base                                                        |
   5|==============================================================================|
   6| Copyright (c)1999-2012, Lukas Gebauer                                        |
   7| All rights reserved.                                                         |
   8|                                                                              |
   9| Redistribution and use in source and binary forms, with or without           |
  10| modification, are permitted provided that the following conditions are met:  |
  11|                                                                              |
  12| Redistributions of source code must retain the above copyright notice, this  |
  13| list of conditions and the following disclaimer.                             |
  14|                                                                              |
  15| Redistributions in binary form must reproduce the above copyright notice,    |
  16| this list of conditions and the following disclaimer in the documentation    |
  17| and/or other materials provided with the distribution.                       |
  18|                                                                              |
  19| Neither the name of Lukas Gebauer nor the names of its contributors may      |
  20| be used to endorse or promote products derived from this software without    |
  21| specific prior written permission.                                           |
  22|                                                                              |
  23| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  |
  24| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE    |
  25| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE   |
  26| ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR  |
  27| ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL       |
  28| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   |
  29| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER   |
  30| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT           |
  31| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY    |
  32| OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  |
  33| DAMAGE.                                                                      |
  34|==============================================================================|
  35| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  36| Portions created by Lukas Gebauer are Copyright (c)1999-2012.                |
  37| All Rights Reserved.                                                         |
  38|==============================================================================|
  39| Contributor(s):                                                              |
  40|==============================================================================|
  41| History: see HISTORY.HTM from distribution package                           |
  42|          (Found at URL: http://www.ararat.cz/synapse/)                       |
  43|==============================================================================}
  44
  45{
  46Special thanks to Gregor Ibic <gregor.ibic@intelicom.si>
  47 (Intelicom d.o.o., http://www.intelicom.si)
  48 for good inspiration about SSL programming.
  49}
  50
  51{$DEFINE ONCEWINSOCK}
  52{Note about define ONCEWINSOCK:
  53If you remove this compiler directive, then socket interface is loaded and
  54initialized on constructor of TBlockSocket class for each socket separately.
  55Socket interface is used only if your need it.
  56
  57If you leave this directive here, then socket interface is loaded and
  58initialized only once at start of your program! It boost performace on high
  59count of created and destroyed sockets. It eliminate possible small resource
  60leak on Windows systems too.
  61}
  62
  63//{$DEFINE RAISEEXCEPT}
  64{When you enable this define, then is Raiseexcept property is on by default
  65}
  66
  67{:@abstract(Synapse's library core)
  68
  69Core with implementation basic socket classes.
  70}
  71
  72{$IFDEF FPC}
  73  {$MODE DELPHI}
  74{$ENDIF}
  75{$IFDEF VER125}
  76  {$DEFINE BCB}
  77{$ENDIF}
  78{$IFDEF BCB}
  79  {$ObjExportAll On}
  80{$ENDIF}
  81{$Q-}
  82{$H+}
  83{$M+}
  84{$TYPEDADDRESS OFF}
  85
  86
  87//old Delphi does not have MSWINDOWS define.
  88{$IFDEF WIN32}
  89  {$IFNDEF MSWINDOWS}
  90    {$DEFINE MSWINDOWS}
  91  {$ENDIF}
  92{$ENDIF}
  93
  94{$IFDEF UNICODE}
  95  {$WARN IMPLICIT_STRING_CAST OFF}
  96  {$WARN IMPLICIT_STRING_CAST_LOSS OFF}
  97{$ENDIF}
  98
  99unit blcksock;
 100
 101interface
 102
 103uses
 104  SysUtils, Classes,
 105  synafpc,
 106  synsock, synautil, synacode, synaip
 107{$IFDEF CIL}
 108  ,System.Net
 109  ,System.Net.Sockets
 110  ,System.Text
 111{$ENDIF}
 112  ;
 113
 114const
 115
 116  SynapseRelease = '40';
 117
 118  cLocalhost = '127.0.0.1';
 119  cAnyHost = '0.0.0.0';
 120  cBroadcast = '255.255.255.255';
 121  c6Localhost = '::1';
 122  c6AnyHost = '::0';
 123  c6Broadcast = 'ffff::1';
 124  cAnyPort = '0';
 125  CR = #$0d;
 126  LF = #$0a;
 127  CRLF = CR + LF;
 128  c64k = 65536;
 129
 130type
 131
 132  {:@abstract(Exception clas used by Synapse)
 133   When you enable generating of exceptions, this exception is raised by
 134   Synapse's units.}
 135  ESynapseError = class(Exception)
 136  private
 137    FErrorCode: Integer;
 138    FErrorMessage: string;
 139  published
 140    {:Code of error. Value depending on used operating system}
 141    property ErrorCode: Integer read FErrorCode Write FErrorCode;
 142    {:Human readable description of error.}
 143    property ErrorMessage: string read FErrorMessage Write FErrorMessage;
 144  end;
 145
 146  {:Types of OnStatus events}
 147  THookSocketReason = (
 148    {:Resolving is begin. Resolved IP and port is in parameter in format like:
 149     'localhost.somewhere.com:25'.}
 150    HR_ResolvingBegin,
 151    {:Resolving is done. Resolved IP and port is in parameter in format like:
 152     'localhost.somewhere.com:25'. It is always same as in HR_ResolvingBegin!}
 153    HR_ResolvingEnd,
 154    {:Socket created by CreateSocket method. It reporting Family of created
 155     socket too!}
 156    HR_SocketCreate,
 157    {:Socket closed by CloseSocket method.}
 158    HR_SocketClose,
 159    {:Socket binded to IP and Port. Binded IP and Port is in parameter in format
 160     like: 'localhost.somewhere.com:25'.}
 161    HR_Bind,
 162    {:Socket connected to IP and Port. Connected IP and Port is in parameter in
 163     format like: 'localhost.somewhere.com:25'.}
 164    HR_Connect,
 165    {:Called when CanRead method is used with @True result.}
 166    HR_CanRead,
 167    {:Called when CanWrite method is used with @True result.}
 168    HR_CanWrite,
 169    {:Socket is swithed to Listen mode. (TCP socket only)}
 170    HR_Listen,
 171    {:Socket Accepting client connection. (TCP socket only)}
 172    HR_Accept,
 173    {:report count of bytes readed from socket. Number is in parameter string.
 174     If you need is in integer, you must use StrToInt function!}
 175    HR_ReadCount,
 176    {:report count of bytes writed to socket. Number is in parameter string. If
 177     you need is in integer, you must use StrToInt function!}
 178    HR_WriteCount,
 179    {:If is limiting of bandwidth on, then this reason is called when sending or
 180     receiving is stopped for satisfy bandwidth limit. Parameter is count of
 181     waiting milliseconds.}
 182    HR_Wait,
 183    {:report situation where communication error occured. When raiseexcept is
 184     @true, then exception is called after this Hook reason.}
 185    HR_Error
 186    );
 187
 188  {:Procedural type for OnStatus event. Sender is calling TBlockSocket object,
 189   Reason is one of set Status events and value is optional data.}
 190  THookSocketStatus = procedure(Sender: TObject; Reason: THookSocketReason;
 191    const Value: String) of object;
 192
 193  {:This procedural type is used for DataFilter hooks.}
 194  THookDataFilter = procedure(Sender: TObject; var Value: AnsiString) of object;
 195
 196  {:This procedural type is used for hook OnCreateSocket. By this hook you can
 197   insert your code after initialisation of socket. (you can set special socket
 198   options, etc.)}
 199  THookCreateSocket = procedure(Sender: TObject) of object;
 200
 201  {:This procedural type is used for monitoring of communication.}
 202  THookMonitor = procedure(Sender: TObject; Writing: Boolean;
 203    const Buffer: TMemory; Len: Integer) of object;
 204
 205  {:This procedural type is used for hook OnAfterConnect. By this hook you can
 206   insert your code after TCP socket has been sucessfully connected.}
 207  THookAfterConnect = procedure(Sender: TObject) of object;
 208
 209  {:This procedural type is used for hook OnVerifyCert. By this hook you can
 210   insert your additional certificate verification code. Usefull to verify server
 211   CN against URL. }
 212
 213  THookVerifyCert = function(Sender: TObject):boolean of object;
 214
 215 {:This procedural type is used for hook OnHeartbeat. By this hook you can
 216   call your code repeately during long socket operations.
 217   You must enable heartbeats by @Link(HeartbeatRate) property!}
 218  THookHeartbeat = procedure(Sender: TObject) of object;
 219
 220  {:Specify family of socket.}
 221  TSocketFamily = (
 222    {:Default mode. Socket family is defined by target address for connection.
 223     It allows instant access to IPv4 and IPv6 nodes. When you need IPv6 address
 224     as destination, then is used IPv6 mode. othervise is used IPv4 mode.
 225     However this mode not working properly with preliminary IPv6 supports!}
 226    SF_Any,
 227    {:Turn this class to pure IPv4 mode. This mode is totally compatible with
 228     previous Synapse releases.}
 229    SF_IP4,
 230    {:Turn to only IPv6 mode.}
 231    SF_IP6
 232    );
 233
 234  {:specify possible values of SOCKS modes.}
 235  TSocksType = (
 236    ST_Socks5,
 237    ST_Socks4
 238    );
 239
 240  {:Specify requested SSL/TLS version for secure connection.}
 241  TSSLType = (
 242    LT_all,
 243    LT_SSLv2,
 244    LT_SSLv3,
 245    LT_TLSv1,
 246    LT_TLSv1_1,
 247    LT_SSHv2
 248    );
 249
 250  {:Specify type of socket delayed option.}
 251  TSynaOptionType = (
 252    SOT_Linger,
 253    SOT_RecvBuff,
 254    SOT_SendBuff,
 255    SOT_NonBlock,
 256    SOT_RecvTimeout,
 257    SOT_SendTimeout,
 258    SOT_Reuse,
 259    SOT_TTL,
 260    SOT_Broadcast,
 261    SOT_MulticastTTL,
 262    SOT_MulticastLoop
 263    );
 264
 265  {:@abstract(this object is used for remember delayed socket option set.)}
 266  TSynaOption = class(TObject)
 267  public
 268    Option: TSynaOptionType;
 269    Enabled: Boolean;
 270    Value: Integer;
 271  end;
 272
 273  TCustomSSL = class;
 274  TSSLClass = class of TCustomSSL;
 275
 276  {:@abstract(Basic IP object.)
 277   This is parent class for other class with protocol implementations. Do not
 278   use this class directly! Use @link(TICMPBlockSocket), @link(TRAWBlockSocket),
 279   @link(TTCPBlockSocket) or @link(TUDPBlockSocket) instead.}
 280  TBlockSocket = class(TObject)
 281  private
 282    FOnStatus: THookSocketStatus;
 283    FOnReadFilter: THookDataFilter;
 284    FOnCreateSocket: THookCreateSocket;
 285    FOnMonitor: THookMonitor;
 286    FOnHeartbeat: THookHeartbeat;
 287    FLocalSin: TVarSin;
 288    FRemoteSin: TVarSin;
 289    FTag: integer;
 290    FBuffer: AnsiString;
 291    FRaiseExcept: Boolean;
 292    FNonBlockMode: Boolean;
 293    FMaxLineLength: Integer;
 294    FMaxSendBandwidth: Integer;
 295    FNextSend: LongWord;
 296    FMaxRecvBandwidth: Integer;
 297    FNextRecv: LongWord;
 298    FConvertLineEnd: Boolean;
 299    FLastCR: Boolean;
 300    FLastLF: Boolean;
 301    FBinded: Boolean;
 302    FFamily: TSocketFamily;
 303    FFamilySave: TSocketFamily;
 304    FIP6used: Boolean;
 305    FPreferIP4: Boolean;
 306    FDelayedOptions: TList;
 307    FInterPacketTimeout: Boolean;
 308    {$IFNDEF CIL}
 309    FFDSet: TFDSet;
 310    {$ENDIF}
 311    FRecvCounter: Integer;
 312    FSendCounter: Integer;
 313    FSendMaxChunk: Integer;
 314    FStopFlag: Boolean;
 315    FNonblockSendTimeout: Integer;
 316    FHeartbeatRate: integer;
 317    FConnectionTimeout: integer;
 318    {$IFNDEF ONCEWINSOCK}
 319    FWsaDataOnce: TWSADATA;
 320    {$ENDIF}
 321    function GetSizeRecvBuffer: Integer;
 322    procedure SetSizeRecvBuffer(Size: Integer);
 323    function GetSizeSendBuffer: Integer;
 324    procedure SetSizeSendBuffer(Size: Integer);
 325    procedure SetNonBlockMode(Value: Boolean);
 326    procedure SetTTL(TTL: integer);
 327    function GetTTL:integer;
 328    procedure SetFamily(Value: TSocketFamily); virtual;
 329    procedure SetSocket(Value: TSocket); virtual;
 330    function GetWsaData: TWSAData;
 331    function FamilyToAF(f: TSocketFamily): TAddrFamily;
 332  protected
 333    FSocket: TSocket;
 334    FLastError: Integer;
 335    FLastErrorDesc: string;
 336    FOwner: TObject;
 337    procedure SetDelayedOption(const Value: TSynaOption);
 338    procedure DelayedOption(const Value: TSynaOption);
 339    procedure ProcessDelayedOptions;
 340    procedure InternalCreateSocket(Sin: TVarSin);
 341    procedure SetSin(var Sin: TVarSin; IP, Port: string);
 342    function GetSinIP(Sin: TVarSin): string;
 343    function GetSinPort(Sin: TVarSin): Integer;
 344    procedure DoStatus(Reason: THookSocketReason; const Value: string);
 345    procedure DoReadFilter(Buffer: TMemory; var Len: Integer);
 346    procedure DoMonitor(Writing: Boolean; const Buffer: TMemory; Len: Integer);
 347    procedure DoCreateSocket;
 348    procedure DoHeartbeat;
 349    procedure LimitBandwidth(Length: Integer; MaxB: integer; var Next: LongWord);
 350    procedure SetBandwidth(Value: Integer);
 351    function TestStopFlag: Boolean;
 352    procedure InternalSendStream(const Stream: TStream; WithSize, Indy: boolean); virtual;
 353    function InternalCanRead(Timeout: Integer): Boolean; virtual;
 354  public
 355    constructor Create;
 356
 357    {:Create object and load all necessary socket library. What library is
 358     loaded is described by STUB parameter. If STUB is empty string, then is
 359     loaded default libraries.}
 360    constructor CreateAlternate(Stub: string);
 361    destructor Destroy; override;
 362
 363    {:If @link(family) is not SF_Any, then create socket with type defined in
 364     @link(Family) property. If family is SF_Any, then do nothing! (socket is
 365     created automaticly when you know what type of socket you need to create.
 366     (i.e. inside @link(Connect) or @link(Bind) call.) When socket is created,
 367     then is aplyed all stored delayed socket options.}
 368    procedure CreateSocket;
 369
 370    {:It create socket. Address resolving of Value tells what type of socket is
 371     created. If Value is resolved as IPv4 IP, then is created IPv4 socket. If
 372     value is resolved as IPv6 address, then is created IPv6 socket.}
 373    procedure CreateSocketByName(const Value: String);
 374
 375    {:Destroy socket in use. This method is also automatically called from
 376     object destructor.}
 377    procedure CloseSocket; virtual;
 378
 379    {:Abort any work on Socket and destroy them.}
 380    procedure AbortSocket; virtual;
 381
 382    {:Connects socket to local IP address and PORT. IP address may be numeric or
 383     symbolic ('192.168.74.50', 'cosi.nekde.cz', 'ff08::1'). The same for PORT
 384     - it may be number or mnemonic port ('23', 'telnet').
 385
 386     If port value is '0', system chooses itself and conects unused port in the
 387     range 1024 to 4096 (this depending by operating system!). Structure
 388     LocalSin is filled after calling this method.
 389
 390     Note: If you call this on non-created socket, then socket is created
 391     automaticly.
 392
 393     Warning: when you call : Bind('0.0.0.0','0'); then is nothing done! In this
 394     case is used implicit system bind instead.}
 395    procedure Bind(IP, Port: string);
 396
 397    {:Connects socket to remote IP address and PORT. The same rules as with
 398     @link(BIND) method are valid. The only exception is that PORT with 0 value
 399     will not be connected!
 400
 401     Structures LocalSin and RemoteSin will be filled with valid values.
 402
 403     When you call this on non-created socket, then socket is created
 404     automaticly. Type of created socket is by @link(Family) property. If is
 405     used SF_IP4, then is created socket for IPv4. If is used SF_IP6, then is
 406     created socket for IPv6. When you have family on SF_Any (default!), then
 407     type of created socket is determined by address resolving of destination
 408     address. (Not work properly on prilimitary winsock IPv6 support!)}
 409    procedure Connect(IP, Port: string); virtual;
 410
 411    {:Sets socket to receive mode for new incoming connections. It is necessary
 412     to use @link(TBlockSocket.BIND) function call before this method to select
 413     receiving port!}
 414    procedure Listen; virtual;
 415
 416    {:Waits until new incoming connection comes. After it comes a new socket is
 417     automatically created (socket handler is returned by this function as
 418     result).}
 419    function Accept: TSocket; virtual;
 420
 421    {:Sends data of LENGTH from BUFFER address via connected socket. System
 422     automatically splits data to packets.}
 423    function SendBuffer(Buffer: Tmemory; Length: Integer): Integer; virtual;
 424
 425    {:One data BYTE is sent via connected socket.}
 426    procedure SendByte(Data: Byte); virtual;
 427
 428    {:Send data string via connected socket. Any terminator is not added! If you
 429     need send true string with CR-LF termination, you must add CR-LF characters
 430     to sended string! Because any termination is not added automaticly, you can
 431     use this function for sending any binary data in binary string.}
 432    procedure SendString(Data: AnsiString); virtual;
 433
 434    {:Send integer as four bytes to socket.}
 435    procedure SendInteger(Data: integer); virtual;
 436
 437    {:Send data as one block to socket. Each block begin with 4 bytes with
 438     length of data in block. This 4 bytes is added automaticly by this
 439     function.}
 440    procedure SendBlock(const Data: AnsiString); virtual;
 441
 442    {:Send data from stream to socket.}
 443    procedure SendStreamRaw(const Stream: TStream); virtual;
 444
 445    {:Send content of stream to socket. It using @link(SendBlock) method}
 446    procedure SendStream(const Stream: TStream); virtual;
 447
 448    {:Send content of stream to socket. It using @link(SendBlock) method and
 449    this is compatible with streams in Indy library.}
 450    procedure SendStreamIndy(const Stream: TStream); virtual;
 451
 452    {:Note: This is low-level receive function. You must be sure if data is
 453     waiting for read before call this function for avoid deadlock!
 454
 455     Waits until allocated buffer is filled by received data. Returns number of
 456     data received, which equals to LENGTH value under normal operation. If it
 457     is not equal the communication channel is possibly broken.
 458
 459     On stream oriented sockets if is received 0 bytes, it mean 'socket is
 460     closed!"
 461
 462     On datagram socket is readed first waiting datagram.}
 463    function RecvBuffer(Buffer: TMemory; Length: Integer): Integer; virtual;
 464
 465    {:Note: This is high-level receive function. It using internal
 466     @link(LineBuffer) and you can combine this function freely with other
 467     high-level functions!
 468
 469     Method waits until data is received. If no data is received within TIMEOUT
 470     (in milliseconds) period, @link(LastError) is set to WSAETIMEDOUT. Methods
 471     serves for reading any size of data (i.e. one megabyte...). This method is
 472     preffered for reading from stream sockets (like TCP).}
 473    function RecvBufferEx(Buffer: Tmemory; Len: Integer;
 474      Timeout: Integer): Integer; virtual;
 475
 476    {:Similar to @link(RecvBufferEx), but readed data is stored in binary
 477     string, not in memory buffer.}
 478    function RecvBufferStr(Len: Integer; Timeout: Integer): AnsiString; virtual;
 479
 480    {:Note: This is high-level receive function. It using internal
 481     @link(LineBuffer) and you can combine this function freely with other
 482     high-level functions.
 483
 484     Waits until one data byte is received which is also returned as function
 485     result. If no data is received within TIMEOUT (in milliseconds)period,
 486     @link(LastError) is set to WSAETIMEDOUT and result have value 0.}
 487    function RecvByte(Timeout: Integer): Byte; virtual;
 488
 489    {:Note: This is high-level receive function. It using internal
 490     @link(LineBuffer) and you can combine this function freely with other
 491     high-level functions.
 492
 493     Waits until one four bytes are received and return it as one Ineger Value.
 494     If no data is received within TIMEOUT (in milliseconds)period,
 495     @link(LastError) is set to WSAETIMEDOUT and result have value 0.}
 496    function RecvInteger(Timeout: Integer): Integer; virtual;
 497
 498    {:Note: This is high-level receive function. It using internal
 499     @link(LineBuffer) and you can combine this function freely with other
 500     high-level functions.
 501
 502     Method waits until data string is received. This string is terminated by
 503     CR-LF characters. The resulting string is returned without this termination
 504     (CR-LF)! If @link(ConvertLineEnd) is used, then CR-LF sequence may not be
 505     exactly CR-LF. See @link(ConvertLineEnd) description. If no data is
 506     received within TIMEOUT (in milliseconds) period, @link(LastError) is set
 507     to WSAETIMEDOUT. You may also specify maximum length of reading data by
 508     @link(MaxLineLength) property.}
 509    function RecvString(Timeout: Integer): AnsiString; virtual;
 510
 511    {:Note: This is high-level receive function. It using internal
 512     @link(LineBuffer) and you can combine this function freely with other
 513     high-level functions.
 514
 515     Method waits until data string is received. This string is terminated by
 516     Terminator string. The resulting string is returned without this
 517     termination. If no data is received within TIMEOUT (in milliseconds)
 518     period, @link(LastError) is set to WSAETIMEDOUT. You may also specify
 519     maximum length of reading data by @link(MaxLineLength) property.}
 520    function RecvTerminated(Timeout: Integer; const Terminator: AnsiString): AnsiString; virtual;
 521
 522    {:Note: This is high-level receive function. It using internal
 523     @link(LineBuffer) and you can combine this function freely with other
 524     high-level functions.
 525
 526     Method reads all data waiting for read. If no data is received within
 527     TIMEOUT (in milliseconds) period, @link(LastError) is set to WSAETIMEDOUT.
 528     Methods serves for reading unknown size of data. Because before call this
 529     function you don't know size of received data, returned data is stored in
 530     dynamic size binary string. This method is preffered for reading from
 531     stream sockets (like TCP). It is very goot for receiving datagrams too!
 532     (UDP protocol)}
 533    function RecvPacket(Timeout: Integer): AnsiString; virtual;
 534
 535    {:Read one block of data from socket. Each block begin with 4 bytes with
 536     length of data in block. This function read first 4 bytes for get lenght,
 537     then it wait for reported count of bytes.}
 538    function RecvBlock(Timeout: Integer): AnsiString; virtual;
 539
 540    {:Read all data from socket to stream until socket is closed (or any error
 541     occured.)}
 542    procedure RecvStreamRaw(const Stream: TStream; Timeout: Integer); virtual;
 543    {:Read requested count of bytes from socket to stream.}
 544    procedure RecvStreamSize(const Stream: TStream; Timeout: Integer; Size: Integer);
 545
 546    {:Receive data to stream. It using @link(RecvBlock) method.}
 547    procedure RecvStream(const Stream: TStream; Timeout: Integer); virtual;
 548
 549    {:Receive data to stream. This function is compatible with similar function
 550    in Indy library. It using @link(RecvBlock) method.}
 551    procedure RecvStreamIndy(const Stream: TStream; Timeout: Integer); virtual;
 552
 553    {:Same as @link(RecvBuffer), but readed data stays in system input buffer.
 554    Warning: this function not respect data in @link(LineBuffer)! Is not
 555    recommended to use this function!}
 556    function PeekBuffer(Buffer: TMemory; Length: Integer): Integer; virtual;
 557
 558    {:Same as @link(RecvByte), but readed data stays in input system buffer.
 559     Warning: this function not respect data in @link(LineBuffer)! Is not
 560    recommended to use this function!}
 561    function PeekByte(Timeout: Integer): Byte; virtual;
 562
 563    {:On stream sockets it returns number of received bytes waiting for picking.
 564     0 is returned when there is no such data. On datagram socket it returns
 565     length of the first waiting datagram. Returns 0 if no datagram is waiting.}
 566    function WaitingData: Integer; virtual;
 567
 568    {:Same as @link(WaitingData), but if exists some of data in @link(Linebuffer),
 569     return their length instead.}
 570    function WaitingDataEx: Integer;
 571
 572    {:Clear all waiting data for read from buffers.}
 573    procedure Purge;
 574
 575    {:Sets linger. Enabled linger means that the system waits another LINGER
 576     (in milliseconds) time for delivery of sent data. This function is only for
 577     stream type of socket! (TCP)}
 578    procedure SetLinger(Enable: Boolean; Linger: Integer);
 579
 580    {:Actualize values in @link(LocalSin).}
 581    procedure GetSinLocal;
 582
 583    {:Actualize values in @link(RemoteSin).}
 584    procedure GetSinRemote;
 585
 586    {:Actualize values in @link(LocalSin) and @link(RemoteSin).}
 587    procedure GetSins;
 588
 589    {:Reset @link(LastError) and @link(LastErrorDesc) to non-error state.}
 590    procedure ResetLastError;
 591
 592    {:If you "manually" call Socket API functions, forward their return code as
 593     parameter to this function, which evaluates it, eventually calls
 594     GetLastError and found error code returns and stores to @link(LastError).}
 595    function SockCheck(SockResult: Integer): Integer; virtual;
 596
 597    {:If @link(LastError) contains some error code and @link(RaiseExcept)
 598     property is @true, raise adequate exception.}
 599    procedure ExceptCheck;
 600
 601    {:Returns local computer name as numerical or symbolic value. It try get
 602     fully qualified domain name. Name is returned in the format acceptable by
 603     functions demanding IP as input parameter.}
 604    function LocalName: string;
 605
 606    {:Try resolve name to all possible IP address. i.e. If you pass as name
 607     result of @link(LocalName) method, you get all IP addresses used by local
 608     system.}
 609    procedure ResolveNameToIP(Name: string; const IPList: TStrings);
 610
 611    {:Try resolve name to primary IP address. i.e. If you pass as name result of
 612     @link(LocalName) method, you get primary IP addresses used by local system.}
 613    function ResolveName(Name: string): string;
 614
 615    {:Try resolve IP to their primary domain name. If IP not have domain name,
 616     then is returned original IP.}
 617    function ResolveIPToName(IP: string): string;
 618
 619    {:Try resolve symbolic port name to port number. (i.e. 'Echo' to 8)}
 620    function ResolvePort(Port: string): Word;
 621
 622    {:Set information about remote side socket. It is good for seting remote
 623     side for sending UDP packet, etc.}
 624    procedure SetRemoteSin(IP, Port: string);
 625
 626    {:Picks IP socket address from @link(LocalSin).}
 627    function GetLocalSinIP: string; virtual;
 628
 629    {:Picks IP socket address from @link(RemoteSin).}
 630    function GetRemoteSinIP: string; virtual;
 631
 632    {:Picks socket PORT number from @link(LocalSin).}
 633    function GetLocalSinPort: Integer; virtual;
 634
 635    {:Picks socket PORT number from @link(RemoteSin).}
 636    function GetRemoteSinPort: Integer; virtual;
 637
 638    {:Return @TRUE, if you can read any data from socket or is incoming
 639     connection on TCP based socket. Status is tested for time Timeout (in
 640     milliseconds). If value in Timeout is 0, status is only tested and
 641     continue. If value in Timeout is -1, run is breaked and waiting for read
 642     data maybe forever.
 643
 644     This function is need only on special cases, when you need use
 645     @link(RecvBuffer) function directly! read functioms what have timeout as
 646     calling parameter, calling this function internally.}
 647    function CanRead(Timeout: Integer): Boolean; virtual;
 648
 649    {:Same as @link(CanRead), but additionally return @TRUE if is some data in
 650     @link(LineBuffer).}
 651    function CanReadEx(Timeout: Integer): Boolean; virtual;
 652
 653    {:Return @TRUE, if you can to socket write any data (not full sending
 654     buffer). Status is tested for time Timeout (in milliseconds). If value in
 655     Timeout is 0, status is only tested and continue. If value in Timeout is
 656     -1, run is breaked and waiting for write data maybe forever.
 657
 658     This function is need only on special cases!}
 659    function CanWrite(Timeout: Integer): Boolean; virtual;
 660
 661    {:Same as @link(SendBuffer), but send datagram to address from
 662     @link(RemoteSin). Usefull for sending reply to datagram received by
 663     function @link(RecvBufferFrom).}
 664    function SendBufferTo(Buffer: TMemory; Length: Integer): Integer; virtual;
 665
 666    {:Note: This is low-lever receive function. You must be sure if data is
 667     waiting for read before call this function for avoid deadlock!
 668
 669     Receives first waiting datagram to allocated buffer. If there is no waiting
 670     one, then waits until one comes. Returns length of datagram stored in
 671     BUFFER. If length exceeds buffer datagram is truncated. After this
 672     @link(RemoteSin) structure contains information about sender of UDP packet.}
 673    function RecvBufferFrom(Buffer: TMemory; Length: Integer): Integer; virtual;
 674{$IFNDEF CIL}
 675    {:This function is for check for incoming data on set of sockets. Whitch
 676    sockets is checked is decribed by SocketList Tlist with TBlockSocket
 677    objects. TList may have maximal number of objects defined by FD_SETSIZE
 678    constant. Return @TRUE, if you can from some socket read any data or is
 679    incoming connection on TCP based socket. Status is tested for time Timeout
 680    (in milliseconds). If value in Timeout is 0, status is only tested and
 681    continue. If value in Timeout is -1, run is breaked and waiting for read
 682    data maybe forever. If is returned @TRUE, CanReadList TList is filled by all
 683    TBlockSocket objects what waiting for read.}
 684    function GroupCanRead(const SocketList: TList; Timeout: Integer;
 685      const CanReadList: TList): Boolean;
 686{$ENDIF}
 687    {:By this method you may turn address reuse mode for local @link(bind). It
 688     is good specially for UDP protocol. Using this with TCP protocol is
 689     hazardous!}
 690    procedure EnableReuse(Value: Boolean);
 691
 692    {:Try set timeout for all sending and receiving operations, if socket
 693     provider can do it. (It not supported by all socket providers!)}
 694    procedure SetTimeout(Timeout: Integer);
 695
 696    {:Try set timeout for all sending operations, if socket provider can do it.
 697     (It not supported by all socket providers!)}
 698    procedure SetSendTimeout(Timeout: Integer);
 699
 700    {:Try set timeout for all receiving operations, if socket provider can do
 701     it. (It not supported by all socket providers!)}
 702    procedure SetRecvTimeout(Timeout: Integer);
 703
 704    {:Return value of socket type.}
 705    function GetSocketType: integer; Virtual;
 706
 707    {:Return value of protocol type for socket creation.}
 708    function GetSocketProtocol: integer; Virtual;
 709
 710    {:WSA structure with information about socket provider. On non-windows 
 711     platforms this structure is simulated!}
 712    property WSAData: TWSADATA read GetWsaData;
 713
 714    {:FDset structure prepared for usage with this socket.}
 715    property FDset: TFDSet read FFDset;
 716
 717    {:Structure describing local socket side.}
 718    property LocalSin: TVarSin read FLocalSin write FLocalSin;
 719
 720    {:Structure describing remote socket side.}
 721    property RemoteSin: TVarSin read FRemoteSin write FRemoteSin;
 722
 723    {:Socket handler. Suitable for "manual" calls to socket API or manual
 724     connection of socket to a previously created socket (i.e by Accept method
 725     on TCP socket)}
 726    property Socket: TSocket read FSocket write SetSocket;
 727
 728    {:Last socket operation error code. Error codes are described in socket
 729     documentation. Human readable error description is stored in
 730     @link(LastErrorDesc) property.}
 731    property LastError: Integer read FLastError;
 732
 733    {:Human readable error description of @link(LastError) code.}
 734    property LastErrorDesc: string read FLastErrorDesc;
 735
 736    {:Buffer used by all high-level receiving functions. This buffer is used for
 737     optimized reading of data from socket. In normal cases you not need access
 738     to this buffer directly!}
 739    property LineBuffer: AnsiString read FBuffer write FBuffer;
 740
 741    {:Size of Winsock receive buffer. If it is not supported by socket provider,
 742     it return as size one kilobyte.}
 743    property SizeRecvBuffer: Integer read GetSizeRecvBuffer write SetSizeRecvBuffer;
 744
 745    {:Size of Winsock send buffer. If it is not supported by socket provider, it
 746     return as size one kilobyte.}
 747    property SizeSendBuffer: Integer read GetSizeSendBuffer write SetSizeSendBuffer;
 748
 749    {:If @True, turn class to non-blocking mode. Not all functions are working
 750     properly in this mode, you must know exactly what you are doing! However
 751     when you have big experience with non-blocking programming, then you can
 752     optimise your program by non-block mode!}
 753    property NonBlockMode: Boolean read FNonBlockMode Write SetNonBlockMode;
 754
 755    {:Set Time-to-live value. (if system supporting it!)}
 756    property TTL: Integer read GetTTL Write SetTTL;
 757
 758    {:If is @true, then class in in IPv6 mode.}
 759    property IP6used: Boolean read FIP6used;
 760
 761    {:Return count of received bytes on this socket from begin of current
 762     connection.}
 763    property RecvCounter: Integer read FRecvCounter;
 764
 765    {:Return count of sended bytes on this socket from begin of current
 766     connection.}
 767    property SendCounter: Integer read FSendCounter;
 768  published
 769    {:Return descriptive string for given error code. This is class function.
 770     You may call it without created object!}
 771    class function GetErrorDesc(ErrorCode: Integer): string;
 772
 773    {:Return descriptive string for @link(LastError).}
 774    function GetErrorDescEx: string; virtual;
 775
 776    {:this value is for free use.}
 777    property Tag: Integer read FTag write FTag;
 778
 779    {:If @true, winsock errors raises exception. Otherwise is setted
 780    @link(LastError) value only and you must check it from your program! Default
 781    value is @false.}
 782    property RaiseExcept: Boolean read FRaiseExcept write FRaiseExcept;
 783
 784    {:Define maximum length in bytes of @link(LineBuffer) for high-level
 785     receiving functions. If this functions try to read more data then this
 786     limit, error is returned! If value is 0 (default), no limitation is used.
 787     This is very good protection for stupid attacks to your server by sending
 788     lot of data without proper terminator... until all your memory is allocated
 789     by LineBuffer!
 790
 791     Note: This maximum length is checked only in functions, what read unknown
 792     number of bytes! (like @link(RecvString) or @link(RecvTerminated))}
 793    property MaxLineLength: Integer read FMaxLineLength Write FMaxLineLength;
 794
 795    {:Define maximal bandwidth for all sending operations in bytes per second.
 796     If value is 0 (default), bandwidth limitation is not used.}
 797    property MaxSendBandwidth: Integer read FMaxSendBandwidth Write FMaxSendBandwidth;
 798
 799    {:Define maximal bandwidth for all receiving operations in bytes per second.
 800     If value is 0 (default), bandwidth limitation is not used.}
 801    property MaxRecvBandwidth: Integer read FMaxRecvBandwidth Write FMaxRecvBandwidth;
 802
 803    {:Define maximal bandwidth for all sending and receiving operations in bytes
 804     per second. If value is 0 (default), bandwidth limitation is not used.}
 805    property MaxBandwidth: Integer Write SetBandwidth;
 806
 807    {:Do a conversion of non-standard line terminators to CRLF. (Off by default)
 808     If @True, then terminators like sigle CR, single LF or LFCR are converted
 809     to CRLF internally. This have effect only in @link(RecvString) method!}
 810    property ConvertLineEnd: Boolean read FConvertLineEnd Write FConvertLineEnd;
 811
 812    {:Specified Family of this socket. When you are using Windows preliminary
 813     support for IPv6, then I recommend to set this property!}
 814    property Family: TSocketFamily read FFamily Write SetFamily;
 815
 816    {:When resolving of domain name return both IPv4 and IPv6 addresses, then
 817     specify if is used IPv4 (dafault - @true) or IPv6.}
 818    property PreferIP4: Boolean read FPreferIP4 Write FPreferIP4;
 819
 820    {:By default (@true) is all timeouts used as timeout between two packets in
 821     reading operations. If you set this to @false, then Timeouts is for overall
 822     reading operation!}
 823    property InterPacketTimeout: Boolean read FInterPacketTimeout Write FInterPacketTimeout;
 824
 825    {:All sended datas was splitted by this value.}
 826    property SendMaxChunk: Integer read FSendMaxChunk Write FSendMaxChunk;
 827
 828    {:By setting this property to @true you can stop any communication. You can
 829     use this property for soft abort of communication.}
 830    property StopFlag: Boolean read FStopFlag Write FStopFlag;
 831
 832    {:Timeout for data sending by non-blocking socket mode.}
 833    property NonblockSendTimeout: Integer read FNonblockSendTimeout Write FNonblockSendTimeout;
 834
 835    {:Timeout for @link(Connect) call. Default value 0 means default system timeout.
 836     Non-zero value means timeout in millisecond.}
 837    property ConnectionTimeout: Integer read FConnectionTimeout write FConnectionTimeout;
 838
 839    {:This event is called by various reasons. It is good for monitoring socket,
 840     create gauges for data transfers, etc.}
 841    property OnStatus: THookSocketStatus read FOnStatus write FOnStatus;
 842
 843    {:this event is good for some internal thinks about filtering readed datas.
 844     It is used by telnet client by example.}
 845    property OnReadFilter: THookDataFilter read FOnReadFilter write FOnReadFilter;
 846
 847    {:This event is called after real socket creation for setting special socket
 848     options, because you not know when socket is created. (it is depended on
 849     Ipv4, IPv6 or automatic mode)}
 850    property OnCreateSocket: THookCreateSocket read FOnCreateSocket write FOnCreateSocket;
 851
 852    {:This event is good for monitoring content of readed or writed datas.}
 853    property OnMonitor: THookMonitor read FOnMonitor write FOnMonitor;
 854
 855    {:This event is good for calling your code during long socket operations.
 856      (Example, for refresing UI if class in not called within the thread.)
 857      Rate of heartbeats can be modified by @link(HeartbeatRate) property.}
 858    property OnHeartbeat: THookHeartbeat read FOnHeartbeat write FOnHeartbeat;
 859
 860    {:Specify typical rate of @link(OnHeartbeat) event and @link(StopFlag) testing.
 861      Default value 0 disabling heartbeats! Value is in milliseconds.
 862      Real rate can be higher or smaller then this value, because it depending
 863      on real socket operations too!
 864      Note: Each heartbeat slowing socket processing.}
 865    property HeartbeatRate: integer read FHeartbeatRate Write FHeartbeatRate;
 866    {:What class own this socket? Used by protocol implementation classes.}
 867    property Owner: TObject read FOwner Write FOwner;
 868  end;
 869
 870  {:@abstract(Support for SOCKS4 and SOCKS5 proxy)
 871   Layer with definition all necessary properties and functions for
 872   implementation SOCKS proxy client. Do not use this class directly.}
 873  TSocksBlockSocket = class(TBlockSocket)
 874  protected
 875    FSocksIP: string;
 876    FSocksPort: string;
 877    FSocksTimeout: integer;
 878    FSocksUsername: string;
 879    FSocksPassword: string;
 880    FUsingSocks: Boolean;
 881    FSocksResolver: Boolean;
 882    FSocksLastError: integer;
 883    FSocksResponseIP: string;
 884    FSocksResponsePort: string;
 885    FSocksLocalIP: string;
 886    FSocksLocalPort: string;
 887    FSocksRemoteIP: string;
 888    FSocksRemotePort: string;
 889    FBypassFlag: Boolean;
 890    FSocksType: TSocksType;
 891    function SocksCode(IP, Port: string): Ansistring;
 892    function SocksDecode(Value: Ansistring): integer;
 893  public
 894    constructor Create;
 895
 896    {:Open connection to SOCKS proxy and if @link(SocksUsername) is set, do
 897     authorisation to proxy. This is needed only in special cases! (it is called
 898     internally!)}
 899    function SocksOpen: Boolean;
 900
 901    {:Send specified request to SOCKS proxy. This is needed only in special
 902     cases! (it is called internally!)}
 903    function SocksRequest(Cmd: Byte; const IP, Port: string): Boolean;
 904
 905    {:Receive response to previosly sended request. This is needed only in
 906     special cases! (it is called internally!)}
 907    function SocksResponse: Boolean;
 908
 909    {:Is @True when class is using SOCKS proxy.}
 910    property UsingSocks: Boolean read FUsingSocks;
 911
 912    {:If SOCKS proxy failed, here is error code returned from SOCKS proxy.}
 913    property SocksLastError: integer read FSocksLastError;
 914  published
 915    {:Address of SOCKS server. If value is empty string, SOCKS support is
 916     disabled. Assingning any value to this property enable SOCKS mode.
 917     Warning: You cannot combine this mode with HTTP-tunneling mode!}
 918    property SocksIP: string read FSocksIP write FSocksIP;
 919
 920    {:Port of SOCKS server. Default value is '1080'.}
 921    property SocksPort: string read FSocksPort write FSocksPort;
 922
 923    {:If you need authorisation on SOCKS server, set username here.}
 924    property SocksUsername: string read FSocksUsername write FSocksUsername;
 925
 926    {:If you need authorisation on SOCKS server, set password here.}
 927    property SocksPassword: string read FSocksPassword write FSocksPassword;
 928
 929    {:Specify timeout for communicatin with SOCKS server. Default is one minute.}
 930    property SocksTimeout: integer read FSocksTimeout write FSocksTimeout;
 931
 932    {:If @True, all symbolic names of target hosts is not translated to IP's
 933     locally, but resolving is by SOCKS proxy. Default is @True.}
 934    property SocksResolver: Boolean read FSocksResolver write FSocksResolver;
 935
 936    {:Specify SOCKS type. By default is used SOCKS5, but you can use SOCKS4 too.
 937     When you select SOCKS4, then if @link(SOCKSResolver) is enabled, then is
 938     used SOCKS4a. Othervise is used pure SOCKS4.}
 939    property SocksType: TSocksType read FSocksType write FSocksType;
 940  end;
 941
 942  {:@abstract(Implementation of TCP socket.)
 943   Supported features: IPv4, IPv6, SSL/TLS or SSH (depending on used plugin),
 944   SOCKS5 proxy (outgoing connections and limited incomming), SOCKS4/4a proxy
 945   (outgoing connections and limited incomming), TCP through HTTP proxy tunnel.}
 946  TTCPBlockSocket = class(TSocksBlockSocket)
 947  protected
 948    FOnAfterConnect: THookAfterConnect;
 949    FSSL: TCustomSSL;
 950    FHTTPTunnelIP: string;
 951    FHTTPTunnelPort: string;
 952    FHTTPTunnel: Boolean;
 953    FHTTPTunnelRemoteIP: string;
 954    FHTTPTunnelRemotePort: string;
 955    FHTTPTunnelUser: string;
 956    FHTTPTunnelPass: string;
 957    FHTTPTunnelTimeout: integer;
 958    procedure SocksDoConnect(IP, Port: string);
 959    procedure HTTPTunnelDoConnect(IP, Port: string);
 960    procedure DoAfterConnect;
 961  public
 962    {:Create TCP socket class with default plugin for SSL/TSL/SSH implementation
 963    (see @link(SSLImplementation))}
 964    constructor Create;
 965
 966    {:Create TCP socket class with desired plugin for SSL/TSL/SSH implementation}
 967    constructor CreateWithSSL(SSLPlugin: TSSLClass);
 968    destructor Destroy; override;
 969
 970    {:See @link(TBlockSocket.CloseSocket)}
 971    procedure CloseSocket; override;
 972
 973    {:See @link(TBlockSocket.WaitingData)}
 974    function WaitingData: Integer; override;
 975
 976    {:Sets socket to receive mode for new incoming connections. It is necessary
 977     to use @link(TBlockSocket.BIND) function call before this method to select
 978     receiving port!
 979
 980     If you use SOCKS, activate incoming TCP connection by this proxy. (By BIND
 981     method of SOCKS.)}
 982    procedure Listen; override;
 983
 984    {:Waits until new incoming connection comes. After it comes a new socket is
 985     automatically created (socket handler is returned by this function as
 986     result).
 987
 988     If you use SOCKS, new socket is not created! In this case is used same
 989     socket as socket for listening! So, you can accept only one connection in
 990     SOCKS mode.}
 991    function Accept: TSocket; override;
 992
 993    {:Connects socket to remote IP address and PORT. The same rules as with
 994     @link(TBlockSocket.BIND) method are valid. The only exception is that PORT
 995     with 0 value will not be connected. After call to this method
 996     a communication channel between local and remote socket is created. Local
 997     socket is assigned automatically if not controlled by previous call to
 998     @link(TBlockSocket.BIND) method. Structures @link(TBlockSocket.LocalSin)
 999     and @link(TBlockSocket.RemoteSin) will be filled with valid values.
1000
1001     If you use SOCKS, activate outgoing TCP connection by SOCKS proxy specified
1002     in @link(TSocksBlockSocket.SocksIP). (By CONNECT method of SOCKS.)
1003
1004     If you use HTTP-tunnel mode, activate outgoing TCP connection by HTTP
1005     tunnel specified in @link(HTTPTunnelIP). (By CONNECT method of HTTP
1006     protocol.)
1007
1008     Note: If you call this on non-created socket, then socket is created
1009     automaticly.}
1010    procedure Connect(IP, Port: string); override;
1011
1012    {:If you need upgrade existing TCP connection to SSL/TLS (or SSH2, if plugin
1013     allows it) mode, then call this method. This method switch this class to
1014     SSL mode and do SSL/TSL handshake.}
1015    procedure SSLDoConnect;
1016
1017    {:By this method you can downgrade existing SSL/TLS connection to normal TCP
1018     connection.}
1019    procedure SSLDoShutdown;
1020
1021    {:If you need use this component as SSL/TLS TCP server, then after accepting
1022     of inbound connection you need start SSL/TLS session by this method. Before
1023     call this function, you must have assigned all neeeded certificates and
1024     keys!}
1025    function SSLAcceptConnection: Boolean;
1026
1027    {:See @link(TBlockSocket.GetLocalSinIP)}
1028    function GetLocalSinIP: string; override;
1029
1030    {:See @link(TBlockSocket.GetRemoteSinIP)}
1031    function GetRemoteSinIP: string; override;
1032
1033    {:See @link(TBlockSocket.GetLocalSinPort)}
1034    function GetLocalSinPort: Integer; override;
1035
1036    {:See @link(TBlockSocket.GetRemoteSinPort)}
1037    function GetRemoteSinPort: Integer; override;
1038
1039    {:See @link(TBlockSocket.SendBuffer)}
1040    function SendBuffer(Buffer: TMemory; Length: Integer): Integer; override;
1041
1042    {:See @link(TBlockSocket.RecvBuffer)}
1043    function RecvBuffer(Buffer: TMemory; Len: Integer): Integer; override;
1044
1045    {:Return value of socket type. For TCP return SOCK_STREAM.}
1046    function GetSocketType: integer; override;
1047
1048    {:Return value of protocol type for socket creation. For TCP return
1049     IPPROTO_TCP.}
1050    function GetSocketProtocol: integer; override;
1051
1052    {:Class implementing SSL/TLS support. It is allways some descendant
1053     of @link(TCustomSSL) class. When programmer not select some SSL plugin
1054     class, then is used @link(TSSLNone)}
1055    property SSL: TCustomSSL read FSSL;
1056
1057    {:@True if is used HTTP tunnel mode.}
1058    property HTTPTunnel: Boolean read FHTTPTunnel;
1059  published
1060    {:Return descriptive string for @link(LastError). On case of error
1061     in SSL/TLS subsystem, it returns right error description.}
1062    function GetErrorDescEx: string; override;
1063
1064    {:Specify IP address of HTTP proxy. Assingning non-empty value to this
1065     property enable HTTP-tunnel mode. This mode is for tunnelling any outgoing
1066     TCP connection through HTTP proxy server. (If policy on HTTP proxy server
1067     allow this!) Warning: You cannot combine this mode with SOCK5 mode!}
1068    property HTTPTunnelIP: string read FHTTPTunnelIP Write FHTTPTunnelIP;
1069
1070    {:Specify port of HTTP proxy for HTTP-tunneling.}
1071    property HTTPTunnelPort: string read FHTTPTunnelPort Write FHTTPTunnelPort;
1072
1073    {:Specify authorisation username for access to HTTP proxy in HTTP-tunnel
1074     mode. If you not need authorisation, then let this property empty.}
1075    property HTTPTunnelUser: string read FHTTPTunnelUser Write FHTTPTunnelUser;
1076
1077    {:Specify authorisation password for access to HTTP proxy in HTTP-tunnel
1078     mode.}
1079    property HTTPTunnelPass: string read FHTTPTunnelPass Write FHTTPTunnelPass;
1080
1081    {:Specify timeout for communication with HTTP proxy in HTTPtunnel mode.}
1082    property HTTPTunnelTimeout: integer read FHTTPTunnelTimeout Write FHTTPTunnelTimeout;
1083
1084    {:This event is called after sucessful TCP socket connection.}
1085    property OnAfterConnect: THookAfterConnect read FOnAfterConnect write FOnAfterConnect;
1086  end;
1087
1088  {:@abstract(Datagram based communication)
1089   This class implementing datagram based communication instead default stream
1090   based communication style.}
1091  TDgramBlockSocket = class(TSocksBlockSocket)
1092  public
1093    {:Fill @link(TBlockSocket.RemoteSin) structure. This address is used for
1094     sending data.}
1095    procedure Connect(IP, Port: string); override;
1096
1097    {:Silently redirected to @link(TBlockSocket.SendBufferTo).}
1098    function SendBuffer(Buffer: TMemory; Length: Integer): Integer; override;
1099
1100    {:Silently redirected to @link(TBlockSocket.RecvBufferFrom).}
1101    function RecvBuffer(Buffer: TMemory; Length: Integer): Integer; override;
1102  end;
1103
1104  {:@abstract(Implementation of UDP socket.)
1105   NOTE: in this class is all receiving redirected to RecvBufferFrom. You can
1106   use for reading any receive function. Preffered is RecvPacket! Similary all
1107   sending is redirected to SendbufferTo. You can use for sending UDP packet any
1108   sending function, like SendString.
1109
1110   Supported features: IPv4, IPv6, unicasts, broadcasts, multicasts, SOCKS5
1111   proxy (only unicasts! Outgoing and incomming.)}
1112  TUDPBlockSocket = class(TDgramBlockSocket)
1113  protected
1114    FSocksControlSock: TTCPBlockSocket;
1115    function UdpAssociation: Boolean;
1116    procedure SetMulticastTTL(TTL: integer);
1117    function GetMulticastTTL:integer;
1118  public
1119    destructor Destroy; override;
1120
1121    {:Enable or disable sending of broadcasts. If seting OK, result is @true.
1122     This method is not supported in SOCKS5 mode! IPv6 does not support
1123     broadcasts! In this case you must use Multicasts instead.}
1124    procedure EnableBroadcast(Value: Boolean);
1125
1126    {:See @link(TBlockSocket.SendBufferTo)}
1127    function SendBufferTo(Buffer: TMemory; Length: Integer): Integer; override;
1128
1129    {:See @link(TBlockSocket.RecvBufferFrom)}
1130    function RecvBufferFrom(Buffer: TMemory; Length: Integer): Integer; override;
1131{$IFNDEF CIL}
1132    {:Add this socket to given multicast group. You cannot use Multicasts in
1133     SOCKS mode!}
1134    procedure AddMulticast(MCastIP:string);
1135
1136    {:Remove this socket from given multicast group.}
1137    procedure DropMulticast(MCastIP:string);
1138{$ENDIF}
1139    {:All sended multicast datagrams is loopbacked to your interface too. (you
1140     can read your sended datas.) You can disable this feature by this function.
1141     This function not working on some Windows systems!}
1142    procedure EnableMultic

Large files files are truncated, but you can click here to view the full file