Skip to content

Commit 7d80a66

Browse files
committed
Merge andreas dev
2 parents 43a6d6f + 50cd56d commit 7d80a66

8 files changed

Lines changed: 226 additions & 106 deletions

File tree

api/net/tcp/connection.hpp

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "tcp_errors.hpp"
2727
#include "write_queue.hpp"
2828
#include <delegate>
29+
#include <util/timer.hpp>
2930

3031
namespace net {
3132
class TCP;
@@ -282,7 +283,7 @@ class Connection : public std::enable_shared_from_this<Connection> {
282283
virtual size_t send(Connection&, WriteBuffer&);
283284

284285
/** Read from a Connection [RECEIVE] */
285-
virtual void receive(Connection&, ReadBuffer&);
286+
virtual void receive(Connection&, ReadBuffer&&);
286287

287288
/** Close a Connection [CLOSE] */
288289
virtual void close(Connection&);
@@ -477,20 +478,11 @@ class Connection : public std::enable_shared_from_this<Connection> {
477478
/** State if connection is in TCP write queue or not. */
478479
bool queued_;
479480

480-
/** When time-wait timer was started. Used in start_time_wait_timeout */
481-
uint64_t time_wait_started;
482-
483481
/** Retransmission timer */
484-
struct {
485-
uint32_t id;
486-
bool active = false;
487-
} rtx_timer;
482+
Timer rtx_timer;
488483

489484
/** Time Wait timeout timer */
490-
struct {
491-
uint32_t id;
492-
bool active = false;
493-
} timewait_timer;
485+
Timer timewait_timer;
494486

495487
/** Number of retransmission attempts on the packet first in RT-queue */
496488
size_t rtx_attempt_ = 0;
@@ -550,8 +542,7 @@ class Connection : public std::enable_shared_from_this<Connection> {
550542
Buffer is cleared for data after every reset.
551543
*/
552544
void read(size_t n, ReadCallback callback) {
553-
ReadBuffer buffer = {new_shared_buffer(n), n};
554-
read(buffer, callback);
545+
read({new_shared_buffer(n), n}, callback);
555546
}
556547

557548
/*
@@ -561,13 +552,13 @@ class Connection : public std::enable_shared_from_this<Connection> {
561552
void read(buffer_t buffer, size_t n, ReadCallback callback)
562553
{ read({buffer, n}, callback); }
563554

564-
void read(ReadBuffer buffer, ReadCallback callback);
555+
void read(ReadBuffer&& buffer, ReadCallback callback);
565556

566557
/*
567558
Assign the read request (read buffer)
568559
*/
569-
void receive(ReadBuffer& buffer)
570-
{ read_request.buffer = {buffer}; }
560+
void receive(ReadBuffer&& buffer)
561+
{ read_request = {buffer}; }
571562

572563
/*
573564
Receive data into the current read requests buffer.
@@ -853,20 +844,20 @@ class Connection : public std::enable_shared_from_this<Connection> {
853844
/*
854845
Start retransmission timer.
855846
*/
856-
void rtx_start();
847+
void rtx_start()
848+
{ rtx_timer.start(rttm.rto_ms()); }
857849

858850
/*
859851
Stop retransmission timer.
860852
*/
861-
void rtx_stop();
853+
void rtx_stop()
854+
{ rtx_timer.stop(); }
862855

863856
/*
864857
Restart retransmission timer.
865858
*/
866-
void rtx_reset() {
867-
rtx_stop();
868-
rtx_start();
869-
}
859+
void rtx_reset()
860+
{ rtx_timer.restart(rttm.rto_ms()); }
870861

871862
/*
872863
Retransmission timeout limit reached

api/net/tcp/connection_states.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ class Connection::Established : public State {
169169

170170
virtual size_t send(Connection&, WriteBuffer&) override;
171171

172-
virtual void receive(Connection&, ReadBuffer&) override;
172+
virtual void receive(Connection&, ReadBuffer&&) override;
173173

174174
virtual void close(Connection&) override;
175175

@@ -207,7 +207,7 @@ class Connection::FinWait1 : public State {
207207
return instance;
208208
}
209209

210-
virtual void receive(Connection&, ReadBuffer&) override;
210+
virtual void receive(Connection&, ReadBuffer&&) override;
211211

212212
virtual void close(Connection&) override;
213213

@@ -246,7 +246,7 @@ class Connection::FinWait2 : public State {
246246
return instance;
247247
}
248248

249-
virtual void receive(Connection&, ReadBuffer&) override;
249+
virtual void receive(Connection&, ReadBuffer&&) override;
250250

251251
virtual void close(Connection&) override;
252252

@@ -284,7 +284,7 @@ class Connection::CloseWait : public State {
284284

285285
virtual size_t send(Connection&, WriteBuffer&) override;
286286

287-
virtual void receive(Connection&, ReadBuffer&) override;
287+
virtual void receive(Connection&, ReadBuffer&&) override;
288288

289289
virtual void close(Connection&) override;
290290

api/net/tcp/read_buffer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ struct ReadBuffer {
7979
void renew() {
8080
remaining = capacity();
8181
offset = 0;
82-
buffer = buffer_t(new uint8_t[remaining], std::default_delete<uint8_t[]>());
82+
buffer = new_shared_buffer(remaining);
8383
push = false;
8484
}
8585
}; // < ReadBuffer

api/net/tcp/read_request.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,22 @@ struct ReadRequest {
3131
ReadBuffer buffer;
3232
ReadCallback callback;
3333

34-
/*ReadRequest()
35-
: buffer(nullptr, 0),
36-
callback({this, &ReadRequest::default_read_callback})
37-
{}*/
34+
ReadRequest()
35+
: buffer{nullptr, 0},
36+
callback{nullptr}
37+
{}
38+
39+
ReadRequest(ReadBuffer buf)
40+
: ReadRequest(buf, nullptr)
41+
{}
3842

3943
ReadRequest(ReadBuffer buf, ReadCallback cb)
4044
: buffer(buf),
4145
callback(cb)
4246
{}
4347

44-
ReadRequest(size_t n = 0)
45-
: buffer(buffer_t(new uint8_t[n], std::default_delete<uint8_t[]>()), n),
48+
ReadRequest(size_t n)
49+
: buffer({new_shared_buffer(n), n}),
4650
callback({this, &ReadRequest::default_read_callback})
4751
{}
4852

api/net/tcp/rttm.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ struct RTTM {
5757

5858
void stop(bool first = false);
5959

60+
auto rto_ms() const
61+
{ return std::chrono::milliseconds{static_cast<unsigned long>(RTO * 1000)}; }
62+
6063
/*
6164
When the first RTT measurement R is made, the host MUST set
6265
@@ -66,7 +69,7 @@ struct RTTM {
6669
6770
where K = 4.
6871
*/
69-
inline void first_rtt_measurement(duration_t R) {
72+
void first_rtt_measurement(duration_t R) {
7073
SRTT = R;
7174
RTTVAR = R/2;
7275
update_rto();
@@ -89,19 +92,18 @@ struct RTTM {
8992
After the computation, a host MUST update
9093
RTO <- SRTT + max (G, K*RTTVAR)
9194
*/
92-
inline void sub_rtt_measurement(duration_t R) {
95+
void sub_rtt_measurement(duration_t R) {
9396
RTTVAR = (1 - beta) * RTTVAR + beta * std::abs(SRTT-R);
9497
SRTT = (1 - alpha) * SRTT + alpha * R;
9598
update_rto();
9699
}
97100

98-
inline void update_rto() {
101+
void update_rto() {
99102
RTO = std::max(SRTT + std::max(CLOCK_G, K * RTTVAR), 1.0);
100103
debug2("<TCP::Connection::RTO> RTO updated: %ums\n",
101104
(uint32_t)(RTO * 1000));
102105
}
103-
104-
}; // < struct RTTM
106+
} __attribute__((packed)); // < struct RTTM
105107

106108
} // < namespace tcp
107109
} // < namespace net

api/util/timer.hpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
4+
// and Alfred Bratterud
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
#pragma once
18+
19+
#ifndef UTIL_TIMER_HPP
20+
#define UTIL_TIMER_HPP
21+
22+
#include <timers>
23+
24+
/**
25+
* @brief A start- and stoppable timer
26+
* @details A timer which can be started, stopped and restarted.
27+
* Uses the underlying Timers interface.
28+
*
29+
*/
30+
class Timer {
31+
public:
32+
using id_t = Timers::id_t;
33+
using duration_t = Timers::duration_t;
34+
using handler_t = Timers::handler_t;
35+
36+
/**
37+
* @brief Constructs a Timer without a handler
38+
*/
39+
Timer() : Timer(nullptr) {}
40+
41+
/**
42+
* @brief Constructs a Timer with a handler
43+
*
44+
* @param on_timeout function to be executed on timeout
45+
*/
46+
Timer(handler_t on_timeout)
47+
: on_timeout_{on_timeout}, running_{false} {}
48+
49+
/**
50+
* @brief Start the timer with a timeout duration
51+
* @details Starts the timer (if not already running)
52+
* and stores the current timer id returned by the underlying Timers.
53+
*
54+
* Requires on_timeout to be set.
55+
*
56+
* @param duration until timing out
57+
*/
58+
inline void start(duration_t);
59+
60+
/**
61+
* @brief Stops the timer
62+
* @details Stops the timer (if running) by
63+
* calling stop with the current id to the underlying Timers.
64+
*/
65+
inline void stop();
66+
67+
/**
68+
* @brief Restart the timer
69+
* @details First stops the timer (if running)
70+
* and then starts the timer with a new refreshed duration.
71+
*
72+
* @param duration until timing out
73+
*/
74+
inline void restart(duration_t);
75+
76+
/**
77+
* @brief Sets the on timeout handler
78+
* @details Sets what to be done when the timer times out.
79+
*
80+
* @param on_timeout a timeout handler
81+
*/
82+
void set_on_timeout(handler_t on_timeout)
83+
{ on_timeout_ = on_timeout; }
84+
85+
/**
86+
* @brief If the timer is running (active)
87+
*
88+
* @return Wether the timer is running or not
89+
*/
90+
bool is_running() const
91+
{ return running_; }
92+
93+
/**
94+
* @brief Destroys the Timer
95+
* @details Makes sure to stop any eventual underlying Timer
96+
* if its running.
97+
*/
98+
~Timer()
99+
{ stop(); }
100+
101+
/** Delete copy and move */
102+
Timer(const Timer&) = delete;
103+
Timer(Timer&&) = delete;
104+
Timer& operator=(const Timer&) = delete;
105+
Timer& operator=(Timer&&) = delete;
106+
107+
private:
108+
/** ID for the running timer. */
109+
Timers::id_t id_;
110+
/** Function to execute on timeout */
111+
handler_t on_timeout_;
112+
/** Wether the timer is running or not */
113+
bool running_;
114+
115+
/**
116+
* @brief Sets the timer to inactive before calling the user callback
117+
* @details Wraps the on timeout handler, setting the timer to not running
118+
* before calling the timeout handler.
119+
* This is the delegate being sent to the underlying Timers interface
120+
*
121+
* @param id the timer id returned by the Timers interface
122+
*/
123+
inline void _internal_timeout(id_t id);
124+
125+
} __attribute__((packed)); // < class Timer
126+
127+
inline void Timer::start(duration_t when) {
128+
Ensures(on_timeout_);
129+
if(!running_) {
130+
id_ = Timers::oneshot(when, {this, &Timer::_internal_timeout});
131+
running_ = true;
132+
}
133+
}
134+
135+
inline void Timer::stop() {
136+
if(running_) {
137+
Timers::stop(id_);
138+
running_ = false;
139+
}
140+
}
141+
142+
inline void Timer::restart(duration_t when) {
143+
stop();
144+
start(when);
145+
}
146+
147+
inline void Timer::_internal_timeout(id_t id) {
148+
running_ = false;
149+
on_timeout_(id);
150+
}
151+
152+
#endif

0 commit comments

Comments
 (0)