Delegating the segment creation and printing to more specialized classes
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sun, 6 Nov 2011 21:58:40 +0000 (19:58 -0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sun, 6 Nov 2011 21:58:40 +0000 (19:58 -0200)
src/tcp/tcppinger.cpp
src/tcp/tcppinger.h

index e055890..73a453c 100644 (file)
@@ -38,6 +38,9 @@ on this file might be covered by the GNU General Public License.
 
 #include <logfunc.hpp>
 
+#include "ip/ipversion.h"
+#include "tcp/tcpsegmentfactory.h"
+
 using namespace std;
 using boost::asio::const_buffers_1;
 using boost::asio::io_service;
@@ -164,53 +167,23 @@ void TcpPinger::start_send()
     ++SequenceNumber;
 
     // Create an TCP header for an ACK request.
-    uint16_t source_port = get_source_address();
-    uint16_t destination_port = get_destination_port();
-    TcpHeader tcp_header = create_ack_request(
-            source_port,
-            destination_port,
-            ++SequenceNumber
-    );
-
     uint32_t source_address = get_source_address();
     uint32_t destination_address = get_destination_address();
+    uint16_t source_port = get_source_port();
+    uint16_t destination_port = get_destination_port();
+    TcpSegmentItem tcp_segment = TcpSegmentFactory::create_tcp_segment_ack_request(
+            IP_VERSION_4, source_address, destination_address,
+            source_port, destination_port, SequenceNumber );
 
-    uint16_t cksum = tcp_header.calculate_tcp_checksum(
-            source_address, destination_address, NULL, 0
-    );
-    tcp_header.set_checksum( cksum );
-
-    send_ack_request( tcp_header );
-}
-
-TcpHeader TcpPinger::create_ack_request(
-        const uint16_t source_port,
-        const uint16_t destination_port,
-        const uint16_t sequence_number
-) const
-{
-    // (5 words of 32 bits = 5 * 4 bytes = 20 bytes)
-    const uint8_t header_size_in_words = 5; // size in units of 32 bits
-    const uint16_t window_size_in_octets = 32768;
-
-    // Create an TCP header for an ACK request.
-    TcpHeader tcp_header;
-    tcp_header.set_source_port( source_port ); // assign a random ephemeral port number
-    tcp_header.set_destination_port( destination_port );
-    tcp_header.set_sequence_number( sequence_number );
-    tcp_header.set_header_length( header_size_in_words );
-    tcp_header.set_acknowledgment( true );
-    tcp_header.set_window_size( window_size_in_octets ); // window size
-
-    return tcp_header;
+    send_ack_request( tcp_segment );
 }
 
-void TcpPinger::send_ack_request( const TcpHeader &tcp_header )
+void TcpPinger::send_ack_request( const TcpSegmentItem tcp_segment )
 {
     // Encode the request packet.
     boost::asio::streambuf request_buffer;
     ostream os( &request_buffer );
-    os << tcp_header;
+    tcp_segment->write( os );
 
     TimeSent = microsec_clock::universal_time();
 
@@ -299,18 +272,16 @@ void TcpPinger::handle_receive_tcp_segment( const size_t &bytes_transferred )
             return;
         }
 
-        Ipv4Header ipv4_header;
-        TcpHeader tcp_header;
-        is >> ipv4_header >> tcp_header;
+        // Decode the reply segment.
+        TcpSegmentItem tcp_segment = TcpSegmentFactory::create_tcp_segment( IP_VERSION_4, is );
 
-        // filter out only the TCP reset (RST) replies. Note that the sequence
+        // Filter out only the TCP reset (RST) replies. Note that the sequence
         // number from RST does not match the sent ACK's sequence number.
-        if ( tcp_header.get_reset() &&
-             ipv4_header.get_source_address() == DestinationEndpoint.address() )
+        if ( tcp_segment->match_rst_reply( DestinationEndpoint.address() ) )
         {
             ReceivedReply = true;
 
-            print_rst_reply( ipv4_header, tcp_header );
+            tcp_segment->print_rst_reply( TimeSent );
 
             set_ping_status( PingStatus_SuccessReply );
 
@@ -330,26 +301,6 @@ void TcpPinger::handle_receive_tcp_segment( const size_t &bytes_transferred )
     }
 }
 
-/**
- * @brief Prints the RST reply.
- *
- * @param ipv4_header The IPv4 header received.
- * @param tcp_header The TCP RST header.
- * @return void
- */
-void TcpPinger::print_rst_reply(
-        const Ipv4Header &ipv4_header,
-        const TcpHeader &tcp_header
-) const
-{
-    ptime now = microsec_clock::universal_time();
-    GlobalLogger.info() << "RST from " << ipv4_header.get_source_address()
-        << ": tcp_seq=" << tcp_header.get_sequence_number()
-        << ", ttl=" << ipv4_header.get_time_to_live()
-        << " time=" << (now - TimeSent).total_milliseconds() << " ms" << endl;
-}
-
-
 void TcpPinger::set_ping_status( PingStatus ping_status )
 {
     PingerStatus = ping_status;
index e7aa8b3..0fd46a1 100644 (file)
@@ -29,8 +29,7 @@ on this file might be covered by the GNU General Public License.
 #include "host/networkinterface.hpp"
 #include "host/pinger.h"
 #include "host/pingstatus.h"
-#include "ip/ipv4header.h"
-#include "tcp/tcpheader.h"
+#include "tcp/tcpsegment.h"
 
 //-----------------------------------------------------------------------------
 // TcpPinger
@@ -69,23 +68,13 @@ private:
     );
 
     void start_send();
-    TcpHeader create_ack_request(
-            const uint16_t source_port,
-            const uint16_t destination_port,
-            const uint16_t sequence_number
-    ) const;
-    void send_ack_request( const TcpHeader &tcp_header );
+    void send_ack_request( const TcpSegmentItem tcp_segment );
     void schedule_timeout_rst_reply();
     void handle_ping_done();
 
     void start_receive();
     void handle_receive_tcp_segment( const std::size_t &bytes_transferred );
 
-    void print_rst_reply(
-            const Ipv4Header &ipv4_header,
-            const TcpHeader &tcp_header
-    ) const;
-
     void set_ping_status( PingStatus ping_status );
 
 private:
@@ -109,7 +98,6 @@ private:
     /// the buffer where the data received will be placed
     boost::asio::streambuf ReplyBuffer;
     /// flag to indicate if we got a reply or not
-    /// number of replies to the ICMP echo request
     bool ReceivedReply;
     /// the amount of time to wait for the reply
     int RstReplyTimeoutInSec;