#include <StreamConvergenceLayer.h>
Inheritance diagram for dtn::StreamConvergenceLayer:
TCP, SCTP, and Bluetooth RFCOMM). The goal is to share as much functionality as possible between protocols that have in-order, reliable, delivery semantics.
For the protocol, bundles are broken up into configurable-sized segments that are sent sequentially. Only a single bundle is inflight on the wire at one time (i.e. we don't interleave segments from different bundles). When segment acknowledgements are enabled (the default behavior), the receiving node sends an acknowledgement for each segment of the bundle that was received.
Keepalive messages are sent back and forth to ensure that the connection remains open. In the case of on demand links, a configurable idle timer is maintained to close the link when no bundle traffic has been sent or received. Links that are expected to be open but have broken due to underlying network conditions (i.e. always on and on demand links) are reopened by a timer that is managed by the contact manager.
Flow control is managed through the poll callbacks given by the base class CLConnection. In send_pending_data, we check if there are any acks that need to be sent, then check if there are bundle segments to be sent (i.e. acks are given priority). The only exception to this is that the connection might be write blocked in the middle of sending a data segment. In that case, we must first finish transmitting the current segment before sending any other acks (or the shutdown message), otherwise those messages will be consumed as part of the payload.
To make sure that we don't deadlock with the other side, we always drain any data that is ready on the channel. All incoming messages mark state in the appropriate data structures (i.e. InFlightList and IncomingList), then rely on send_pending_data to send the appropriate responses.
To record the segments we've sent, we fill in the sent_data_ sparse bitmap with the range of bytes as we send segments out. As acks come in, we extend the ack_data_ field to match. Once the whole bundle is acked, the entry is removed from the InFlightList.
To track segments that we have received but haven't yet acked, we set a single bit for the offset of the end of the segment in the ack_data_ bitmap as well as extending the contiguous range in rcvd_data_. That way, the gap in the ack_data_ structure expresses the individual segment lengths that were sent by the peer. Then, once the acks are sent, we fill in the contiguous range to identify as such.
Definition at line 97 of file StreamConvergenceLayer.h.
Public Member Functions | |
StreamConvergenceLayer (const char *logpath, const char *cl_name, u_int8_t cl_version) | |
Constructor. | |
Protected Types | |
enum | contact_header_flags_t { SEGMENT_ACK_ENABLED = 0x1, REACTIVE_FRAG_ENABLED = 0x2 } |
Values for ContactHeader flags. More... | |
enum | stream_cl_header_type_t { START_BUNDLE = 0x1, END_BUNDLE = 0x2, DATA_SEGMENT = 0x3, ACK_SEGMENT = 0x4, KEEPALIVE = 0x5, SHUTDOWN = 0x6 } |
Valid type codes for the protocol headers. More... | |
typedef ConnectionConvergenceLayer::LinkParams | LinkParams |
For some gcc variants, this typedef seems to be needed. | |
Protected Member Functions | |
void | dump_link (Link *link, oasys::StringBuffer *buf) |
Virtual from ConvergenceLayer. | |
bool | parse_link_params (LinkParams *params, int argc, const char **argv, const char **invalidp) |
Virtual from ConnectionConvergenceLayer. | |
bool | finish_init_link (Link *link, LinkParams *params) |
Virtual from ConnectionConvergenceLayer. | |
Protected Attributes | |
dtn::StreamConvergenceLayer::ContactHeader | packed |
Contact initiation header. | |
u_int8_t | cl_version_ |
Version of the actual CL protocol. | |
Classes | |
class | Connection |
Stream connection class. More... | |
struct | ContactHeader |
Contact initiation header. More... | |
class | StreamLinkParams |
Link parameters shared among all stream based convergence layers. More... |
typedef ConnectionConvergenceLayer::LinkParams dtn::StreamConvergenceLayer::LinkParams [protected] |
For some gcc variants, this typedef seems to be needed.
Definition at line 235 of file StreamConvergenceLayer.h.
enum dtn::StreamConvergenceLayer::contact_header_flags_t [protected] |
Values for ContactHeader flags.
SEGMENT_ACK_ENABLED | segment acks requested |
REACTIVE_FRAG_ENABLED | reactive fragmentation enabled |
Definition at line 109 of file StreamConvergenceLayer.h.
enum dtn::StreamConvergenceLayer::stream_cl_header_type_t [protected] |
Valid type codes for the protocol headers.
START_BUNDLE | begin a new bundle transmission |
END_BUNDLE | end of a bundle transmission |
DATA_SEGMENT | a segment of bundle data (followed by a SDNV segment length) |
ACK_SEGMENT | acknowledgement of a segment (followed by a SDNV ack length) |
KEEPALIVE | keepalive packet |
SHUTDOWN | about to shutdown |
Definition at line 129 of file StreamConvergenceLayer.h.
dtn::StreamConvergenceLayer::StreamConvergenceLayer | ( | const char * | logpath, | |
const char * | cl_name, | |||
u_int8_t | cl_version | |||
) |
void dtn::StreamConvergenceLayer::dump_link | ( | Link * | link, | |
oasys::StringBuffer * | buf | |||
) | [protected, virtual] |
Virtual from ConvergenceLayer.
Reimplemented from dtn::ConnectionConvergenceLayer.
Reimplemented in dtn::TCPConvergenceLayer.
Definition at line 116 of file StreamConvergenceLayer.cc.
References oasys::StringBuffer::appendf(), ASSERT, dtn::Link::cl_info(), dtn::ConnectionConvergenceLayer::dump_link(), dtn::StreamConvergenceLayer::StreamLinkParams::keepalive_interval_, dtn::StreamConvergenceLayer::StreamLinkParams::segment_ack_enabled_, and dtn::StreamConvergenceLayer::StreamLinkParams::segment_length_.
Referenced by dtn::TCPConvergenceLayer::dump_link().
bool dtn::StreamConvergenceLayer::parse_link_params | ( | LinkParams * | params, | |
int | argc, | |||
const char ** | argv, | |||
const char ** | invalidp | |||
) | [protected, virtual] |
Virtual from ConnectionConvergenceLayer.
Reimplemented from dtn::ConnectionConvergenceLayer.
Reimplemented in dtn::TCPConvergenceLayer.
Definition at line 69 of file StreamConvergenceLayer.cc.
References oasys::OptParser::addopt(), ASSERT, count, dtn::StreamConvergenceLayer::StreamLinkParams::keepalive_interval_, oasys::OptParser::parse_and_shift(), dtn::ConnectionConvergenceLayer::parse_link_params(), dtn::StreamConvergenceLayer::StreamLinkParams::segment_ack_enabled_, and dtn::StreamConvergenceLayer::StreamLinkParams::segment_length_.
Referenced by dtn::TCPConvergenceLayer::parse_link_params().
bool dtn::StreamConvergenceLayer::finish_init_link | ( | Link * | link, | |
LinkParams * | params | |||
) | [protected, virtual] |
Virtual from ConnectionConvergenceLayer.
Reimplemented from dtn::ConnectionConvergenceLayer.
Definition at line 101 of file StreamConvergenceLayer.cc.
References ASSERT, dtn::StreamConvergenceLayer::StreamLinkParams::segment_ack_enabled_, and dtn::Link::set_reliable().
struct dtn::StreamConvergenceLayer::ContactHeader dtn::StreamConvergenceLayer::packed [protected] |
Contact initiation header.
Sent at the beginning of a contact, and immediately followed by a SDNV length of the AnnounceBundle then the bundle itself.
u_int8_t dtn::StreamConvergenceLayer::cl_version_ [protected] |