diff --git a/channeld/channel.c b/channeld/channel.c index 51750402e..3d2d3a7b2 100644 --- a/channeld/channel.c +++ b/channeld/channel.c @@ -1514,22 +1514,13 @@ static void handle_peer_fail_malformed_htlc(struct peer *peer, const u8 *msg) static void handle_pong(struct peer *peer, const u8 *pong) { - u8 *ignored; - - status_trace("Got pong!"); - if (!fromwire_pong(pong, pong, &ignored)) + const char *err = got_pong(pong, &peer->num_pings_outstanding); + if (err) peer_failed(&peer->cs, peer->gossip_index, &peer->channel_id, - "Bad pong %s", tal_hex(pong, pong)); + "%s", err); - if (!peer->num_pings_outstanding) - peer_failed(&peer->cs, - peer->gossip_index, - &peer->channel_id, - "Unexpected pong"); - - peer->num_pings_outstanding--; wire_sync_write(MASTER_FD, take(towire_channel_ping_reply(pong, tal_len(pong)))); } diff --git a/common/ping.c b/common/ping.c index dad7b9eca..992b9da49 100644 --- a/common/ping.c +++ b/common/ping.c @@ -1,4 +1,6 @@ #include +#include +#include #include bool check_ping_make_pong(const tal_t *ctx, const u8 *ping, u8 **pong) @@ -31,6 +33,10 @@ bool check_ping_make_pong(const tal_t *ctx, const u8 *ping, u8 **pong) * as secrets, or portions of initialized memory. */ ignored = tal_arrz(ctx, u8, num_pong_bytes); +#if DEVELOPER + /* Embed version */ + strncpy((char *)ignored, version(), num_pong_bytes); +#endif *pong = towire_pong(ctx, ignored); tal_free(ignored); } else @@ -53,3 +59,25 @@ u8 *make_ping(const tal_t *ctx, u16 num_pong_bytes, u16 padlen) tal_free(ignored); return ping; } + +const char *got_pong(const u8 *pong, size_t *num_pings_outstanding) +{ + u8 *ignored; + int i; + + if (!fromwire_pong(pong, pong, &ignored)) + return "Bad pong"; + + if (*num_pings_outstanding == 0) + return "Unexpected pong"; + + for (i = 0; i < tal_len(ignored); i++) { + if (ignored[i] < ' ' || ignored[i] == 127) + break; + } + status_trace("Got pong %zu bytes (%.*s...)", + tal_len(ignored), i, (char *)ignored); + + (*num_pings_outstanding)--; + return NULL; +} diff --git a/common/ping.h b/common/ping.h index 60678f661..490dc4ac4 100644 --- a/common/ping.h +++ b/common/ping.h @@ -10,4 +10,7 @@ bool check_ping_make_pong(const tal_t *ctx, const u8 *ping, u8 **pong); /* Make a ping packet requesting num_pong_bytes */ u8 *make_ping(const tal_t *ctx, u16 num_pong_bytes, u16 padlen); +/* Returns error string if something wrong. */ +const char *got_pong(const u8 *pong, size_t *num_pings_outstanding); + #endif /* LIGHTNING_COMMON_PING_H */ diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 2f3908986..22fed49d7 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -502,20 +502,13 @@ static void handle_ping(struct peer *peer, u8 *ping) static void handle_pong(struct peer *peer, const u8 *pong) { - u8 *ignored; + const char *err = got_pong(pong, &peer->local->num_pings_outstanding); - status_trace("Got pong!"); - if (!fromwire_pong(pong, pong, &ignored)) { - peer_error(peer, "Bad pong"); + if (err) { + peer_error(peer, "%s", err); return; } - if (!peer->local->num_pings_outstanding) { - peer_error(peer, "Unexpected pong"); - return; - } - - peer->local->num_pings_outstanding--; daemon_conn_send(&peer->daemon->master, take(towire_gossip_ping_reply(pong, true, tal_len(pong)))); diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index eb90f6299..c68787eea 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -1863,11 +1863,17 @@ class LightningDTests(BaseLightningDTests): # Test gossip pinging. self.ping_tests(l1, l2) + if DEVELOPER: + l1.daemon.wait_for_log('Got pong 1000 bytes \({}\.\.\.\)' + .format(l2.info['version']), timeout=1) self.fund_channel(l1, l2, 10**5) # channeld pinging self.ping_tests(l1, l2) + if DEVELOPER: + l1.daemon.wait_for_log('Got pong 1000 bytes \({}\.\.\.\)' + .format(l2.info['version'])) @unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") def test_routing_gossip_reconnect(self):