Browse Source

cryptopkt: don't create clever io routine, embed callback in io_data.

We have a structure, let's use it to store the callback and avoid
lots of complex code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
8131ff57a8
  1. 118
      daemon/cryptopkt.c

118
daemon/cryptopkt.c

@ -11,7 +11,6 @@
#include <ccan/build_assert/build_assert.h>
#include <ccan/crypto/sha256/sha256.h>
#include <ccan/endian/endian.h>
#include <ccan/io/io_plan.h>
#include <ccan/mem/mem.h>
#include <ccan/short_types/short_types.h>
#include <inttypes.h>
@ -108,9 +107,11 @@ struct io_data {
struct dir_state in, out;
/* Header we're currently reading. */
size_t len_in;
struct crypto_pkt hdr_in;
/* Callback once packet decrypted. */
struct io_plan *(*cb)(struct io_conn *, struct peer *);
/* For negotiation phase. */
struct key_negotiate *neg;
};
@ -182,8 +183,8 @@ static bool decrypt_in_place(void *data, size_t len,
return false;
}
static Pkt *decrypt_body(struct peer *peer, struct crypto_pkt *cpkt,
size_t data_len)
static Pkt *decrypt_pkt(struct peer *peer, struct crypto_pkt *cpkt,
size_t data_len)
{
struct io_data *iod = peer->io_data;
struct ProtobufCAllocator prototal;
@ -235,69 +236,15 @@ static struct crypto_pkt *encrypt_pkt(struct peer *peer, const Pkt *pkt, u64 ack
return cpkt;
}
static int do_read_packet(int fd, struct io_plan_arg *arg)
static struct io_plan *decrypt_body(struct io_conn *conn, struct peer *peer)
{
struct peer *peer = arg->u1.vp;
struct io_data *iod = peer->io_data;
u64 max;
size_t data_off;
int ret;
/* Still reading header? */
if (iod->len_in < CRYPTO_HDR_LEN) {
ret = read(fd, (char *)&iod->hdr_in + iod->len_in,
CRYPTO_HDR_LEN - iod->len_in);
if (ret <= 0)
return -1;
iod->len_in += ret;
/* More to go? */
if (iod->len_in != CRYPTO_HDR_LEN)
return 0;
/* We have header: Check it. */
if (!decrypt_in_place(&iod->hdr_in, CRYPTO_HDR_LEN_NOTAG,
&iod->in.nonce, &iod->in.enckey)) {
log_unusual(peer->log, "Header decryption failed");
return -1;
}
/* BOLT #1: `length` MUST NOT exceed 1MB (1048576 bytes). */
if (le32_to_cpu(iod->hdr_in.length) > MAX_PKT_LEN) {
log_unusual(peer->log,
"Packet overlength: %"PRIu64,
le64_to_cpu(iod->hdr_in.length));
return -1;
}
/* Allocate room for body, copy header. */
max = CRYPTO_HDR_LEN
+ le32_to_cpu(iod->hdr_in.length)
+ crypto_aead_chacha20poly1305_ABYTES;
iod->in.cpkt = (struct crypto_pkt *)tal_arr(peer, char, max);
memcpy(iod->in.cpkt, &iod->hdr_in, CRYPTO_HDR_LEN);
return 0;
}
/* Reading body. */
data_off = iod->len_in - CRYPTO_HDR_LEN;
max = le32_to_cpu(iod->hdr_in.length)
+ crypto_aead_chacha20poly1305_ABYTES;
ret = read(fd, iod->in.cpkt->data + data_off, max - data_off);
if (ret <= 0)
return -1;
iod->len_in += ret;
if (iod->len_in <= max)
return 0;
/* We have full packet. */
peer->inpkt = decrypt_body(peer, iod->in.cpkt,
le32_to_cpu(iod->hdr_in.length));
peer->inpkt = decrypt_pkt(peer, iod->in.cpkt,
le32_to_cpu(iod->hdr_in.length));
if (!peer->inpkt)
return -1;
return io_close(conn);
/* Increment count if it wasn't an authenticate packet */
if (peer->inpkt->pkt_case != PKT__PKT_AUTH)
@ -308,8 +255,41 @@ static int do_read_packet(int fd, struct io_plan_arg *arg)
le32_to_cpu(iod->hdr_in.length),
peer->inpkt->pkt_case == PKT__PKT_AUTH ? "PKT_AUTH"
: input_name(peer->inpkt->pkt_case));
return 1;
return iod->cb(conn, peer);
}
static struct io_plan *decrypt_header(struct io_conn *conn, struct peer *peer)
{
struct io_data *iod = peer->io_data;
size_t body_len;
/* We have header: Check it. */
if (!decrypt_in_place(&iod->hdr_in, CRYPTO_HDR_LEN_NOTAG,
&iod->in.nonce, &iod->in.enckey)) {
log_unusual(peer->log, "Header decryption failed");
return io_close(conn);
}
log_debug(peer->log, "Decrypted header len %u",
le32_to_cpu(iod->hdr_in.length));
/* BOLT #1: `length` MUST NOT exceed 1MB (1048576 bytes). */
if (le32_to_cpu(iod->hdr_in.length) > MAX_PKT_LEN) {
log_unusual(peer->log,
"Packet overlength: %"PRIu64,
le64_to_cpu(iod->hdr_in.length));
return io_close(conn);
}
/* Allocate room for body, copy header. */
body_len = le32_to_cpu(iod->hdr_in.length)
+ crypto_aead_chacha20poly1305_ABYTES;
iod->in.cpkt = (struct crypto_pkt *)tal_arr(peer, char,
CRYPTO_HDR_LEN + body_len);
memcpy(iod->in.cpkt, &iod->hdr_in, CRYPTO_HDR_LEN);
return io_read(conn, iod->in.cpkt->data, body_len, decrypt_body, peer);
}
struct io_plan *peer_read_packet(struct io_conn *conn,
@ -317,13 +297,11 @@ struct io_plan *peer_read_packet(struct io_conn *conn,
struct io_plan *(*cb)(struct io_conn *,
struct peer *))
{
struct io_plan_arg *arg = io_plan_arg(conn, IO_IN);
struct io_data *iod = peer->io_data;
peer->io_data->len_in = 0;
arg->u1.vp = peer;
return io_set_plan(conn, IO_IN, do_read_packet,
(struct io_plan *(*)(struct io_conn *, void *))cb,
peer);
iod->cb = cb;
return io_read(conn, &iod->hdr_in, CRYPTO_HDR_LEN,
decrypt_header, peer);
}
/* Caller must free data! */

Loading…
Cancel
Save