Skip to content

Commit 6dae011

Browse files
committed
connectd: clearly differentiate incoming and outgoing paths.
This should make it clearer where the problem seen in #4297 is. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 3c87e1f commit 6dae011

File tree

4 files changed

+61
-29
lines changed

4 files changed

+61
-29
lines changed

connectd/connectd.c

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -272,32 +272,44 @@ static struct connecting *find_connecting(struct daemon *daemon,
272272
return NULL;
273273
}
274274

275-
/*~ Once we've connected, we disable the callback which would cause us to
275+
/*~ Once we've connected out, we disable the callback which would cause us to
276276
* to try the next address. */
277-
static void connected_to_peer(struct daemon *daemon,
278-
struct io_conn *conn,
279-
const struct node_id *id)
277+
static void connected_out_to_peer(struct daemon *daemon,
278+
struct io_conn *conn,
279+
const struct node_id *id)
280280
{
281-
struct connecting *outgoing;
281+
struct connecting *connect = find_connecting(daemon, id);
282282

283283
/* We allocate 'conn' as a child of 'connect': we don't want to free
284284
* it just yet though. tal_steal() it onto the permanent 'daemon'
285285
* struct. */
286286
tal_steal(daemon, conn);
287287

288-
/* This is either us (if conn is an outgoing connection), or
289-
* NULL or a separate attempt (if we're an incoming): in
290-
* that case, kill the outgoing in favor of our successful
291-
* incoming connection. */
292-
outgoing = find_connecting(daemon, id);
293-
if (outgoing) {
294-
/* Don't call destroy_io_conn, since we're done. */
295-
if (outgoing->conn)
296-
io_set_finish(outgoing->conn, NULL, NULL);
297-
298-
/* Now free the 'connecting' struct. */
299-
tal_free(outgoing);
300-
}
288+
/* We only allow one outgoing attempt at a time */
289+
assert(connect->conn == conn);
290+
291+
/* Don't call destroy_io_conn, since we're done. */
292+
io_set_finish(conn, NULL, NULL);
293+
294+
/* Now free the 'connecting' struct. */
295+
tal_free(connect);
296+
}
297+
298+
/*~ Once they've connected in, stop trying to connect out (if we were). */
299+
static void peer_connected_in(struct daemon *daemon,
300+
struct io_conn *conn,
301+
const struct node_id *id)
302+
{
303+
struct connecting *connect = find_connecting(daemon, id);
304+
305+
if (!connect)
306+
return;
307+
308+
/* Don't call destroy_io_conn, since we're done. */
309+
io_set_finish(connect->conn, NULL, NULL);
310+
311+
/* Now free the 'connecting' struct since we succeeded. */
312+
tal_free(connect);
301313
}
302314

303315
/*~ Every per-peer daemon needs a connection to the gossip daemon; this allows
@@ -368,6 +380,7 @@ struct peer_reconnected {
368380
struct wireaddr_internal addr;
369381
struct crypto_state cs;
370382
const u8 *their_features;
383+
bool incoming;
371384
};
372385

373386
/*~ For simplicity, lightningd only ever deals with a single connection per
@@ -384,7 +397,7 @@ static struct io_plan *retry_peer_connected(struct io_conn *conn,
384397
/*~ Usually the pattern is to return this directly, but we have to free
385398
* our temporary structure. */
386399
plan = peer_connected(conn, pr->daemon, &pr->id, &pr->addr, &pr->cs,
387-
take(pr->their_features));
400+
take(pr->their_features), pr->incoming);
388401
tal_free(pr);
389402
return plan;
390403
}
@@ -396,7 +409,8 @@ static struct io_plan *peer_reconnected(struct io_conn *conn,
396409
const struct node_id *id,
397410
const struct wireaddr_internal *addr,
398411
const struct crypto_state *cs,
399-
const u8 *their_features TAKES)
412+
const u8 *their_features TAKES,
413+
bool incoming)
400414
{
401415
u8 *msg;
402416
struct peer_reconnected *pr;
@@ -413,6 +427,7 @@ static struct io_plan *peer_reconnected(struct io_conn *conn,
413427
pr->id = *id;
414428
pr->cs = *cs;
415429
pr->addr = *addr;
430+
pr->incoming = incoming;
416431

417432
/*~ Note that tal_dup_talarr() will do handle the take() of features
418433
* (turning it into a simply tal_steal() in those cases). */
@@ -436,7 +451,8 @@ struct io_plan *peer_connected(struct io_conn *conn,
436451
const struct node_id *id,
437452
const struct wireaddr_internal *addr,
438453
struct crypto_state *cs,
439-
const u8 *their_features TAKES)
454+
const u8 *their_features TAKES,
455+
bool incoming)
440456
{
441457
u8 *msg;
442458
struct per_peer_state *pps;
@@ -445,7 +461,7 @@ struct io_plan *peer_connected(struct io_conn *conn,
445461

446462
if (node_set_get(&daemon->peers, id))
447463
return peer_reconnected(conn, daemon, id, addr, cs,
448-
their_features);
464+
their_features, incoming);
449465

450466
/* We promised we'd take it by marking it TAKEN above; prepare to free it. */
451467
if (taken(their_features))
@@ -478,7 +494,16 @@ struct io_plan *peer_connected(struct io_conn *conn,
478494
}
479495

480496
/* We've successfully connected. */
481-
connected_to_peer(daemon, conn, id);
497+
if (incoming)
498+
peer_connected_in(daemon, conn, id);
499+
else
500+
connected_out_to_peer(daemon, conn, id);
501+
502+
if (find_connecting(daemon, id))
503+
status_failed(STATUS_FAIL_INTERNAL_ERROR,
504+
"After %s connection on %p, still trying to connect conn %p?",
505+
incoming ? "incoming" : "outgoing",
506+
conn, find_connecting(daemon, id)->conn);
482507

483508
/* This contains the per-peer state info; gossipd fills in pps->gs */
484509
pps = new_per_peer_state(tmpctx, cs);
@@ -524,7 +549,7 @@ static struct io_plan *handshake_in_success(struct io_conn *conn,
524549
node_id_from_pubkey(&id, id_key);
525550
status_peer_debug(&id, "Connect IN");
526551
return peer_exchange_initmsg(conn, daemon, daemon->our_features,
527-
cs, &id, addr);
552+
cs, &id, addr, true);
528553
}
529554

530555
/*~ If the timer goes off, we simply free everything, which hangs up. */
@@ -598,7 +623,7 @@ static struct io_plan *handshake_out_success(struct io_conn *conn,
598623
status_peer_debug(&id, "Connect OUT");
599624
return peer_exchange_initmsg(conn, connect->daemon,
600625
connect->daemon->our_features,
601-
cs, &id, addr);
626+
cs, &id, addr, false);
602627
}
603628

604629
struct io_plan *connection_out(struct io_conn *conn, struct connecting *connect)

connectd/connectd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct io_plan *peer_connected(struct io_conn *conn,
2222
const struct node_id *id,
2323
const struct wireaddr_internal *addr,
2424
struct crypto_state *cs,
25-
const u8 *their_features TAKES);
25+
const u8 *their_features TAKES,
26+
bool incoming);
2627

2728
#endif /* LIGHTNING_CONNECTD_CONNECTD_H */

connectd/peer_exchange_initmsg.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ struct peer {
2626

2727
/* Buffer for reading/writing message. */
2828
u8 *msg;
29+
30+
bool incoming;
2931
};
3032

3133
static bool contains_common_chain(struct bitcoin_blkid *chains)
@@ -93,7 +95,8 @@ static struct io_plan *peer_init_received(struct io_conn *conn,
9395
* be disconnected if it's a reconnect. */
9496
return peer_connected(conn, peer->daemon, &peer->id,
9597
&peer->addr, &peer->cs,
96-
take(features));
98+
take(features),
99+
peer->incoming);
97100
}
98101

99102
static struct io_plan *peer_init_hdr_received(struct io_conn *conn,
@@ -139,7 +142,8 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
139142
const struct feature_set *our_features,
140143
const struct crypto_state *cs,
141144
const struct node_id *id,
142-
const struct wireaddr_internal *addr)
145+
const struct wireaddr_internal *addr,
146+
bool incoming)
143147
{
144148
/* If conn is closed, forget peer */
145149
struct peer *peer = tal(conn, struct peer);
@@ -150,6 +154,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
150154
peer->id = *id;
151155
peer->addr = *addr;
152156
peer->cs = *cs;
157+
peer->incoming = incoming;
153158

154159
/* BOLT #1:
155160
*

connectd/peer_exchange_initmsg.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
1515
const struct feature_set *our_features,
1616
const struct crypto_state *cs,
1717
const struct node_id *id,
18-
const struct wireaddr_internal *addr);
18+
const struct wireaddr_internal *addr,
19+
bool incoming);
1920

2021
#endif /* LIGHTNING_CONNECTD_PEER_EXCHANGE_INITMSG_H */

0 commit comments

Comments
 (0)