mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
peer_control: don't double-free on permanent fail of non-persistent peer.
peer_fail_permanent() frees peer->owner, but for bad_peer() we're being called by the sd->badpeercb(), which then goes on to io_close(conn) which is a child of sd. We need to detach the two for this case, so neither tries to free the other. This leads to a corner case when the subd exits after the peer is gone: subd->peer is NULL, so we have to handle that too. Fixes: #282 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
b7bb0be944
commit
2fe2a0bcf9
@@ -216,7 +216,12 @@ void peer_fail_transient(struct peer *peer, const char *fmt, ...)
|
||||
/* When daemon reports a STATUS_FAIL_PEER_BAD, it goes here. */
|
||||
static void bad_peer(struct subd *subd, const char *msg)
|
||||
{
|
||||
peer_fail_permanent_str(subd->peer, msg);
|
||||
struct peer *peer = subd->peer;
|
||||
|
||||
/* Don't close peer->owner, subd will clean that up. */
|
||||
peer->owner = NULL;
|
||||
subd->peer = NULL;
|
||||
peer_fail_permanent_str(peer, msg);
|
||||
}
|
||||
|
||||
void peer_set_condition(struct peer *peer, enum peer_state old_state,
|
||||
@@ -684,8 +689,8 @@ struct peer *peer_by_id(struct lightningd *ld, const struct pubkey *id)
|
||||
/* When a per-peer subdaemon exits, see if we need to do anything. */
|
||||
static void peer_owner_finished(struct subd *subd, int status)
|
||||
{
|
||||
/* If peer has moved on, do nothing. */
|
||||
if (subd->peer->owner != subd) {
|
||||
/* If peer has moved on, do nothing (can be NULL if it errored out) */
|
||||
if (!subd->peer || subd->peer->owner != subd) {
|
||||
log_debug(subd->ld->log, "Subdaemon %s died (%i), peer moved",
|
||||
subd->name, status);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user