Documentation for TCP header.
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 18 Feb 2012 14:21:18 +0000 (12:21 -0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sat, 18 Feb 2012 14:22:36 +0000 (12:22 -0200)
src/tcp/tcpheader.cpp
src/tcp/tcpheader.h

index 5f743ad..df56c7f 100644 (file)
@@ -40,90 +40,246 @@ using boost::asio::ip::address_v6;
 
 static const size_t TcpHeaderSizeInBytes = 20;
 
+/**
+ * @brief Create a TCP header object.
+ */
 TcpHeader::TcpHeader() :
     Payload( TcpHeaderSizeInBytes )
 {
 }
 
+/**
+ * @brief Identify the segment's sending end point.
+ *
+ * @return The source TCP port.
+ */
 uint16_t TcpHeader::get_source_port() const
 {
     return Payload.decode16( 0, 1 );
 }
 
+/**
+ * @brief Identify the segment's receiving end point.
+ *
+ * @return The destination TCP port.
+ */
 uint16_t TcpHeader::get_destination_port() const
 {
     return Payload.decode16( 2, 3 );
 }
 
+/**
+ * @brief Identify the amount of bytes sent by one end point.
+ *
+ * @details If the SYN flag is set, then this is the initial sequence number.
+ * The sequence number of the actual first data byte and the acknowledged number
+ * in the corresponding ACK are then this sequence number plus 1.
+ * If the SYN flag is clear, then this is the accumulated sequence number of
+ * the first data byte of this segment for the current session.
+ *
+ * @return The sequence number.
+ */
 uint32_t TcpHeader::get_sequence_number() const
 {
     return Payload.decode32( 4, 7 );
 }
 
+/**
+ * @brief Identify the amount of bytes received by one end point.
+ *
+ * @details If the ACK flag is set then the value of this field is the next
+ * sequence number that the receiver is expecting. This acknowledges receipt of
+ * all prior bytes (if any). The first ACK sent by each end acknowledges the
+ * other end's initial sequence number itself, but no data.
+ *
+ * @return The acknowledgment number.
+ */
 uint32_t TcpHeader::get_acknowledgment_number() const
 {
     return Payload.decode32( 8, 11 );
 }
 
+/**
+ * @brief The TCP header length (a.k.a data offset) tells how many 32-bit words
+ * are contained in the TCP header (e.g. 5 words is equivalent to 20 bytes).
+ *
+ * @details The minimum size header is 5 words and the maximum is 15 words thus
+ * giving the minimum size of 20 bytes and maximum of 60 bytes, allowing for up
+ * to 40 bytes of options in the header.
+ *
+ * @return The header length in 32-bit words.
+ */
 uint8_t TcpHeader::get_header_length() const
 {
     return ( Payload[12] & 0xF0 ) >> 4;
 }
 
+/**
+ * @brief The CWR flag is used to signal congestion when Explicit Congestion
+ * Notification is used, as specified in RFC 3168.
+ *
+ * @details CWR is set by the TCP sender to signal Congestion Window Reduced to
+ * the TCP receiver so that it knows the sender has slowed down and can stop
+ * sending the ECN-Echo.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_congestion_window_reduced() const
 {
     return ( Payload[13] & 0x80 );
 }
 
+/**
+ * @brief The ECE flag is used to signal congestion when Explicit Congestion
+ * Notification is used, as specified in RFC 3168.
+ *
+ * @details If the SYN flag is clear, ECE is set by the TCP receiver to signal
+ * an ECN-Echo to the TCP sender to tell it to slow down when the TCP receiver
+ * gets a congestion indication from the network.
+ * If the SYN flag is set, that the TCP peer is ECN capable.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_ecn_echo() const
 {
     return ( Payload[13] & 0x40 );
 }
 
+/**
+ * @brief URG is set to 1 if the Urgent Pointer is in use.
+ *
+ * @details The Urgent Pointer is used to indicate a byte offset from the
+ * current sequence number at which urgent data are to be found. This facility
+ * is in lieu of interrupt messages.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_urgent() const
 {
     return ( Payload[13] & 0x20 );
 }
 
+/**
+ * @brief ACK bit is set to 1 to indicate that the Acknowledgment Number is
+ * valid.
+ *
+ * @details All packets after the initial SYN packet sent by the client should
+ * have this flag set.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_acknowledgment() const
 {
     return ( Payload[13] & 0x10 );
 }
 
+/**
+ * @brief PSH bit indicates pushed data.
+ *
+ * @details The receiver is hereby kindly requested to deliver the data to the
+ * application upon arrival and not to buffer it until a full buffer has been
+ * received.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_push() const
 {
     return ( Payload[13] & 0x08 );
 }
 
+/**
+ * @brief RST bit is used to abruptly reset a connection that has become
+ * confused due to a host crash or some other reason. RST is also used to reject
+ * an invalid segment or refuse an attempt to open a connection.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_reset() const
 {
     return ( Payload[13] & 0x04 );
 }
 
+/**
+ * @brief SYN bit is used to establish connections.
+ *
+ * @details Only the first segment sent from each end point should have this
+ * flag set. The connection request has SYN=1 and ACK=0 to indicate that the
+ * piggyback acknowledgment field is not in use. The connection reply does bear
+ * an acknowledgment, however, so it has SYN=1 and ACK=1. In essence, the SYN
+ * bit is used to denote both CONNECTION REQUEST and CONNECTION ACCEPTED, with
+ * the ACK bit used to distinguish between those two possibilities.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_synchronize() const
 {
     return ( Payload[13] & 0x02 );
 }
 
+/**
+ * @brief FIN bit is used to release a connection.
+ *
+ * @details It specifies that the sender has no more data to transmit. However,
+ * after closing a connection, the closing end point may continue receive data
+ * indefinitely. Both SYN and FIN segments have sequence numbers and are thus
+ * guaranteed to be processed in the correct order.
+ *
+ * @return @c true if the flag is on, or @c false otherwise.
+ */
 bool TcpHeader::get_finish() const
 {
     return ( Payload[13] & 0x01 );
 }
 
+/**
+ * @brief The Window Size field tells how many bytes may be sent starting at the
+ * byte acknowledged.
+ *
+ * @details Flow control in TCP is handled using a variable-sized sliding
+ * window. A window size of 0 says that the bytes up to and including the
+ * acknowledgment number - 1 have been received, but that the receiver has not
+ * had a chance to consume the data and would like no more data for the moment.
+ * The receiver can later grant permission to send by transmitting a segment
+ * with the same acknowledgment number and a nonzero window size.
+ *
+ * @return The amount of bytes the receiver is willing to receive.
+ */
 uint16_t TcpHeader::get_window_size() const
 {
     return Payload.decode16( 14, 15 );
 }
 
+/**
+ * @brief The 16-bit checksum is used for error-checking of the header and data
+ *
+ * @return A 16-bit checksum.
+ */
 uint16_t TcpHeader::get_checksum() const
 {
     return Payload.decode16( 16, 17 );
 }
 
+/**
+ * @brief Calculate the TCP checksum for IPv4 addresses, as defined in RFC 793.
+ *
+ * @details The checksum field is the 16 bit one's complement of the one's
+ * complement sum of all 16 bit words in the header and text.  If a segment
+ * contains an odd number of header and text octets to be checksummed, the last
+ * octet is padded on the right with zeros to form a 16 bit word for checksum
+ * purposes.  The pad is not transmitted as part of the segment.  While
+ * computing the checksum, the checksum field itself is replaced with zeros.
+ *
+ * @param src_addr The 32-bits compromising the source IPv4 address.
+ * @param dest_addr The 32-bits compromising the destination IPv4 address.
+ * @param tcp_payload_data The payload data (not the header).
+ * @param tcp_payload_size_in_bytes The amount of bytes present in the payload.
+ *
+ * @return The one's complement checksum of the TCP header and the given payload.
+ */
 uint16_t TcpHeader::calculate_tcp_checksum(
         const address_v4::bytes_type &src_addr,
         const address_v4::bytes_type &dest_addr,
-        const uint8_t* tcp_payload_data,
+        const uint8_t *tcp_payload_data,
         const uint16_t tcp_payload_size_in_bytes )
 {
     set_checksum( 0 );
@@ -168,10 +324,25 @@ uint16_t TcpHeader::calculate_tcp_checksum(
     return cksum;
 }
 
+/**
+ * @brief Calculate the TCP checksum for IPv6 addresses, as defined in RFC 2460.
+ *
+ * @details Any transport or other upper-layer protocol that includes the
+ * addresses from the IP header in its checksum computation must be modified
+ * for use over IPv6, to include the 128-bit IPv6 addresses instead of 32-bit
+ * IPv4 addresses.
+ *
+ * @param src_addr The 128-bits compromising the source IPv6 address.
+ * @param dest_addr The 128-bits compromising the destination IPv6 address.
+ * @param tcp_payload_data The payload data (not the header).
+ * @param tcp_payload_size_in_bytes The amount of bytes present in the payload.
+ *
+ * @return The one's complement checksum of the TCP header and the given payload.
+ */
 uint16_t TcpHeader::calculate_tcp_checksum(
         const address_v6::bytes_type &src_addr,
         const address_v6::bytes_type &dest_addr,
-        const uint8_t* tcp_payload_data,
+        const uint8_t *tcp_payload_data,
         const uint16_t tcp_payload_size_in_bytes )
 {
     set_checksum( 0 );
@@ -215,26 +386,51 @@ uint16_t TcpHeader::calculate_tcp_checksum(
     return cksum;
 }
 
+/**
+ * @see get_source_port
+ *
+ * @param port The source TCP port.
+ */
 void TcpHeader::set_source_port( const uint16_t port )
 {
     Payload.encode16( 0, 1, port );
 }
 
+/**
+ * @see get_destination_port
+ *
+ * @param port The destination TCP port.
+ */
 void TcpHeader::set_destination_port( const uint16_t port )
 {
     Payload.encode16( 2, 3, port );
 }
 
+/**
+ * @see get_sequence_number
+ *
+ * @param seq_num The sequence number.
+ */
 void TcpHeader::set_sequence_number( const uint32_t seq_num )
 {
     Payload.encode32( 4, 7, seq_num );
 }
 
+/**
+ * @see get_acknowledgment_number
+ *
+ * @param ack_num The acknowledgment number.
+ */
 void TcpHeader::set_acknowledgment_number( const uint32_t ack_num )
 {
     Payload.encode32( 8, 11, ack_num );
 }
 
+/**
+ * @see get_header_length
+ *
+ * @param offset The header length in 32-bit words.
+ */
 void TcpHeader::set_header_length( const uint8_t offset )
 {
     uint8_t high_nimble = static_cast<uint8_t>( ( offset << 4 ) & 0xF0 );
@@ -242,59 +438,109 @@ void TcpHeader::set_header_length( const uint8_t offset )
     Payload[12] = high_nimble | lower_nimble;
 }
 
+/**
+ * @see get_congestion_window_reduced
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_congestion_window_reduced( bool bit )
 {
     uint8_t bit_mask = bit ? 0x80 : 0x00;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_ecn_echo
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_ecn_echo( bool bit )
 {
     uint8_t bit_mask = bit ? 0x40 : 0x00 ;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_urgent
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_urgent( bool bit )
 {
     uint8_t bit_mask = bit ? 0x20 : 0x00 ;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_acknowledgment
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_acknowledgment( bool bit )
 {
     uint8_t bit_mask = bit ? 0x10 : 0x00 ;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_push
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_push( bool bit )
 {
     uint8_t bit_mask = bit ? 0x08 : 0x00 ;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_reset
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_reset( bool bit )
 {
     uint8_t bit_mask = bit ? 0x04 : 0x00 ;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_synchronize
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_synchronize( bool bit )
 {
     uint8_t bit_mask = bit ? 0x02 : 0x00 ;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_finish
+ *
+ * @param bit @c true if the flag is on, or @c false otherwise.
+ */
 void TcpHeader::set_finish( bool bit )
 {
     uint8_t bit_mask = bit ? 0x01 : 0x00 ;
     Payload[13] = Payload[13] | bit_mask;
 }
 
+/**
+ * @see get_window_size
+ *
+ * @param wnd_size The amount of bytes this end point is willing to receive.
+ */
 void TcpHeader::set_window_size( const uint16_t wnd_size )
 {
     Payload.encode16( 14, 15, wnd_size );
 }
 
+/**
+ * @see get_checksum
+ *
+ * @param sum The 16-bit checksum of header and data.
+ */
 void TcpHeader::set_checksum( const uint16_t sum )
 {
     Payload.encode16( 16, 17, sum );
index 33cd52d..3f985b2 100644 (file)
@@ -53,9 +53,9 @@ on this file might be covered by the GNU General Public License.
  * |              acknowledgment number (if ACK set)              |   20 bytes
  * |                                                              |       |
  * +-------+-------+-+-+-+-+-+-+-+-+------------------------------+       |
- * | data  | reser-|C|E|U|A|P|R|S|F|                              |       |
- * |offset | ved   |W|C|R|C|S|S|Y|I|        window size           |       |
- * |       |       |R|E|G|K|H|T|N|N|                              |       |
+ * |  TCP  | reser-|C|E|U|A|P|R|S|F|                              |       |
+ * | header| ved   |W|C|R|C|S|S|Y|I|        window size           |       |
+ * |length |       |R|E|G|K|H|T|N|N|                              |       |
  * +---------------+-+-+-+-+-+-+-+-+------------------------------+       |
  * |                               |                              |       |
  * |          checksum             | urgent pointer (if URG set)  |       |