diff --git a/api/net/tcp/tcp.hpp b/api/net/tcp/tcp.hpp index d4f1504774..64825db690 100644 --- a/api/net/tcp/tcp.hpp +++ b/api/net/tcp/tcp.hpp @@ -537,6 +537,21 @@ namespace net { */ void transmit(tcp::Packet_ptr); + /** + * @brief Creates an outgoing TCP packet. + * + * @return A tcp packet ptr + */ + tcp::Packet_ptr create_outgoing_packet(); + + /** + * @brief Sends a TCP reset based on the values of the incoming packet. + * Used when packet are addressed to closed ports or already dead connections. + * + * @param[in] incoming The incoming tcp packet "to reset". + */ + void send_reset(const tcp::Packet& incoming); + /** * @brief Generate a unique initial sequence number (ISS). * diff --git a/src/net/tcp/connection.cpp b/src/net/tcp/connection.cpp index 811a34997d..d3e2c3cdc9 100644 --- a/src/net/tcp/connection.cpp +++ b/src/net/tcp/connection.cpp @@ -318,11 +318,9 @@ Connection::~Connection() { rtx_clear(); } -Packet_ptr Connection::create_outgoing_packet() { - auto packet = static_unique_ptr_cast((host_.inet_).create_packet()); - //auto packet = std::static_pointer_cast(create_packet()); - - packet->init(); +Packet_ptr Connection::create_outgoing_packet() +{ + auto packet = host_.create_outgoing_packet(); // Set Source (local == the current connection) packet->set_source(local()); // Set Destination (remote) diff --git a/src/net/tcp/listener.cpp b/src/net/tcp/listener.cpp index 64f1e095a6..8535d68682 100644 --- a/src/net/tcp/listener.cpp +++ b/src/net/tcp/listener.cpp @@ -62,6 +62,13 @@ void Listener::segment_arrived(Packet_ptr packet) { // if it's a new attempt (SYN) else { + // don't waste time if the packet does not have SYN + if(UNLIKELY(not packet->isset(SYN))) + { + host_.send_reset(*packet); + return; + } + // Stat increment number of connection attempts host_.connection_attempts_++; diff --git a/src/net/tcp/tcp.cpp b/src/net/tcp/tcp.cpp index 6b4d27a744..97cce0a9d3 100644 --- a/src/net/tcp/tcp.cpp +++ b/src/net/tcp/tcp.cpp @@ -202,6 +202,9 @@ void TCP::receive(net::Packet_ptr packet_ptr) { return; } + // Send a reset + send_reset(*packet); + drop(*packet); } @@ -263,6 +266,27 @@ void TCP::transmit(tcp::Packet_ptr packet) { _network_layer_out(std::move(packet)); } +tcp::Packet_ptr TCP::create_outgoing_packet() +{ + auto packet = static_unique_ptr_cast(inet_.create_packet()); + packet->init(); + return packet; +} + +void TCP::send_reset(const tcp::Packet& in) +{ + // TODO: maybe worth to just swap the fields in + // the incoming packet and send that one + auto out = create_outgoing_packet(); + // increase incoming SEQ and ACK by 1 and set RST + ACK + out->set_seq(in.ack()+1).set_ack(in.seq()+1).set_flags(RST | ACK); + // swap dest and src + out->set_source(in.destination()); + out->set_destination(in.source()); + + transmit(std::move(out)); +} + seq_t TCP::generate_iss() { // Do something to get a iss. return rand();