@@ -272,32 +272,44 @@ static struct connecting *find_connecting(struct daemon *daemon,
272
272
return NULL ;
273
273
}
274
274
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
276
276
* 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 )
280
280
{
281
- struct connecting * outgoing ;
281
+ struct connecting * connect = find_connecting ( daemon , id ) ;
282
282
283
283
/* We allocate 'conn' as a child of 'connect': we don't want to free
284
284
* it just yet though. tal_steal() it onto the permanent 'daemon'
285
285
* struct. */
286
286
tal_steal (daemon , conn );
287
287
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 );
301
313
}
302
314
303
315
/*~ Every per-peer daemon needs a connection to the gossip daemon; this allows
@@ -368,6 +380,7 @@ struct peer_reconnected {
368
380
struct wireaddr_internal addr ;
369
381
struct crypto_state cs ;
370
382
const u8 * their_features ;
383
+ bool incoming ;
371
384
};
372
385
373
386
/*~ 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,
384
397
/*~ Usually the pattern is to return this directly, but we have to free
385
398
* our temporary structure. */
386
399
plan = peer_connected (conn , pr -> daemon , & pr -> id , & pr -> addr , & pr -> cs ,
387
- take (pr -> their_features ));
400
+ take (pr -> their_features ), pr -> incoming );
388
401
tal_free (pr );
389
402
return plan ;
390
403
}
@@ -396,7 +409,8 @@ static struct io_plan *peer_reconnected(struct io_conn *conn,
396
409
const struct node_id * id ,
397
410
const struct wireaddr_internal * addr ,
398
411
const struct crypto_state * cs ,
399
- const u8 * their_features TAKES )
412
+ const u8 * their_features TAKES ,
413
+ bool incoming )
400
414
{
401
415
u8 * msg ;
402
416
struct peer_reconnected * pr ;
@@ -413,6 +427,7 @@ static struct io_plan *peer_reconnected(struct io_conn *conn,
413
427
pr -> id = * id ;
414
428
pr -> cs = * cs ;
415
429
pr -> addr = * addr ;
430
+ pr -> incoming = incoming ;
416
431
417
432
/*~ Note that tal_dup_talarr() will do handle the take() of features
418
433
* (turning it into a simply tal_steal() in those cases). */
@@ -436,7 +451,8 @@ struct io_plan *peer_connected(struct io_conn *conn,
436
451
const struct node_id * id ,
437
452
const struct wireaddr_internal * addr ,
438
453
struct crypto_state * cs ,
439
- const u8 * their_features TAKES )
454
+ const u8 * their_features TAKES ,
455
+ bool incoming )
440
456
{
441
457
u8 * msg ;
442
458
struct per_peer_state * pps ;
@@ -445,7 +461,7 @@ struct io_plan *peer_connected(struct io_conn *conn,
445
461
446
462
if (node_set_get (& daemon -> peers , id ))
447
463
return peer_reconnected (conn , daemon , id , addr , cs ,
448
- their_features );
464
+ their_features , incoming );
449
465
450
466
/* We promised we'd take it by marking it TAKEN above; prepare to free it. */
451
467
if (taken (their_features ))
@@ -478,7 +494,16 @@ struct io_plan *peer_connected(struct io_conn *conn,
478
494
}
479
495
480
496
/* 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 );
482
507
483
508
/* This contains the per-peer state info; gossipd fills in pps->gs */
484
509
pps = new_per_peer_state (tmpctx , cs );
@@ -524,7 +549,7 @@ static struct io_plan *handshake_in_success(struct io_conn *conn,
524
549
node_id_from_pubkey (& id , id_key );
525
550
status_peer_debug (& id , "Connect IN" );
526
551
return peer_exchange_initmsg (conn , daemon , daemon -> our_features ,
527
- cs , & id , addr );
552
+ cs , & id , addr , true );
528
553
}
529
554
530
555
/*~ 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,
598
623
status_peer_debug (& id , "Connect OUT" );
599
624
return peer_exchange_initmsg (conn , connect -> daemon ,
600
625
connect -> daemon -> our_features ,
601
- cs , & id , addr );
626
+ cs , & id , addr , false );
602
627
}
603
628
604
629
struct io_plan * connection_out (struct io_conn * conn , struct connecting * connect )
0 commit comments