You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
9.7 KiB
236 lines
9.7 KiB
/*===
|
|
Direct Network Protocl -- Frame format header file
|
|
|
|
|
|
Evan Schrier 10/98
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
Direct Network Protocol
|
|
|
|
| MEDIA HEADER | Var Len DN Header | Client Data |
|
|
|
|
There are two types of packets that may be exchanged between Direct Network
|
|
endpoints:
|
|
|
|
Data Packets (D Frame) User data transmission
|
|
Control Packets (C Frame) Internal link-state packets with no user data
|
|
|
|
|
|
|
|
*/
|
|
|
|
/*
|
|
COMMAND FIELD
|
|
|
|
The command field is the first byte of all frames. The first BIT of the command frame is always
|
|
the COMMAND FRAME vs DATA FRAME opcode. The seven high bits of the Command field are flags. We have
|
|
a requirement that the command field of all protocol packets must never be all zeros. Therefore, when
|
|
the opcode bit is zero (COMMAND FRAME) we must be sure that one flag bit is always set. The highest flag bit,
|
|
the USER2 flag is not relevant to COMMAND frames so we will always set the most significant bit when the opcode
|
|
bit is zero.
|
|
|
|
The seven command field flag bits are defined as follows:
|
|
|
|
RELIABLE - Data delivery of this frame is guarenteed
|
|
SEQUENTIAL - Data in this frame must be delivered in the order it was sent, with respect to other SEQ frames
|
|
POLL - Protocol requests an immediate acknowledgement to this frame
|
|
NEW MESSAGE - This frame is the first or only frame in a message
|
|
END MESSAGE - This frame is the last or only frame in a message
|
|
USER1 - First flag controlled by the higher layer (direct play core)
|
|
USER2 - Second flag controlled by core. These flags are specified in the send API and are delivered with the data
|
|
|
|
|
|
DATA FRAMES
|
|
|
|
Data frames are between 4 and 20 bytes in length. They should typically be only 4 bytes. Following the
|
|
Command byte in all data frames in the Control byte. This byte contains a 3-bit retry counter and 5 additional
|
|
flags. The Control byte flags are defined as follows:
|
|
|
|
END OF STREAM - This frame is the last data frame the transmitting partner will send.
|
|
SACK_MASK_ONE - The low 32-bit Selective Acknowledgment mask is present in this header
|
|
SACK_MASK_TWO - The high 32-bit Selective Acknowledgment mask is present in this header
|
|
SEND_MASK_ONE - The low 32-bit Cancel Send mask is present in this header
|
|
SEND_MASK_TWO - The high 32-bit Cancel Send mask is present in this header
|
|
|
|
After Control byte come two one byte values: Sequence number for this frame, and Next Receive sequence number
|
|
expected by this partner. After these two bytes comes zero through four bitmasks as specified by the control flags.
|
|
After the bitmasks, the rest of the frame is user data to be delivered to the direct play core.
|
|
*/
|
|
#ifndef _DNET_FRAMES_
|
|
#define _DNET_FRAMES_
|
|
|
|
/*
|
|
Command FRAME Extended Opcodes
|
|
|
|
A CFrame without an opcode is a vehicle for non-piggybacked acknowledgement
|
|
information. The following sub-commands are defined at this time:
|
|
|
|
SACK - Only Ack/Nack info present
|
|
CONNECT - Initialize a reliable connection
|
|
CONNECTED - Response to CONNECT request, or CONNECTED depending on which side of the handshake
|
|
*/
|
|
|
|
#define FRAME_EXOPCODE_CONNECT 1
|
|
#define FRAME_EXOPCODE_CONNECTED 2
|
|
#define FRAME_EXOPCODE_CONNECTED_SIGNED 3
|
|
#define FRAME_EXOPCODE_HARD_DISCONNECT 4
|
|
#define FRAME_EXOPCODE_SACK 6
|
|
|
|
// These structures are used to decode network data and so need to be packed
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
typedef UNALIGNED struct dataframe DFRAME, *PDFRAME;
|
|
typedef UNALIGNED struct cframe CFRAME, *PCFRAME;
|
|
typedef UNALIGNED struct sackframe8 SACKFRAME8, *PSACKFRAME8;
|
|
typedef UNALIGNED struct cframe_connectedsigned CFRAME_CONNECTEDSIGNED, * PCFRAME_CONNECTEDSIGNED;
|
|
|
|
#ifndef DPNBUILD_NOMULTICAST
|
|
typedef UNALIGNED struct multicastframe MCASTFRAME, *PMCASTFRAME;
|
|
#endif // !DPNBUILD_NOMULTICAST
|
|
|
|
typedef UNALIGNED struct coalesceheader COALESCEHEADER, *PCOALESCEHEADER;
|
|
|
|
// Packet Header is common to all frame formats
|
|
|
|
#define PACKET_COMMAND_DATA 0x01 // Frame contains user data
|
|
#define PACKET_COMMAND_END_COALESCE 0x01 // This is the last coalesced subframe
|
|
#define PACKET_COMMAND_RELIABLE 0x02 // Frame should be delivered reliably
|
|
#define PACKET_COMMAND_SEQUENTIAL 0x04 // Frame should be indicated sequentially
|
|
#define PACKET_COMMAND_POLL 0x08 // Partner should acknowlege immediately
|
|
#define PACKET_COMMAND_COALESCE_BIG_1 0x08 // This coalesced subframe is over 255 bytes
|
|
#define PACKET_COMMAND_NEW_MSG 0x10 // Data frame is first in message
|
|
#define PACKET_COMMAND_COALESCE_BIG_2 0x10 // This coalesced subframe is over 511 bytes
|
|
#define PACKET_COMMAND_END_MSG 0x20 // Data frame is last in message
|
|
#define PACKET_COMMAND_COALESCE_BIG_3 0x20 // This coalesced subframe is over 1023 bytes
|
|
#define PACKET_COMMAND_USER_1 0x40 // First user controlled flag
|
|
#define PACKET_COMMAND_USER_2 0x80 // Second user controlled flag
|
|
#define PACKET_COMMAND_CFRAME 0x80 // Set high-bit on command frames because first byte must never be zero
|
|
|
|
#define PACKET_CONTROL_RETRY 0x01 // This flag designates this frame as a retry of a previously xmitted frame
|
|
#define PACKET_CONTROL_KEEPALIVE 0x02 // Designates this frame as a keep alive frame for dx9 and onwards
|
|
#define PACKET_CONTROL_CORRELATE 0x02 // For pre-dx9 this bit in a frame meant 'please send an immediate ack'
|
|
#define PACKET_CONTROL_COALESCE 0x04 // This packet contains multiple coalesced packets
|
|
#define PACKET_CONTROL_END_STREAM 0x08 // This packet serves as Disconnect frame.
|
|
#define PACKET_CONTROL_SACK_MASK1 0x10 // The low 32-bit SACK mask is included in this frame.
|
|
#define PACKET_CONTROL_SACK_MASK2 0x20 // The high 32 bit SACK mask is present
|
|
#define PACKET_CONTROL_SEND_MASK1 0x40 // The low 32-bit SEND mask is included in this frame
|
|
#define PACKET_CONTROL_SEND_MASK2 0x80 // The high 32-bit SEND mask is included in this frame
|
|
|
|
#define PACKET_CONTROL_VARIABLE_MASKS 0xF0 // All four mask bits above
|
|
|
|
// Options for signing in connected signed frames (cframe_connectedsigned::dwSigningOpts)
|
|
|
|
#define PACKET_SIGNING_FAST 0x00000001 //packets over link should be fast signed
|
|
#define PACKET_SIGNING_FULL 0x00000002 //packets over link should be full signed
|
|
|
|
|
|
/* NEW DATA FRAMES
|
|
**
|
|
** Here in the new unified world we have only two frame types! CommandFrames and DataFrames...
|
|
**
|
|
*/
|
|
|
|
struct dataframe
|
|
{
|
|
BYTE bCommand;
|
|
BYTE bControl;
|
|
BYTE bSeq;
|
|
BYTE bNRcv;
|
|
};
|
|
|
|
|
|
/*
|
|
** COMMAND FRAMES
|
|
**
|
|
** Command frames are everything that is not part of the reliable stream. This is most of the control traffic
|
|
** although some control traffic is part of the stream (keep-alive, End-of-Stream)
|
|
*/
|
|
|
|
struct cframe
|
|
{
|
|
BYTE bCommand;
|
|
BYTE bExtOpcode; // CFrame sub-command
|
|
BYTE bMsgID; // Correlator in case ExtOpcode requires a response
|
|
BYTE bRspID; // Correlator in case this is a response
|
|
// For Hard Disconnects this is set to the seq # of the next dataframe that would be sent
|
|
DWORD dwVersion; // Protocol version #
|
|
DWORD dwSessID; // Session identifier
|
|
DWORD tTimestamp; // local tick count
|
|
};
|
|
|
|
struct cframe_connectedsigned
|
|
{
|
|
//first set of members match cframe exactly
|
|
BYTE bCommand;
|
|
BYTE bExtOpcode; // CFrame sub-command. Always FRAME_EXOPCODE_CONNECTED_SIGNED
|
|
BYTE bMsgID; // Correlator in case ExtOpcode requires a response
|
|
BYTE bRspID; // Correlator in case this is a response
|
|
DWORD dwVersion; // Protocol version #
|
|
DWORD dwSessID; // Session identifier
|
|
DWORD tTimestamp; // local tick count
|
|
|
|
//additional members for cframe_signedconnected
|
|
ULONGLONG ullConnectSig; // used to verify the connect sequence
|
|
ULONGLONG ullSenderSecret; // secret used to sign packets by the sender of this frame
|
|
ULONGLONG ullReceiverSecret; // secret that should be used to sign packets by the receiver of this frame
|
|
DWORD dwSigningOpts; // used to signal the signing settings
|
|
DWORD dwEchoTimestamp; // contains the original timestamp from the connect or connectsigned that
|
|
// provoked this frame as a reply. Allows the receiver to calculate the RTT
|
|
};
|
|
|
|
/*
|
|
** Selective Acknowledgement packet format
|
|
**
|
|
** When a specific acknowledgement frame is sent there may be two additional pieces
|
|
** of data included with the frame. One is a bitmask allowing selective acknowledgment
|
|
** of non-sequential frames. The other is timing information about the last frame acked
|
|
** by this ACK (NRcv - 1). Specifically, it includes the lowest Retry number that this
|
|
** node received, and the ms delay between that packets arrival and the sending of this
|
|
** Ack.
|
|
*/
|
|
|
|
|
|
#define SACK_FLAGS_RESPONSE 0x01 // indicates that Retry and Timestamp fields are valid
|
|
#define SACK_FLAGS_SACK_MASK1 0x02
|
|
#define SACK_FLAGS_SACK_MASK2 0x04
|
|
#define SACK_FLAGS_SEND_MASK1 0x08
|
|
#define SACK_FLAGS_SEND_MASK2 0x10
|
|
|
|
// First format is used when DATAGRAM_INFO flag is clear
|
|
|
|
struct sackframe8
|
|
{
|
|
BYTE bCommand; // As above
|
|
BYTE bExtOpcode; // As above
|
|
BYTE bFlags; // Additional flags for sack frame
|
|
BYTE bRetry;
|
|
BYTE bNSeq; // Since this frame has no sequence number, this is the next Seq we will send
|
|
BYTE bNRcv; // As above
|
|
BYTE bReserved1; // We shipped DX8 with bad packing, so these were actually there
|
|
BYTE bReserved2; // We shipped DX8 with bad packing, so these were actually there
|
|
DWORD tTimestamp; // Local timestamp when packet (NRcv - 1) arrived
|
|
};
|
|
|
|
|
|
#ifndef DPNBUILD_NOMULTICAST
|
|
struct multicastframe
|
|
{
|
|
DWORD dwVersion; // Protocol version #
|
|
DWORD dwSessID; // Session identifier
|
|
};
|
|
#endif // !DPNBUILD_NOMULTICAST
|
|
|
|
struct coalesceheader
|
|
{
|
|
BYTE bSize; // The 8 least significant bits of the size of the data for this coalesced message
|
|
BYTE bCommand; // PACKET_COMMAND_XXX values
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
#endif // _DNET_FRAMES_
|