Skip to content

Commit ea950e6

Browse files
committed
Merge branch 'master' of https://github.com/maglar0/libcurvecpr into bug/9, refs #9
2 parents 3939c78 + 0920edb commit ea950e6

18 files changed

+1623
-16
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/client.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include <sodium/crypto_box.h>
1111

12+
#include <errno.h>
13+
1214
static const unsigned char _zeros[128] = { 0 };
1315

1416
void curvecpr_client_new (struct curvecpr_client *client, const struct curvecpr_client_cf *cf)
@@ -70,7 +72,8 @@ int curvecpr_client_connected (struct curvecpr_client *client)
7072
curvecpr_bytes_copy(p.box, data + 16, 80);
7173
}
7274

73-
cf->ops.send(client, (const unsigned char *)&p, sizeof(struct curvecpr_packet_hello));
75+
if (cf->ops.send(client, (const unsigned char *)&p, sizeof(struct curvecpr_packet_hello)))
76+
return -EAGAIN;
7477

7578
return 0;
7679
}

libcurvecpr/lib/messager.c

Lines changed: 14 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. */
@@ -517,6 +523,11 @@ long long curvecpr_messager_next_timeout (struct curvecpr_messager *messager)
517523

518524
if (at > block->clock + chicago->rtt_timeout)
519525
at = block->clock + chicago->rtt_timeout;
526+
527+
/* Writing faster than wr_rate does not make sense and will cause spinning. BUT, if
528+
there is something to acknowledge, block might still be resent. */
529+
if (cf->ops.recvmarkq_is_empty(messager) && at < messager->my_sent_clock + chicago->wr_rate)
530+
at = messager->my_sent_clock + chicago->wr_rate;
520531
}
521532

522533
if (chicago->clock > at)

libcurvecpr/lib/server_recv.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static int _handle_initiate (struct curvecpr_server *server, struct curvecpr_ses
161161
curvecpr_bytes_zero(vouch, 16);
162162
curvecpr_bytes_copy(vouch + 16, p_box->vouch, 48);
163163

164-
if (crypto_box_afternm(vouch, vouch, 64, nonce, s_new.my_global_their_global_key))
164+
if (crypto_box_open_afternm(vouch, vouch, 64, nonce, s_new.my_global_their_global_key))
165165
return -EINVAL;
166166

167167
if (!curvecpr_bytes_equal(vouch + 32, s_new.their_session_pk, 32))
@@ -171,6 +171,7 @@ static int _handle_initiate (struct curvecpr_server *server, struct curvecpr_ses
171171
/* All good, we can go ahead and submit the client for registration. */
172172
s_new.their_session_nonce = curvecpr_bytes_unpack_uint64(p->nonce);
173173
curvecpr_bytes_copy(s_new.my_domain_name, p_box->server_domain_name, 256);
174+
curvecpr_bytes_copy(s_new.their_extension, p->client_extension, 16);
174175

175176
if (cf->ops.put_session(server, &s_new, priv, &s_new_stored))
176177
return -EINVAL; /* This can fail for a variety of reasons that are up to

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/Makefile.am

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ messager_test_send_with_1_failure_moves_message_from_sendq_SOURCES = messager/te
1818
check_PROGRAMS += messager/test_timeout_callback_fires
1919
messager_test_timeout_callback_fires_SOURCES = messager/test_timeout_callback_fires.c
2020

21+
check_PROGRAMS += messager/test_delivery
22+
messager_test_delivery_SOURCES = messager/test_delivery.c
23+
2124
check_PROGRAMS += util/test_nanoseconds
2225
util_test_nanoseconds_SOURCES = util/test_nanoseconds.c
2326

27+
check_PROGRAMS += packet_delivery/packet_delivery
28+
packet_delivery_packet_delivery_SOURCES = packet_delivery/packet_delivery.c
29+
2430
TESTS = $(check_PROGRAMS)

libcurvecpr/test/messager/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/test_recv_requests_removal_from_sendmarkq
33
/test_send_with_1_failure_moves_message_from_sendq
44
/test_timeout_callback_fires
5+
/test_delivery

0 commit comments

Comments
 (0)