Skip to content

Commit afedf0e

Browse files
committed
cryptopkt: implement ack callbacks.
For the change to asynchronous updates as specified by BOLT #2, we need to know when the other side acknowledged a packet. This creates a simple callback mechanism for it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 8131ff5 commit afedf0e

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

daemon/cryptopkt.c

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ static void setup_crypto(struct dir_state *dir,
102102
dir->cpkt = NULL;
103103
}
104104

105+
struct ack {
106+
struct list_node list;
107+
u64 pktnum;
108+
void (*ack_cb)(struct peer *peer, void *);
109+
void *ack_arg;
110+
};
111+
105112
struct io_data {
106113
/* Stuff we need to keep around to talk to peer. */
107114
struct dir_state in, out;
@@ -114,6 +121,9 @@ struct io_data {
114121

115122
/* For negotiation phase. */
116123
struct key_negotiate *neg;
124+
125+
/* Tracking what needs acks. */
126+
struct list_head acks;
117127
};
118128

119129
static void *proto_tal_alloc(void *allocator_data, size_t size)
@@ -239,6 +249,7 @@ static struct crypto_pkt *encrypt_pkt(struct peer *peer, const Pkt *pkt, u64 ack
239249
static struct io_plan *decrypt_body(struct io_conn *conn, struct peer *peer)
240250
{
241251
struct io_data *iod = peer->io_data;
252+
struct ack *ack;
242253

243254
/* We have full packet. */
244255
peer->inpkt = decrypt_pkt(peer, iod->in.cpkt,
@@ -256,6 +267,15 @@ static struct io_plan *decrypt_body(struct io_conn *conn, struct peer *peer)
256267
peer->inpkt->pkt_case == PKT__PKT_AUTH ? "PKT_AUTH"
257268
: input_name(peer->inpkt->pkt_case));
258269

270+
/* Do callbacks for any packets it acknowledged receiving. */
271+
while ((ack = list_top(&iod->acks, struct ack, list)) != NULL) {
272+
if (le64_to_cpu(iod->hdr_in.acknowledge) < ack->pktnum)
273+
break;
274+
ack->ack_cb(peer, ack->ack_arg);
275+
list_del_from(&iod->acks, &ack->list);
276+
tal_free(ack);
277+
}
278+
259279
return iod->cb(conn, peer);
260280
}
261281

@@ -305,11 +325,13 @@ struct io_plan *peer_read_packet(struct io_conn *conn,
305325
}
306326

307327
/* Caller must free data! */
308-
struct io_plan *peer_write_packet(struct io_conn *conn,
309-
struct peer *peer,
310-
const Pkt *pkt,
311-
struct io_plan *(*next)(struct io_conn *,
312-
struct peer *))
328+
struct io_plan *peer_write_packet_(struct io_conn *conn,
329+
struct peer *peer,
330+
const Pkt *pkt,
331+
void (*ack_cb)(struct peer *peer, void *),
332+
void *ack_arg,
333+
struct io_plan *(*next)(struct io_conn *,
334+
struct peer *))
313335
{
314336
struct io_data *iod = peer->io_data;
315337
size_t totlen;
@@ -320,6 +342,15 @@ struct io_plan *peer_write_packet(struct io_conn *conn,
320342

321343
iod->out.cpkt = encrypt_pkt(peer, pkt, peer->io_data->in.count, &totlen);
322344

345+
/* Set up ack callback if any. */
346+
if (ack_cb) {
347+
struct ack *ack = tal(peer, struct ack);
348+
ack->pktnum = peer->io_data->out.count;
349+
ack->ack_cb = ack_cb;
350+
ack->ack_arg = ack_arg;
351+
list_add_tail(&iod->acks, &ack->list);
352+
}
353+
323354
/* We don't add to count for authenticate case. */
324355
if (pkt->pkt_case != PKT__PKT_AUTH)
325356
peer->io_data->out.count++;
@@ -476,7 +507,7 @@ static struct io_plan *keys_exchanged(struct io_conn *conn, struct peer *peer)
476507

477508
/* FIXME: Free auth afterwards. */
478509
auth = authenticate_pkt(peer, &peer->dstate->id, &sig);
479-
return peer_write_packet(conn, peer, auth, receive_proof);
510+
return peer_write_packet(conn, peer, auth, NULL, NULL, receive_proof);
480511
}
481512

482513
/* Read and ignore any extra bytes... */
@@ -564,6 +595,7 @@ struct io_plan *peer_crypto_setup(struct io_conn *conn, struct peer *peer,
564595
BUILD_ASSERT(CRYPTO_HDR_LEN == offsetof(struct crypto_pkt, data));
565596

566597
peer->io_data = tal(peer, struct io_data);
598+
list_head_init(&peer->io_data->acks);
567599

568600
/* We store negotiation state here. */
569601
neg = peer->io_data->neg = tal(peer->io_data, struct key_negotiate);

daemon/cryptopkt.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "config.h"
44
#include "lightning.pb-c.h"
55
#include <ccan/io/io.h>
6+
#include <ccan/typesafe_cb/typesafe_cb.h>
67

78
struct peer;
89

@@ -17,10 +18,18 @@ struct io_plan *peer_read_packet(struct io_conn *conn,
1718
struct io_plan *(*cb)(struct io_conn *,
1819
struct peer *));
1920

20-
struct io_plan *peer_write_packet(struct io_conn *conn,
21-
struct peer *peer,
22-
const Pkt *pkt,
23-
struct io_plan *(*next)(struct io_conn *,
24-
struct peer *));
21+
struct io_plan *peer_write_packet_(struct io_conn *conn,
22+
struct peer *peer,
23+
const Pkt *pkt,
24+
void (*ack_cb)(struct peer *peer, void *),
25+
void *ack_arg,
26+
struct io_plan *(*next)(struct io_conn *,
27+
struct peer *));
2528

29+
#define peer_write_packet(conn, peer, pkt, ack_cb, ack_arg, next) \
30+
peer_write_packet_((conn), (peer), (pkt), \
31+
typesafe_cb_preargs(void, void *, \
32+
(ack_cb), (ack_arg), \
33+
struct peer *), \
34+
(ack_arg), (next))
2635
#endif /* LIGHTNING_DAEMON_CRYPTOPKT_H */

daemon/peer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ static struct io_plan *pkt_out(struct io_conn *conn, struct peer *peer)
240240
out = peer->outpkt[0];
241241
memmove(peer->outpkt, peer->outpkt + 1, (sizeof(*peer->outpkt)*(n-1)));
242242
tal_resize(&peer->outpkt, n-1);
243-
return peer_write_packet(conn, peer, out, pkt_out);
243+
return peer_write_packet(conn, peer, out, NULL, NULL, pkt_out);
244244
}
245245

246246
static struct io_plan *pkt_in(struct io_conn *conn, struct peer *peer)

0 commit comments

Comments
 (0)