diff --git a/daemon/packets.c b/daemon/packets.c index 9763fef2a..4ec56445a 100644 --- a/daemon/packets.c +++ b/daemon/packets.c @@ -213,6 +213,19 @@ void queue_pkt_revocation(struct peer *peer, queue_pkt(peer, PKT__PKT_UPDATE_REVOCATION, u); } +/* Send a serialized nested packet. */ +void queue_pkt_nested(struct peer *peer, + int type, + const u8 *nested_pkt) +{ + NestedPkt *pb = tal(peer, NestedPkt); + nested_pkt__init(pb); + pb->type = type; + pb->inner_pkt.len = tal_count(nested_pkt); + pb->inner_pkt.data = tal_dup_arr(pb, u8, nested_pkt, pb->inner_pkt.len, 0); + queue_pkt(peer, PKT__PKT_NESTED, pb); +} + Pkt *pkt_err(struct peer *peer, const char *msg, ...) { Error *e = tal(peer, Error); diff --git a/daemon/packets.h b/daemon/packets.h index c2ba2ed73..03d6a0fc2 100644 --- a/daemon/packets.h +++ b/daemon/packets.h @@ -24,6 +24,7 @@ void queue_pkt_revocation(struct peer *peer, const struct sha256 *next_hash); void queue_pkt_close_shutdown(struct peer *peer); void queue_pkt_close_signature(struct peer *peer); +void queue_pkt_nested(struct peer *peer, int type, const u8 *nested_pkt); Pkt *pkt_err(struct peer *peer, const char *msg, ...); Pkt *pkt_init(struct peer *peer, u64 ack); diff --git a/daemon/peer.c b/daemon/peer.c index dc5189d2a..063abd984 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -1854,6 +1854,39 @@ static bool peer_start_shutdown(struct peer *peer) return db_commit_transaction(peer) == NULL; } +/* Shim to handle the new packet format until we complete the + * switch. Handing the protobuf in anyway to fall back on protobuf + * based error handling. */ +static bool nested_pkt_in(struct peer *peer, const u32 type, + const u8 *innerpkt, size_t innerpktlen, + const Pkt *pkt) +{ + switch (type) { + case WIRE_CHANNEL_ANNOUNCEMENT: + handle_channel_announcement( + peer, fromwire_channel_announcement(peer, innerpkt, &innerpktlen)); + break; + case WIRE_CHANNEL_UPDATE: + handle_channel_update( + peer, fromwire_channel_update(peer, innerpkt, &innerpktlen)); + break; + case WIRE_NODE_ANNOUNCEMENT: + handle_node_announcement( + peer, fromwire_node_announcement(peer, innerpkt, &innerpktlen)); + break; + default: + /* BOLT01: Unknown even typed packets MUST kill the + connection, unknown odd-typed packets MAY be ignored. */ + if (type % 2 == 0){ + return peer_received_unexpected_pkt(peer, pkt, __func__); + } else { + log_debug(peer->log, "Ignoring odd typed (%d) unknown packet.", type); + return true; + } + } + return true; +} + /* This is the io loop while we're in normal mode. */ static bool normal_pkt_in(struct peer *peer, const Pkt *pkt) { @@ -2164,11 +2197,18 @@ static void clear_output_queue(struct peer *peer) static struct io_plan *pkt_in(struct io_conn *conn, struct peer *peer) { - bool keep_going; + bool keep_going = true; /* We ignore packets if they tell us to, or we're closing already */ if (peer->fake_close || !state_can_io(peer->state)) keep_going = true; + + /* Sidestep the state machine for nested packets */ + else if (peer->inpkt->pkt_case == PKT__PKT_NESTED) + keep_going = nested_pkt_in(peer, peer->inpkt->nested->type, + peer->inpkt->nested->inner_pkt.data, + peer->inpkt->nested->inner_pkt.len, + peer->inpkt); else if (state_is_normal(peer->state)) keep_going = normal_pkt_in(peer, peer->inpkt); else if (state_is_shutdown(peer->state)) diff --git a/daemon/peer.h b/daemon/peer.h index e9640b721..41301557a 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -14,6 +14,7 @@ #include "netaddr.h" #include "protobuf_convert.h" #include "state.h" +#include "wire/gen_wire.h" #include #include #include