|
|
Line 412: |
Line 412: |
| | | |
| | | |
− | '''TCP protocol transport''' | + | '''TCP specific classes''' |
| | | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
| + | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" |
− | | + | |
− | <code>TTCPProtocolTransport = class(TProtocolTransport)</code>
| + | |
− | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
| + | |
− | {| class="wikitable" style="font-size: 14px; background: white;" | + | |
− | |-
| + | |
− | | <code>constructor Create;</code>
| + | |
− | | style="width: 50%;"|
| + | |
− | |-
| + | |
− | | <code>destructor Destroy; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''private'''</div>
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''public'''</div>
| + | |
| |- | | |- |
− | | <code>Socket:TTCPSocket;</code> | + | | [[TTCPProtocolTransport|<code>TTCPProtocolTransport = class(TProtocolTransport)</code>]] |
− | | Socket for responding to non matched segments
| + | |
| |- | | |- |
| |} | | |} |
− | </div></div>
| + | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" |
− | | + | |
− | '''TCP protocol'''
| + | |
− | | + | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
| + | |
− | | + | |
− | <code>TTCPProtocol = class(TNetworkProtocol)</code>
| + | |
− | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
| + | |
− | {| class="wikitable" style="font-size: 14px; background: white;"
| + | |
| |- | | |- |
− | | <code>constructor Create(AManager:TProtocolManager; const AName:String);</code> | + | | [[TTCPProtocol|<code>TTCPProtocol = class(TNetworkProtocol)</code>]] |
− | | style="width: 50%;"|
| + | |
− | |-
| + | |
− | | <code>destructor Destroy; override;</code> | + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''private'''</div>
| + | |
− | |-
| + | |
− | | <code>FNextPort:Word;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>FMinBacklog:Integer;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>FMaxBacklog:Integer;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>FReceiveBacklog:Integer;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function PacketHandler(AHandle:THandle; ASource,ADest,APacket:Pointer; ASize:Integer; ABroadcast:Boolean):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SegmentHandler(ASocket:TTCPSocket; ASource,ADest,APacket:Pointer; ASize:Integer):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function ResetHandler(ASocket:TTCPSocket; ASource,ADest,APacket:Pointer; ASize:Integer):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function CloneSocket(ASocket:TTCPSocket; ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ALock:Boolean; AState:LongWord):TTCPSocket;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function GetTCPOptionsSize(ASocket:TTCPSocket; AOptions:Pointer):Word;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function CreateTCPOptions(ASocket:TTCPSocket; AOptions:Pointer; AFlags:Byte):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function HandleTCPOptions(ASocket:TTCPSocket; AOptions:Pointer; AFlags:Byte):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function InsertTCPOption(ASocket:TTCPSocket; AOptions:Pointer; AOption:Byte):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function ExtractTCPOption(ASocket:TTCPSocket; AOptions:Pointer; AOption:Byte):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function SendReset(ASocket:TTCPSocket):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SendAcknowledge(ASocket:TTCPSocket):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function SendSegment(ASocket:TTCPSocket; ASource,ADest:Pointer; ASourcePort,ADestPort:Word; ASequence,AAcknowledge:LongWord; AWindow,AUrgent:Word; AFlags:Byte; AOptions,AData:Pointer; ASize:Integer):Integer;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''protected'''</div>
| + | |
− | |-
| + | |
− | | <code>function OpenPort(ASocket:TProtocolSocket; APort:Word):Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function ClosePort(ASocket:TProtocolSocket):Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function FindPort(APort:Word; AWrite,ALock:Boolean):TProtocolPort; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function SelectCheck(ASource,ADest:PFDSet; ACode:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SelectWait(ASocket:TProtocolSocket; ACode:Integer; ATimeout:LongWord):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''public'''</div>
| + | |
− | |-
| + | |
− | | <code>function Accept(ASocket:TProtocolSocket; ASockAddr:PSockAddr; AAddrLength:PInteger):TProtocolSocket; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Bind(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; AAddrLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function CloseSocket(ASocket:TProtocolSocket):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Connect(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; AAddrLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function IoctlSocket(ASocket:TProtocolSocket; ACmd:DWORD; var AArg:u_long):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetPeerName(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; var AAddrLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetSockName(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; var AAddrLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetSockOpt(ASocket:TProtocolSocket; ALevel,AOptName:Integer; AOptValue:PChar; var AOptLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Listen(ASocket:TProtocolSocket; ABacklog:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Recv(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function RecvFrom(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer; var AFromAddr:TSockAddr; var AFromLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Select(ANfds:Integer; AReadfds,AWritefds,AExceptfds:PFDSet; ATimeout:PTimeVal):LongInt; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Send(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SendTo(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer; var AToAddr:TSockAddr; AToLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SetSockOpt(ASocket:TProtocolSocket; ALevel,AOptName:Integer; AOptValue:PChar; AOptLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Shutdown(ASocket:TProtocolSocket; AHow:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Socket(AFamily,AStruct,AProtocol:Integer):TProtocolSocket; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function AddTransport(ATransport:TNetworkTransport):Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function RemoveTransport(ATransport:TNetworkTransport):Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function FindSocket(AFamily,AStruct,AProtocol:Word; ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ABroadcast,AListen,ALock:Boolean; AState:LongWord):TProtocolSocket; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure FlushSockets(All:Boolean); override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function StartProtocol:Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function StopProtocol:Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function ProcessProtocol:Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function ProcessSockets:Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function ProcessSocket(ASocket:TProtocolSocket):Boolean; override;</code>
| + | |
− | |
| + | |
| |- | | |- |
| |} | | |} |
− | </div></div>
| + | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" |
− | | + | |
− | '''TCP socket'''
| + | |
− | | + | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
| + | |
− | | + | |
− | <code>TTCPSocket = class(TProtocolSocket)</code>
| + | |
− | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
| + | |
− | {| class="wikitable" style="font-size: 14px; background: white;"
| + | |
| |- | | |- |
− | |colspan="2"|Note: SOCK_STREAM | + | | [[TTCPSocket|<code>TTCPSocket = class(TProtocolSocket)</code>]] |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>constructor Create(AProtocol:TNetworkProtocol; ATransport:TNetworkTransport);</code> | + | |
− | | style="width: 50%;"|
| + | |
− | |-
| + | |
− | | <code>destructor Destroy; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''private'''</div>
| + | |
− | |-
| + | |
− | | <code>FBackLog:Integer;</code>
| + | |
− | | Backlog size of Listen/Accept Queue
| + | |
− | |-
| + | |
− | | <code>FListener:TProtocolSocket;</code>
| + | |
− | | The Listener socket for this socket (If applicable)
| + | |
− | |-
| + | |
− | | <code>FAcceptQueue:TSocketList;</code>
| + | |
− | | Sockets waiting for connection Accept
| + | |
− | |-
| + | |
− | | <code>FReceiveQueue:TSocketList;</code>
| + | |
− | | Sockets waiting for SYN/ACK handshake
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>FSendData:TTCPSendBuffer;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>FRecvData:TTCPRecvBuffer;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>procedure SetBackLog(ABackLog:Integer);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetListener(AListener:TProtocolSocket);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''public'''</div>
| + | |
− | |-
| + | |
− | | <code>property BackLog:Integer read FBackLog write SetBackLog;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property Listener:TProtocolSocket read FListener write SetListener;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property AcceptQueue:TSocketList read FAcceptQueue;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property ReceiveQueue:TSocketList read FReceiveQueue;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>property SendData:TTCPSendBuffer read FSendData;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property RecvData:TTCPRecvBuffer read FRecvData;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function GetOption(ALevel,AOptName:Integer; AOptValue:PChar; var AOptLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SetOption(ALevel,AOptName:Integer; AOptValue:PChar; AOptLength:Integer):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function IoCtl(ACommand:DWORD; var AArgument:u_long):Integer; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function IsConnected(ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ABroadcast:Boolean):Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function IsListening(ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ABroadcast:Boolean):Boolean; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function Listen:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Connect:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Reconnect:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Disconnect:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function Accept(APeek,ALock:Boolean; AState:LongWord):TTCPSocket;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function RecvSegment(ASequence,AAcknowledge:LongWord; AWindow,AUrgent:Word; AFlags:Byte; AData:Pointer; ASize:Word):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SendSegment(var ASequence,AAcknowledge:LongWord; var AWindow,AUrgent:Word; var AFlags:Byte; var AData:Pointer; var ASize:Word):Boolean;</code>
| + | |
− | |
| + | |
| |- | | |- |
| |} | | |} |
− | </div></div>
| + | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" |
− | | + | |
− | '''TCP state'''
| + | |
− | | + | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
| + | |
− | | + | |
− | <code>TTCPState = class(TProtocolState)</code>
| + | |
− | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
| + | |
− | {| class="wikitable" style="font-size: 14px; background: white;" | + | |
− | |-
| + | |
− | | <code>constructor Create;</code>
| + | |
− | | style="width: 50%;"|
| + | |
− | |-
| + | |
− | | <code>destructor Destroy; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''private'''</div>
| + | |
− | |-
| + | |
− | | <code>FState:LongWord;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>procedure SetState(AState:LongWord);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function GetListening:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetListening(AValue:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetEstablished:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetEstablished(AValue:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetClosed:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetClosed(AValue:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function GetSynchronized:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''public'''</div>
| + | |
− | |-
| + | |
− | | <code>property State:LongWord read FState write SetState;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>property Listening:Boolean read GetListening write SetListening;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property Established:Boolean read GetEstablished write SetEstablished;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property Closed:Boolean read GetClosed write SetClosed;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
| |- | | |- |
− | | <code>property Synchronized:Boolean read GetSynchronized;</code> | + | | [[TTCPState|<code>TTCPState = class(TProtocolState)</code>]] |
− | |
| + | |
| |- | | |- |
| |} | | |} |
− | </div></div>
| + | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" |
− | | + | |
− | '''TCP options'''
| + | |
− | | + | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
| + | |
− | | + | |
− | <code>TTCPOptions = class(TProtocolOptions)</code>
| + | |
− | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
| + | |
− | {| class="wikitable" style="font-size: 14px; background: white;"
| + | |
| |- | | |- |
− | |colspan="2"|Note: For Get/Set Options Level = TCP_PROTO Option = TCP_NODELAY, TCP_MAXSEG etc | + | | [[TTCPOptions|<code>TTCPOptions = class(TProtocolOptions)</code>]] |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>constructor Create;</code> | + | |
− | | style="width: 50%;"|
| + | |
− | |-
| + | |
− | | <code>destructor Destroy; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''private'''</div>
| + | |
− | |-
| + | |
− | | <code>FMemory:TMemoryStream;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>FOptions:LongWord;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>FMaxSeg:Word;</code>
| + | |
− | | MSS Option in TCP Header (MSS we send to Remote)
| + | |
− | |-
| + | |
− | | <code>FWindowScale:Byte;</code>
| + | |
− | | Window Scale Option in TCP Header (Window Scale we send to Remote)
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>procedure SetMaxSeg(AMaxSeg:Word);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetWindowScale(AWindowScale:Byte);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function GetOptions:Pointer;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetNoDelay:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetNoDelay(ANoDelay:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetNoPush:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetNoPush(ANoPush:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetNoOpt:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetNoOpt(ANoOpt:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetBsdUrgent:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetBsdUrgent(ABsdUrgent:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetNoSack:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure SetNoSack(ANoSack:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''public'''</div>
| + | |
− | |-
| + | |
− | | <code>property MaxSeg:Word read FMaxSeg write SetMaxSeg;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property WindowScale:Byte read FWindowScale write SetWindowScale;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>property Options:Pointer read GetOptions;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property NoDelay:Boolean read GetNoDelay write SetNoDelay;</code>
| + | |
− | | Determines if we Delay small segments until previous sends are ACKed
| + | |
− | |-
| + | |
− | | <code>property NoPush:Boolean read GetNoPush write SetNoPush;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property NoOpt:Boolean read GetNoOpt write SetNoOpt;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property BsdUrgent:Boolean read GetBsdUrgent write SetBsdUrgent;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>property NoSack:Boolean read GetNoSack write SetNoSack;</code>
| + | |
− | | Determines if we send SACKOK to Remote
| + | |
| |- | | |- |
| |} | | |} |
− | </div></div>
| + | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" |
− | | + | |
− | '''TCP send buffer'''
| + | |
− | | + | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
| + | |
− | | + | |
− | <code>TTCPSendBuffer = class(TSocketBuffer)</code>
| + | |
− | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
| + | |
− | {| class="wikitable" style="font-size: 14px; background: white;"
| + | |
| |- | | |- |
− | | <code>constructor Create(ASocket:TTransportSocket);</code> | + | | [[TTCPSendBuffer|<code>TTCPSendBuffer = class(TSocketBuffer)</code>]] |
− | | style="width: 50%;"|
| + | |
− | |-
| + | |
− | | <code>destructor Destroy; override;</code> | + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''private'''</div>
| + | |
− | |-
| + | |
− | | <code>FFirst:PTCPSegment;</code>
| + | |
− | | Pointer to First Segment
| + | |
− | |-
| + | |
− | | <code>FLast:PTCPSegment;</code>
| + | |
− | | Pointer to Last Segment
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function AddSegment(ASequence:LongWord; AFlags:Byte; ASize:Word):PTCPSegment;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function RemoveSegment(ASegment:PTCPSegment):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure FlushSegments(All:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''protected'''</div>
| + | |
− | |-
| + | |
− | | <code>procedure SetSize(ASize:LongWord); override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''public'''</div>
| + | |
− | |-
| + | |
− | | <code>StartSequence:LongWord;</code>
| + | |
− | | Initial Sequence number of Local (ISS)
| + | |
− | |-
| + | |
− | | <code>NextSequence:LongWord;</code>
| + | |
− | | Next Sequence number to Send (SND.NXT
| + | |
− | |-
| + | |
− | | <code>LastSequence:LongWord;</code>
| + | |
− | | Last Sequence number in Buffer
| + | |
− | |-
| + | |
− | | <code>LastAcknowledge:LongWord;</code>
| + | |
− | | Last Acknowledged number from Remote (SND.UNA)
| + | |
− | Note: LastAcknowledge is the NextSequence that Remote expects to Receive or the first Unacknowledged Sequence number. If LastAcknowledge equals NextSequence all segments have been Acknowledged LastSequence is the last sequence in our buffer to send. If NextSequence equals LastSequence there is no more data to send.
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>UrgentPointer:LongWord;</code>
| + | |
− | | (SND.UP)
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>MaxSeg:Word;</code>
| + | |
− | | Remote Max Segment Size (Learned from Remote)
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>WindowSize:LongWord;</code>
| + | |
− | | Remote Window Size (SND.WND)
| + | |
− | |-
| + | |
− | | <code>WindowScale:Byte;</code>
| + | |
− | | Remote Window Scale
| + | |
− | |-
| + | |
− | | <code>WindowTimeout:Int64;</code>
| + | |
− | | Timeout for probing small/zero Window
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>CongestionWindow:Word;</code>
| + | |
− | | Slow Start Window Size
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>SynSequence:LongWord;</code>
| + | |
− | | Sequence number of our SYN
| + | |
− | |-
| + | |
− | | <code>FinSequence:LongWord;</code>
| + | |
− | | Sequence number of our FIN
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>WindowSequence:LongWord;</code>
| + | |
− | | Sequence number of last Window update (SND.WL1)
| + | |
− | |-
| + | |
− | | <code>WindowAcknowledge:LongWord;</code>
| + | |
− | | Acknowledge number of last Window update (SND.WL2)
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>NoPush:Boolean;</code>
| + | |
− | | Disable Push on final segment
| + | |
− | |-
| + | |
− | | <code>NoSack:Boolean;</code>
| + | |
− | | Selective Ack not in use
| + | |
− | |-
| + | |
− | | <code>NoNagle:Boolean;</code>
| + | |
− | | Nagle not in use
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>VjSa:LongWord;</code>
| + | |
− | | VJ's alg, standard average
| + | |
− | |-
| + | |
− | | <code>VjSd:LongWord;</code>
| + | |
− | | VJ's alg, standard deviation
| + | |
− | |-
| + | |
− | | <code>VjLast:LongWord;</code>
| + | |
− | | VJ's alg, last transmit time
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function CheckIdle:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function SynAcknowledged:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function FinAcknowledged:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function TestAcknowledge(AAcknowledge:LongWord):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function CheckAcknowledge(AAcknowledge:LongWord):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function ValidateAcknowledge(AAcknowledge:LongWord):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function WriteData(var ABuffer; ASize,AFlags:Integer):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function Finish:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function Synchronize:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function ReadSegment(var ASequence:LongWord; var AUrgent:Word; var AFlags:Byte; var AData:Pointer; var ASize:Word; AForce:Boolean):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function AcknowledgeSegments(ASequence,AAcknowledge:LongWord; AWindow:Word):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function TimestampSegment(AOptions:Pointer; var AOffset:Word):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function SelectiveAckSegments(AOptions:Pointer; var AOffset:Word; ASize:Byte):Boolean;</code>
| + | |
− | |
| + | |
| |- | | |- |
| |} | | |} |
− | </div></div>
| + | {| class="wikitable" style="font-size: 14px; text-align: left; width: 100%; height: 50px;" |
− | | + | |
− | '''TCP receive buffer'''
| + | |
− | | + | |
− | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
| + | |
− | | + | |
− | <code>TTCPRecvBuffer = class(TSocketBuffer)</code>
| + | |
− | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
| + | |
− | {| class="wikitable" style="font-size: 14px; background: white;" | + | |
− | |-
| + | |
− | | <code>constructor Create(ASocket:TTransportSocket);</code>
| + | |
− | | style="width: 50%;"|
| + | |
− | |-
| + | |
− | | <code>destructor Destroy; override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''private'''</div>
| + | |
− | |-
| + | |
− | | <code>FUrgent:LongWord;</code>
| + | |
− | | Number of OOB bytes readable from Buffer
| + | |
− | |-
| + | |
− | | <code>FAvailable:LongWord;</code>
| + | |
− | | Number of bytes readable from Buffer
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>FFirst:PTCPSegment;</code>
| + | |
− | | Pointer to First Segment
| + | |
− | |-
| + | |
− | | <code>FLast:PTCPSegment;</code>
| + | |
− | | Pointer to Last Segment
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function DelayOverride(ASegment:PTCPSegment):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function GetSegment(ASequence:LongWord; ALength:Word):PTCPSegment;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetPrevious(ASequence:LongWord; ALength:Word):PTCPSegment;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetOverlapped(ASequence:LongWord; ALength:Word):PTCPSegment;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function AddSegment(APrev:PTCPSegment; ASequence:LongWord; AFlags:Byte; ASize:Word):PTCPSegment;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function RemoveSegment(ASegment:PTCPSegment):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>procedure FlushSegments(All:Boolean);</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''protected'''</div>
| + | |
− | |-
| + | |
− | | <code>procedure SetSize(ASize:LongWord); override;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|<div style="font-family: monospace,courier;">'''public'''</div>
| + | |
− | |-
| + | |
− | | <code>StartSequence:LongWord;</code>
| + | |
− | | Initial Sequence number of Remote (IRS)
| + | |
− | |-
| + | |
− | | <code>NextSequence:LongWord;</code>
| + | |
− | | Next Sequence number to Receive (RCV.NXT)
| + | |
− | |-
| + | |
− | | <code>LastSequence:LongWord;</code>
| + | |
− | | Last Sequence number in Buffer (Including Unacknowledged data)
| + | |
− | |-
| + | |
− | | <code>LastAcknowledge:LongWord;</code>
| + | |
− | | Last Acknowledged number to Remote
| + | |
− | Note: NextSequence is the next byte we expect to Receive from Remote. LastAcknowledge will be the first Unacknowledged Seqeunce number of the Remote. LastSequence is the last sequence we have received from the Remote. If NextSequence equals LastSequence and LastAcknowledge equals NextSequence all segments have been Acknowledged.
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>UrgentPointer:LongWord;</code>
| + | |
− | | (RCV.UP)
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>MaxSeg:Word;</code>
| + | |
− | | Local Max Segment Size
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>WindowSize:LongWord;</code>
| + | |
− | | Local Window Size (RCV.WND)
| + | |
− | |-
| + | |
− | | <code>WindowScale:Byte;</code>
| + | |
− | | Local Window Scale
| + | |
− | |-
| + | |
− | | <code>LastWindow:LongWord;</code>
| + | |
− | | Last Window value sent to Remote
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>SynSequence:LongWord;</code>
| + | |
− | | Sequence number of remote SYN
| + | |
− | |-
| + | |
− | | <code>FinSequence:LongWord;</code>
| + | |
− | | Sequence number of remote FIN
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>NoSack:Boolean;</code>
| + | |
− | | Selective Ack not in use
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function CheckIdle:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function GetUrgent:LongWord;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function GetAvailable:LongWord;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function SynReceived:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function FinReceived:Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function CheckSequence(ASequence:LongWord; ASize:Word):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function ReadData(var ABuffer; var ASize:Integer; AFlags:Integer):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function WriteSegment(ASequence:LongWord; AUrgent:Word; AFlags:Byte; AData:Pointer; ASize:Word):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | | <code>function AcknowledgeSegments(var AAcknowledge:LongWord; var AWindow:Word; AForce:Boolean):Boolean;</code>
| + | |
− | |
| + | |
− | |-
| + | |
− | |colspan="2"|
| + | |
− | |-
| + | |
− | | <code>function TimestampSegment(AOptions:Pointer; var AOffset:Word):Boolean;</code>
| + | |
− | |
| + | |
| |- | | |- |
− | | <code>function SelectiveAckSegments(AOptions:Pointer; var AOffset:Word):Boolean;</code> | + | | [[TTCPRecvBuffer|<code>TTCPRecvBuffer = class(TSocketBuffer)</code>]] |
− | |
| + | |
| |- | | |- |
| |} | | |} |
− | </div></div>
| |
| <br /> | | <br /> |
| | | |
Send adds new segments to the end of the list only accepts ACKs for whole segments.
Recv adds/inserts segments in correct SEQ order accepts overlapping segments only sends ACKs for whole segments.
Send will coalesce small data writes into larger segments if options allow this.
Recv will store the segments exactly as received.
TCP Sequence numbers are compared using modulo 2^32 arithmetic. The following calculations provide the necessary handling of wraparound etc.