-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathpacket.cc
93 lines (81 loc) · 2.47 KB
/
packet.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <cassert>
#include "address.hh"
#include "packet.hh"
#include "timestamp.hh"
using namespace std;
using namespace Network;
/* Make outgoing data packet */
Packet::Packet( const Address & addr, const uint64_t sequence_number )
: addr_( addr ),
sequence_number_( sequence_number ),
send_timestamp_(),
ack_sequence_number_( -1 ),
ack_send_timestamp_(),
ack_recv_timestamp_(),
recv_timestamp_(),
payload_len_( DATA_PACKET_SIZE - HEADER_SIZE )
{
assert( !is_ack() );
}
/* Make ACK */
Packet::Packet( const Address & addr, const uint64_t sequence_number,
const Packet & other )
: addr_( addr ),
sequence_number_( sequence_number ),
send_timestamp_(),
ack_sequence_number_( other.sequence_number() ),
ack_send_timestamp_( other.send_timestamp() ),
ack_recv_timestamp_( other.recv_timestamp() ),
recv_timestamp_(),
payload_len_( 0 )
{
assert( is_ack() );
}
/* Make incoming packet from wire */
Packet::Packet( const Address & addr, const string & str,
const struct timespec & receive_ts )
: addr_( addr ),
sequence_number_(), send_timestamp_(),
ack_sequence_number_(), ack_send_timestamp_(),
ack_recv_timestamp_(),
recv_timestamp_( timestamp( receive_ts ) ),
payload_len_()
{
if ( str.size() < HEADER_SIZE ) {
throw string( "Incoming datagram not long enough to decode." );
}
sequence_number_ = str.substr( 0*sizeof( uint64_t ), sizeof( uint64_t ) );
send_timestamp_ = str.substr( 1*sizeof( uint64_t ), sizeof( uint64_t ) );
ack_sequence_number_ = str.substr( 2*sizeof(uint64_t), sizeof(uint64_t) );
ack_send_timestamp_ = str.substr( 3*sizeof(uint64_t), sizeof(uint64_t) );
ack_recv_timestamp_ = str.substr( 4*sizeof(uint64_t), sizeof(uint64_t) );
payload_len_ = str.size() - HEADER_SIZE;
}
/* Prepare to send */
void Packet::set_send_timestamp( void )
{
/* Fill in send timestamp */
send_timestamp_ = Integer64( timestamp() );
}
/* Make wire representation of packet */
string Packet::str( void ) const
{
string ret = sequence_number_.str()
+ send_timestamp_.str()
+ ack_sequence_number_.str()
+ ack_send_timestamp_.str()
+ ack_recv_timestamp_.str()
+ string( payload_len_, 'x' );
assert( ret.size() <= DATA_PACKET_SIZE );
return ret;
}
/* An ACK has an ack_sequence_number less than 2^64 - 1. */
bool Packet::is_ack( void ) const
{
if ( ack_sequence_number() == uint64_t( -1 ) ) {
return false;
}
/* It's an ACK. */
assert( payload_len_ == 0 );
return true;
}