diff options
Diffstat (limited to 'net/third_party/udt/src/packet.cpp')
-rw-r--r-- | net/third_party/udt/src/packet.cpp | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/net/third_party/udt/src/packet.cpp b/net/third_party/udt/src/packet.cpp new file mode 100644 index 0000000..79334b7 --- /dev/null +++ b/net/third_party/udt/src/packet.cpp @@ -0,0 +1,410 @@ +/***************************************************************************** +Copyright (c) 2001 - 2011, The Board of Trustees of the University of Illinois. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the + above copyright notice, this list of conditions + and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the University of Illinois + nor the names of its contributors may be used to + endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +/***************************************************************************** +written by + Yunhong Gu, last updated 02/12/2011 +*****************************************************************************/ + + +////////////////////////////////////////////////////////////////////////////// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Packet Header | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | | +// ~ Data / Control Information Field ~ +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |0| Sequence Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |ff |o| Message Number | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Time Stamp | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Destination Socket ID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// bit 0: +// 0: Data Packet +// 1: Control Packet +// bit ff: +// 11: solo message packet +// 10: first packet of a message +// 01: last packet of a message +// bit o: +// 0: in order delivery not required +// 1: in order delivery required +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |1| Type | Reserved | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Additional Info | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Time Stamp | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Destination Socket ID | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// bit 1-15: +// 0: Protocol Connection Handshake +// Add. Info: Undefined +// Control Info: Handshake information (see CHandShake) +// 1: Keep-alive +// Add. Info: Undefined +// Control Info: None +// 2: Acknowledgement (ACK) +// Add. Info: The ACK sequence number +// Control Info: The sequence number to which (but not include) all the previous packets have beed received +// Optional: RTT +// RTT Variance +// available receiver buffer size (in bytes) +// advertised flow window size (number of packets) +// estimated bandwidth (number of packets per second) +// 3: Negative Acknowledgement (NAK) +// Add. Info: Undefined +// Control Info: Loss list (see loss list coding below) +// 4: Congestion/Delay Warning +// Add. Info: Undefined +// Control Info: None +// 5: Shutdown +// Add. Info: Undefined +// Control Info: None +// 6: Acknowledgement of Acknowledement (ACK-square) +// Add. Info: The ACK sequence number +// Control Info: None +// 7: Message Drop Request +// Add. Info: Message ID +// Control Info: first sequence number of the message +// last seqeunce number of the message +// 8: Error Signal from the Peer Side +// Add. Info: Error code +// Control Info: None +// 0x7FFF: Explained by bits 16 - 31 +// +// bit 16 - 31: +// This space is used for future expansion or user defined control packets. +// +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |1| Sequence Number a (first) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |0| Sequence Number b (last) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// |0| Sequence Number (single) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// Loss List Field Coding: +// For any consectutive lost seqeunce numbers that the differnece between +// the last and first is more than 1, only record the first (a) and the +// the last (b) sequence numbers in the loss list field, and modify the +// the first bit of a to 1. +// For any single loss or consectutive loss less than 2 packets, use +// the original sequence numbers in the field. + + +#include <cstring> +#include "packet.h" + + +const int CPacket::m_iPktHdrSize = 16; +const int CHandShake::m_iContentSize = 48; + + +// Set up the aliases in the constructure +CPacket::CPacket(): +m_iSeqNo((int32_t&)(m_nHeader[0])), +m_iMsgNo((int32_t&)(m_nHeader[1])), +m_iTimeStamp((int32_t&)(m_nHeader[2])), +m_iID((int32_t&)(m_nHeader[3])), +m_pcData((char*&)(m_PacketVector[1].iov_base)), +__pad() +{ + for (int i = 0; i < 4; ++ i) + m_nHeader[i] = 0; + m_PacketVector[0].iov_base = (char *)m_nHeader; + m_PacketVector[0].iov_len = CPacket::m_iPktHdrSize; + m_PacketVector[1].iov_base = NULL; + m_PacketVector[1].iov_len = 0; +} + +CPacket::~CPacket() +{ +} + +int CPacket::getLength() const +{ + return m_PacketVector[1].iov_len; +} + +void CPacket::setLength(const int& len) +{ + m_PacketVector[1].iov_len = len; +} + +void CPacket::pack(const int& pkttype, void* lparam, void* rparam, const int& size) +{ + // Set (bit-0 = 1) and (bit-1~15 = type) + m_nHeader[0] = 0x80000000 | (pkttype << 16); + + // Set additional information and control information field + switch (pkttype) + { + case 2: //0010 - Acknowledgement (ACK) + // ACK packet seq. no. + if (NULL != lparam) + m_nHeader[1] = *(int32_t *)lparam; + + // data ACK seq. no. + // optional: RTT (microsends), RTT variance (microseconds) advertised flow window size (packets), and estimated link capacity (packets per second) + m_PacketVector[1].iov_base = (char *)rparam; + m_PacketVector[1].iov_len = size; + + break; + + case 6: //0110 - Acknowledgement of Acknowledgement (ACK-2) + // ACK packet seq. no. + m_nHeader[1] = *(int32_t *)lparam; + + // control info field should be none + // but "writev" does not allow this + m_PacketVector[1].iov_base = (char *)&__pad; //NULL; + m_PacketVector[1].iov_len = 4; //0; + + break; + + case 3: //0011 - Loss Report (NAK) + // loss list + m_PacketVector[1].iov_base = (char *)rparam; + m_PacketVector[1].iov_len = size; + + break; + + case 4: //0100 - Congestion Warning + // control info field should be none + // but "writev" does not allow this + m_PacketVector[1].iov_base = (char *)&__pad; //NULL; + m_PacketVector[1].iov_len = 4; //0; + + break; + + case 1: //0001 - Keep-alive + // control info field should be none + // but "writev" does not allow this + m_PacketVector[1].iov_base = (char *)&__pad; //NULL; + m_PacketVector[1].iov_len = 4; //0; + + break; + + case 0: //0000 - Handshake + // control info filed is handshake info + m_PacketVector[1].iov_base = (char *)rparam; + m_PacketVector[1].iov_len = size; //sizeof(CHandShake); + + break; + + case 5: //0101 - Shutdown + // control info field should be none + // but "writev" does not allow this + m_PacketVector[1].iov_base = (char *)&__pad; //NULL; + m_PacketVector[1].iov_len = 4; //0; + + break; + + case 7: //0111 - Message Drop Request + // msg id + m_nHeader[1] = *(int32_t *)lparam; + + //first seq no, last seq no + m_PacketVector[1].iov_base = (char *)rparam; + m_PacketVector[1].iov_len = size; + + break; + + case 8: //1000 - Error Signal from the Peer Side + // Error type + m_nHeader[1] = *(int32_t *)lparam; + + // control info field should be none + // but "writev" does not allow this + m_PacketVector[1].iov_base = (char *)&__pad; //NULL; + m_PacketVector[1].iov_len = 4; //0; + + break; + + case 32767: //0x7FFF - Reserved for user defined control packets + // for extended control packet + // "lparam" contains the extended type information for bit 16 - 31 + // "rparam" is the control information + m_nHeader[0] |= *(int32_t *)lparam; + + if (NULL != rparam) + { + m_PacketVector[1].iov_base = (char *)rparam; + m_PacketVector[1].iov_len = size; + } + else + { + m_PacketVector[1].iov_base = (char *)&__pad; + m_PacketVector[1].iov_len = 4; + } + + break; + + default: + break; + } +} + +iovec* CPacket::getPacketVector() +{ + return m_PacketVector; +} + +int CPacket::getFlag() const +{ + // read bit 0 + return m_nHeader[0] >> 31; +} + +int CPacket::getType() const +{ + // read bit 1~15 + return (m_nHeader[0] >> 16) & 0x00007FFF; +} + +int CPacket::getExtendedType() const +{ + // read bit 16~31 + return m_nHeader[0] & 0x0000FFFF; +} + +int32_t CPacket::getAckSeqNo() const +{ + // read additional information field + return m_nHeader[1]; +} + +int CPacket::getMsgBoundary() const +{ + // read [1] bit 0~1 + return m_nHeader[1] >> 30; +} + +bool CPacket::getMsgOrderFlag() const +{ + // read [1] bit 2 + return (1 == ((m_nHeader[1] >> 29) & 1)); +} + +int32_t CPacket::getMsgSeq() const +{ + // read [1] bit 3~31 + return m_nHeader[1] & 0x1FFFFFFF; +} + +CPacket* CPacket::clone() const +{ + CPacket* pkt = new CPacket; + memcpy(pkt->m_nHeader, m_nHeader, m_iPktHdrSize); + pkt->m_pcData = new char[m_PacketVector[1].iov_len]; + memcpy(pkt->m_pcData, m_pcData, m_PacketVector[1].iov_len); + pkt->m_PacketVector[1].iov_len = m_PacketVector[1].iov_len; + + return pkt; +} + +CHandShake::CHandShake(): +m_iVersion(0), +m_iType(0), +m_iISN(0), +m_iMSS(0), +m_iFlightFlagSize(0), +m_iReqType(0), +m_iID(0), +m_iCookie(0), +m_piPeerIP() +{ +} + +int CHandShake::serialize(char* buf, int& size) +{ + if (size < m_iContentSize) + return -1; + + int32_t* p = (int32_t*)buf; + *p++ = m_iVersion; + *p++ = m_iType; + *p++ = m_iISN; + *p++ = m_iMSS; + *p++ = m_iFlightFlagSize; + *p++ = m_iReqType; + *p++ = m_iID; + *p++ = m_iCookie; + for (int i = 0; i < 4; ++ i) + *p++ = m_piPeerIP[i]; + + size = m_iContentSize; + + return 0; +} + +int CHandShake::deserialize(const char* buf, const int& size) +{ + if (size < m_iContentSize) + return -1; + + int32_t* p = (int32_t*)buf; + m_iVersion = *p++; + m_iType = *p++; + m_iISN = *p++; + m_iMSS = *p++; + m_iFlightFlagSize = *p++; + m_iReqType = *p++; + m_iID = *p++; + m_iCookie = *p++; + for (int i = 0; i < 4; ++ i) + m_piPeerIP[i] = *p++; + + return 0; +} |