lightningd/cryptomsg: discard unknown odd messages internally.

This saves all callers having to handle it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-04-01 20:55:59 +10:30
parent 47da80fdca
commit 4839916038
6 changed files with 82 additions and 3 deletions

View File

@ -10,6 +10,7 @@
#include <lightningd/status.h> #include <lightningd/status.h>
#include <sodium/crypto_aead_chacha20poly1305.h> #include <sodium/crypto_aead_chacha20poly1305.h>
#include <utils.h> #include <utils.h>
#include <wire/peer_wire.h>
#include <wire/wire.h> #include <wire/wire.h>
#include <wire/wire_io.h> #include <wire/wire_io.h>
@ -132,6 +133,16 @@ static struct io_plan *peer_decrypt_body(struct io_conn *conn,
if (!decrypted) if (!decrypted)
return io_close(conn); return io_close(conn);
/* BOLT #1:
*
* A node MUST ignore a received message of unknown type, if that type
* is odd.
*/
if (unlikely(unknown_msg_discardable(decrypted))) {
pcs->in = tal_free(pcs->in);
return peer_read_message(conn, pcs, pcs->next_in);
}
/* Steal cs->in: we free it after, and decrypted too unless /* Steal cs->in: we free it after, and decrypted too unless
* they steal but be careful not to touch anything after * they steal but be careful not to touch anything after
* next_in (could free itself) */ * next_in (could free itself) */

View File

@ -32,7 +32,7 @@ struct peer_crypto_state {
/* Initializes peer->cs (still need to read in cs->cs) */ /* Initializes peer->cs (still need to read in cs->cs) */
void init_peer_crypto_state(struct peer *peer, struct peer_crypto_state *pcs); void init_peer_crypto_state(struct peer *peer, struct peer_crypto_state *pcs);
/* Get decrypted message */ /* Get decrypted message: ignores unknown odd messages. */
struct io_plan *peer_read_message(struct io_conn *conn, struct io_plan *peer_read_message(struct io_conn *conn,
struct peer_crypto_state *cs, struct peer_crypto_state *cs,
struct io_plan *(*next)(struct io_conn *, struct io_plan *(*next)(struct io_conn *,
@ -49,7 +49,7 @@ struct io_plan *peer_write_message(struct io_conn *conn,
void towire_crypto_state(u8 **pptr, const struct crypto_state *cs); void towire_crypto_state(u8 **pptr, const struct crypto_state *cs);
void fromwire_crypto_state(const u8 **ptr, size_t *max, struct crypto_state *cs); void fromwire_crypto_state(const u8 **ptr, size_t *max, struct crypto_state *cs);
/* Low-level functions for sync comms. */ /* Low-level functions for sync comms: doesn't discard unknowns! */
u8 *cryptomsg_encrypt_msg(const tal_t *ctx, u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
struct crypto_state *cs, struct crypto_state *cs,
const u8 *msg); const u8 *msg);

View File

@ -3,6 +3,7 @@
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <lightningd/status.h> #include <lightningd/status.h>
#include <stdio.h> #include <stdio.h>
#include <wire/peer_wire.h>
#include <wire/wire_io.h> #include <wire/wire_io.h>
#undef io_read #undef io_read
@ -37,6 +38,9 @@ static void do_write(const void *buf, size_t len)
#define status_trace(fmt, ...) \ #define status_trace(fmt, ...) \
printf(fmt "\n", __VA_ARGS__) printf(fmt "\n", __VA_ARGS__)
/* We test what look like unknown messages. */
#define unknown_msg_discardable(x) 0
#include "../cryptomsg.c" #include "../cryptomsg.c"
const void *trc; const void *trc;

View File

@ -4,7 +4,8 @@
wire-wrongdir: wire-wrongdir:
$(MAKE) -C .. wire-all $(MAKE) -C .. wire-all
WIRE_HEADERS := wire/wire.h \ WIRE_HEADERS := wire/peer_wire.h \
wire/wire.h \
wire/wire_sync.h \ wire/wire_sync.h \
wire/wire_io.h wire/wire_io.h
WIRE_GEN_HEADERS := wire/gen_peer_wire.h wire/gen_onion_wire.h WIRE_GEN_HEADERS := wire/gen_peer_wire.h wire/gen_onion_wire.h
@ -13,6 +14,7 @@ WIRE_GEN_ONION_SRC := wire/gen_onion_wire.c
WIRE_SRC := wire/wire_sync.c \ WIRE_SRC := wire/wire_sync.c \
wire/wire_io.c \ wire/wire_io.c \
wire/fromwire.c \ wire/fromwire.c \
wire/peer_wire.c \
wire/towire.c wire/towire.c
WIRE_OBJS := $(WIRE_SRC:.c=.o) $(WIRE_GEN_SRC:.c=.o) WIRE_OBJS := $(WIRE_SRC:.c=.o) $(WIRE_GEN_SRC:.c=.o)

42
wire/peer_wire.c Normal file
View File

@ -0,0 +1,42 @@
#include <wire/peer_wire.h>
static bool unknown_type(enum wire_type t)
{
switch (t) {
case WIRE_INIT:
case WIRE_ERROR:
case WIRE_OPEN_CHANNEL:
case WIRE_ACCEPT_CHANNEL:
case WIRE_FUNDING_CREATED:
case WIRE_FUNDING_SIGNED:
case WIRE_FUNDING_LOCKED:
case WIRE_SHUTDOWN:
case WIRE_CLOSING_SIGNED:
case WIRE_UPDATE_ADD_HTLC:
case WIRE_UPDATE_FULFILL_HTLC:
case WIRE_UPDATE_FAIL_HTLC:
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
case WIRE_COMMITMENT_SIGNED:
case WIRE_REVOKE_AND_ACK:
case WIRE_UPDATE_FEE:
case WIRE_ANNOUNCEMENT_SIGNATURES:
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_NODE_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
return false;
}
return true;
}
/* Return true if it's an unknown message. cursor is a tal ptr. */
bool unknown_msg(const u8 *cursor)
{
return unknown_type(fromwire_peektype(cursor));
}
/* Return true if it's an unknown ODD message. cursor is a tal ptr. */
bool unknown_msg_discardable(const u8 *cursor)
{
enum wire_type t = fromwire_peektype(cursor);
return unknown_type(t) && (t & 1);
}

20
wire/peer_wire.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef LIGHTNING_WIRE_PEER_WIRE_H
#define LIGHTNING_WIRE_PEER_WIRE_H
#include "config.h"
#include <stdbool.h>
#include <wire/gen_peer_wire.h>
/* BOLT #1:
*
* A node MUST ignore a received message of unknown type, if that type is odd.
*
* A node MUST fail the channels if it receives a message of unknown type, if
* that type is even.
*/
/* Return true if it's an unknown message. cursor is a tal ptr. */
bool unknown_msg(const u8 *cursor);
/* Return true if it's an unknown ODD message. cursor is a tal ptr. */
bool unknown_msg_discardable(const u8 *cursor);
#endif /* LIGHTNING_WIRE_PEER_WIRE_H */