void Connection::transmit(TCP::Packet_ptr packet) { debug("<TCP::Connection::transmit> Transmitting: %s \n", packet->to_string().c_str()); host_.transmit(packet); // Don't think we would like to retransmit reset packets..? //if(!packet->isset(RST)) // add_retransmission(packet); }
void TCP::transmit(tcp::Packet_ptr packet) { // Generate checksum. packet->set_tcp_checksum(); debug2("<TCP::transmit> %s\n", packet->to_string().c_str()); // Stat increment bytes transmitted and packets transmitted (*bytes_tx_) += packet->tcp_data_length(); (*packets_tx_)++; _network_layer_out(std::move(packet)); }
void Connection::add_option(TCP::Option::Kind kind, TCP::Packet_ptr packet) { switch(kind) { case Option::MSS: { packet->add_tcp_option<Option::opt_mss>(host_.MSS()); debug2("<TCP::Connection::add_option@Option::MSS> Packet: %s - MSS: %u\n", packet->to_string().c_str(), ntohs(*(uint16_t*)(packet->tcp_options()+2))); break; } default: break; } }
void Connection::transmit(TCP::Packet_ptr packet) { if(!rttm.active and packet->end() == cb.SND.NXT) { //printf("<TCP::Connection::transmit> Starting RTT measurement.\n"); rttm.start(); } //if(packet->seq() + packet->tcp_data_length() != cb.SND.NXT) //printf("<TCP::Connection::transmit> rseq=%u rack=%u\n", // packet->seq() - cb.ISS, packet->ack() - cb.IRS); debug2("<TCP::Connection::transmit> TX %s\n", packet->to_string().c_str()); host_.transmit(packet); if(packet->should_rtx() and !rtx_timer.active) { rtx_start(); } }
void Connection::add_retransmission(TCP::Packet_ptr packet) { debug2("<TCP::Connection::add_retransmission> Packet added to retransmission. \n"); auto self = shared_from_this(); hw::PIT::instance().onTimeout(RTO(), [packet, self] { // Packet hasnt been ACKed. if(packet->seq() > self->tcb().SND.UNA) { debug("<TCP::Connection::add_retransmission@onTimeout> Packet unacknowledge, retransmitting...\n"); self->transmit(packet); } else { debug2("<TCP::Connection::add_retransmission@onTimeout> Packet acknowledged %s \n", packet->to_string().c_str()); // Signal user? } }); }