Skip to content

Commit c046e87

Browse files
committed
Made chicago's get time function a callback in order to prepare for unit testing
1 parent 06446ab commit c046e87

File tree

11 files changed

+79
-14
lines changed

11 files changed

+79
-14
lines changed

libcurvecpr/include/curvecpr/chicago.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
#ifndef __CURVECPR_CHICAGO_H
22
#define __CURVECPR_CHICAGO_H
33

4+
struct curvecpr_chicago_ops {
5+
/* Get current time in nanoseconds. The time 0 can be any time as long
6+
as present time is not too close to it (>100 seconds should be ok) and
7+
it doesn't change during the lifetime of this chicago instance (i.e.
8+
it doesn't have to be for example 1970-01-01, but can be the number of
9+
nanoseconds since the computer booted+100s or whatever).
10+
You can pass in curvecpr_util_nanoseconds() here if you want. */
11+
long long (*get_nanoseconds)(void *priv);
12+
};
13+
14+
struct curvecpr_chicago_cf {
15+
struct curvecpr_chicago_ops ops;
16+
void *priv;
17+
};
18+
419
struct curvecpr_chicago {
520
long long clock;
621

@@ -24,9 +39,11 @@ struct curvecpr_chicago {
2439
long long ns_last_edge;
2540
long long ns_last_doubling;
2641
long long ns_last_panic;
42+
43+
struct curvecpr_chicago_cf cf;
2744
};
2845

29-
void curvecpr_chicago_new (struct curvecpr_chicago *chicago);
46+
void curvecpr_chicago_new (struct curvecpr_chicago *chicago, const struct curvecpr_chicago_cf *cf);
3047
void curvecpr_chicago_refresh_clock (struct curvecpr_chicago *chicago);
3148
void curvecpr_chicago_on_timeout (struct curvecpr_chicago *chicago);
3249
void curvecpr_chicago_on_recv (struct curvecpr_chicago *chicago, long long ns_sent);

libcurvecpr/include/curvecpr/messager.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,28 @@
1010

1111
struct curvecpr_messager;
1212

13+
14+
/* The callbacks you need to implement to get a reliable stream transport.
15+
You need to implement the three data structures mentioned below.
16+
Terminology:
17+
sendq (send queue): The data waiting to get sent. When you want to send
18+
something, you divide it into curvecpr_block:s (each at most
19+
messager->my_maximum_send_bytes in size) and put it in this
20+
queue (you have to do this yourself). When you call
21+
curvecpr_messager_process_sendq() it will check
22+
this queue for data ready to be sent. It might not happen
23+
immediately, but at a later invocation depending on the
24+
decongestion algorithm and packets waiting to be resent etc.
25+
sendmarkq (sent-to-be-marked queue): When a curvecpr_block is sent
26+
(using the send() callback function), it is moved from sendq to
27+
sendmarkq (if it wasn't moved earlier and this is just a resend).
28+
It waits here until it has been acknowledged by the recipient.
29+
recvmarkq (received-to-be-marked): Received curvecpr_block:s are stored
30+
here until we have sent an ACK (which happens right after they are
31+
stored actually). You need to assemble the stream data from this
32+
data structure yourself.
33+
34+
*/
1335
struct curvecpr_messager_ops {
1436
int (*sendq_head)(struct curvecpr_messager *messager, struct curvecpr_block **block_stored);
1537
int (*sendq_move_to_sendmarkq)(struct curvecpr_messager *messager, const struct curvecpr_block *block, struct curvecpr_block **block_stored);
@@ -19,17 +41,22 @@ struct curvecpr_messager_ops {
1941
the time at which they were last sent. */
2042
int (*sendmarkq_head)(struct curvecpr_messager *messager, struct curvecpr_block **block_stored);
2143
int (*sendmarkq_get)(struct curvecpr_messager *messager, crypto_uint32 acknowledging_id, struct curvecpr_block **block_stored);
44+
45+
/* This is called for all ranges in incoming messages's acknowledge structure */
2246
int (*sendmarkq_remove_range)(struct curvecpr_messager *messager, unsigned long long start, unsigned long long end);
2347
unsigned char (*sendmarkq_is_full)(struct curvecpr_messager *messager);
2448

49+
/* This is called once for each message coming in that is not a pure acknowledgement */
2550
int (*recvmarkq_put)(struct curvecpr_messager *messager, const struct curvecpr_block *block, struct curvecpr_block **block_stored);
51+
2652
int (*recvmarkq_get_nth_unacknowledged)(struct curvecpr_messager *messager, unsigned int n, struct curvecpr_block **block_stored);
2753
unsigned char (*recvmarkq_is_empty)(struct curvecpr_messager *messager);
2854
int (*recvmarkq_remove_range)(struct curvecpr_messager *messager, unsigned long long start, unsigned long long end);
2955

3056
int (*send)(struct curvecpr_messager *messager, const unsigned char *buf, size_t num);
3157

3258
void (*put_next_timeout)(struct curvecpr_messager *messager, const long long timeout_ns);
59+
long long (*get_nanoseconds)(void *priv);
3360
};
3461

3562
struct curvecpr_messager_cf {
@@ -50,6 +77,9 @@ struct curvecpr_messager {
5077
unsigned char my_eof;
5178
unsigned char my_final;
5279

80+
/* The client can only send 512 bytes/message until we know that an
81+
initiation packet has reached the server. Then this variable is raised
82+
to 1024 bytes. The server can send 1024 bytes/message from the start. */
5383
size_t my_maximum_send_bytes;
5484

5585
crypto_uint64 my_sent_bytes;
@@ -68,6 +98,7 @@ struct curvecpr_messager {
6898

6999
void curvecpr_messager_new (struct curvecpr_messager *messager, const struct curvecpr_messager_cf *cf, unsigned char client);
70100
int curvecpr_messager_recv (struct curvecpr_messager *messager, const unsigned char *buf, size_t num);
101+
/* Call this function on timeout and when you have added things to sendq if it was empty. */
71102
int curvecpr_messager_process_sendq (struct curvecpr_messager *messager);
72103
long long curvecpr_messager_next_timeout (struct curvecpr_messager *messager);
73104

libcurvecpr/include/curvecpr/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define __CURVECPR_UTIL_H
33

44
long long curvecpr_util_random_mod_n (long long n);
5-
long long curvecpr_util_nanoseconds (void);
5+
long long curvecpr_util_nanoseconds (void *);
66
int curvecpr_util_encode_domain_name (unsigned char *destination, const char *source);
77

88
#endif

libcurvecpr/lib/chicago.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,13 @@ static void _update_on_timeout (struct curvecpr_chicago *chicago)
123123
}
124124
}
125125

126-
void curvecpr_chicago_new (struct curvecpr_chicago *chicago)
126+
void curvecpr_chicago_new (struct curvecpr_chicago *chicago, const struct curvecpr_chicago_cf *cf)
127127
{
128128
curvecpr_bytes_zero(chicago, sizeof(struct curvecpr_chicago));
129129

130+
if (cf)
131+
curvecpr_bytes_copy(&chicago->cf, cf, sizeof(struct curvecpr_chicago_cf));
132+
130133
curvecpr_chicago_refresh_clock(chicago);
131134

132135
chicago->rtt_latest = 0;
@@ -153,7 +156,7 @@ void curvecpr_chicago_new (struct curvecpr_chicago *chicago)
153156

154157
void curvecpr_chicago_refresh_clock (struct curvecpr_chicago *chicago)
155158
{
156-
chicago->clock = curvecpr_util_nanoseconds();
159+
chicago->clock = chicago->cf.ops.get_nanoseconds(chicago->cf.priv);
157160
}
158161

159162
void curvecpr_chicago_on_timeout (struct curvecpr_chicago *chicago)

libcurvecpr/lib/messager.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,17 @@ void curvecpr_messager_new (struct curvecpr_messager *messager, const struct cur
5252
curvecpr_bytes_zero(messager, sizeof(struct curvecpr_messager));
5353

5454
/* Initialize configuration. */
55-
if (cf)
56-
curvecpr_bytes_copy(&messager->cf, cf, sizeof(struct curvecpr_messager_cf));
55+
curvecpr_bytes_copy(&messager->cf, cf, sizeof(struct curvecpr_messager_cf));
5756

5857
/* Initialize congestion handling. */
59-
curvecpr_chicago_new(&messager->chicago);
58+
struct curvecpr_chicago_ops chicago_ops = {
59+
.get_nanoseconds = cf->ops.get_nanoseconds
60+
};
61+
struct curvecpr_chicago_cf chicago_cf = {
62+
.ops = chicago_ops,
63+
.priv = cf->priv
64+
};
65+
curvecpr_chicago_new(&messager->chicago, &chicago_cf);
6066

6167
/* If we're in client mode, initiate packets have a maximum size of 512 bytes.
6268
Otherwise, we're in server mode, and we can start at 1024. */

libcurvecpr/lib/util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ long long curvecpr_util_random_mod_n (long long n)
3434

3535
/* XXX: Y2036 problems; should upgrade to a 128-bit type for this. */
3636
/* XXX: Nanosecond granularity limits users to 1 terabyte per second. */
37-
long long curvecpr_util_nanoseconds (void)
37+
long long curvecpr_util_nanoseconds (void *priv)
3838
{
3939
/* XXX: host_get_clock_service() has been officially deprecated for years;
4040
this may need to be updated in the future. */

libcurvecpr/test/messager/test_new_configures_object.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <check_extras.h>
33

44
#include <curvecpr/messager.h>
5+
#include <curvecpr/util.h>
56

67
static char static_priv[] = "Hello!";
78

@@ -27,7 +28,8 @@ START_TEST (test_new_configures_object)
2728
.ops = {
2829
.sendmarkq_is_full = t_sendmarkq_is_full,
2930
.sendq_is_empty = t_sendq_is_empty,
30-
.sendmarkq_head = t_sendmarkq_head
31+
.sendmarkq_head = t_sendmarkq_head,
32+
.get_nanoseconds = curvecpr_util_nanoseconds
3133
},
3234
.priv = static_priv
3335
};

libcurvecpr/test/messager/test_recv_requests_removal_from_sendmarkq.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <curvecpr/messager.h>
55

66
#include <curvecpr/bytes.h>
7+
#include <curvecpr/util.h>
78

89
static unsigned char t_sendmarkq_is_full (struct curvecpr_messager *messager)
910
{
@@ -36,7 +37,8 @@ START_TEST (test_recv_requests_removal_from_sendmarkq)
3637
.sendmarkq_is_full = t_sendmarkq_is_full,
3738
.sendq_is_empty = t_sendq_is_empty,
3839
.sendmarkq_head = t_sendmarkq_head,
39-
.sendmarkq_remove_range = t_sendmarkq_remove_range
40+
.sendmarkq_remove_range = t_sendmarkq_remove_range,
41+
.get_nanoseconds = curvecpr_util_nanoseconds
4042
}
4143
};
4244
unsigned char buf[1024] = { 0 };

libcurvecpr/test/messager/test_send_with_1_failure_moves_message_from_sendq.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <check_extras.h>
33

44
#include <curvecpr/messager.h>
5+
#include <curvecpr/util.h>
56

67
static struct curvecpr_block static_block = {
78
.id = 0,
@@ -74,7 +75,8 @@ START_TEST (test_send_with_1_failure_moves_message_from_sendq)
7475
.sendmarkq_head = t_sendmarkq_head,
7576
.sendq_head = t_sendq_head,
7677
.send = t_send,
77-
.sendq_move_to_sendmarkq = t_sendq_move_to_sendmarkq
78+
.sendq_move_to_sendmarkq = t_sendq_move_to_sendmarkq,
79+
.get_nanoseconds = curvecpr_util_nanoseconds
7880
},
7981
.priv = &send_counter
8082
};

libcurvecpr/test/messager/test_timeout_callback_fires.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <check_extras.h>
33

44
#include <curvecpr/messager.h>
5+
#include <curvecpr/util.h>
56

67
long long test_timeout = -1LL;
78

@@ -67,7 +68,8 @@ START_TEST (test_timeout_callback_fires)
6768
.sendq_head = t_sendq_head,
6869
.send = t_send,
6970
.sendq_move_to_sendmarkq = t_sendq_move_to_sendmarkq,
70-
.put_next_timeout = t_put_next_timeout
71+
.put_next_timeout = t_put_next_timeout,
72+
.get_nanoseconds = curvecpr_util_nanoseconds
7173
}
7274
};
7375

0 commit comments

Comments
 (0)