Browse Source

opening: don't die if we get a gossip packet.

Using 'taskset -c 0' I managed to slow down pytest enough to trigger this
locally.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
a12a670d85
  1. 35
      lightningd/opening/opening.c
  2. 30
      wire/peer_wire.c
  3. 2
      wire/peer_wire.h

35
lightningd/opening/opening.c

@ -15,6 +15,7 @@
#include <lightningd/key_derive.h>
#include <lightningd/opening/gen_opening_wire.h>
#include <lightningd/peer_failed.h>
#include <lightningd/ping.h>
#include <lightningd/status.h>
#include <secp256k1.h>
#include <signal.h>
@ -22,6 +23,7 @@
#include <type_to_string.h>
#include <version.h>
#include <wire/gen_peer_wire.h>
#include <wire/peer_wire.h>
#include <wire/wire.h>
#include <wire/wire_sync.h>
@ -162,6 +164,33 @@ static void temporary_channel_id(struct channel_id *channel_id)
channel_id->id[i] = pseudorand(256);
}
/* We have to handle random gossip message and pings. */
static u8 *read_next_peer_msg(struct state *state, const tal_t *ctx)
{
for (;;) {
u8 *msg = sync_crypto_read(ctx, &state->cs, PEER_FD);
if (!msg)
return NULL;
if (fromwire_peektype(msg) == WIRE_PING) {
u8 *pong;
if (!check_ping_make_pong(ctx, msg, &pong)) {
status_trace("Bad ping message");
return tal_free(msg);
}
if (pong && !sync_crypto_write(&state->cs, PEER_FD,
pong))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_WRITE_FAILED,
"Sending pong");
tal_free(pong);
} else if (gossip_msg(msg)) {
/* FIXME: Send to gossip daemon! */
} else {
return msg;
}
}
}
static u8 *open_channel(struct state *state,
const struct pubkey *our_funding_pubkey,
const struct basepoints *ours,
@ -219,7 +248,7 @@ static u8 *open_channel(struct state *state,
state->remoteconf = tal(state, struct channel_config);
msg = sync_crypto_read(tmpctx, &state->cs, PEER_FD);
msg = read_next_peer_msg(state, tmpctx);
if (!msg)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Reading accept_channel");
@ -339,7 +368,7 @@ static u8 *open_channel(struct state *state,
* commitment transaction, so they can broadcast it knowing they can
* redeem their funds if they need to.
*/
msg = sync_crypto_read(tmpctx, &state->cs, PEER_FD);
msg = read_next_peer_msg(state, tmpctx);
if (!msg)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Reading funding_signed");
@ -518,7 +547,7 @@ static u8 *recv_channel(struct state *state,
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_WRITE_FAILED,
"Writing accept_channel");
msg = sync_crypto_read(state, &state->cs, PEER_FD);
msg = read_next_peer_msg(state, state);
if (!msg)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Reading funding_created");

30
wire/peer_wire.c

@ -30,6 +30,36 @@ static bool unknown_type(enum wire_type t)
return true;
}
bool gossip_msg(u8 *cursor)
{
switch (fromwire_peektype(cursor)) {
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_NODE_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
return true;
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_PING:
case WIRE_PONG:
break;
}
return false;
}
/* Return true if it's an unknown message. cursor is a tal ptr. */
bool unknown_msg(const u8 *cursor)
{

2
wire/peer_wire.h

@ -16,5 +16,7 @@
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);
/* Return true if it's a gossip message. */
bool gossip_msg(u8 *cursor);
#endif /* LIGHTNING_WIRE_PEER_WIRE_H */

Loading…
Cancel
Save