diff --git a/channeld/Makefile b/channeld/Makefile index 241bec9df..18224212f 100644 --- a/channeld/Makefile +++ b/channeld/Makefile @@ -60,6 +60,7 @@ CHANNELD_COMMON_OBJS := \ common/node_id.o \ common/peer_billboard.o \ common/peer_failed.o \ + common/per_peer_state.o \ common/permute_tx.o \ common/ping.o \ common/pseudorand.o \ diff --git a/channeld/channel_wire.csv b/channeld/channel_wire.csv index 3b7bdc69b..bf39c0857 100644 --- a/channeld/channel_wire.csv +++ b/channeld/channel_wire.csv @@ -1,6 +1,7 @@ #include #include #include +#include # Begin! (passes gossipd-client fd) channel_init,1000 @@ -16,7 +17,7 @@ channel_init,,feerate_per_kw,2*u32 channel_init,,feerate_min,u32 channel_init,,feerate_max,u32 channel_init,,first_commit_sig,struct bitcoin_signature -channel_init,,crypto_state,struct crypto_state +channel_init,,per_peer_state,struct per_peer_state channel_init,,remote_fundingkey,struct pubkey channel_init,,remote_basepoints,struct basepoints channel_init,,remote_per_commit,struct pubkey @@ -162,7 +163,7 @@ channel_got_shutdown,,scriptpubkey,scriptpubkey_len*u8 # Shutdown is complete, ready for closing negotiation. + peer_fd & gossip_fd. channel_shutdown_complete,1025 -channel_shutdown_complete,,crypto_state,struct crypto_state +channel_shutdown_complete,,per_peer_state,struct per_peer_state # Re-enable commit timer. channel_dev_reenable_commit,1026 diff --git a/channeld/channeld.c b/channeld/channeld.c index f2427f549..76f21b592 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -61,13 +61,10 @@ /* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = HSM */ #define MASTER_FD STDIN_FILENO -#define PEER_FD 3 -#define GOSSIP_FD 4 -#define GOSSIP_STORE_FD 5 #define HSM_FD 6 struct peer { - struct crypto_state cs; + struct per_peer_state *pps; bool funding_locked[NUM_SIDES]; u64 next_index[NUM_SIDES]; @@ -316,7 +313,7 @@ static void send_channel_update(struct peer *peer, int disable_flag) peer->fee_base, peer->fee_per_satoshi, advertised_htlc_max(peer->channel)); - wire_sync_write(GOSSIP_FD, take(msg)); + wire_sync_write(peer->pps->gossip_fd, take(msg)); } /** @@ -338,7 +335,7 @@ static void make_channel_local_active(struct peer *peer) &peer->short_channel_ids[LOCAL], &peer->node_ids[REMOTE], peer->channel->funding); - wire_sync_write(GOSSIP_FD, take(msg)); + wire_sync_write(peer->pps->gossip_fd, take(msg)); /* Tell gossipd and the other side what parameters we expect should * they route through us */ @@ -394,7 +391,7 @@ static void send_announcement_signatures(struct peer *peer) NULL, &peer->channel_id, &peer->short_channel_ids[LOCAL], &peer->announcement_node_sigs[LOCAL], &peer->announcement_bitcoin_sigs[LOCAL]); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); } /* Tentatively create a channel_announcement, possibly with invalid @@ -437,7 +434,7 @@ static void check_short_ids_match(struct peer *peer) if (!short_channel_id_eq(&peer->short_channel_ids[LOCAL], &peer->short_channel_ids[REMOTE])) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "We disagree on short_channel_ids:" " I have %s, you say %s", @@ -453,7 +450,7 @@ static void announce_channel(struct peer *peer) cannounce = create_channel_announcement(tmpctx, peer); - wire_sync_write(GOSSIP_FD, cannounce); + wire_sync_write(peer->pps->gossip_fd, cannounce); send_channel_update(peer, 0); } @@ -537,12 +534,12 @@ static void handle_peer_funding_locked(struct peer *peer, const u8 *msg) peer->old_remote_per_commit = peer->remote_per_commit; if (!fromwire_funding_locked(msg, &chanid, &peer->remote_per_commit)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad funding_locked %s", tal_hex(msg, msg)); if (!channel_id_eq(&chanid, &peer->channel_id)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Wrong channel id in %s (expected %s)", tal_hex(tmpctx, msg), @@ -567,14 +564,14 @@ static void handle_peer_announcement_signatures(struct peer *peer, const u8 *msg &peer->short_channel_ids[REMOTE], &peer->announcement_node_sigs[REMOTE], &peer->announcement_bitcoin_sigs[REMOTE])) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad announcement_signatures %s", tal_hex(msg, msg)); /* Make sure we agree on the channel ids */ if (!channel_id_eq(&chanid, &peer->channel_id)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Wrong channel_id: expected %s, got %s", type_to_string(tmpctx, struct channel_id, @@ -640,7 +637,7 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg) if (!fromwire_update_add_htlc(msg, &channel_id, &id, &amount, &payment_hash, &cltv_expiry, onion_routing_packet)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad peer_add_htlc %s", tal_hex(msg, msg)); @@ -648,7 +645,7 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg) cltv_expiry, &payment_hash, onion_routing_packet, &htlc); if (add_err != CHANNEL_ERR_ADD_OK) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad peer_add_htlc: %s", channel_add_err_name(add_err)); @@ -666,7 +663,7 @@ static void handle_peer_feechange(struct peer *peer, const u8 *msg) u32 feerate; if (!fromwire_update_fee(msg, &channel_id, &feerate)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fee %s", tal_hex(msg, msg)); } @@ -679,7 +676,7 @@ static void handle_peer_feechange(struct peer *peer, const u8 *msg) * - MUST fail the channel. */ if (peer->channel->funder != REMOTE) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "update_fee from non-funder?"); @@ -694,7 +691,7 @@ static void handle_peer_feechange(struct peer *peer, const u8 *msg) * - SHOULD fail the channel. */ if (feerate < peer->feerate_min || feerate > peer->feerate_max) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "update_fee %u outside range %u-%u", feerate, peer->feerate_min, peer->feerate_max); @@ -707,7 +704,7 @@ static void handle_peer_feechange(struct peer *peer, const u8 *msg) * - but MAY delay this check until the `update_fee` is committed. */ if (!channel_update_feerate(peer->channel, feerate)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "update_fee %u unaffordable", feerate); @@ -779,7 +776,7 @@ static void maybe_send_shutdown(struct peer *peer) send_channel_update(peer, ROUTING_FLAGS_DISABLED); msg = towire_shutdown(NULL, &peer->channel_id, peer->final_scriptpubkey); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); peer->send_shutdown = false; peer->shutdown_sent[LOCAL] = true; billboard_update(peer); @@ -832,13 +829,13 @@ static u8 *gossipd_wait_sync_reply(const tal_t *ctx, status_trace("Sending gossipd %u", fromwire_peektype(msg)); - wire_sync_write(GOSSIP_FD, msg); + wire_sync_write(peer->pps->gossip_fd, msg); status_trace("... , awaiting %u", replytype); for (;;) { int type; - reply = wire_sync_read(tmpctx, GOSSIP_FD); + reply = wire_sync_read(tmpctx, peer->pps->gossip_fd); /* Gossipd hangs up on us to kill us when a new * connection comes in. */ if (!reply) @@ -850,8 +847,7 @@ static u8 *gossipd_wait_sync_reply(const tal_t *ctx, break; } - handle_gossip_msg(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, - &peer->cs, take(reply)); + handle_gossip_msg(peer->pps, take(reply)); } return reply; @@ -1078,8 +1074,7 @@ static void maybe_send_ping(struct peer *peer) return; /* Send a ping to try to elicit a receive. */ - sync_crypto_write_no_delay(&peer->cs, PEER_FD, - take(make_ping(NULL, 1, 0))); + sync_crypto_write_no_delay(peer->pps, take(make_ping(NULL, 1, 0))); peer->expecting_pong = true; } @@ -1156,7 +1151,7 @@ static void send_commit(struct peer *peer) feerate, max); msg = towire_update_fee(NULL, &peer->channel_id, feerate); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); } /* BOLT #2: @@ -1198,7 +1193,7 @@ static void send_commit(struct peer *peer) msg = towire_commitment_signed(NULL, &peer->channel_id, &commit_sig.s, htlc_sigs); - sync_crypto_write_no_delay(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write_no_delay(peer->pps, take(msg)); maybe_send_shutdown(peer); @@ -1276,7 +1271,7 @@ static void send_revocation(struct peer *peer) start_commit_timer(peer); } - sync_crypto_write_no_delay(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write_no_delay(peer->pps, take(msg)); } static u8 *got_commitsig_msg(const tal_t *ctx, @@ -1385,7 +1380,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) status_trace("Oh hi LND! Empty commitment at #%"PRIu64, peer->next_index[LOCAL]); if (peer->last_empty_commitment == peer->next_index[LOCAL] - 1) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "commit_sig with no changes (again!)"); peer->last_empty_commitment = peer->next_index[LOCAL]; @@ -1399,7 +1394,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) if (!fromwire_commitment_signed(tmpctx, msg, &channel_id, &commit_sig.s, &htlc_sigs)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad commit_sig %s", tal_hex(msg, msg)); /* SIGHASH_ALL is implied. */ @@ -1429,7 +1424,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) if (!check_tx_sig(txs[0], 0, NULL, wscripts[0], &peer->channel->funding_pubkey[REMOTE], &commit_sig)) { dump_htlcs(peer->channel, "receiving commit_sig"); - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad commit_sig signature %"PRIu64" %s for tx %s wscript %s key %s feerate %u", peer->next_index[LOCAL], @@ -1452,7 +1447,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) * - MUST fail the channel. */ if (tal_count(htlc_sigs) != tal_count(txs) - 1) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Expected %zu htlc sigs, not %zu", tal_count(txs) - 1, tal_count(htlc_sigs)); @@ -1472,7 +1467,7 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg) if (!check_tx_sig(txs[1+i], 0, NULL, wscripts[1+i], &remote_htlckey, &sig)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad commit_sig signature %s for htlc %s wscript %s key %s", type_to_string(msg, struct bitcoin_signature, &sig), @@ -1532,13 +1527,13 @@ static void handle_peer_revoke_and_ack(struct peer *peer, const u8 *msg) if (!fromwire_revoke_and_ack(msg, &channel_id, &old_commit_secret, &next_per_commit)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad revoke_and_ack %s", tal_hex(msg, msg)); } if (peer->revocations_received != peer->next_index[REMOTE] - 2) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Unexpected revoke_and_ack"); } @@ -1552,13 +1547,13 @@ static void handle_peer_revoke_and_ack(struct peer *peer, const u8 *msg) */ memcpy(&privkey, &old_commit_secret, sizeof(privkey)); if (!pubkey_from_privkey(&privkey, &per_commit_point)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad privkey %s", type_to_string(msg, struct privkey, &privkey)); } if (!pubkey_eq(&per_commit_point, &peer->old_remote_per_commit)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Wrong privkey %s for %"PRIu64" %s", type_to_string(msg, struct privkey, &privkey), @@ -1604,7 +1599,7 @@ static void handle_peer_fulfill_htlc(struct peer *peer, const u8 *msg) if (!fromwire_update_fulfill_htlc(msg, &channel_id, &id, &preimage)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fulfill_htlc %s", tal_hex(msg, msg)); } @@ -1623,7 +1618,7 @@ static void handle_peer_fulfill_htlc(struct peer *peer, const u8 *msg) case CHANNEL_ERR_HTLC_UNCOMMITTED: case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE: case CHANNEL_ERR_BAD_PREIMAGE: - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fulfill_htlc: failed to fulfill %" PRIu64 " error %s", id, channel_remove_err_name(e)); @@ -1641,7 +1636,7 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg) if (!fromwire_update_fail_htlc(msg, msg, &channel_id, &id, &reason)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fail_htlc %s", tal_hex(msg, msg)); } @@ -1658,7 +1653,7 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg) case CHANNEL_ERR_HTLC_UNCOMMITTED: case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE: case CHANNEL_ERR_BAD_PREIMAGE: - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fail_htlc: failed to remove %" PRIu64 " error %s", id, @@ -1679,7 +1674,7 @@ static void handle_peer_fail_malformed_htlc(struct peer *peer, const u8 *msg) if (!fromwire_update_fail_malformed_htlc(msg, &channel_id, &id, &sha256_of_onion, &failure_code)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fail_malformed_htlc %s", tal_hex(msg, msg)); @@ -1692,7 +1687,7 @@ static void handle_peer_fail_malformed_htlc(struct peer *peer, const u8 *msg) * - MUST fail the channel. */ if (!(failure_code & BADONION)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fail_malformed_htlc failure code %u", failure_code); @@ -1730,7 +1725,7 @@ static void handle_peer_fail_malformed_htlc(struct peer *peer, const u8 *msg) case CHANNEL_ERR_HTLC_UNCOMMITTED: case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE: case CHANNEL_ERR_BAD_PREIMAGE: - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad update_fail_malformed_htlc: failed to remove %" PRIu64 " error %s", id, channel_remove_err_name(e)); @@ -1747,7 +1742,7 @@ static void handle_peer_shutdown(struct peer *peer, const u8 *shutdown) send_channel_update(peer, ROUTING_FLAGS_DISABLED); if (!fromwire_shutdown(tmpctx, shutdown, &channel_id, &scriptpubkey)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Bad shutdown %s", tal_hex(peer, shutdown)); @@ -1764,7 +1759,7 @@ static void handle_peer_shutdown(struct peer *peer, const u8 *shutdown) && !memeq(scriptpubkey, tal_count(scriptpubkey), peer->remote_upfront_shutdown_script, tal_count(peer->remote_upfront_shutdown_script))) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "scriptpubkey %s is not as agreed upfront (%s)", tal_hex(peer, scriptpubkey), @@ -1803,9 +1798,7 @@ static void peer_in(struct peer *peer, const u8 *msg) return; } - if (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, - &peer->cs, - &peer->channel_id, msg)) + if (handle_peer_gossip_or_error(peer->pps, &peer->channel_id, msg)) return; /* Must get funding_locked before almost anything. */ @@ -1816,7 +1809,7 @@ static void peer_in(struct peer *peer, const u8 *msg) /* lnd sends these early; it's harmless. */ && type != WIRE_UPDATE_FEE && type != WIRE_ANNOUNCEMENT_SIGNATURES) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "%s (%u) before funding locked", wire_type_name(type), type); @@ -1879,7 +1872,7 @@ static void peer_in(struct peer *peer, const u8 *msg) abort(); } - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Peer sent unknown message %u (%s)", type, wire_type_name(type)); @@ -1890,7 +1883,7 @@ static void resend_revoke(struct peer *peer) struct pubkey point; /* Current commit is peer->next_index[LOCAL]-1, revoke prior */ u8 *msg = make_revocation_msg(peer, peer->next_index[LOCAL]-2, &point); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); } static void send_fail_or_fulfill(struct peer *peer, const struct htlc *h) @@ -1933,11 +1926,11 @@ static void send_fail_or_fulfill(struct peer *peer, const struct htlc *h) msg = towire_update_fulfill_htlc(NULL, &peer->channel_id, h->id, h->r); } else - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "HTLC %"PRIu64" state %s not failed/fulfilled", h->id, htlc_state_name(h->state)); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); } static void resend_commitment(struct peer *peer, const struct changed_htlc *last) @@ -1971,7 +1964,7 @@ static void resend_commitment(struct peer *peer, const struct changed_htlc *last /* I think this can happen if we actually received revoke_and_ack * then they asked for a retransmit */ if (!h) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "Can't find HTLC %"PRIu64" to resend", last[i].id); @@ -1983,7 +1976,7 @@ static void resend_commitment(struct peer *peer, const struct changed_htlc *last abs_locktime_to_blocks( &h->expiry), h->routing); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); } else if (h->state == SENT_REMOVE_COMMIT) { send_fail_or_fulfill(peer, h); } @@ -1993,7 +1986,7 @@ static void resend_commitment(struct peer *peer, const struct changed_htlc *last if (peer->channel->funder == LOCAL) { msg = towire_update_fee(NULL, &peer->channel_id, channel_feerate(peer->channel, REMOTE)); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); } /* Re-send the commitment_signed itself. */ @@ -2001,7 +1994,7 @@ static void resend_commitment(struct peer *peer, const struct changed_htlc *last &commit_sig); msg = towire_commitment_signed(NULL, &peer->channel_id, &commit_sig.s, htlc_sigs); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); /* If we have already received the revocation for the previous, the * other side shouldn't be asking for a retransmit! */ @@ -2041,7 +2034,7 @@ static void check_future_dataloss_fields(struct peer *peer, tal_hex(tmpctx, msg)); if (!correct) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad future last_local_per_commit_secret: %"PRIu64 " vs %"PRIu64, @@ -2066,7 +2059,7 @@ static void check_future_dataloss_fields(struct peer *peer, remote_current_per_commitment_point))); /* We have to send them an error to trigger dropping to chain. */ - peer_failed(&peer->cs, &peer->channel_id, "Awaiting unilateral close"); + peer_failed(peer->pps, &peer->channel_id, "Awaiting unilateral close"); } /* BOLT #2: @@ -2119,7 +2112,7 @@ static void check_current_dataloss_fields(struct peer *peer, if (!secret_eq_consttime(&old_commit_secret, last_local_per_commit_secret)) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish: your_last_per_commitment_secret %"PRIu64 ": %s should be %s", @@ -2140,7 +2133,7 @@ static void check_current_dataloss_fields(struct peer *peer, if (next_local_commitment_number == peer->revocations_received + 1) { if (!pubkey_eq(remote_current_per_commitment_point, &peer->old_remote_per_commit)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish: remote's " "my_current_per_commitment_point %"PRIu64 @@ -2157,7 +2150,7 @@ static void check_current_dataloss_fields(struct peer *peer, /* We've sent a commit sig but haven't gotten a revoke+ack back */ if (!pubkey_eq(remote_current_per_commitment_point, &peer->remote_per_commit)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish: remote's " "my_current_per_commitment_point %"PRIu64 @@ -2254,7 +2247,7 @@ static void peer_reconnect(struct peer *peer, peer->revocations_received); } - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); peer_billboard(false, "Sent reestablish, waiting for theirs"); @@ -2263,9 +2256,8 @@ static void peer_reconnect(struct peer *peer, * before we've reestablished channel). */ do { clean_tmpctx(); - msg = sync_crypto_read(tmpctx, &peer->cs, PEER_FD); - } while (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, - &peer->cs, &peer->channel_id, msg) + msg = sync_crypto_read(tmpctx, peer->pps); + } while (handle_peer_gossip_or_error(peer->pps, &peer->channel_id, msg) || capture_premature_msg(&premature_msgs, msg)); if (dataloss_protect) { @@ -2275,7 +2267,7 @@ static void peer_reconnect(struct peer *peer, &next_remote_revocation_number, &last_local_per_commitment_secret, &remote_current_per_commitment_point)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish dataloss msg: %s %s", wire_type_name(fromwire_peektype(msg)), @@ -2285,7 +2277,7 @@ static void peer_reconnect(struct peer *peer, if (!fromwire_channel_reestablish(msg, &channel_id, &next_local_commitment_number, &next_remote_revocation_number)) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish msg: %s %s", wire_type_name(fromwire_peektype(msg)), @@ -2314,7 +2306,7 @@ static void peer_reconnect(struct peer *peer, msg = towire_funding_locked(NULL, &peer->channel_id, &peer->next_local_per_commit); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); } /* Note: next_index is the index of the current commit we're working @@ -2339,7 +2331,7 @@ static void peer_reconnect(struct peer *peer, if (next_remote_revocation_number == peer->next_index[LOCAL] - 2) { /* Don't try to retransmit revocation index -1! */ if (peer->next_index[LOCAL] < 2) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish revocation_number: %" PRIu64, @@ -2347,7 +2339,7 @@ static void peer_reconnect(struct peer *peer, } retransmit_revoke_and_ack = true; } else if (next_remote_revocation_number < peer->next_index[LOCAL] - 1) { - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish revocation_number: %"PRIu64 " vs %"PRIu64, @@ -2357,7 +2349,7 @@ static void peer_reconnect(struct peer *peer, if (!dataloss_protect) /* They don't support option_data_loss_protect, we * fail it due to unexpected number */ - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish revocation_number: %"PRIu64 " vs %"PRIu64, @@ -2384,7 +2376,7 @@ static void peer_reconnect(struct peer *peer, if (next_local_commitment_number == peer->next_index[REMOTE] - 1) { /* We completed opening, we don't re-transmit that one! */ if (next_local_commitment_number == 0) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish commitment_number: %" PRIu64, @@ -2401,7 +2393,7 @@ static void peer_reconnect(struct peer *peer, * - SHOULD fail the channel. */ } else if (next_local_commitment_number != peer->next_index[REMOTE]) - peer_failed(&peer->cs, + peer_failed(peer->pps, &peer->channel_id, "bad reestablish commitment_number: %"PRIu64 " vs %"PRIu64, @@ -2514,7 +2506,7 @@ static void handle_funding_depth(struct peer *peer, const u8 *msg) msg = towire_funding_locked(NULL, &peer->channel_id, &peer->next_local_per_commit); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); peer->funding_locked[LOCAL] = true; } @@ -2565,7 +2557,7 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg) peer->htlc_id, amount, &payment_hash, cltv_expiry, onion_routing_packet); - sync_crypto_write(&peer->cs, PEER_FD, take(msg)); + sync_crypto_write(peer->pps, take(msg)); start_commit_timer(peer); /* Tell the master. */ msg = towire_channel_offer_htlc_reply(NULL, peer->htlc_id, @@ -2872,7 +2864,7 @@ static void init_channel(struct peer *peer) feerate_per_kw, &peer->feerate_min, &peer->feerate_max, &peer->their_commit_sig, - &peer->cs, + &peer->pps, &funding_pubkey[REMOTE], &points[REMOTE], &peer->remote_per_commit, @@ -2916,6 +2908,8 @@ static void init_channel(struct peer *peer) &remote_ann_bitcoin_sig)) { master_badmsg(WIRE_CHANNEL_INIT, msg); } + /* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = HSM */ + per_peer_state_set_fds(peer->pps, 3, 4, 5); status_trace("init %s: remote_per_commit = %s, old_remote_per_commit = %s" " next_idx_local = %"PRIu64 @@ -3007,7 +3001,7 @@ static void init_channel(struct peer *peer) /* If we have a funding_signed message, send that immediately */ if (funding_signed) - sync_crypto_write(&peer->cs, PEER_FD, take(funding_signed)); + sync_crypto_write(peer->pps, take(funding_signed)); /* Reenable channel */ channel_announcement_negotiate(peer); @@ -3019,10 +3013,8 @@ static void send_shutdown_complete(struct peer *peer) { /* Now we can tell master shutdown is complete. */ wire_sync_write(MASTER_FD, - take(towire_channel_shutdown_complete(NULL, &peer->cs))); - fdpass_send(MASTER_FD, PEER_FD); - fdpass_send(MASTER_FD, GOSSIP_FD); - fdpass_send(MASTER_FD, GOSSIP_STORE_FD); + take(towire_channel_shutdown_complete(NULL, peer->pps))); + per_peer_state_fdpass_send(MASTER_FD, peer->pps); close(MASTER_FD); } @@ -3064,12 +3056,12 @@ int main(int argc, char *argv[]) FD_ZERO(&fds_in); FD_SET(MASTER_FD, &fds_in); - FD_SET(PEER_FD, &fds_in); - FD_SET(GOSSIP_FD, &fds_in); + FD_SET(peer->pps->peer_fd, &fds_in); + FD_SET(peer->pps->gossip_fd, &fds_in); FD_ZERO(&fds_out); - FD_SET(PEER_FD, &fds_out); - nfds = GOSSIP_FD+1; + FD_SET(peer->pps->peer_fd, &fds_out); + nfds = peer->pps->gossip_fd+1; while (!shutdown_complete(peer)) { struct timemono first; @@ -3122,18 +3114,17 @@ int main(int argc, char *argv[]) "Can't read command: %s", strerror(errno)); req_in(peer, msg); - } else if (FD_ISSET(PEER_FD, &rfds)) { + } else if (FD_ISSET(peer->pps->peer_fd, &rfds)) { /* This could take forever, but who cares? */ - msg = sync_crypto_read(tmpctx, &peer->cs, PEER_FD); + msg = sync_crypto_read(tmpctx, peer->pps); peer_in(peer, msg); - } else if (FD_ISSET(GOSSIP_FD, &rfds)) { - msg = wire_sync_read(tmpctx, GOSSIP_FD); + } else if (FD_ISSET(peer->pps->gossip_fd, &rfds)) { + msg = wire_sync_read(tmpctx, peer->pps->gossip_fd); /* Gossipd hangs up on us to kill us when a new * connection comes in. */ if (!msg) peer_failed_connection_lost(); - handle_gossip_msg(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, - &peer->cs, take(msg)); + handle_gossip_msg(peer->pps, take(msg)); } } diff --git a/closingd/Makefile b/closingd/Makefile index 6086bea51..cda00c58e 100644 --- a/closingd/Makefile +++ b/closingd/Makefile @@ -62,6 +62,7 @@ CLOSINGD_COMMON_OBJS := \ common/msg_queue.o \ common/peer_billboard.o \ common/peer_failed.o \ + common/per_peer_state.o \ common/permute_tx.o \ common/read_peer_msg.o \ common/socket_close.o \ diff --git a/closingd/closing_wire.csv b/closingd/closing_wire.csv index c92cb8b45..040b600d0 100644 --- a/closingd/closing_wire.csv +++ b/closingd/closing_wire.csv @@ -1,8 +1,9 @@ #include #include +#include # Begin! (passes peer fd, gossipd-client fd) closing_init,2001 -closing_init,,crypto_state,struct crypto_state +closing_init,,pps,struct per_peer_state closing_init,,funding_txid,struct bitcoin_txid closing_init,,funding_txout,u16 closing_init,,funding_satoshi,struct amount_sat diff --git a/closingd/closingd.c b/closingd/closingd.c index c7479ba81..337ce44fc 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -27,13 +28,10 @@ /* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */ #define REQ_FD STDIN_FILENO -#define PEER_FD 3 -#define GOSSIP_FD 4 -#define GOSSIP_STORE_FD 5 #define HSM_FD 6 static struct bitcoin_tx *close_tx(const tal_t *ctx, - struct crypto_state *cs, + struct per_peer_state *pps, const struct channel_id *channel_id, u8 *scriptpubkey[NUM_SIDES], const struct bitcoin_txid *funding_txid, @@ -50,7 +48,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, out_minus_fee[LOCAL] = out[LOCAL]; out_minus_fee[REMOTE] = out[REMOTE]; if (!amount_sat_sub(&out_minus_fee[funder], out[funder], fee)) - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "Funder cannot afford fee %s (%s and %s)", type_to_string(tmpctx, struct amount_sat, &fee), type_to_string(tmpctx, struct amount_sat, @@ -73,7 +71,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, out_minus_fee[REMOTE], dust_limit); if (!tx) - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "Both outputs below dust limit:" " funding = %s" " fee = %s" @@ -90,7 +88,7 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx, /* Handle random messages we might get, returning the first non-handled one. */ static u8 *closing_read_peer_msg(const tal_t *ctx, - struct crypto_state *cs, + struct per_peer_state *pps, const struct channel_id *channel_id) { for (;;) { @@ -98,22 +96,17 @@ static u8 *closing_read_peer_msg(const tal_t *ctx, bool from_gossipd; clean_tmpctx(); - msg = peer_or_gossip_sync_read(ctx, PEER_FD, GOSSIP_FD, - cs, &from_gossipd); + msg = peer_or_gossip_sync_read(ctx, pps, &from_gossipd); if (from_gossipd) { - handle_gossip_msg(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, - cs, take(msg)); + handle_gossip_msg(pps, take(msg)); continue; } - if (!handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, - GOSSIP_STORE_FD, - cs, - channel_id, msg)) + if (!handle_peer_gossip_or_error(pps, channel_id, msg)) return msg; } } -static void do_reconnect(struct crypto_state *cs, +static void do_reconnect(struct per_peer_state *pps, const struct channel_id *channel_id, const u64 next_index[NUM_SIDES], u64 revocations_received, @@ -174,13 +167,13 @@ static void do_reconnect(struct crypto_state *cs, revocations_received, last_remote_per_commit_secret, &my_current_per_commitment_point); - sync_crypto_write(cs, PEER_FD, take(msg)); + sync_crypto_write(pps, take(msg)); /* They might have already send reestablish, which triggered us */ if (!channel_reestablish) { do { tal_free(channel_reestablish); - channel_reestablish = closing_read_peer_msg(tmpctx, cs, + channel_reestablish = closing_read_peer_msg(tmpctx, pps, channel_id); /* They *should* send reestablish first, but lnd * sends other messages, which we can ignore since @@ -192,7 +185,7 @@ static void do_reconnect(struct crypto_state *cs, if (!fromwire_channel_reestablish(channel_reestablish, &their_channel_id, &next_local_commitment_number, &next_remote_revocation_number)) { - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "bad reestablish msg: %s %s", wire_type_name(fromwire_peektype(channel_reestablish)), tal_hex(tmpctx, channel_reestablish)); @@ -210,13 +203,13 @@ static void do_reconnect(struct crypto_state *cs, * - MUST retransmit `shutdown`. */ msg = towire_shutdown(NULL, channel_id, final_scriptpubkey); - sync_crypto_write(cs, PEER_FD, take(msg)); + sync_crypto_write(pps, take(msg)); /* FIXME: Spec says to re-xmit funding_locked here if we haven't * done any updates. */ } -static void send_offer(struct crypto_state *cs, +static void send_offer(struct per_peer_state *pps, const struct channel_id *channel_id, const struct pubkey funding_pubkey[NUM_SIDES], u8 *scriptpubkey[NUM_SIDES], @@ -238,7 +231,7 @@ static void send_offer(struct crypto_state *cs, * transaction, as specified in [BOLT * #3](03-transactions.md#closing-transaction). */ - tx = close_tx(tmpctx, cs, channel_id, + tx = close_tx(tmpctx, pps, channel_id, scriptpubkey, funding_txid, funding_txout, @@ -270,7 +263,7 @@ static void send_offer(struct crypto_state *cs, assert(our_sig.sighash_type == SIGHASH_ALL); msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s); - sync_crypto_write(cs, PEER_FD, take(msg)); + sync_crypto_write(pps, take(msg)); } static void tell_master_their_offer(const struct bitcoin_signature *their_sig, @@ -292,7 +285,7 @@ static void tell_master_their_offer(const struct bitcoin_signature *their_sig, /* Returns fee they offered. */ static struct amount_sat -receive_offer(struct crypto_state *cs, +receive_offer(struct per_peer_state *pps, const struct channel_id *channel_id, const struct pubkey funding_pubkey[NUM_SIDES], const u8 *funding_wscript, @@ -314,7 +307,7 @@ receive_offer(struct crypto_state *cs, /* Wait for them to say something interesting */ do { - msg = closing_read_peer_msg(tmpctx, cs, channel_id); + msg = closing_read_peer_msg(tmpctx, pps, channel_id); /* BOLT #2: * @@ -336,7 +329,7 @@ receive_offer(struct crypto_state *cs, their_sig.sighash_type = SIGHASH_ALL; if (!fromwire_closing_signed(msg, &their_channel_id, &received_fee, &their_sig.s)) - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "Expected closing_signed: %s", tal_hex(tmpctx, msg)); @@ -347,7 +340,7 @@ receive_offer(struct crypto_state *cs, * specified in [BOLT #3](03-transactions.md#closing-transaction): * - MUST fail the connection. */ - tx = close_tx(tmpctx, cs, channel_id, + tx = close_tx(tmpctx, pps, channel_id, scriptpubkey, funding_txid, funding_txout, @@ -376,7 +369,7 @@ receive_offer(struct crypto_state *cs, * `dust_limit_satoshis`. * - MAY eliminate its own output. */ - trimmed = close_tx(tmpctx, cs, channel_id, + trimmed = close_tx(tmpctx, pps, channel_id, scriptpubkey, funding_txid, funding_txout, @@ -386,7 +379,7 @@ receive_offer(struct crypto_state *cs, if (!trimmed || !check_tx_sig(trimmed, 0, NULL, funding_wscript, &funding_pubkey[REMOTE], &their_sig)) { - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "Bad closing_signed signature for" " %s (and trimmed version %s)", type_to_string(tmpctx, @@ -470,7 +463,7 @@ static void adjust_feerange(struct feerange *feerange, } /* Figure out what we should offer now. */ -static struct amount_sat adjust_offer(struct crypto_state *cs, +static struct amount_sat adjust_offer(struct per_peer_state *pps, const struct channel_id *channel_id, const struct feerange *feerange, struct amount_sat remote_offer, @@ -480,7 +473,7 @@ static struct amount_sat adjust_offer(struct crypto_state *cs, /* Within 1 satoshi? Agree. */ if (!amount_sat_add(&min_plus_one, feerange->min, AMOUNT_SAT(1))) - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "Fee offer %s min too large", type_to_string(tmpctx, struct amount_sat, &feerange->min)); @@ -490,7 +483,7 @@ static struct amount_sat adjust_offer(struct crypto_state *cs, /* Max is below our minimum acceptable? */ if (amount_sat_less(feerange->max, min_fee_to_accept)) - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "Feerange %s-%s" " below minimum acceptable %s", type_to_string(tmpctx, struct amount_sat, @@ -505,7 +498,7 @@ static struct amount_sat adjust_offer(struct crypto_state *cs, min_fee_to_accept = feerange->min; if (!amount_sat_add(&avg, feerange->max, min_fee_to_accept)) - peer_failed(cs, channel_id, + peer_failed(pps, channel_id, "Fee offer %s max too large", type_to_string(tmpctx, struct amount_sat, &feerange->max)); @@ -539,8 +532,8 @@ int main(int argc, char *argv[]) { setup_locale(); - struct crypto_state cs; const tal_t *ctx = tal(NULL, char); + struct per_peer_state *pps; u8 *msg; struct pubkey funding_pubkey[NUM_SIDES]; struct bitcoin_txid funding_txid, closing_txid; @@ -564,7 +557,7 @@ int main(int argc, char *argv[]) msg = wire_sync_read(tmpctx, REQ_FD); if (!fromwire_closing_init(ctx, msg, - &cs, + &pps, &funding_txid, &funding_txout, &funding, &funding_pubkey[LOCAL], @@ -586,6 +579,9 @@ int main(int argc, char *argv[]) &last_remote_per_commit_secret)) master_badmsg(WIRE_CLOSING_INIT, msg); + /* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */ + per_peer_state_set_fds(pps, 3, 4, 5); + status_trace("out = %s/%s", type_to_string(tmpctx, struct amount_sat, &out[LOCAL]), type_to_string(tmpctx, struct amount_sat, &out[REMOTE])); @@ -600,7 +596,7 @@ int main(int argc, char *argv[]) &funding_pubkey[REMOTE]); if (reconnected) - do_reconnect(&cs, &channel_id, + do_reconnect(pps, &channel_id, next_index, revocations_received, channel_reestablish, final_scriptpubkey, &last_remote_per_commit_secret); @@ -626,7 +622,7 @@ int main(int argc, char *argv[]) whose_turn = funder; for (size_t i = 0; i < 2; i++, whose_turn = !whose_turn) { if (whose_turn == LOCAL) { - send_offer(&cs, + send_offer(pps, &channel_id, funding_pubkey, scriptpubkey, &funding_txid, funding_txout, funding, out, funder, @@ -644,7 +640,7 @@ int main(int argc, char *argv[]) struct amount_sat, &offer[LOCAL])); offer[REMOTE] - = receive_offer(&cs, + = receive_offer(pps, &channel_id, funding_pubkey, funding_wscript, scriptpubkey, &funding_txid, @@ -669,11 +665,11 @@ int main(int argc, char *argv[]) offer[!whose_turn], !whose_turn); if (whose_turn == LOCAL) { - offer[LOCAL] = adjust_offer(&cs, + offer[LOCAL] = adjust_offer(pps, &channel_id, &feerange, offer[REMOTE], min_fee_to_accept); - send_offer(&cs, &channel_id, + send_offer(pps, &channel_id, funding_pubkey, scriptpubkey, &funding_txid, funding_txout, funding, out, funder, @@ -686,7 +682,7 @@ int main(int argc, char *argv[]) " theirs was %"PRIu64" satoshi,", offer[LOCAL], offer[REMOTE]); offer[REMOTE] - = receive_offer(&cs, &channel_id, + = receive_offer(pps, &channel_id, funding_pubkey, funding_wscript, scriptpubkey, &funding_txid, @@ -711,7 +707,7 @@ int main(int argc, char *argv[]) /* We're done! */ /* Properly close the channel first. */ - if (!socket_close(PEER_FD)) + if (!socket_close(pps->peer_fd)) status_unusual("Closing and draining peerfd gave error: %s", strerror(errno)); /* Sending the below will kill us! */ diff --git a/common/Makefile b/common/Makefile index c795c4df7..529ef3af9 100644 --- a/common/Makefile +++ b/common/Makefile @@ -36,6 +36,7 @@ COMMON_SRC_NOGEN := \ common/msg_queue.c \ common/node_id.c \ common/param.c \ + common/per_peer_state.c \ common/peer_billboard.c \ common/peer_failed.c \ common/permute_tx.c \ diff --git a/common/crypto_sync.c b/common/crypto_sync.c index 5b2e168a0..2bea9b203 100644 --- a/common/crypto_sync.c +++ b/common/crypto_sync.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -13,7 +14,7 @@ #include #include -void sync_crypto_write(struct crypto_state *cs, int fd, const void *msg TAKES) +void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES) { #if DEVELOPER bool post_sabotage = false; @@ -22,12 +23,12 @@ void sync_crypto_write(struct crypto_state *cs, int fd, const void *msg TAKES) u8 *enc; status_peer_io(LOG_IO_OUT, msg); - enc = cryptomsg_encrypt_msg(NULL, cs, msg); + enc = cryptomsg_encrypt_msg(NULL, &pps->cs, msg); #if DEVELOPER switch (dev_disconnect(type)) { case DEV_DISCONNECT_BEFORE: - dev_sabotage_fd(fd); + dev_sabotage_fd(pps->peer_fd); peer_failed_connection_lost(); case DEV_DISCONNECT_DROPPKT: enc = tal_free(enc); /* FALL THRU */ @@ -35,19 +36,19 @@ void sync_crypto_write(struct crypto_state *cs, int fd, const void *msg TAKES) post_sabotage = true; break; case DEV_DISCONNECT_BLACKHOLE: - dev_blackhole_fd(fd); + dev_blackhole_fd(pps->peer_fd); break; case DEV_DISCONNECT_NORMAL: break; } #endif - if (!write_all(fd, enc, tal_count(enc))) + if (!write_all(pps->peer_fd, enc, tal_count(enc))) peer_failed_connection_lost(); tal_free(enc); #if DEVELOPER if (post_sabotage) - dev_sabotage_fd(fd); + dev_sabotage_fd(pps->peer_fd); #endif } @@ -62,7 +63,7 @@ void sync_crypto_write(struct crypto_state *cs, int fd, const void *msg TAKES) * afterwards. Even if this is wrong on other non-Linux platforms, it * only means one extra packet. */ -void sync_crypto_write_no_delay(struct crypto_state *cs, int fd, +void sync_crypto_write_no_delay(struct per_peer_state *pps, const void *msg TAKES) { int val; @@ -81,7 +82,7 @@ void sync_crypto_write_no_delay(struct crypto_state *cs, int fd, #endif val = 1; - if (setsockopt(fd, IPPROTO_TCP, opt, &val, sizeof(val)) != 0) { + if (setsockopt(pps->peer_fd, IPPROTO_TCP, opt, &val, sizeof(val)) != 0) { /* This actually happens in testing, where we blackhole the fd */ if (!complained) { status_broken("setsockopt %s=1: %s", @@ -90,34 +91,35 @@ void sync_crypto_write_no_delay(struct crypto_state *cs, int fd, complained = true; } } - sync_crypto_write(cs, fd, msg); + sync_crypto_write(pps, msg); val = 0; - setsockopt(fd, IPPROTO_TCP, opt, &val, sizeof(val)); + setsockopt(pps->peer_fd, IPPROTO_TCP, opt, &val, sizeof(val)); } -u8 *sync_crypto_read(const tal_t *ctx, struct crypto_state *cs, int fd) +u8 *sync_crypto_read(const tal_t *ctx, struct per_peer_state *pps) { u8 hdr[18], *enc, *dec; u16 len; - if (!read_all(fd, hdr, sizeof(hdr))) { + if (!read_all(pps->peer_fd, hdr, sizeof(hdr))) { status_trace("Failed reading header: %s", strerror(errno)); peer_failed_connection_lost(); } - if (!cryptomsg_decrypt_header(cs, hdr, &len)) { - status_trace("Failed hdr decrypt with rn=%"PRIu64, cs->rn-1); + if (!cryptomsg_decrypt_header(&pps->cs, hdr, &len)) { + status_trace("Failed hdr decrypt with rn=%"PRIu64, + pps->cs.rn-1); peer_failed_connection_lost(); } enc = tal_arr(ctx, u8, len + 16); - if (!read_all(fd, enc, tal_count(enc))) { + if (!read_all(pps->peer_fd, enc, tal_count(enc))) { status_trace("Failed reading body: %s", strerror(errno)); peer_failed_connection_lost(); } - dec = cryptomsg_decrypt_body(ctx, cs, enc); + dec = cryptomsg_decrypt_body(ctx, &pps->cs, enc); tal_free(enc); if (!dec) peer_failed_connection_lost(); diff --git a/common/crypto_sync.h b/common/crypto_sync.h index b86c67db9..29816289d 100644 --- a/common/crypto_sync.h +++ b/common/crypto_sync.h @@ -4,16 +4,16 @@ #include #include -struct crypto_state; +struct per_peer_state; /* Exits with peer_failed_connection_lost() if write fails. */ -void sync_crypto_write(struct crypto_state *cs, int fd, const void *msg TAKES); +void sync_crypto_write(struct per_peer_state *pps, const void *msg TAKES); /* Same, but disabled nagle for this message. */ -void sync_crypto_write_no_delay(struct crypto_state *cs, int fd, +void sync_crypto_write_no_delay(struct per_peer_state *pps, const void *msg TAKES); /* Exits with peer_failed_connection_lost() if can't read packet. */ -u8 *sync_crypto_read(const tal_t *ctx, struct crypto_state *cs, int fd); +u8 *sync_crypto_read(const tal_t *ctx, struct per_peer_state *pps); #endif /* LIGHTNING_COMMON_CRYPTO_SYNC_H */ diff --git a/common/peer_failed.c b/common/peer_failed.c index 41318dc74..7eb8a51f0 100644 --- a/common/peer_failed.c +++ b/common/peer_failed.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,11 +9,24 @@ #include #include +/* Fatal error here, return peer control to lightningd */ +static void NORETURN +peer_fatal_continue(const u8 *msg TAKES, const struct per_peer_state *pps) +{ + int reason = fromwire_peektype(msg); + breakpoint(); + status_send(msg); + + status_send_fd(pps->peer_fd); + status_send_fd(pps->gossip_fd); + status_send_fd(pps->gossip_store_fd); + exit(0x80 | (reason & 0xFF)); +} + /* We only support one channel per peer anyway */ -void peer_failed_(int peer_fd, int gossip_fd, int gossip_store_fd, - struct crypto_state *cs, - const struct channel_id *channel_id, - const char *fmt, ...) +void peer_failed(struct per_peer_state *pps, + const struct channel_id *channel_id, + const char *fmt, ...) { va_list ap; const char *desc; @@ -24,20 +38,19 @@ void peer_failed_(int peer_fd, int gossip_fd, int gossip_store_fd, /* Tell peer the error. */ err = towire_errorfmt(desc, channel_id, "%s", desc); - sync_crypto_write(cs, peer_fd, err); + sync_crypto_write(pps, err); /* Tell master the error so it can re-xmit. */ msg = towire_status_peer_error(NULL, channel_id, - desc, cs, + desc, pps, err); peer_billboard(true, desc); tal_free(desc); - status_send_fatal(take(msg), peer_fd, gossip_fd, gossip_store_fd); + peer_fatal_continue(take(msg), pps); } /* We're failing because peer sent us an error message */ -void peer_failed_received_errmsg(int peer_fd, int gossip_fd, int gossip_store_fd, - struct crypto_state *cs, +void peer_failed_received_errmsg(struct per_peer_state *pps, const char *desc, const struct channel_id *channel_id) { @@ -46,13 +59,12 @@ void peer_failed_received_errmsg(int peer_fd, int gossip_fd, int gossip_store_fd if (!channel_id) channel_id = &all_channels; - msg = towire_status_peer_error(NULL, channel_id, desc, cs, NULL); + msg = towire_status_peer_error(NULL, channel_id, desc, pps, NULL); peer_billboard(true, "Received error from peer: %s", desc); - status_send_fatal(take(msg), peer_fd, gossip_fd, gossip_store_fd); + peer_fatal_continue(take(msg), pps); } void peer_failed_connection_lost(void) { - status_send_fatal(take(towire_status_peer_connection_lost(NULL)), - -1, -1, -1); + status_send_fatal(take(towire_status_peer_connection_lost(NULL))); } diff --git a/common/peer_failed.h b/common/peer_failed.h index 51cf274ca..3f068718f 100644 --- a/common/peer_failed.h +++ b/common/peer_failed.h @@ -5,27 +5,22 @@ #include struct channel_id; +struct per_peer_state; /** * peer_failed - Exit with error for peer. - * @cs: the peer's current crypto state. + * @pps: the per-peer state. * @channel_id: channel with error, or NULL for all. * @fmt...: format as per status_failed(STATUS_FAIL_PEER_BAD) */ -#define peer_failed(cs, channel_id, ...) \ - peer_failed_(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, \ - (cs), (channel_id), __VA_ARGS__) - -void peer_failed_(int peer_fd, int gossip_fd, int gossip_store_fd, - struct crypto_state *cs, - const struct channel_id *channel_id, - const char *fmt, ...) - PRINTF_FMT(6,7) NORETURN; +void peer_failed(struct per_peer_state *pps, + const struct channel_id *channel_id, + const char *fmt, ...) + PRINTF_FMT(3,4) NORETURN; /* We're failing because peer sent us an error message: NULL * channel_id means all channels. */ -void peer_failed_received_errmsg(int peer_fd, int gossip_fd, int gossip_store_fd, - struct crypto_state *cs, +void peer_failed_received_errmsg(struct per_peer_state *pps, const char *desc, const struct channel_id *channel_id) NORETURN; diff --git a/common/peer_status_wire.csv b/common/peer_status_wire.csv index f69467f2b..4134df089 100644 --- a/common/peer_status_wire.csv +++ b/common/peer_status_wire.csv @@ -1,10 +1,10 @@ -#include +#include # An error occurred: if error_for_them, that to go to them. status_peer_error,0xFFF4 # This is implied if error_for_them, but master tries not to parse packets. status_peer_error,,channel,struct channel_id status_peer_error,,desc,wirestring -status_peer_error,,crypto_state,struct crypto_state +status_peer_error,,pps,struct per_peer_state status_peer_error,,len,u16 status_peer_error,,error_for_them,len*u8 diff --git a/common/per_peer_state.c b/common/per_peer_state.c new file mode 100644 index 000000000..31d355785 --- /dev/null +++ b/common/per_peer_state.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +static void destroy_per_peer_state(struct per_peer_state *pps) +{ + if (pps->peer_fd != -1) + close(pps->peer_fd); + if (pps->gossip_fd != -1) + close(pps->gossip_fd); + if (pps->gossip_store_fd != -1) + close(pps->gossip_store_fd); +} + +struct per_peer_state *new_per_peer_state(const tal_t *ctx, + const struct crypto_state *cs) +{ + struct per_peer_state *pps = tal(ctx, struct per_peer_state); + + pps->cs = *cs; + pps->peer_fd = pps->gossip_fd = pps->gossip_store_fd = -1; + tal_add_destructor(pps, destroy_per_peer_state); + return pps; +} + +void per_peer_state_set_fds(struct per_peer_state *pps, + int peer_fd, int gossip_fd, int gossip_store_fd) +{ + assert(pps->peer_fd == -1); + assert(pps->gossip_fd == -1); + assert(pps->gossip_store_fd == -1); + pps->peer_fd = peer_fd; + pps->gossip_fd = gossip_fd; + pps->gossip_store_fd = gossip_store_fd; +} + +void per_peer_state_set_fds_arr(struct per_peer_state *pps, const int *fds) +{ + /* We expect 3 fds. */ + assert(tal_count(fds) == 3); + per_peer_state_set_fds(pps, fds[0], fds[1], fds[2]); +} + +void towire_per_peer_state(u8 **pptr, const struct per_peer_state *pps) +{ + towire_crypto_state(pptr, &pps->cs); +} + +void per_peer_state_fdpass_send(int fd, const struct per_peer_state *pps) +{ + assert(pps->peer_fd != -1); + assert(pps->gossip_fd != -1); + assert(pps->gossip_store_fd != -1); + fdpass_send(fd, pps->peer_fd); + fdpass_send(fd, pps->gossip_fd); + fdpass_send(fd, pps->gossip_store_fd); +} + +struct per_peer_state *fromwire_per_peer_state(const tal_t *ctx, + const u8 **cursor, size_t *max) +{ + struct crypto_state cs; + + fromwire_crypto_state(cursor, max, &cs); + return new_per_peer_state(ctx, &cs); +} diff --git a/common/per_peer_state.h b/common/per_peer_state.h new file mode 100644 index 000000000..ed6fa9cf1 --- /dev/null +++ b/common/per_peer_state.h @@ -0,0 +1,36 @@ +#ifndef LIGHTNING_COMMON_PER_PEER_STATE_H +#define LIGHTNING_COMMON_PER_PEER_STATE_H +#include "config.h" + +#include +#include + +/* Things we hand between daemons to talk to peers. */ +struct per_peer_state { + /* Cryptographic state needed to exchange messages with the peer (as + * featured in BOLT #8) */ + struct crypto_state cs; + /* If not -1, closed on freeing */ + int peer_fd, gossip_fd, gossip_store_fd; +}; + +/* Allocate a new per-peer state and add destructor to close fds if set; + * sets fds to -1. */ +struct per_peer_state *new_per_peer_state(const tal_t *ctx, + const struct crypto_state *cs); + +/* Initialize the fds (must be -1 previous) */ +void per_peer_state_set_fds(struct per_peer_state *pps, + int peer_fd, int gossip_fd, int gossip_store_fd); + +/* Array version of above: tal_count(fds) must be 3 */ +void per_peer_state_set_fds_arr(struct per_peer_state *pps, const int *fds); + +/* These routines do *part* of the work: you need to per_peer_state_fdpass_send + * or receive the three fds afterwards! */ +void towire_per_peer_state(u8 **pptr, const struct per_peer_state *pps); +void per_peer_state_fdpass_send(int fd, const struct per_peer_state *pps); + +struct per_peer_state *fromwire_per_peer_state(const tal_t *ctx, + const u8 **cursor, size_t *max); +#endif /* LIGHTNING_COMMON_PER_PEER_STATE_H */ diff --git a/common/read_peer_msg.c b/common/read_peer_msg.c index 330a7437e..f0b6ab3a3 100644 --- a/common/read_peer_msg.c +++ b/common/read_peer_msg.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -15,27 +16,27 @@ #include u8 *peer_or_gossip_sync_read(const tal_t *ctx, - int peer_fd, int gossip_fd, - struct crypto_state *cs, + struct per_peer_state *pps, bool *from_gossipd) { fd_set readfds; u8 *msg; FD_ZERO(&readfds); - FD_SET(peer_fd, &readfds); - FD_SET(gossip_fd, &readfds); + FD_SET(pps->peer_fd, &readfds); + FD_SET(pps->gossip_fd, &readfds); - select(peer_fd > gossip_fd ? peer_fd + 1 : gossip_fd + 1, + select(pps->peer_fd > pps->gossip_fd + ? pps->peer_fd + 1 : pps->gossip_fd + 1, &readfds, NULL, NULL, NULL); - if (FD_ISSET(peer_fd, &readfds)) { - msg = sync_crypto_read(ctx, cs, peer_fd); + if (FD_ISSET(pps->peer_fd, &readfds)) { + msg = sync_crypto_read(ctx, pps); *from_gossipd = false; return msg; } - msg = wire_sync_read(ctx, gossip_fd); + msg = wire_sync_read(ctx, pps->gossip_fd); if (!msg) status_failed(STATUS_FAIL_GOSSIP_IO, "Error reading gossip msg: %s", @@ -83,26 +84,22 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected, return !channel_id_eq(expected, actual); } -static void new_gossip_store(int gossip_store_fd, int new_gossip_store_fd) +static void new_gossip_store(struct per_peer_state *pps, int new_gossip_store_fd) { - if (dup2(new_gossip_store_fd, gossip_store_fd) == -1) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Could not dup2 new fd %i onto %i: %s", - new_gossip_store_fd, gossip_store_fd, - strerror(errno)); + close(pps->gossip_store_fd); + pps->gossip_store_fd = new_gossip_store_fd; } -void handle_gossip_msg(int peer_fd, int gossip_fd, int gossip_store_fd, - struct crypto_state *cs, const u8 *msg TAKES) +void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES) { u8 *gossip; u64 offset; if (fromwire_gossipd_new_store_fd(msg)) { - new_gossip_store(gossip_store_fd, fdpass_recv(gossip_fd)); + new_gossip_store(pps, fdpass_recv(pps->gossip_fd)); goto out; } else if (fromwire_gossipd_send_gossip_from_store(msg, &offset)) - gossip = gossip_store_read(tmpctx, gossip_store_fd, offset); + gossip = gossip_store_read(tmpctx, pps->gossip_store_fd, offset); else if (!fromwire_gossipd_send_gossip(tmpctx, msg, &gossip)) { status_broken("Got bad message from gossipd: %s", tal_hex(msg, msg)); @@ -111,10 +108,10 @@ void handle_gossip_msg(int peer_fd, int gossip_fd, int gossip_store_fd, /* Gossipd can send us gossip messages, OR errors */ if (is_msg_for_gossipd(gossip)) { - sync_crypto_write(cs, peer_fd, gossip); + sync_crypto_write(pps, gossip); } else if (fromwire_peektype(gossip) == WIRE_ERROR) { status_debug("Gossipd told us to send error"); - sync_crypto_write(cs, peer_fd, gossip); + sync_crypto_write(pps, gossip); peer_failed_connection_lost(); } else { status_broken("Gossipd gave us bad send_gossip message %s", @@ -127,8 +124,7 @@ out: tal_free(msg); } -bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, int gossip_store_fd, - struct crypto_state *cs, +bool handle_peer_gossip_or_error(struct per_peer_state *pps, const struct channel_id *channel_id, const u8 *msg TAKES) { @@ -137,16 +133,14 @@ bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, int gossip_store_fd struct channel_id actual; if (is_msg_for_gossipd(msg)) { - wire_sync_write(gossip_fd, msg); + wire_sync_write(pps->gossip_fd, msg); /* wire_sync_write takes, so don't take again. */ return true; } if (is_peer_error(tmpctx, msg, channel_id, &err, &all_channels)) { if (err) - peer_failed_received_errmsg(peer_fd, gossip_fd, - gossip_store_fd, - cs, err, + peer_failed_received_errmsg(pps, err, all_channels ? NULL : channel_id); @@ -159,7 +153,7 @@ bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, int gossip_store_fd status_trace("Rejecting %s for unknown channel_id %s", wire_type_name(fromwire_peektype(msg)), type_to_string(tmpctx, struct channel_id, &actual)); - sync_crypto_write(cs, peer_fd, + sync_crypto_write(pps, take(towire_errorfmt(NULL, &actual, "Multiple channels" " unsupported"))); diff --git a/common/read_peer_msg.h b/common/read_peer_msg.h index 73d5b1c97..fc548f28e 100644 --- a/common/read_peer_msg.h +++ b/common/read_peer_msg.h @@ -6,12 +6,12 @@ struct crypto_state; struct channel_id; +struct per_peer_state; /** * peer_or_gossip_sync_read - read a peer message, or maybe a gossip msg. * @ctx: context to allocate return packet from. - * @peer_fd, @gossip_fd: peer and gossip fd. - * @cs: the cryptostate (updated) + * @pps: the per-peer peer state and fds * @from_gossipd: true if the msg was from gossipd, otherwise false. * * Will call peer_failed_connection_lost() or @@ -24,8 +24,7 @@ struct channel_id; * a valid message. */ u8 *peer_or_gossip_sync_read(const tal_t *ctx, - int peer_fd, int gossip_fd, - struct crypto_state *cs, + struct per_peer_state *pps, bool *from_gossipd); /** @@ -57,8 +56,7 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected, /** * handle_peer_gossip_or_error - simple handler for all the above cases. - * @peer_fd, @gossip_fd, @gossip_store_fd: peer, gossip and gossip_store fds. - * @cs: the cryptostate (updated) + * @pps: per-peer state. * @channel_id: the channel id of the current channel. * @msg: the peer message (only taken if returns true). * @@ -66,15 +64,10 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected, * to gossipd), an error packet (causes peer_failed_received_errmsg or * ignored), or a message about the wrong channel (sends sync error reply). */ -bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, int gossip_store_fd, - struct crypto_state *cs, +bool handle_peer_gossip_or_error(struct per_peer_state *pps, const struct channel_id *channel_id, const u8 *msg TAKES); /* We got this message from gossipd: forward/quit as it asks. */ -void handle_gossip_msg(int peer_fd, - int gossip_fd, - int gossip_store_fd, - struct crypto_state *cs, - const u8 *msg TAKES); +void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES); #endif /* LIGHTNING_COMMON_READ_PEER_MSG_H */ diff --git a/common/status.c b/common/status.c index 3086e7dcc..5d242ef17 100644 --- a/common/status.c +++ b/common/status.c @@ -162,20 +162,18 @@ static NORETURN void flush_and_exit(int reason) exit(0x80 | (reason & 0xFF)); } -void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2, int fd3) +void status_send_fd(int fd) +{ + assert(!status_conn); + fdpass_send(status_fd, fd); +} + +void status_send_fatal(const u8 *msg TAKES) { int reason = fromwire_peektype(msg); breakpoint(); status_send(msg); - /* We don't support async fd passing here. */ - if (fd1 != -1) { - assert(!status_conn); - fdpass_send(status_fd, fd1); - fdpass_send(status_fd, fd2); - fdpass_send(status_fd, fd3); - } - flush_and_exit(reason); } @@ -193,8 +191,7 @@ void status_failed(enum status_failreason reason, const char *fmt, ...) if (reason == STATUS_FAIL_INTERNAL_ERROR) send_backtrace(str); - status_send_fatal(take(towire_status_fail(NULL, reason, str)), - -1, -1, -1); + status_send_fatal(take(towire_status_fail(NULL, reason, str))); } void master_badmsg(u32 type_expected, const u8 *msg) diff --git a/common/status.h b/common/status.h index 16827ed3a..cb5a1ebc1 100644 --- a/common/status.h +++ b/common/status.h @@ -11,6 +11,7 @@ struct channel_id; struct daemon_conn; +struct per_peer_state; /* Simple status reporting API. */ void status_setup_sync(int fd); @@ -51,5 +52,8 @@ void status_failed(enum status_failreason code, void master_badmsg(u32 type_expected, const u8 *msg) NORETURN; void status_send(const u8 *msg TAKES); -void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2, int fd3) NORETURN; +void status_send_fatal(const u8 *msg TAKES) NORETURN; + +/* Only for sync status! */ +void status_send_fd(int fd); #endif /* LIGHTNING_COMMON_STATUS_H */ diff --git a/common/status_wire.csv b/common/status_wire.csv index 5bd88e3f3..33c9eb677 100644 --- a/common/status_wire.csv +++ b/common/status_wire.csv @@ -1,3 +1,4 @@ +#include #include status_log,0xFFF0 diff --git a/connectd/Makefile b/connectd/Makefile index 443fde468..e1e4c7dfb 100644 --- a/connectd/Makefile +++ b/connectd/Makefile @@ -54,6 +54,7 @@ CONNECTD_COMMON_OBJS := \ common/memleak.o \ common/msg_queue.o \ common/node_id.o \ + common/per_peer_state.o \ common/pseudorand.o \ common/status.o \ common/status_wire.o \ diff --git a/connectd/connect_wire.csv b/connectd/connect_wire.csv index e54ba1746..b3d395dd4 100644 --- a/connectd/connect_wire.csv +++ b/connectd/connect_wire.csv @@ -1,4 +1,5 @@ #include +#include #include #include @@ -49,7 +50,7 @@ connectctl_connect_failed,,addrhint,?struct wireaddr_internal connect_peer_connected,2002 connect_peer_connected,,id,struct node_id connect_peer_connected,,addr,struct wireaddr_internal -connect_peer_connected,,crypto_state,struct crypto_state +connect_peer_connected,,cs,struct crypto_state connect_peer_connected,,gflen,u16 connect_peer_connected,,globalfeatures,gflen*u8 connect_peer_connected,,lflen,u16 diff --git a/connectd/peer_exchange_initmsg.c b/connectd/peer_exchange_initmsg.c index 98a0117d8..c495c963c 100644 --- a/connectd/peer_exchange_initmsg.c +++ b/connectd/peer_exchange_initmsg.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/devtools/Makefile b/devtools/Makefile index d9a544ede..2e6c13964 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -10,9 +10,11 @@ DEVTOOLS_COMMON_OBJS := \ common/bech32.o \ common/bech32_util.o \ common/bolt11.o \ + common/crypto_state.o \ common/decode_short_channel_ids.o \ common/hash_u5.o \ common/node_id.o \ + common/per_peer_state.o \ common/type_to_string.o \ common/utils.o \ common/version.o \ diff --git a/devtools/gossipwith.c b/devtools/gossipwith.c index f55edc286..6fe28a294 100644 --- a/devtools/gossipwith.c +++ b/devtools/gossipwith.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -115,9 +116,10 @@ static struct io_plan *handshake_success(struct io_conn *conn, char **args) { u8 *msg; - struct crypto_state cs = *orig_cs; + struct per_peer_state *pps = new_per_peer_state(conn, orig_cs); u8 *localfeatures; + pps->peer_fd = io_conn_fd(conn); if (initial_sync) { localfeatures = tal(conn, u8); localfeatures[0] = (1 << 3); @@ -126,9 +128,9 @@ static struct io_plan *handshake_success(struct io_conn *conn, msg = towire_init(NULL, NULL, localfeatures); - sync_crypto_write(&cs, conn->fd, take(msg)); + sync_crypto_write(pps, take(msg)); /* Ignore their init message. */ - tal_free(sync_crypto_read(NULL, &cs, conn->fd)); + tal_free(sync_crypto_read(NULL, pps)); /* Did they ask us to send any messages? Do so now. */ if (stream_stdin) { @@ -140,7 +142,7 @@ static struct io_plan *handshake_success(struct io_conn *conn, if (!read_all(STDIN_FILENO, msg, msglen)) err(1, "Only read partial message"); - sync_crypto_write(&cs, conn->fd, take(msg)); + sync_crypto_write(pps, take(msg)); } } @@ -148,12 +150,12 @@ static struct io_plan *handshake_success(struct io_conn *conn, u8 *m = tal_hexdata(NULL, *args, strlen(*args)); if (!m) errx(1, "Invalid hexdata '%s'", *args); - sync_crypto_write(&cs, conn->fd, take(m)); + sync_crypto_write(pps, take(m)); args++; } /* Now write out whatever we get. */ - while ((msg = sync_crypto_read(NULL, &cs, conn->fd)) != NULL) { + while ((msg = sync_crypto_read(NULL, pps)) != NULL) { be16 len = cpu_to_be16(tal_bytelen(msg)); if (!write_all(STDOUT_FILENO, &len, sizeof(len)) diff --git a/lightningd/Makefile b/lightningd/Makefile index 932d8a46c..88ce4ebf6 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -42,6 +42,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/msg_queue.o \ common/node_id.o \ common/param.o \ + common/per_peer_state.o \ common/permute_tx.o \ common/pseudorand.o \ common/sphinx.o \ @@ -84,7 +85,6 @@ LIGHTNINGD_SRC := \ lightningd/pay.c \ lightningd/peer_control.c \ lightningd/peer_htlcs.c \ - lightningd/peer_comms.c \ lightningd/ping.c \ lightningd/plugin.c \ lightningd/plugin_hook.c \ diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 7ffc42e28..a516bd083 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -202,22 +202,17 @@ static void peer_start_closingd_after_shutdown(struct channel *channel, const u8 *msg, const int *fds) { - struct peer_comms *pcomms = new_peer_comms(msg); + struct per_peer_state *pps; - /* We expect 3 fds. */ - assert(tal_count(fds) == 3); - - if (!fromwire_channel_shutdown_complete(msg, &pcomms->cs)) { + if (!fromwire_channel_shutdown_complete(tmpctx, msg, &pps)) { channel_internal_error(channel, "bad shutdown_complete: %s", tal_hex(msg, msg)); return; } - pcomms->peer_fd = fds[0]; - pcomms->gossip_fd = fds[1]; - pcomms->gossip_store_fd = fds[2]; + per_peer_state_set_fds_arr(pps, fds); /* This sets channel->owner, closes down channeld. */ - peer_start_closingd(channel, pcomms, false, NULL); + peer_start_closingd(channel, pps, false, NULL); channel_set_state(channel, CHANNELD_SHUTTING_DOWN, CLOSINGD_SIGEXCHANGE); } @@ -279,7 +274,7 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) } void peer_start_channeld(struct channel *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const u8 *funding_signed, bool reconnected) { @@ -314,9 +309,9 @@ void peer_start_channeld(struct channel *channel, channel_msg, channel_errmsg, channel_set_billboard, - take(&pcomms->peer_fd), - take(&pcomms->gossip_fd), - take(&pcomms->gossip_store_fd), + take(&pps->peer_fd), + take(&pps->gossip_fd), + take(&pps->gossip_store_fd), take(&hsmfd), NULL), false); @@ -390,7 +385,7 @@ void peer_start_channeld(struct channel *channel, feerate_min(ld, NULL), feerate_max(ld, NULL), &channel->last_sig, - &pcomms->cs, + pps, &channel->channel_info.remote_fundingkey, &channel->channel_info.theirbase, &channel->channel_info.remote_per_commit, diff --git a/lightningd/channel_control.h b/lightningd/channel_control.h index 57c168db0..0edd5753b 100644 --- a/lightningd/channel_control.h +++ b/lightningd/channel_control.h @@ -7,10 +7,10 @@ struct channel; struct crypto_state; struct lightningd; -struct peer_comms; +struct per_peer_state; void peer_start_channeld(struct channel *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const u8 *funding_signed, bool reconnected); diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 88721eee7..ce573c074 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include #include -#include #include #include @@ -153,7 +153,7 @@ static unsigned closing_msg(struct subd *sd, const u8 *msg, const int *fds UNUSE } void peer_start_closingd(struct channel *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, bool reconnected, const u8 *channel_reestablish) { @@ -183,9 +183,9 @@ void peer_start_closingd(struct channel *channel, closing_wire_type_name, closing_msg, channel_errmsg, channel_set_billboard, - take(&pcomms->peer_fd), - take(&pcomms->gossip_fd), - take(&pcomms->gossip_store_fd), + take(&pps->peer_fd), + take(&pps->gossip_fd), + take(&pps->gossip_store_fd), take(&hsmfd), NULL), false); @@ -265,7 +265,7 @@ void peer_start_closingd(struct channel *channel, return; } initmsg = towire_closing_init(tmpctx, - &pcomms->cs, + pps, &channel->funding_txid, channel->funding_outnum, channel->funding, diff --git a/lightningd/closing_control.h b/lightningd/closing_control.h index 5e77c6db4..cbaa76ab9 100644 --- a/lightningd/closing_control.h +++ b/lightningd/closing_control.h @@ -5,10 +5,10 @@ struct channel_id; struct crypto_state; -struct peer_comms; +struct per_peer_state; void peer_start_closingd(struct channel *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, bool reconnected, const u8 *channel_reestablish); diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index 6e53aeba9..b90952bbb 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -376,7 +376,7 @@ static bool tell_if_missing(const struct channel *channel, /* Only error onchaind can get is if it dies. */ static void onchain_error(struct channel *channel, - struct peer_comms *pcomms UNUSED, + struct per_peer_state *pps UNUSED, const struct channel_id *channel_id UNUSED, const char *desc, const u8 *err_for_them UNUSED) diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index f85c2ed8e..19804adb0 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -300,12 +300,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, struct channel *channel; struct lightningd *ld = openingd->ld; u8 *remote_upfront_shutdown_script; - struct peer_comms *pcomms = new_peer_comms(resp); - - assert(tal_count(fds) == 3); - pcomms->peer_fd = fds[0]; - pcomms->gossip_fd = fds[1]; - pcomms->gossip_store_fd = fds[2]; + struct per_peer_state *pps; /* This is a new channel_info.their_config so set its ID to 0 */ channel_info.their_config.id = 0; @@ -314,7 +309,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, &channel_info.their_config, &remote_commit, &remote_commit_sig, - &pcomms->cs, + &pps, &channel_info.theirbase.revocation, &channel_info.theirbase.payment, &channel_info.theirbase.htlc, @@ -334,6 +329,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, tal_hex(fc->cmd, resp))); goto failed; } + per_peer_state_set_fds_arr(pps, fds); + log_debug(ld->log, "%s", type_to_string(tmpctx, struct pubkey, &channel_info.remote_per_commit)); @@ -460,7 +457,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, wallet_confirm_utxos(ld->wallet, fc->wtx.utxos); /* Start normal channel daemon. */ - peer_start_channeld(channel, pcomms, NULL, false); + peer_start_channeld(channel, pps, NULL, false); subd_release_channel(openingd, fc->uc); fc->uc->openingd = NULL; @@ -492,13 +489,9 @@ static void opening_fundee_finished(struct subd *openingd, u8 channel_flags; struct channel *channel; u8 *remote_upfront_shutdown_script; - struct peer_comms *pcomms = new_peer_comms(reply); + struct per_peer_state *pps; log_debug(uc->log, "Got opening_fundee_finish_response"); - assert(tal_count(fds) == 3); - pcomms->peer_fd = fds[0]; - pcomms->gossip_fd = fds[1]; - pcomms->gossip_store_fd = fds[2]; /* This is a new channel_info.their_config, set its ID to 0 */ channel_info.their_config.id = 0; @@ -507,7 +500,7 @@ static void opening_fundee_finished(struct subd *openingd, &channel_info.their_config, &remote_commit, &remote_commit_sig, - &pcomms->cs, + &pps, &channel_info.theirbase.revocation, &channel_info.theirbase.payment, &channel_info.theirbase.htlc, @@ -528,6 +521,7 @@ static void opening_fundee_finished(struct subd *openingd, uncommitted_channel_disconnect(uc, "bad OPENING_FUNDEE_REPLY"); goto failed; } + per_peer_state_set_fds_arr(pps, fds); /* openingd should never accept them funding channel in this case. */ if (peer_active_channel(uc->peer)) { @@ -560,7 +554,7 @@ static void opening_fundee_finished(struct subd *openingd, channel_watch_funding(ld, channel); /* On to normal operation! */ - peer_start_channeld(channel, pcomms, funding_signed, false); + peer_start_channeld(channel, pps, funding_signed, false); subd_release_channel(openingd, uc); uc->openingd = NULL; @@ -598,13 +592,13 @@ static void opening_funder_failed(struct subd *openingd, const u8 *msg, } static void opening_channel_errmsg(struct uncommitted_channel *uc, - struct peer_comms *pcomms, + struct per_peer_state *pps, const struct channel_id *channel_id UNUSED, const char *desc, const u8 *err_for_them UNUSED) { /* Close fds, if any. */ - tal_free(pcomms); + tal_free(pps); uncommitted_channel_disconnect(uc, desc); tal_free(uc); } @@ -921,7 +915,7 @@ static unsigned int openingd_msg(struct subd *openingd, } void peer_start_openingd(struct peer *peer, - struct peer_comms *pcomms, + struct per_peer_state *pps, const u8 *send_msg) { int hsmfd; @@ -945,9 +939,9 @@ void peer_start_openingd(struct peer *peer, openingd_msg, opening_channel_errmsg, opening_channel_set_billboard, - take(&pcomms->peer_fd), - take(&pcomms->gossip_fd), - take(&pcomms->gossip_store_fd), + take(&pps->peer_fd), + take(&pps->gossip_fd), + take(&pps->gossip_store_fd), take(&hsmfd), NULL); if (!uc->openingd) { uncommitted_channel_disconnect(uc, @@ -974,7 +968,7 @@ void peer_start_openingd(struct peer *peer, &uc->our_config, max_to_self_delay, min_effective_htlc_capacity, - &pcomms->cs, &uc->local_basepoints, + pps, &uc->local_basepoints, &uc->local_funding_pubkey, uc->minimum_depth, feerate_min(peer->ld, NULL), diff --git a/lightningd/opening_control.h b/lightningd/opening_control.h index b39cb103c..23df19eb3 100644 --- a/lightningd/opening_control.h +++ b/lightningd/opening_control.h @@ -7,14 +7,14 @@ struct channel_id; struct crypto_state; struct json_stream; struct lightningd; -struct peer_comms; +struct per_peer_state; struct uncommitted_channel; void json_add_uncommitted_channel(struct json_stream *response, const struct uncommitted_channel *uc); void peer_start_openingd(struct peer *peer, - struct peer_comms *pcomms, + struct per_peer_state *pps, const u8 *msg); void kill_uncommitted_channel(struct uncommitted_channel *uc, diff --git a/lightningd/peer_comms.c b/lightningd/peer_comms.c deleted file mode 100644 index c518d2de6..000000000 --- a/lightningd/peer_comms.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -static void destroy_peer_comms(struct peer_comms *pcomms) -{ - if (pcomms->peer_fd != -1) - close(pcomms->peer_fd); - if (pcomms->gossip_fd != -1) - close(pcomms->gossip_fd); - if (pcomms->gossip_store_fd != -1) - close(pcomms->gossip_store_fd); -} - -struct peer_comms *new_peer_comms(const tal_t *ctx) -{ - struct peer_comms *pcomms = tal(ctx, struct peer_comms); - - tal_add_destructor(pcomms, destroy_peer_comms); - return pcomms; -} diff --git a/lightningd/peer_comms.h b/lightningd/peer_comms.h deleted file mode 100644 index 15e6b530c..000000000 --- a/lightningd/peer_comms.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef LIGHTNING_LIGHTNINGD_PEER_COMMS_H -#define LIGHTNING_LIGHTNINGD_PEER_COMMS_H -#include "config.h" - -#include -#include - -/* Things we hand between daemons to talk to peers. */ -struct peer_comms { - struct crypto_state cs; - /* If not -1, closed on freeing */ - int peer_fd, gossip_fd, gossip_store_fd; -}; - -struct peer_comms *new_peer_comms(const tal_t *ctx); -#endif /* LIGHTNING_LIGHTNINGD_PEER_COMMS_H */ diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 5e3669b2c..00b3a0232 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -370,13 +370,13 @@ void drop_to_chain(struct lightningd *ld, struct channel *channel, } void channel_errmsg(struct channel *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const struct channel_id *channel_id UNUSED, const char *desc, const u8 *err_for_them) { - /* No peer_comms means a subd crash or disconnection. */ - if (!pcomms) { + /* No per_peer_state means a subd crash or disconnection. */ + if (!pps) { channel_fail_transient(channel, "%s: %s", channel->owner->name, desc); return; @@ -421,7 +421,7 @@ struct peer_connected_hook_payload { struct channel *channel; struct wireaddr_internal addr; struct peer *peer; - struct peer_comms *pcomms; + struct per_peer_state *pps; }; static void json_add_htlcs(struct lightningd *ld, @@ -760,7 +760,7 @@ peer_connected_hook_cb(struct peer_connected_hook_payload *payload, assert(!channel->owner); channel->peer->addr = addr; - peer_start_channeld(channel, payload->pcomms, NULL, + peer_start_channeld(channel, payload->pps, NULL, true); tal_free(payload); return; @@ -769,7 +769,7 @@ peer_connected_hook_cb(struct peer_connected_hook_payload *payload, assert(!channel->owner); channel->peer->addr = addr; - peer_start_closingd(channel, payload->pcomms, + peer_start_closingd(channel, payload->pps, true, NULL); tal_free(payload); return; @@ -783,7 +783,7 @@ peer_connected_hook_cb(struct peer_connected_hook_payload *payload, error = NULL; send_error: - peer_start_openingd(peer, payload->pcomms, error); + peer_start_openingd(peer, payload->pps, error); tal_free(payload); } @@ -801,21 +801,21 @@ void peer_connected(struct lightningd *ld, const u8 *msg, u8 *globalfeatures, *localfeatures; struct peer *peer; struct peer_connected_hook_payload *hook_payload; + struct crypto_state cs; hook_payload = tal(NULL, struct peer_connected_hook_payload); hook_payload->ld = ld; - hook_payload->pcomms = new_peer_comms(hook_payload); - hook_payload->pcomms->peer_fd = peer_fd; - hook_payload->pcomms->gossip_fd = gossip_fd; - hook_payload->pcomms->gossip_store_fd = gossip_store_fd; - if (!fromwire_connect_peer_connected(msg, msg, &id, &hook_payload->addr, - &hook_payload->pcomms->cs, + &cs, &globalfeatures, &localfeatures)) fatal("Connectd gave bad CONNECT_PEER_CONNECTED message %s", tal_hex(msg, msg)); + hook_payload->pps = new_per_peer_state(hook_payload, &cs); + per_peer_state_set_fds(hook_payload->pps, + peer_fd, gossip_fd, gossip_store_fd); + /* Complete any outstanding connect commands. */ connect_succeeded(ld, &id); diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 797424e7d..8ad197f17 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -15,7 +15,7 @@ #include #include -struct peer_comms; +struct per_peer_state; struct peer { /* Inside ld->peers. */ @@ -75,7 +75,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg, #define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL void channel_errmsg(struct channel *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const struct channel_id *channel_id, const char *desc, const u8 *err_for_them); diff --git a/lightningd/subd.c b/lightningd/subd.c index 8d5bc5663..f961b0cfc 100644 --- a/lightningd/subd.c +++ b/lightningd/subd.c @@ -11,12 +11,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -368,21 +368,19 @@ static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[3]) void *channel = sd->channel; struct channel_id channel_id; char *desc; - struct peer_comms *pcomms = new_peer_comms(msg); + struct per_peer_state *pps; u8 *err_for_them; if (!fromwire_status_peer_error(msg, msg, &channel_id, &desc, - &pcomms->cs, &err_for_them)) + &pps, &err_for_them)) return false; - pcomms->peer_fd = fds[0]; - pcomms->gossip_fd = fds[1]; - pcomms->gossip_store_fd = fds[2]; + per_peer_state_set_fds_arr(pps, fds); /* Don't free sd; we may be about to free channel. */ sd->channel = NULL; - sd->errcb(channel, pcomms, &channel_id, desc, err_for_them); + sd->errcb(channel, pps, &channel_id, desc, err_for_them); return true; } @@ -610,7 +608,7 @@ static struct subd *new_subd(struct lightningd *ld, unsigned int (*msgcb)(struct subd *, const u8 *, const int *fds), void (*errcb)(void *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const struct channel_id *channel_id, const char *desc, const u8 *err_for_them), @@ -700,7 +698,7 @@ struct subd *new_channel_subd_(struct lightningd *ld, unsigned int (*msgcb)(struct subd *, const u8 *, const int *fds), void (*errcb)(void *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const struct channel_id *channel_id, const char *desc, const u8 *err_for_them), diff --git a/lightningd/subd.h b/lightningd/subd.h index fcde5e871..2d21bc43e 100644 --- a/lightningd/subd.h +++ b/lightningd/subd.h @@ -11,7 +11,7 @@ struct crypto_state; struct io_conn; -struct peer_comms; +struct per_peer_state; /* By convention, replies are requests + 100 */ #define SUBD_REPLY_OFFSET 100 @@ -39,11 +39,11 @@ struct subd { unsigned (*msgcb)(struct subd *, const u8 *, const int *); const char *(*msgname)(int msgtype); - /* If peer_comms == NULL, it was a disconnect/crash. Otherwise, + /* If per_peer_state == NULL, it was a disconnect/crash. Otherwise, * sufficient information to hand back to gossipd, including the * error message we sent them if any. */ void (*errcb)(void *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const struct channel_id *channel_id, const char *desc, const u8 *err_for_them); @@ -117,7 +117,7 @@ struct subd *new_channel_subd_(struct lightningd *ld, unsigned int (*msgcb)(struct subd *, const u8 *, const int *fds), void (*errcb)(void *channel, - struct peer_comms *pcomms, + struct per_peer_state *pps, const struct channel_id *channel_id, const char *desc, const u8 *err_for_them), @@ -131,7 +131,7 @@ struct subd *new_channel_subd_(struct lightningd *ld, (msgname), (msgcb), \ typesafe_cb_postargs(void, void *, (errcb), \ (channel), \ - struct peer_comms *, \ + struct per_peer_state *, \ const struct channel_id *, \ const char *, const u8 *), \ typesafe_cb_postargs(void, void *, (billboardcb), \ diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c index 7ca42d4d0..9590aebb8 100644 --- a/lightningd/test/run-find_my_abspath.c +++ b/lightningd/test/run-find_my_abspath.c @@ -70,7 +70,7 @@ bool fromwire_status_fail(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, enu bool fromwire_status_peer_billboard(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, bool *perm UNNEEDED, wirestring **happenings UNNEEDED) { fprintf(stderr, "fromwire_status_peer_billboard called!\n"); abort(); } /* Generated stub for fromwire_status_peer_error */ -bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct channel_id *channel UNNEEDED, wirestring **desc UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **error_for_them UNNEEDED) +bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct channel_id *channel UNNEEDED, wirestring **desc UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **error_for_them UNNEEDED) { fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); } /* Generated stub for get_log_book */ struct log_book *get_log_book(const struct log *log UNNEEDED) @@ -125,15 +125,15 @@ struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, struct log_book *new_log_book(size_t max_mem UNNEEDED, enum log_level printlevel UNNEEDED) { fprintf(stderr, "new_log_book called!\n"); abort(); } -/* Generated stub for new_peer_comms */ -struct peer_comms *new_peer_comms(const tal_t *ctx UNNEEDED) -{ fprintf(stderr, "new_peer_comms called!\n"); abort(); } /* Generated stub for new_topology */ struct chain_topology *new_topology(struct lightningd *ld UNNEEDED, struct log *log UNNEEDED) { fprintf(stderr, "new_topology called!\n"); abort(); } /* Generated stub for onchaind_replay_channels */ void onchaind_replay_channels(struct lightningd *ld UNNEEDED) { fprintf(stderr, "onchaind_replay_channels called!\n"); abort(); } +/* Generated stub for per_peer_state_set_fds_arr */ +void per_peer_state_set_fds_arr(struct per_peer_state *pps UNNEEDED, const int *fds UNNEEDED) +{ fprintf(stderr, "per_peer_state_set_fds_arr called!\n"); abort(); } /* Generated stub for plugins_config */ void plugins_config(struct plugins *plugins UNNEEDED) { fprintf(stderr, "plugins_config called!\n"); abort(); } diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index ebb2bd283..fac183984 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -83,7 +83,7 @@ void fatal(const char *fmt UNNEEDED, ...) bool fromwire_channel_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED) { fprintf(stderr, "fromwire_channel_dev_memleak_reply called!\n"); abort(); } /* Generated stub for fromwire_connect_peer_connected */ -bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED) +bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *cs UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED) { fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); } /* Generated stub for fromwire_gossip_get_incoming_channels_reply */ bool fromwire_gossip_get_incoming_channels_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct route_info **route_info UNNEEDED) @@ -260,9 +260,10 @@ struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, struct log_book *new_log_book(size_t max_mem UNNEEDED, enum log_level printlevel UNNEEDED) { fprintf(stderr, "new_log_book called!\n"); abort(); } -/* Generated stub for new_peer_comms */ -struct peer_comms *new_peer_comms(const tal_t *ctx UNNEEDED) -{ fprintf(stderr, "new_peer_comms called!\n"); abort(); } +/* Generated stub for new_per_peer_state */ +struct per_peer_state *new_per_peer_state(const tal_t *ctx UNNEEDED, + const struct crypto_state *cs UNNEEDED) +{ fprintf(stderr, "new_per_peer_state called!\n"); abort(); } /* Generated stub for new_reltimer_ */ struct oneshot *new_reltimer_(struct timers *timers UNNEEDED, const tal_t *ctx UNNEEDED, @@ -367,21 +368,25 @@ void peer_memleak_done(struct command *cmd UNNEEDED, struct subd *leaker UNNEEDE { fprintf(stderr, "peer_memleak_done called!\n"); abort(); } /* Generated stub for peer_start_channeld */ void peer_start_channeld(struct channel *channel UNNEEDED, - struct peer_comms *pcomms UNNEEDED, + struct per_peer_state *pps UNNEEDED, const u8 *funding_signed UNNEEDED, bool reconnected UNNEEDED) { fprintf(stderr, "peer_start_channeld called!\n"); abort(); } /* Generated stub for peer_start_closingd */ void peer_start_closingd(struct channel *channel UNNEEDED, - struct peer_comms *pcomms UNNEEDED, + struct per_peer_state *pps UNNEEDED, bool reconnected UNNEEDED, const u8 *channel_reestablish UNNEEDED) { fprintf(stderr, "peer_start_closingd called!\n"); abort(); } /* Generated stub for peer_start_openingd */ void peer_start_openingd(struct peer *peer UNNEEDED, - struct peer_comms *pcomms UNNEEDED, + struct per_peer_state *pps UNNEEDED, const u8 *msg UNNEEDED) { fprintf(stderr, "peer_start_openingd called!\n"); abort(); } +/* Generated stub for per_peer_state_set_fds */ +void per_peer_state_set_fds(struct per_peer_state *pps UNNEEDED, + int peer_fd UNNEEDED, int gossip_fd UNNEEDED, int gossip_store_fd UNNEEDED) +{ fprintf(stderr, "per_peer_state_set_fds called!\n"); abort(); } /* Generated stub for plugin_hook_call_ */ void plugin_hook_call_(struct lightningd *ld UNNEEDED, const struct plugin_hook *hook UNNEEDED, void *payload UNNEEDED, void *cb_arg UNNEEDED) diff --git a/openingd/Makefile b/openingd/Makefile index 11104c3a2..fbd762fc4 100644 --- a/openingd/Makefile +++ b/openingd/Makefile @@ -58,6 +58,7 @@ OPENINGD_COMMON_OBJS := \ common/keyset.o \ common/memleak.o \ common/msg_queue.o \ + common/per_peer_state.o \ common/peer_billboard.o \ common/peer_failed.o \ common/permute_tx.o \ diff --git a/openingd/opening_wire.csv b/openingd/opening_wire.csv index 1d4504423..82dc8ed66 100644 --- a/openingd/opening_wire.csv +++ b/openingd/opening_wire.csv @@ -1,6 +1,7 @@ #include #include #include +#include opening_init,6000 # Which network are we configured for? @@ -10,7 +11,7 @@ opening_init,,our_config,struct channel_config # Minimum/maximum configuration values we'll accept opening_init,,max_to_self_delay,u32 opening_init,,min_effective_htlc_capacity_msat,struct amount_msat -opening_init,,crypto_state,struct crypto_state +opening_init,,pps,struct per_peer_state opening_init,,our_basepoints,struct basepoints opening_init,,our_funding_pubkey,struct pubkey # Constraints in case the other end tries to open a channel. @@ -62,7 +63,7 @@ opening_funder_reply,6101 opening_funder_reply,,their_config,struct channel_config opening_funder_reply,,first_commit,struct bitcoin_tx opening_funder_reply,,first_commit_sig,struct bitcoin_signature -opening_funder_reply,,crypto_state,struct crypto_state +opening_funder_reply,,pps,struct per_peer_state opening_funder_reply,,revocation_basepoint,struct pubkey opening_funder_reply,,payment_basepoint,struct pubkey opening_funder_reply,,htlc_basepoint,struct pubkey @@ -86,7 +87,7 @@ opening_fundee,6003 opening_fundee,,their_config,struct channel_config opening_fundee,,first_commit,struct bitcoin_tx opening_fundee,,first_commit_sig,struct bitcoin_signature -opening_fundee,,crypto_state,struct crypto_state +opening_fundee,,pps,struct per_peer_state opening_fundee,,revocation_basepoint,struct pubkey opening_fundee,,payment_basepoint,struct pubkey opening_fundee,,htlc_basepoint,struct pubkey diff --git a/openingd/openingd.c b/openingd/openingd.c index ddcb8d76c..05b1a9898 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -50,16 +50,11 @@ /* stdin == lightningd, 3 == peer, 4 == gossipd, 5 = gossip_store, 6 = hsmd */ #define REQ_FD STDIN_FILENO -#define PEER_FD 3 -#define GOSSIP_FD 4 -#define GOSSIP_STORE_FD 5 #define HSM_FD 6 /* Global state structure. This is only for the one specific peer and channel */ struct state { - /* Cryptographic state needed to exchange messages with the peer (as - * featured in BOLT #8) */ - struct crypto_state cs; + struct per_peer_state *pps; /* Features they offered */ u8 *localfeatures; @@ -157,7 +152,7 @@ static void negotiation_failed(struct state *state, bool am_funder, msg = towire_errorfmt(NULL, &state->channel_id, "You gave bad parameters: %s", errmsg); - sync_crypto_write(&state->cs, PEER_FD, take(msg)); + sync_crypto_write(state->pps, take(msg)); negotiation_aborted(state, am_funder, errmsg); } @@ -366,19 +361,17 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state, clean_tmpctx(); /* This helper routine polls both the peer and gossipd. */ - msg = peer_or_gossip_sync_read(ctx, PEER_FD, GOSSIP_FD, - &state->cs, &from_gossipd); + msg = peer_or_gossip_sync_read(ctx, state->pps, &from_gossipd); /* Use standard helper for gossip msgs (forwards, if it's an * error, exits). */ if (from_gossipd) { - handle_gossip_msg(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, - &state->cs, take(msg)); + handle_gossip_msg(state->pps, take(msg)); continue; } /* Some messages go straight to gossipd. */ if (is_msg_for_gossipd(msg)) { - wire_sync_write(GOSSIP_FD, take(msg)); + wire_sync_write(state->pps->gossip_fd, take(msg)); continue; } @@ -404,9 +397,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state, err); wire_sync_write(REQ_FD, take(msg)); } - peer_failed_received_errmsg(PEER_FD, GOSSIP_FD, - GOSSIP_STORE_FD, - &state->cs, err, + peer_failed_received_errmsg(state->pps, err, NULL); } negotiation_aborted(state, am_funder, @@ -427,7 +418,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state, wire_type_name(fromwire_peektype(msg)), type_to_string(tmpctx, struct channel_id, &actual)); - sync_crypto_write(&state->cs, PEER_FD, + sync_crypto_write(state->pps, take(towire_errorfmt(NULL, &actual, "Multiple channels" " unsupported"))); @@ -528,7 +519,7 @@ static u8 *funder_channel(struct state *state, &state->first_per_commitment_point[LOCAL], channel_flags, dev_upfront_shutdown_script(tmpctx)); - sync_crypto_write(&state->cs, PEER_FD, take(msg)); + sync_crypto_write(state->pps, take(msg)); /* This is usually a very transient state... */ peer_billboard(false, @@ -568,7 +559,7 @@ static u8 *funder_channel(struct state *state, &theirs.htlc, &state->first_per_commitment_point[REMOTE], &state->remote_upfront_shutdown_script)) - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Parsing accept_channel with option_upfront_shutdown_script %s", tal_hex(msg, msg)); } else if (!fromwire_accept_channel(msg, &id_in, @@ -585,7 +576,7 @@ static u8 *funder_channel(struct state *state, &theirs.delayed_payment, &theirs.htlc, &state->first_per_commitment_point[REMOTE])) - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Parsing accept_channel %s", tal_hex(msg, msg)); @@ -595,7 +586,7 @@ static u8 *funder_channel(struct state *state, * `temporary_channel_id` in the `open_channel` message. */ if (!channel_id_eq(&id_in, &state->channel_id)) /* In this case we exit, since we don't know what's going on. */ - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "accept_channel ids don't match: sent %s got %s", type_to_string(msg, struct channel_id, &id_in), @@ -705,7 +696,7 @@ static u8 *funder_channel(struct state *state, /* We were supposed to do enough checks above, but just in case, * new_initial_channel will fail to create absurd channels */ if (!state->channel) - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "could not create channel with given config"); @@ -760,7 +751,7 @@ static u8 *funder_channel(struct state *state, &state->funding_txid, state->funding_txout, &sig.s); - sync_crypto_write(&state->cs, PEER_FD, msg); + sync_crypto_write(state->pps, msg); /* BOLT #2: * @@ -781,7 +772,7 @@ static u8 *funder_channel(struct state *state, sig.sighash_type = SIGHASH_ALL; if (!fromwire_funding_signed(msg, &id_in, &sig.s)) - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Parsing funding_signed: %s", tal_hex(msg, msg)); @@ -812,7 +803,7 @@ static u8 *funder_channel(struct state *state, &state->funding_txid, state->funding_txout); if (!channel_id_eq(&id_in, &state->channel_id)) - peer_failed(&state->cs, &id_in, + peer_failed(state->pps, &id_in, "funding_signed ids don't match: expected %s got %s", type_to_string(msg, struct channel_id, &state->channel_id), @@ -836,7 +827,7 @@ static u8 *funder_channel(struct state *state, } if (!check_tx_sig(tx, 0, NULL, wscript, &their_funding_pubkey, &sig)) { - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Bad signature %s on tx %s using key %s", type_to_string(tmpctx, struct bitcoin_signature, @@ -864,7 +855,7 @@ static u8 *funder_channel(struct state *state, &state->remoteconf, tx, &sig, - &state->cs, + state->pps, &theirs.revocation, &theirs.payment, &theirs.htlc, @@ -934,7 +925,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &state->first_per_commitment_point[REMOTE], &channel_flags, &state->remote_upfront_shutdown_script)) - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Parsing open_channel with option_upfront_shutdown_script %s", tal_hex(tmpctx, open_channel_msg)); } else if (!fromwire_open_channel(open_channel_msg, &chain_hash, @@ -955,7 +946,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &theirs.htlc, &state->first_per_commitment_point[REMOTE], &channel_flags)) - peer_failed(&state->cs, NULL, + peer_failed(state->pps, NULL, "Bad open_channel %s", tal_hex(open_channel_msg, open_channel_msg)); @@ -994,7 +985,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) * - `push_msat` is greater than `funding_satoshis` * 1000. */ if (amount_msat_greater_sat(state->push_msat, state->funding)) { - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Their push_msat %s" " would be too large for funding_satoshis %s", @@ -1089,7 +1080,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) if (err_reason) { u8 *errmsg = towire_errorfmt(NULL, &state->channel_id, "%s", err_reason); - sync_crypto_write(&state->cs, PEER_FD, take(errmsg)); + sync_crypto_write(state->pps, take(errmsg)); return NULL; } @@ -1110,7 +1101,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &state->first_per_commitment_point[LOCAL], dev_upfront_shutdown_script(tmpctx)); - sync_crypto_write(&state->cs, PEER_FD, take(msg)); + sync_crypto_write(state->pps, take(msg)); peer_billboard(false, "Incoming channel: accepted, now waiting for them to create funding tx"); @@ -1127,7 +1118,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &state->funding_txid, &state->funding_txout, &theirsig.s)) - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Parsing funding_created"); @@ -1137,7 +1128,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) * `temporary_channel_id` in the `open_channel` message. */ if (!channel_id_eq(&id_in, &state->channel_id)) - peer_failed(&state->cs, &id_in, + peer_failed(state->pps, &id_in, "funding_created ids don't match: sent %s got %s", type_to_string(msg, struct channel_id, &state->channel_id), @@ -1161,7 +1152,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) /* We don't expect this to fail, but it does do some additional * internal sanity checks. */ if (!state->channel) - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "We could not create channel with given config"); @@ -1196,7 +1187,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) * a courtesy to other implementaters whose brains may be so * twisted by coding in Go, Scala and Rust that they can no * longer read C code. */ - peer_failed(&state->cs, + peer_failed(state->pps, &state->channel_id, "Bad signature %s on tx %s using key %s", type_to_string(tmpctx, struct bitcoin_signature, @@ -1261,7 +1252,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) &state->remoteconf, local_commit, &theirsig, - &state->cs, + state->pps, &theirs.revocation, &theirs.payment, &theirs.htlc, @@ -1284,7 +1275,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) * surprise. */ static u8 *handle_peer_in(struct state *state) { - u8 *msg = sync_crypto_read(tmpctx, &state->cs, PEER_FD); + u8 *msg = sync_crypto_read(tmpctx, state->pps); enum wire_type t = fromwire_peektype(msg); struct channel_id channel_id; @@ -1322,15 +1313,13 @@ static u8 *handle_peer_in(struct state *state) case WIRE_UPDATE_FEE: case WIRE_ANNOUNCEMENT_SIGNATURES: /* Standard cases */ - if (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, - GOSSIP_STORE_FD, - &state->cs, + if (handle_peer_gossip_or_error(state->pps, &state->channel_id, msg)) return NULL; break; } - sync_crypto_write(&state->cs, PEER_FD, + sync_crypto_write(state->pps, take(towire_errorfmt(NULL, extract_channel_id(msg, &channel_id) ? &channel_id : NULL, "Unexpected message %s: %s", @@ -1344,17 +1333,17 @@ static u8 *handle_peer_in(struct state *state) peer_failed_connection_lost(); } -/*~ If we see the GOSSIP_FD readable, we read a whole message. Sure, we might +/*~ If we see the gossip_fd readable, we read a whole message. Sure, we might * block, but we trust gossipd. */ static void handle_gossip_in(struct state *state) { - u8 *msg = wire_sync_read(NULL, GOSSIP_FD); + u8 *msg = wire_sync_read(NULL, state->pps->gossip_fd); if (!msg) status_failed(STATUS_FAIL_GOSSIP_IO, "Reading gossip: %s", strerror(errno)); - handle_gossip_msg(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, &state->cs, take(msg)); + handle_gossip_msg(state->pps, take(msg)); } /*~ Is this message of type `error` with the special zero-id @@ -1472,7 +1461,7 @@ int main(int argc, char *argv[]) &state->localconf, &state->max_to_self_delay, &state->min_effective_htlc_capacity, - &state->cs, + &state->pps, &state->our_points, &state->our_funding_pubkey, &state->minimum_depth, @@ -1481,10 +1470,13 @@ int main(int argc, char *argv[]) &inner)) master_badmsg(WIRE_OPENING_INIT, msg); + /* 3 == peer, 4 == gossipd, 5 = gossip_store, 6 = hsmd */ + per_peer_state_set_fds(state->pps, 3, 4, 5); + /*~ If lightningd wanted us to send a msg, do so before we waste time * doing work. If it's a global error, we'll close immediately. */ if (inner != NULL) { - sync_crypto_write(&state->cs, PEER_FD, inner); + sync_crypto_write(state->pps, inner); fail_if_all_error(inner); tal_free(inner); } @@ -1523,9 +1515,9 @@ int main(int argc, char *argv[]) /*~ We manually run a little poll() loop here. With only three fds */ pollfd[0].fd = REQ_FD; pollfd[0].events = POLLIN; - pollfd[1].fd = GOSSIP_FD; + pollfd[1].fd = state->pps->gossip_fd; pollfd[1].events = POLLIN; - pollfd[2].fd = PEER_FD; + pollfd[2].fd = state->pps->peer_fd; pollfd[2].events = POLLIN; /* We exit when we get a conclusion to write to lightningd: either @@ -1553,10 +1545,8 @@ int main(int argc, char *argv[]) * means that if the peer or gossipd wrote us any messages we didn't * read yet, it will simply be read by the next daemon. */ wire_sync_write(REQ_FD, msg); - fdpass_send(REQ_FD, PEER_FD); - fdpass_send(REQ_FD, GOSSIP_FD); - fdpass_send(REQ_FD, GOSSIP_STORE_FD); - status_trace("Sent %s with fd", + per_peer_state_fdpass_send(REQ_FD, state->pps); + status_trace("Sent %s with fds", opening_wire_type_name(fromwire_peektype(msg))); /* This frees the entire tal tree. */ diff --git a/tools/generate-wire.py b/tools/generate-wire.py index 1e09e7740..a640edf8f 100755 --- a/tools/generate-wire.py +++ b/tools/generate-wire.py @@ -42,6 +42,7 @@ varlen_structs = [ 'utxo', 'bitcoin_tx', 'wirestring', + 'per_peer_state', ] diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index ed33afa2d..658281864 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -95,7 +95,7 @@ bool fromwire_channel_offer_htlc_reply(const tal_t *ctx UNNEEDED, const void *p bool fromwire_channel_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, u32 *feerate UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_signature *commit_sig UNNEEDED, secp256k1_ecdsa_signature **htlc_sigs UNNEEDED) { fprintf(stderr, "fromwire_channel_sending_commitsig called!\n"); abort(); } /* Generated stub for fromwire_connect_peer_connected */ -bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED) +bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *cs UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED) { fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); } /* Generated stub for fromwire_gossip_get_channel_peer_reply */ bool fromwire_gossip_get_channel_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id **peer_id UNNEEDED) @@ -351,9 +351,10 @@ void log_add(struct log *log UNNEEDED, const char *fmt UNNEEDED, ...) void log_io(struct log *log UNNEEDED, enum log_level dir UNNEEDED, const char *comment UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) { fprintf(stderr, "log_io called!\n"); abort(); } -/* Generated stub for new_peer_comms */ -struct peer_comms *new_peer_comms(const tal_t *ctx UNNEEDED) -{ fprintf(stderr, "new_peer_comms called!\n"); abort(); } +/* Generated stub for new_per_peer_state */ +struct per_peer_state *new_per_peer_state(const tal_t *ctx UNNEEDED, + const struct crypto_state *cs UNNEEDED) +{ fprintf(stderr, "new_per_peer_state called!\n"); abort(); } /* Generated stub for notify_connect */ void notify_connect(struct lightningd *ld UNNEEDED, struct node_id *nodeid UNNEEDED, struct wireaddr_internal *addr UNNEEDED) @@ -454,21 +455,25 @@ void peer_memleak_done(struct command *cmd UNNEEDED, struct subd *leaker UNNEEDE { fprintf(stderr, "peer_memleak_done called!\n"); abort(); } /* Generated stub for peer_start_channeld */ void peer_start_channeld(struct channel *channel UNNEEDED, - struct peer_comms *pcomms UNNEEDED, + struct per_peer_state *pps UNNEEDED, const u8 *funding_signed UNNEEDED, bool reconnected UNNEEDED) { fprintf(stderr, "peer_start_channeld called!\n"); abort(); } /* Generated stub for peer_start_closingd */ void peer_start_closingd(struct channel *channel UNNEEDED, - struct peer_comms *pcomms UNNEEDED, + struct per_peer_state *pps UNNEEDED, bool reconnected UNNEEDED, const u8 *channel_reestablish UNNEEDED) { fprintf(stderr, "peer_start_closingd called!\n"); abort(); } /* Generated stub for peer_start_openingd */ void peer_start_openingd(struct peer *peer UNNEEDED, - struct peer_comms *pcomms UNNEEDED, + struct per_peer_state *pps UNNEEDED, const u8 *msg UNNEEDED) { fprintf(stderr, "peer_start_openingd called!\n"); abort(); } +/* Generated stub for per_peer_state_set_fds */ +void per_peer_state_set_fds(struct per_peer_state *pps UNNEEDED, + int peer_fd UNNEEDED, int gossip_fd UNNEEDED, int gossip_store_fd UNNEEDED) +{ fprintf(stderr, "per_peer_state_set_fds called!\n"); abort(); } /* Generated stub for plugin_hook_call_ */ void plugin_hook_call_(struct lightningd *ld UNNEEDED, const struct plugin_hook *hook UNNEEDED, void *payload UNNEEDED, void *cb_arg UNNEEDED)