Unit TCP

From Ultibo.org
Revision as of 02:41, 24 April 2018 by Ultibo (Talk | contribs)

Jump to: navigation, search

Return to Unit Reference


Description


Ultibo TCP (Transmission Control Protocol) unit

Notes:

Segment handling:

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 Send and Recv do not use a block buffer as per UDP etc. Instead the data for each Segment is stored in memory (TCP_MAX_MSS) allocated with the Segment. The Free and Used values still track the amount of data in the buffer but this method allows OOB data to be handled correctly.

TCP Sequence numbers are compared using modulo 2^32 arithmetic. The following calculations provide the necessary handling of wraparound etc.

LT = (A - B) < 0

LEQ = (A - B) <= 0

GT = (A - B) > 0

GEQ = (A - B) >= 0


See GlobalSock.pas for actual functions that implement this.

Constants



TCP specific constants TCP_*
Note: Some TCP definitions are in the Protocol or IP modules
 
TCP_PROTOCOL_NAME = 'TCP';  
 
TCP_TIMER_INTERVAL = 1; 1ms timer interval for TCP
 
MIN_TCP_PACKET = 20; Not Counting Adapter and Transport Header
MAX_TCP_PACKET = 1480; Not Counting Adapter and Transport Header
 
TCP_DEFAULT_MSS = 536; Default Segment Size for TCP (576 - TCP - IP)
TCP_MAX_MSS = 1460; Max Segment Size for TCP (1500 - TCP - IP)
 
TCP_MAX_LIFETIME = 120000; Max Segment Lifetime (2 minutes)
 
TCP_TIMEOUT = 0; Wait forever on a TCP Read/Write
TCP_BUFFER_SIZE = 262144; 65536; TCP Send/Receive Buffer Sizes
TCP_WINDOW_SIZE = 64240; Sliding Window Receive Size (44 x MSS)
TCP_INITIAL_WINDOW = 8192; Initial Window to advertise in SYN packet
 
TCP_TIMEOUT_OFFSET = 10; How much time offset to allow from the designated value
 
TCP_ADVERT_TIMEOUT = 100; Time to wait before sending a window size update after closing the receive window
 
TCP_WINDOW_TIMEOUT = 5000; Time to wait before probing small/zero Window
TCP_ACK_TIMEOUT = 200; Max Delayed Ack Time
 
TCP_CONNECT_COUNT = 3; Number of Connect retries (on RST) before Failure
TCP_RESTART_TIMEOUT = 400; Timeout between Connect retries (Milliseconds)
 
TCP_RETRY_COUNT = 10; Number of Retransmits before Reset
 
TCP_RETRY_TIMEOUT:array[1..TCP_RETRY_COUNT] of LongWord = (250,500,1000,2000,4000,8000,15000,30000,60000,120000);
 
TCP_KEEPALIVE_COUNT = 3; Number of Failed Keepalives before Reset
 
TCP_KEEPALIVE_TIMEOUT:array[1..TCP_KEEPALIVE_COUNT] of LongWord = (600000,60000,60000);
 
TCP_MAX_PORT = 65536;  
 
TCP_HEADER_SIZE = 20; SizeOf(TTCPHeader) Does Not Allow for Options
TCP_OPTIONS_SIZE = 40; Maximum Allowed Options
 
TCP_SEGMENT_SIZE = 68; SizeOf(TTCPSegment) Including TSocketTimerItem


TCP socket state TCP_STATE_*
TCP_STATE_LISTEN = 0; listening for connection
TCP_STATE_SYNSENT = 1; SYN sent, active open
TCP_STATE_SYNREC = 2; SYN received, SYNACK sent
TCP_STATE_ESTAB = 3; established
TCP_STATE_FINWAIT1 = 4; sent FIN
TCP_STATE_FINWAIT2 = 5; sent FIN, received FINACK
TCP_STATE_CLOSWAIT = 6; received FIN waiting for close
TCP_STATE_CLOSING = 7; sent FIN, received FIN (waiting for FINACK)
TCP_STATE_LASTACK = 8; FIN received, FINACK + FIN sent
TCP_STATE_TIMEWAIT = 9; dally after sending final FINACK
TCP_STATE_CLOSED = 10; FINACK received


TCP header option TCPOPT_*
TCPOPT_EOL = 0; end-of-option list
TCPOPT_NOP = 1; no-operation
TCPOPT_MAXSEG = 2; maximum segment size
TCPOPT_WINDOW = 3; window scale factor (rfc1072)
TCPOPT_SACKOK = 4; selective ack ok (rfc1072)
TCPOPT_SACK = 5; selective ack (rfc1072)
TCPOPT_ECHO = 6; echo (rfc1072)
TCPOPT_ECHOREPLY = 7; echo (rfc1072)
TCPOPT_TIMESTAMP = 8; timestamps (rfc1323)
TCPOPT_CC = 11; T/TCP CC options (rfc1644)
TCPOPT_CCNEW = 12; T/TCP CC options (rfc1644)
TCPOPT_CCECHO = 13; T/TCP CC options (rfc1644)


TCP header flag TCP_FLAG_*
TCP_FLAG_FIN = $01;  
TCP_FLAG_SYN = $02;  
TCP_FLAG_RST = $04;  
TCP_FLAG_PUSH = $08;  
TCP_FLAG_ACK = $10;  
TCP_FLAG_URG = $20;  
TCP_FLAG_MASK = $3F;  
 
Van Jacobson's Algorithm; max std. average and std. deviation
MAX_VJSA = 80000;  
MAX_VJSD = 20000;  
INIT_VJSA = 220;  


TCP port TCP_PORT_*
TCP_PORT_START = 49152; First dynamic port (Previously 1024) As per IANA assignment
TCP_PORT_STOP = 65534; Last dynamic port (Previously 5000) Short of IANA assignment to allow for rollover


Type definitions



TCP header

PTCPHeader = ^TTCPHeader;

TTCPHeader = packed record

Note: Some TCP definitions are in the Protocol or IP modules
Note: 20 Bytes unless TCP Options are added
SourcePort:Word; Network Order
DestPort:Word; Network Order
Sequence:LongWord; First Sequence number in Data
Acknowledge:LongWord; Next Sequence number expected
HeaderLength:Byte; Number of 32 bit words in Header and Options (Bits 4-7 Reserved)
Flags:Byte; Flags for TCP Control (Bits 1-2 Reserved)
WindowSize:Word; Max 65536 (See WindowScale for higher values)
Checksum:Word; As per standard (Header, Options and Data)
Urgent:Word;  

TCP segment

PTCPSegment = ^TTCPSegment;

TTCPSegment = record

Note: 48 Bytes (Used by TCPSendBuffer/TCPRecvBuffer)
Size:Word; Size of Segment Data (Can be zero)
Data:Pointer; Pointer to Data in Buffer (Can be nil)
FirstSequence:LongWord; Start Sequence of Data
LastSequence:LongWord; End Sequence of Data (including Control bits)(actually the Start Sequence of next Segment)
 
Control:Word; Control Bits on this segment (SYN/FIN/URG) (Send/Recv)
Transferred:WordBool; Data has been Transferred to/from Buffer (Send/Recv)
Acknowledged:WordBool; Data has been Acknowledged (Send/Recv)
SelectiveAck:WordBool; Data has been Selective Acknowledged (Send/Recv)
RoundTripTime:Int64;  
 
Count:Word; Transmit Count (Send)
Timeout:Int64; Transmit (Send)/Acknowledge (Recv) Timeout
Prev:PTCPSegment; Pointer to Prev Segment
Next:PTCPSegment; Pointer to Next Segment
 
Item:TSocketTimerItem; Socket Timer Item for this Segment


Class definitions



TCP protocol transport

TTCPProtocolTransport = class(TProtocolTransport)

constructor Create;  
destructor Destroy; override;  
private
 
public
Socket:TTCPSocket; Socket for responding to non matched segments

TCP protocol

TTCPProtocol = class(TNetworkProtocol)

constructor Create(AManager:TProtocolManager; const AName:String);  
destructor Destroy; override;  
private
FNextPort:Word;  
FMinBacklog:Integer;  
FMaxBacklog:Integer;  
FReceiveBacklog:Integer;  
 
function PacketHandler(AHandle:THandle; ASource,ADest,APacket:Pointer; ASize:Integer; ABroadcast:Boolean):Boolean;  
function SegmentHandler(ASocket:TTCPSocket; ASource,ADest,APacket:Pointer; ASize:Integer):Boolean;  
function ResetHandler(ASocket:TTCPSocket; ASource,ADest,APacket:Pointer; ASize:Integer):Boolean;  
 
function CloneSocket(ASocket:TTCPSocket; ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ALock:Boolean; AState:LongWord):TTCPSocket;  
 
function GetTCPOptionsSize(ASocket:TTCPSocket; AOptions:Pointer):Word;  
 
function CreateTCPOptions(ASocket:TTCPSocket; AOptions:Pointer; AFlags:Byte):Boolean;  
function HandleTCPOptions(ASocket:TTCPSocket; AOptions:Pointer; AFlags:Byte):Boolean;  
 
function InsertTCPOption(ASocket:TTCPSocket; AOptions:Pointer; AOption:Byte):Boolean;  
function ExtractTCPOption(ASocket:TTCPSocket; AOptions:Pointer; AOption:Byte):Boolean;  
 
function SendReset(ASocket:TTCPSocket):Boolean;  
function SendAcknowledge(ASocket:TTCPSocket):Boolean;  
 
function SendSegment(ASocket:TTCPSocket; ASource,ADest:Pointer; ASourcePort,ADestPort:Word; ASequence,AAcknowledge:LongWord; AWindow,AUrgent:Word; AFlags:Byte; AOptions,AData:Pointer; ASize:Integer):Integer;  
protected
function OpenPort(ASocket:TProtocolSocket; APort:Word):Boolean; override;  
function ClosePort(ASocket:TProtocolSocket):Boolean; override;  
function FindPort(APort:Word; AWrite,ALock:Boolean):TProtocolPort; override;  
 
function SelectCheck(ASource,ADest:PFDSet; ACode:Integer):Integer; override;  
function SelectWait(ASocket:TProtocolSocket; ACode:Integer; ATimeout:LongWord):Integer; override;  
public
function Accept(ASocket:TProtocolSocket; ASockAddr:PSockAddr; AAddrLength:PInteger):TProtocolSocket; override;  
function Bind(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; AAddrLength:Integer):Integer; override;  
function CloseSocket(ASocket:TProtocolSocket):Integer; override;  
function Connect(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; AAddrLength:Integer):Integer; override;  
function IoctlSocket(ASocket:TProtocolSocket; ACmd:DWORD; var AArg:u_long):Integer; override;  
function GetPeerName(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; var AAddrLength:Integer):Integer; override;  
function GetSockName(ASocket:TProtocolSocket; var ASockAddr:TSockAddr; var AAddrLength:Integer):Integer; override;  
function GetSockOpt(ASocket:TProtocolSocket; ALevel,AOptName:Integer; AOptValue:PChar; var AOptLength:Integer):Integer; override;  
function Listen(ASocket:TProtocolSocket; ABacklog:Integer):Integer; override;  
function Recv(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer):Integer; override;  
function RecvFrom(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer; var AFromAddr:TSockAddr; var AFromLength:Integer):Integer; override;  
function Select(ANfds:Integer; AReadfds,AWritefds,AExceptfds:PFDSet; ATimeout:PTimeVal):LongInt; override;  
function Send(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer):Integer; override;  
function SendTo(ASocket:TProtocolSocket; var ABuffer; ALength,AFlags:Integer; var AToAddr:TSockAddr; AToLength:Integer):Integer; override;  
function SetSockOpt(ASocket:TProtocolSocket; ALevel,AOptName:Integer; AOptValue:PChar; AOptLength:Integer):Integer; override;  
function Shutdown(ASocket:TProtocolSocket; AHow:Integer):Integer; override;  
function Socket(AFamily,AStruct,AProtocol:Integer):TProtocolSocket; override;  
 
function AddTransport(ATransport:TNetworkTransport):Boolean; override;  
function RemoveTransport(ATransport:TNetworkTransport):Boolean; override;  
 
function FindSocket(AFamily,AStruct,AProtocol:Word; ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ABroadcast,AListen,ALock:Boolean; AState:LongWord):TProtocolSocket; override;  
procedure FlushSockets(All:Boolean); override;  
 
function StartProtocol:Boolean; override;  
function StopProtocol:Boolean; override;  
function ProcessProtocol:Boolean; override;  
 
function ProcessSockets:Boolean; override;  
function ProcessSocket(ASocket:TProtocolSocket):Boolean; override;  

TCP socket

TTCPSocket = class(TProtocolSocket)

Note: SOCK_STREAM
 
constructor Create(AProtocol:TNetworkProtocol; ATransport:TNetworkTransport);  
destructor Destroy; override;  
private
FBackLog:Integer; Backlog size of Listen/Accept Queue
FListener:TProtocolSocket; The Listener socket for this socket (If applicable)
FAcceptQueue:TSocketList; Sockets waiting for connection Accept
FReceiveQueue:TSocketList; Sockets waiting for SYN/ACK handshake
 
FSendData:TTCPSendBuffer;  
FRecvData:TTCPRecvBuffer;  
 
procedure SetBackLog(ABackLog:Integer);  
procedure SetListener(AListener:TProtocolSocket);  
public
property BackLog:Integer read FBackLog write SetBackLog;  
property Listener:TProtocolSocket read FListener write SetListener;  
property AcceptQueue:TSocketList read FAcceptQueue;  
property ReceiveQueue:TSocketList read FReceiveQueue;  
 
property SendData:TTCPSendBuffer read FSendData;  
property RecvData:TTCPRecvBuffer read FRecvData;  
 
function GetOption(ALevel,AOptName:Integer; AOptValue:PChar; var AOptLength:Integer):Integer; override;  
function SetOption(ALevel,AOptName:Integer; AOptValue:PChar; AOptLength:Integer):Integer; override;  
function IoCtl(ACommand:DWORD; var AArgument:u_long):Integer; override;  
 
function IsConnected(ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ABroadcast:Boolean):Boolean; override;  
function IsListening(ALocalAddress,ARemoteAddress:Pointer; ALocalPort,ARemotePort:Word; ABroadcast:Boolean):Boolean; override;  
 
function Listen:Boolean;  
function Connect:Boolean;  
function Reconnect:Boolean;  
function Disconnect:Boolean;  
 
function Accept(APeek,ALock:Boolean; AState:LongWord):TTCPSocket;  
 
function RecvSegment(ASequence,AAcknowledge:LongWord; AWindow,AUrgent:Word; AFlags:Byte; AData:Pointer; ASize:Word):Boolean;  
function SendSegment(var ASequence,AAcknowledge:LongWord; var AWindow,AUrgent:Word; var AFlags:Byte; var AData:Pointer; var ASize:Word):Boolean;  

TCP state

TTCPState = class(TProtocolState)

constructor Create;  
destructor Destroy; override;  
private
FState:LongWord;  
 
procedure SetState(AState:LongWord);  
 
function GetListening:Boolean;  
procedure SetListening(AValue:Boolean);  
function GetEstablished:Boolean;  
procedure SetEstablished(AValue:Boolean);  
function GetClosed:Boolean;  
procedure SetClosed(AValue:Boolean);  
 
function GetSynchronized:Boolean;  
public
property State:LongWord read FState write SetState;  
 
property Listening:Boolean read GetListening write SetListening;  
property Established:Boolean read GetEstablished write SetEstablished;  
property Closed:Boolean read GetClosed write SetClosed;  
 
property Synchronized:Boolean read GetSynchronized;  

TCP options

TTCPOptions = class(TProtocolOptions)

Note: For Get/Set Options Level = TCP_PROTO Option = TCP_NODELAY, TCP_MAXSEG etc
 
constructor Create;  
destructor Destroy; override;  
private
FMemory:TMemoryStream;  
FOptions:LongWord;  
 
FMaxSeg:Word; MSS Option in TCP Header (MSS we send to Remote)
FWindowScale:Byte; Window Scale Option in TCP Header (Window Scale we send to Remote)
 
procedure SetMaxSeg(AMaxSeg:Word);  
procedure SetWindowScale(AWindowScale:Byte);  
 
function GetOptions:Pointer;  
function GetNoDelay:Boolean;  
procedure SetNoDelay(ANoDelay:Boolean);  
function GetNoPush:Boolean;  
procedure SetNoPush(ANoPush:Boolean);  
function GetNoOpt:Boolean;  
procedure SetNoOpt(ANoOpt:Boolean);  
function GetBsdUrgent:Boolean;  
procedure SetBsdUrgent(ABsdUrgent:Boolean);  
function GetNoSack:Boolean;  
procedure SetNoSack(ANoSack:Boolean);  
public
property MaxSeg:Word read FMaxSeg write SetMaxSeg;  
property WindowScale:Byte read FWindowScale write SetWindowScale;  
 
property Options:Pointer read GetOptions;  
property NoDelay:Boolean read GetNoDelay write SetNoDelay; Determines if we Delay small segments until previous sends are ACKed
property NoPush:Boolean read GetNoPush write SetNoPush;  
property NoOpt:Boolean read GetNoOpt write SetNoOpt;  
property BsdUrgent:Boolean read GetBsdUrgent write SetBsdUrgent;  
property NoSack:Boolean read GetNoSack write SetNoSack; Determines if we send SACKOK to Remote

TCP send buffer

TTCPSendBuffer = class(TSocketBuffer)

constructor Create(ASocket:TTransportSocket);  
destructor Destroy; override;  
private
FFirst:PTCPSegment; Pointer to First Segment
FLast:PTCPSegment; Pointer to Last Segment
 
function AddSegment(ASequence:LongWord; AFlags:Byte; ASize:Word):PTCPSegment;  
function RemoveSegment(ASegment:PTCPSegment):Boolean;  
procedure FlushSegments(All:Boolean);  
protected
procedure SetSize(ASize:LongWord); override;  
public
StartSequence:LongWord; Initial Sequence number of Local (ISS)
NextSequence:LongWord; Next Sequence number to Send (SND.NXT
LastSequence:LongWord; Last Sequence number in Buffer
LastAcknowledge:LongWord; 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.

 
UrgentPointer:LongWord; (SND.UP)
 
MaxSeg:Word; Remote Max Segment Size (Learned from Remote)
 
WindowSize:LongWord; Remote Window Size (SND.WND)
WindowScale:Byte; Remote Window Scale
WindowTimeout:Int64; Timeout for probing small/zero Window
 
CongestionWindow:Word; Slow Start Window Size
 
SynSequence:LongWord; Sequence number of our SYN
FinSequence:LongWord; Sequence number of our FIN
 
WindowSequence:LongWord; Sequence number of last Window update (SND.WL1)
WindowAcknowledge:LongWord; Acknowledge number of last Window update (SND.WL2)
 
NoPush:Boolean; Disable Push on final segment
NoSack:Boolean; Selective Ack not in use
NoNagle:Boolean; Nagle not in use
 
VjSa:LongWord; VJ's alg, standard average
VjSd:LongWord; VJ's alg, standard deviation
VjLast:LongWord; VJ's alg, last transmit time
 
function CheckIdle:Boolean;  
 
function SynAcknowledged:Boolean;  
function FinAcknowledged:Boolean;  
 
function TestAcknowledge(AAcknowledge:LongWord):Boolean;  
function CheckAcknowledge(AAcknowledge:LongWord):Boolean;  
function ValidateAcknowledge(AAcknowledge:LongWord):Boolean;  
 
function WriteData(var ABuffer; ASize,AFlags:Integer):Boolean;  
 
function Finish:Boolean;  
function Synchronize:Boolean;  
 
function ReadSegment(var ASequence:LongWord; var AUrgent:Word; var AFlags:Byte; var AData:Pointer; var ASize:Word; AForce:Boolean):Boolean;  
function AcknowledgeSegments(ASequence,AAcknowledge:LongWord; AWindow:Word):Boolean;  
 
function TimestampSegment(AOptions:Pointer; var AOffset:Word):Boolean;  
function SelectiveAckSegments(AOptions:Pointer; var AOffset:Word; ASize:Byte):Boolean;  

TCP receive buffer

TTCPRecvBuffer = class(TSocketBuffer)

constructor Create(ASocket:TTransportSocket);  
destructor Destroy; override;  
private
FUrgent:LongWord; Number of OOB bytes readable from Buffer
FAvailable:LongWord; Number of bytes readable from Buffer
 
FFirst:PTCPSegment; Pointer to First Segment
FLast:PTCPSegment; Pointer to Last Segment
 
function DelayOverride(ASegment:PTCPSegment):Boolean;  
 
function GetSegment(ASequence:LongWord; ALength:Word):PTCPSegment;  
function GetPrevious(ASequence:LongWord; ALength:Word):PTCPSegment;  
function GetOverlapped(ASequence:LongWord; ALength:Word):PTCPSegment;  
 
function AddSegment(APrev:PTCPSegment; ASequence:LongWord; AFlags:Byte; ASize:Word):PTCPSegment;  
function RemoveSegment(ASegment:PTCPSegment):Boolean;  
procedure FlushSegments(All:Boolean);  
protected
procedure SetSize(ASize:LongWord); override;  
public
StartSequence:LongWord; Initial Sequence number of Remote (IRS)
NextSequence:LongWord; Next Sequence number to Receive (RCV.NXT)
LastSequence:LongWord; Last Sequence number in Buffer (Including Unacknowledged data)
LastAcknowledge:LongWord; 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.

 
UrgentPointer:LongWord; (RCV.UP)
 
MaxSeg:Word; Local Max Segment Size
 
WindowSize:LongWord; Local Window Size (RCV.WND)
WindowScale:Byte; Local Window Scale
LastWindow:LongWord; Last Window value sent to Remote
 
SynSequence:LongWord; Sequence number of remote SYN
FinSequence:LongWord; Sequence number of remote FIN
 
NoSack:Boolean; Selective Ack not in use
 
function CheckIdle:Boolean;  
 
function GetUrgent:LongWord;  
function GetAvailable:LongWord;  
 
function SynReceived:Boolean;  
function FinReceived:Boolean;  
 
function CheckSequence(ASequence:LongWord; ASize:Word):Boolean;  
 
function ReadData(var ABuffer; var ASize:Integer; AFlags:Integer):Boolean;  
 
function WriteSegment(ASequence:LongWord; AUrgent:Word; AFlags:Byte; AData:Pointer; ASize:Word):Boolean;  
function AcknowledgeSegments(var AAcknowledge:LongWord; var AWindow:Word; AForce:Boolean):Boolean;  
 
function TimestampSegment(AOptions:Pointer; var AOffset:Word):Boolean;  
function SelectiveAckSegments(AOptions:Pointer; var AOffset:Word):Boolean;  


Public variables


None defined

Function declarations



Initialization functions

procedure TCPInit;
Description: To be documented
Note None documented


TCP functions

function CheckTCP(AFamily:Word; ABuffer:Pointer):Boolean;
Description: Verify that the packet is a valid TCP packet
Buffer The complete packet including Transport header


function GetTCPHeaderOffset(AFamily:Word; ABuffer:Pointer):Word;
Description: To be documented
Buffer The complete packet including Transport header


function GetTCPHeaderLength(AFamily:Word; ABuffer:Pointer):Word;
Description: To be documented
Buffer The complete packet including Transport header


function GetTCPOptionsLength(AFamily:Word; ABuffer:Pointer):Word;
Description: To be documented
Buffer The complete packet including Transport header


function GetTCPDataOffset(AFamily:Word; ABuffer:Pointer):Word;
Description: To be documented
Buffer The complete packet including Transport header


function GetTCPDataLength(AFamily:Word; ABuffer:Pointer):Word;
Description: To be documented
Buffer The complete packet including Transport header


function ChecksumTCPRecv(AFamily:Word; APseudo:PIPPseudo; ABuffer:Pointer; AOffset,ALength:Word):Word;
Description: Validate the Checksum of TCP Pseudo, Header and Data on Receive
Note None documented


function ChecksumTCPSend(AFamily:Word; APseudo:PIPPseudo; AHeader:PTCPHeader; AOptions,AData:Pointer; AOptionsLength,ADataLength:Word):Word;
Description: Checksum the TCP Pseudo, Header, Options and Data on Send
Note None documented


Return to Unit Reference