Skip to content

Commit 8d03d99

Browse files
authored
Merge pull request #1433 from fwsGonzo/dev
Various TCP fixes
2 parents d8973c7 + 3a335b1 commit 8d03d99

8 files changed

Lines changed: 55 additions & 47 deletions

File tree

api/net/ip4/addr.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,11 @@ struct Addr {
107107

108108
const static std::regex ipv4_address_pattern
109109
{
110-
"^\\s*(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\."
111-
"(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\."
112-
"(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\."
113-
"(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\s*$"
110+
111+
#define OCTET_PATTERN "(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)"
112+
"^\\s*" OCTET_PATTERN "\\." OCTET_PATTERN "\\." OCTET_PATTERN "\\." OCTET_PATTERN "\\s*$"
113+
#undef OCTET_PATTERN
114+
114115
};
115116

116117
std::smatch ipv4_parts;

api/net/tcp/tcp.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "packet.hpp"
2727

2828
#include <map> // connections, listeners
29-
#include <queue> // writeq
29+
#include <deque> // writeq
3030
#include <net/inet.hpp>
3131
#include <net/socket.hpp>
3232
#include <net/port_util.hpp>
@@ -710,7 +710,7 @@ namespace net {
710710
*
711711
* @param[in] <unnamed> A ptr to a Connection
712712
*/
713-
void queue_offer(tcp::Connection_ptr);
713+
void queue_offer(tcp::Connection&);
714714

715715
/**
716716
* @brief Force the TCP to process the it's queue with the current amount of available packets.

api/util/statman.hpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,27 @@
2525
#include <membitmap>
2626
#include <smp_utils>
2727

28-
/** This type is thrown when Statman's span is full */
2928
struct Stats_out_of_memory : public std::out_of_range {
3029
explicit Stats_out_of_memory()
31-
: std::out_of_range(std::string{"Statman has no room for more statistics"})
30+
: std::out_of_range("Statman has no room for more statistics")
3231
{}
33-
}; //< struct Stats_out_of_memory
32+
};
3433

35-
36-
/** This type is thrown from within the operations of class Statman */
3734
struct Stats_exception : public std::runtime_error {
3835
using runtime_error::runtime_error;
39-
}; //< struct Stats_exception
36+
};
4037

41-
///
42-
///
43-
///
4438
class Stat {
4539
public:
46-
static const int MAX_NAME_LEN {47};
47-
///
48-
///
49-
///
40+
static const int MAX_NAME_LEN = 47;
41+
5042
enum Stat_type: uint8_t
5143
{
5244
FLOAT,
5345
UINT32,
5446
UINT64
5547
};
5648

57-
///
58-
///
59-
///
6049
Stat(const Stat_type type, const std::string& name);
6150
~Stat() = default;
6251

@@ -93,7 +82,7 @@ class Stat {
9382
};
9483
Stat_type type_;
9584

96-
char name_[MAX_NAME_LEN];
85+
char name_[MAX_NAME_LEN+1];
9786

9887
Stat(const Stat& other) = delete;
9988
Stat(const Stat&& other) = delete;

src/kernel/timers.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ struct alignas(SMP_ALIGN) timer_system
6565
// timers sorted by timestamp
6666
std::multimap<duration_t, Timers::id_t> scheduled;
6767
/** Stats */
68-
int64_t* oneshot_started;
69-
int64_t* oneshot_stopped;
70-
uint32_t* periodic_started;
71-
uint32_t* periodic_stopped;
68+
int64_t* oneshot_started = nullptr;
69+
int64_t* oneshot_stopped = nullptr;
70+
uint32_t* periodic_started = nullptr;
71+
uint32_t* periodic_stopped = nullptr;
7272
};
7373
static SMP_ARRAY<timer_system> systems;
7474

@@ -83,7 +83,7 @@ void Timers::init(const start_func_t& start, const stop_func_t& stop)
8383
system.arch_start_func = start;
8484
system.arch_stop_func = stop;
8585

86-
std::string CPU = "cpu" + std::to_string(SMP::cpu_id());
86+
const std::string CPU = "cpu" + std::to_string(SMP::cpu_id());
8787
system.oneshot_started = (int64_t*) &Statman::get().create(Stat::UINT64, CPU + ".timers.oneshot_started").get_uint64();
8888
system.oneshot_stopped = (int64_t*) &Statman::get().create(Stat::UINT64, CPU + ".timers.oneshot_stopped").get_uint64();
8989
system.periodic_started = &Statman::get().create(Stat::UINT32, CPU + ".timers.periodic_started").get_uint32();

src/net/tcp/connection.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ size_t Connection::receive(seq_t seq, const uint8_t* data, size_t n, bool PUSH)
143143

144144
void Connection::write(Chunk buffer)
145145
{
146+
if (UNLIKELY(buffer.size() == 0)) {
147+
throw TCP_error("Can't write zero bytes to TCP stream");
148+
}
149+
146150
// Only write if allowed
147151
if(state_->is_writable())
148152
{
@@ -199,9 +203,9 @@ void Connection::offer(size_t& packets)
199203
debug2("<Connection::offer> Finished working offer with [%u] packets left and a queue of (%u) with a usable window of %i\n",
200204
packets, writeq.size(), usable_window());
201205

202-
if(can_send() and not queued_)
206+
if (this->can_send() and not this->is_queued())
203207
{
204-
host_.queue_offer(retrieve_shared());
208+
host_.queue_offer(*this);
205209
}
206210
}
207211

@@ -267,8 +271,11 @@ void Connection::receive_disconnect() {
267271
Expects(read_request and read_request->buffer.buffer());
268272
auto& buf = read_request->buffer;
269273

270-
if(read_request->callback)
271-
read_request->callback(buf.buffer(), buf.size());
274+
if(read_request->callback) {
275+
// TODO: consider adding back when SACK is complete
276+
//if (buf.size() > 0 && buf.missing() == 0)
277+
// read_request->callback(buf.buffer(), buf.size());
278+
}
272279
}
273280

274281
void Connection::segment_arrived(Packet_ptr incoming)

src/net/tcp/tcp.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -489,15 +489,25 @@ void TCP::request_offer(Connection& conn) {
489489
debug2("<TCP::request_offer> %s requestin offer: uw=%u rem=%u\n",
490490
conn.to_string().c_str(), conn.usable_window(), conn.sendq_remaining());
491491

492+
// Note: Must be called even if packets is 0
493+
// because the connectoin is responsible for requeuing itself (see Connection::offer)
492494
conn.offer(packets);
493495
}
494496

495-
void TCP::queue_offer(Connection_ptr conn)
497+
498+
void TCP::queue_offer(Connection& conn)
496499
{
497-
if(not conn->is_queued() and conn->can_send())
500+
if(not conn.is_queued() and conn.can_send())
498501
{
499-
debug("<TCP::queue_offer> %s queued\n", conn->to_string().c_str());
500-
writeq.push_back(conn);
501-
conn->set_queued(true);
502+
try {
503+
debug("<TCP::queue_offer> %s queued\n", conn.to_string().c_str());
504+
writeq.push_back(conn.retrieve_shared());
505+
conn.set_queued(true);
506+
}
507+
catch (std::exception& e) {
508+
printf("ERROR: Could not find connection for %p: %s\n",
509+
&conn, conn.to_string().c_str());
510+
throw;
511+
}
502512
}
503513
}

src/util/statman.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,11 @@ Statman& Statman::get() {
2828

2929
///////////////////////////////////////////////////////////////////////////////
3030
Stat::Stat(const Stat_type type, const std::string& name)
31-
: type_{type}
31+
: ui64(0), type_{type}
3232
{
3333
if(name.size() > MAX_NAME_LEN)
3434
throw Stats_exception{"Creating stat: Name cannot be longer than " + std::to_string(MAX_NAME_LEN) + " characters"};
3535

36-
switch (type) {
37-
case UINT32: ui32 = 0; break;
38-
case UINT64: ui64 = 0; break;
39-
case FLOAT: f = 0.0f; break;
40-
default: throw Stats_exception{"Unimplemented stat type"};
41-
}
42-
4336
snprintf(name_, sizeof(name_), "%s", name.c_str());
4437
}
4538

@@ -79,7 +72,7 @@ uint64_t& Stat::get_uint64() {
7972
void Statman::init(const uintptr_t start, const Size_type num_bytes)
8073
{
8174
if (num_bytes < 0)
82-
throw Stats_exception{"Creating Statman: A negative number of bytes has been given"};
75+
throw Stats_exception("Can't initialize statman with negative size");
8376

8477
const int N = num_bytes / sizeof(Stat);
8578
this->stats_ = reinterpret_cast<Stat*>(start);
@@ -103,7 +96,7 @@ Stat& Statman::create(const Stat::Stat_type type, const std::string& name) {
10396
volatile scoped_spinlock lock(this->stlock);
10497
#endif
10598
if (name.empty())
106-
throw Stats_exception{"Cannot create Stat with no name"};
99+
throw Stats_exception("Cannot create Stat with no name");
107100

108101
const int idx = bitmap.first_free();
109102
if (idx == -1 || idx >= capacity())

test/net/unit/ip4_addr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ CASE("Create IP4 addresses from strings")
9696
}
9797
**/
9898

99+
EXPECT_NO_THROW(Addr("202.209.27.78"));
100+
EXPECT_NO_THROW(Addr("212.209.27.78"));
101+
EXPECT_NO_THROW(Addr("222.209.27.78"));
102+
EXPECT_NO_THROW(Addr("232.209.27.78"));
103+
EXPECT_NO_THROW(Addr("242.209.27.78"));
104+
EXPECT_NO_THROW(Addr("255.209.27.78"));
105+
EXPECT_THROWS(Addr("265.209.27.78"));
106+
EXPECT_THROWS(Addr("256.209.27.78"));
99107
EXPECT_THROWS(Addr{"LUL"});
100108
EXPECT_THROWS(Addr{"12310298310298301283"});
101109
EXPECT_THROWS(const Addr invalid1{"256.256.256.256"});

0 commit comments

Comments
 (0)