Skip to content

Commit 0f35441

Browse files
committed
protocol: move ack out of header into specific packets.
This reflects the BOLT #1/#2 protocol change, as suggeted by Pierre. Signed-off-by: Rusty Russell <[email protected]>
1 parent 0e07cc7 commit 0f35441

File tree

7 files changed

+141
-56
lines changed

7 files changed

+141
-56
lines changed

daemon/cryptopkt.c

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,17 @@
2222
#define MAX_PKT_LEN (1024 * 1024)
2323

2424
/* BOLT#1:
25-
The header consists of the following fields in order:
26-
27-
* `acknowledge`: an 8-byte little-endian field indicating the number of non-`authenticate` messages received and processed so far.
28-
* `length`: a 4-byte little-endian field indicating the size of the unencrypted body.
25+
`length` is a 4-byte little-endian field indicating the size of the unencrypted body.
2926
*/
3027

31-
/* Do NOT take sizeof() this, since there's extra padding at the end! */
3228
struct crypto_pkt {
33-
le64 acknowledge;
3429
le32 length;
3530
u8 auth_tag[crypto_aead_chacha20poly1305_ABYTES];
3631

3732
/* ... contents... */
3833
u8 data[];
3934
};
4035

41-
/* Use this instead of sizeof(struct crypto_pkt) */
42-
#define CRYPTO_HDR_LEN_NOTAG (8 + 4)
43-
#define CRYPTO_HDR_LEN (CRYPTO_HDR_LEN_NOTAG + crypto_aead_chacha20poly1305_ABYTES)
44-
4536
/* Temporary structure for negotiation (peer->io_data->neg) */
4637
struct key_negotiate {
4738
/* Our session secret key. */
@@ -113,7 +104,7 @@ struct io_data {
113104
/* Stuff we need to keep around to talk to peer. */
114105
struct dir_state in, out;
115106

116-
/* Header we're currently reading. */
107+
/* Length we're currently reading. */
117108
struct crypto_pkt hdr_in;
118109

119110
/* Callback once packet decrypted. */
@@ -221,22 +212,21 @@ static Pkt *decrypt_pkt(struct peer *peer, struct crypto_pkt *cpkt,
221212
return ret;
222213
}
223214

224-
static struct crypto_pkt *encrypt_pkt(struct peer *peer, const Pkt *pkt, u64 ack,
215+
static struct crypto_pkt *encrypt_pkt(struct peer *peer, const Pkt *pkt,
225216
size_t *totlen)
226217
{
227218
struct crypto_pkt *cpkt;
228219
size_t len;
229220
struct io_data *iod = peer->io_data;
230221

231222
len = pkt__get_packed_size(pkt);
232-
*totlen = CRYPTO_HDR_LEN + len + crypto_aead_chacha20poly1305_ABYTES;
223+
*totlen = sizeof(*cpkt) + len + crypto_aead_chacha20poly1305_ABYTES;
233224

234225
cpkt = (struct crypto_pkt *)tal_arr(peer, char, *totlen);
235-
cpkt->acknowledge = cpu_to_le64(ack);
236226
cpkt->length = cpu_to_le32(len);
237227

238228
/* Encrypt header. */
239-
encrypt_in_place(cpkt, CRYPTO_HDR_LEN_NOTAG,
229+
encrypt_in_place(cpkt, sizeof(cpkt->length),
240230
&iod->out.nonce, &iod->out.enckey);
241231

242232
/* Encrypt body. */
@@ -246,11 +236,29 @@ static struct crypto_pkt *encrypt_pkt(struct peer *peer, const Pkt *pkt, u64 ack
246236
return cpkt;
247237
}
248238

249-
static struct io_plan *decrypt_body(struct io_conn *conn, struct peer *peer)
239+
void peer_process_acks(struct peer *peer, uint64_t acknum)
250240
{
251241
struct io_data *iod = peer->io_data;
252242
struct ack *ack;
253243

244+
while ((ack = list_top(&iod->acks, struct ack, list)) != NULL) {
245+
if (acknum < ack->pktnum)
246+
break;
247+
ack->ack_cb(peer, ack->ack_arg);
248+
list_del_from(&iod->acks, &ack->list);
249+
tal_free(ack);
250+
}
251+
}
252+
253+
uint64_t peer_outgoing_ack(const struct peer *peer)
254+
{
255+
return peer->io_data->in.count;
256+
}
257+
258+
static struct io_plan *decrypt_body(struct io_conn *conn, struct peer *peer)
259+
{
260+
struct io_data *iod = peer->io_data;
261+
254262
/* We have full packet. */
255263
peer->inpkt = decrypt_pkt(peer, iod->in.cpkt,
256264
le32_to_cpu(iod->hdr_in.length));
@@ -261,21 +269,11 @@ static struct io_plan *decrypt_body(struct io_conn *conn, struct peer *peer)
261269
if (peer->inpkt->pkt_case != PKT__PKT_AUTH)
262270
iod->in.count++;
263271

264-
log_debug(peer->log, "Received packet ACK=%"PRIu64" LEN=%u, type=%s",
265-
le64_to_cpu(iod->hdr_in.acknowledge),
272+
log_debug(peer->log, "Received packet LEN=%u, type=%s",
266273
le32_to_cpu(iod->hdr_in.length),
267274
peer->inpkt->pkt_case == PKT__PKT_AUTH ? "PKT_AUTH"
268275
: input_name(peer->inpkt->pkt_case));
269276

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-
279277
return iod->cb(conn, peer);
280278
}
281279

@@ -284,8 +282,8 @@ static struct io_plan *decrypt_header(struct io_conn *conn, struct peer *peer)
284282
struct io_data *iod = peer->io_data;
285283
size_t body_len;
286284

287-
/* We have header: Check it. */
288-
if (!decrypt_in_place(&iod->hdr_in, CRYPTO_HDR_LEN_NOTAG,
285+
/* We have length: Check it. */
286+
if (!decrypt_in_place(&iod->hdr_in.length, sizeof(iod->hdr_in.length),
289287
&iod->in.nonce, &iod->in.enckey)) {
290288
log_unusual(peer->log, "Header decryption failed");
291289
return io_close(conn);
@@ -305,9 +303,9 @@ static struct io_plan *decrypt_header(struct io_conn *conn, struct peer *peer)
305303
body_len = le32_to_cpu(iod->hdr_in.length)
306304
+ crypto_aead_chacha20poly1305_ABYTES;
307305

308-
iod->in.cpkt = (struct crypto_pkt *)tal_arr(peer, char,
309-
CRYPTO_HDR_LEN + body_len);
310-
memcpy(iod->in.cpkt, &iod->hdr_in, CRYPTO_HDR_LEN);
306+
iod->in.cpkt = (struct crypto_pkt *)
307+
tal_arr(peer, char, sizeof(iod->hdr_in) + body_len);
308+
*iod->in.cpkt = iod->hdr_in;
311309

312310
return io_read(conn, iod->in.cpkt->data, body_len, decrypt_body, peer);
313311
}
@@ -320,7 +318,7 @@ struct io_plan *peer_read_packet(struct io_conn *conn,
320318
struct io_data *iod = peer->io_data;
321319

322320
iod->cb = cb;
323-
return io_read(conn, &iod->hdr_in, CRYPTO_HDR_LEN,
321+
return io_read(conn, &iod->hdr_in, sizeof(iod->hdr_in),
324322
decrypt_header, peer);
325323
}
326324

@@ -340,7 +338,7 @@ struct io_plan *peer_write_packet_(struct io_conn *conn,
340338
* via io_write */
341339
tal_free(iod->out.cpkt);
342340

343-
iod->out.cpkt = encrypt_pkt(peer, pkt, peer->io_data->in.count, &totlen);
341+
iod->out.cpkt = encrypt_pkt(peer, pkt, &totlen);
344342

345343
/* Set up ack callback if any. */
346344
if (ack_cb) {
@@ -417,24 +415,26 @@ static struct io_plan *check_proof(struct io_conn *conn, struct peer *peer)
417415
return io_close(conn);
418416
}
419417

420-
tal_free(auth);
421-
422418
/* Auth messages don't add to count. */
423419
assert(peer->io_data->in.count == 0);
424420

425421
/* BOLT #1:
426-
* The receiver MUST NOT examine the `acknowledge` value until
427-
* after the authentication fields have been successfully
428-
* validated. The `acknowledge` field MUST BE set to the
429-
* number of non-authenticate messages received and processed.
422+
*
423+
* The receiver MUST NOT examine the `ack` value until after
424+
* the authentication fields have been successfully validated.
425+
* The `ack` field MUST BE set to the number of
426+
* non-authenticate messages received and processed if
427+
* non-zero.
430428
*/
431429
/* FIXME: Handle reconnects. */
432-
if (le64_to_cpu(peer->io_data->hdr_in.acknowledge) != 0) {
430+
if (auth->ack != 0) {
433431
log_unusual(peer->log, "FIXME: non-zero acknowledge %"PRIu64,
434-
le64_to_cpu(peer->io_data->hdr_in.acknowledge));
432+
auth->ack);
435433
return io_close(conn);
436434
}
437435

436+
tal_free(auth);
437+
438438
/* All complete, return to caller. */
439439
cb = neg->cb;
440440
peer->io_data->neg = tal_free(neg);
@@ -524,6 +524,8 @@ static struct io_plan *discard_extra(struct io_conn *conn, struct peer *peer)
524524

525525
len -= sizeof(neg->their_sessionpubkey);
526526
discard = tal_arr(neg, char, len);
527+
log_unusual(peer->log, "Ignoring %zu extra handshake bytes",
528+
len);
527529
return io_read(conn, discard, len, keys_exchanged, peer);
528530
}
529531

@@ -592,7 +594,12 @@ struct io_plan *peer_crypto_setup(struct io_conn *conn, struct peer *peer,
592594
secp256k1_pubkey sessionkey;
593595
struct key_negotiate *neg;
594596

595-
BUILD_ASSERT(CRYPTO_HDR_LEN == offsetof(struct crypto_pkt, data));
597+
/* BOLT #1:
598+
*
599+
* The 4-byte length for each message is encrypted separately
600+
* (resulting in a 20 byte header when the authentication tag
601+
* is appended) */
602+
BUILD_ASSERT(sizeof(struct crypto_pkt) == 20);
596603

597604
peer->io_data = tal(peer, struct io_data);
598605
list_head_init(&peer->io_data->acks);

daemon/cryptopkt.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,11 @@ struct io_plan *peer_write_packet_(struct io_conn *conn,
3232
(ack_cb), (ack_arg), \
3333
struct peer *), \
3434
(ack_arg), (next))
35+
36+
/* Acknowledgements are contained in some messages: caller must call this */
37+
void peer_process_acks(struct peer *peer, uint64_t ack);
38+
39+
/* Ack counter for outgoing packets. */
40+
uint64_t peer_outgoing_ack(const struct peer *peer);
41+
3542
#endif /* LIGHTNING_DAEMON_CRYPTOPKT_H */

daemon/packets.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "close_tx.h"
44
#include "commit_tx.h"
55
#include "controlled_time.h"
6+
#include "cryptopkt.h"
67
#include "find_p2sh_out.h"
78
#include "lightningd.h"
89
#include "log.h"
@@ -333,6 +334,7 @@ void queue_pkt_commit(struct peer *peer)
333334
/* Now send message */
334335
update_commit__init(u);
335336
u->sig = signature_to_proto(u, &ci->sig->sig);
337+
u->ack = peer_outgoing_ack(peer);
336338

337339
queue_pkt(peer, PKT__PKT_UPDATE_COMMIT, u);
338340
}
@@ -362,6 +364,7 @@ void queue_pkt_revocation(struct peer *peer)
362364

363365
u->next_revocation_hash = sha256_to_proto(u,
364366
&peer->us.next_revocation_hash);
367+
u->ack = peer_outgoing_ack(peer);
365368

366369
queue_pkt(peer, PKT__PKT_UPDATE_REVOCATION, u);
367370
}

daemon/peer.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,17 @@ static struct io_plan *pkt_in(struct io_conn *conn, struct peer *peer)
280280
idata.pkt = tal_steal(ctx, peer->inpkt);
281281

282282
/* We ignore packets if they tell us to. */
283-
if (peer->cond != PEER_CLOSED)
283+
if (peer->cond != PEER_CLOSED) {
284+
/* These two packets contain acknowledgements. */
285+
if (idata.pkt->pkt_case == PKT__PKT_UPDATE_COMMIT)
286+
peer_process_acks(peer,
287+
idata.pkt->update_commit->ack);
288+
else if (idata.pkt->pkt_case == PKT__PKT_UPDATE_REVOCATION)
289+
peer_process_acks(peer,
290+
idata.pkt->update_revocation->ack);
291+
284292
state_event(peer, peer->inpkt->pkt_case, &idata);
293+
}
285294

286295
/* Free peer->inpkt unless stolen above. */
287296
tal_free(ctx);

0 commit comments

Comments
 (0)