Skip to content

Commit 46c33c4

Browse files
committed
connectd: at disconnected, tell lightningd how long we were connected.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent ef357e8 commit 46c33c4

File tree

15 files changed

+79
-25
lines changed

15 files changed

+79
-25
lines changed

connectd/connectd.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,15 @@ static struct peer *new_peer(struct daemon *daemon,
112112
const struct crypto_state *cs,
113113
const u8 *their_features,
114114
enum is_websocket is_websocket,
115+
struct timemono connect_starttime,
115116
struct io_conn *conn STEALS,
116117
int *fd_for_subd)
117118
{
118119
struct peer *peer = tal(daemon, struct peer);
119120

120121
peer->daemon = daemon;
121122
peer->id = *id;
123+
peer->connect_starttime = connect_starttime;
122124
peer->counter = daemon->connection_counter++;
123125
peer->cs = *cs;
124126
peer->subds = tal_arr(peer, struct subd *, 0);
@@ -258,11 +260,12 @@ static void reset_reconnect_timer(struct peer *peer)
258260

259261
void send_disconnected(struct daemon *daemon,
260262
const struct node_id *id,
261-
u64 connectd_counter)
263+
u64 connectd_counter,
264+
struct timemono starttime)
262265
{
263266
/* lightningd: it's gone */
264267
daemon_conn_send(daemon->master,
265-
take(towire_connectd_peer_disconnected(NULL, id, connectd_counter)));
268+
take(towire_connectd_peer_disconnected(NULL, id, connectd_counter, time_to_nsec(timemono_since(starttime)))));
266269

267270
/* Tell gossipd to stop asking this peer gossip queries */
268271
daemon_conn_send(daemon->gossipd,
@@ -282,6 +285,7 @@ struct io_plan *peer_connected(struct io_conn *conn,
282285
struct crypto_state *cs,
283286
const u8 *their_features TAKES,
284287
enum is_websocket is_websocket,
288+
struct timemono starttime,
285289
bool incoming)
286290
{
287291
u8 *msg;
@@ -294,11 +298,13 @@ struct io_plan *peer_connected(struct io_conn *conn,
294298
const char *connect_reason;
295299
u64 connect_time_nsec;
296300
u64 prev_connectd_counter;
301+
struct timemono prev_connect_start;
297302

298303
/* We remove any previous connection immediately, on the assumption it's dead */
299304
oldpeer = peer_htable_get(daemon->peers, id);
300305
if (oldpeer) {
301306
prev_connectd_counter = oldpeer->counter;
307+
prev_connect_start = oldpeer->connect_starttime;
302308
destroy_peer_immediately(oldpeer);
303309
}
304310

@@ -320,7 +326,8 @@ struct io_plan *peer_connected(struct io_conn *conn,
320326
if (unsup != -1) {
321327
/* We were going to send a reconnect message, but not now! */
322328
if (oldpeer)
323-
send_disconnected(daemon, id, prev_connectd_counter);
329+
send_disconnected(daemon, id, prev_connectd_counter,
330+
prev_connect_start);
324331
status_peer_unusual(id, "Unsupported feature %u", unsup);
325332
msg = towire_warningfmt(NULL, NULL, "Unsupported feature %u",
326333
unsup);
@@ -331,7 +338,8 @@ struct io_plan *peer_connected(struct io_conn *conn,
331338
if (!feature_check_depends(their_features, &depender, &missing)) {
332339
/* We were going to send a reconnect message, but not now! */
333340
if (oldpeer)
334-
send_disconnected(daemon, id, prev_connectd_counter);
341+
send_disconnected(daemon, id, prev_connectd_counter,
342+
prev_connect_start);
335343
status_peer_unusual(id, "Feature %zu requires feature %zu",
336344
depender, missing);
337345
msg = towire_warningfmt(NULL, NULL,
@@ -374,13 +382,14 @@ struct io_plan *peer_connected(struct io_conn *conn,
374382
}
375383

376384
/* This contains the per-peer state info; gossipd fills in pps->gs */
377-
peer = new_peer(daemon, id, cs, their_features, is_websocket, conn,
385+
peer = new_peer(daemon, id, cs, their_features, is_websocket, starttime, conn,
378386
&subd_fd);
379387
/* Only takes over conn if it succeeds. */
380388
if (!peer) {
381389
/* We were going to send a reconnect message, but not now! */
382390
if (oldpeer)
383-
send_disconnected(daemon, id, prev_connectd_counter);
391+
send_disconnected(daemon, id, prev_connectd_counter,
392+
prev_connect_start);
384393
return io_close(conn);
385394
}
386395

@@ -398,7 +407,8 @@ struct io_plan *peer_connected(struct io_conn *conn,
398407
prev_connectd_counter,
399408
peer->counter,
400409
addr, remote_addr,
401-
incoming, their_features);
410+
incoming, their_features,
411+
time_to_nsec(timemono_since(prev_connect_start)));
402412
} else {
403413
/* Tell gossipd about new peer */
404414
msg = towire_gossipd_new_peer(NULL, id, option_gossip_queries);
@@ -438,13 +448,15 @@ static struct io_plan *handshake_in_success(struct io_conn *conn,
438448
struct crypto_state *cs,
439449
struct oneshot *timeout,
440450
enum is_websocket is_websocket,
451+
struct timemono starttime,
441452
struct daemon *daemon)
442453
{
443454
struct node_id id;
444455
node_id_from_pubkey(&id, id_key);
445456
status_peer_debug(&id, "Connect IN");
446457
return peer_exchange_initmsg(conn, daemon, daemon->our_features,
447-
cs, &id, addr, timeout, is_websocket, true);
458+
cs, &id, addr, timeout, is_websocket,
459+
starttime, true);
448460
}
449461

450462
/*~ If the timer goes off, we simply free everything, which hangs up. */
@@ -730,6 +742,7 @@ static struct io_plan *handshake_out_success(struct io_conn *conn,
730742
struct crypto_state *cs,
731743
struct oneshot *timeout,
732744
enum is_websocket is_websocket,
745+
struct timemono starttime,
733746
struct connecting *connect)
734747
{
735748
struct node_id id;
@@ -739,7 +752,8 @@ static struct io_plan *handshake_out_success(struct io_conn *conn,
739752
status_peer_debug(&id, "Connect OUT");
740753
return peer_exchange_initmsg(conn, connect->daemon,
741754
connect->daemon->our_features,
742-
cs, &id, addr, timeout, is_websocket, false);
755+
cs, &id, addr, timeout, is_websocket,
756+
starttime, false);
743757
}
744758

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

connectd/connectd.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ struct peer {
6464
struct node_id id;
6565
/* Counters and keys for symmetric crypto */
6666
struct crypto_state cs;
67+
/* Time when we first connected */
68+
struct timemono connect_starttime;
6769

6870
/* Connection to the peer (NULL if it's disconnected and we're flushing) */
6971
struct io_conn *to_peer;
@@ -388,12 +390,14 @@ struct io_plan *peer_connected(struct io_conn *conn,
388390
struct crypto_state *cs,
389391
const u8 *their_features TAKES,
390392
enum is_websocket is_websocket,
393+
struct timemono starttime,
391394
bool incoming);
392395

393396
/* Tell gossipd and lightningd that this peer is gone. */
394397
void send_disconnected(struct daemon *daemon,
395398
const struct node_id *id,
396-
u64 connectd_counter);
399+
u64 connectd_counter,
400+
struct timemono starttime);
397401

398402
/* Free peer immediately (don't wait for draining). */
399403
void destroy_peer_immediately(struct peer *peer);

connectd/connectd_wire.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ msgdata,connectd_peer_connected,connect_nsec,u64,
9090
msgtype,connectd_peer_disconnected,2006
9191
msgdata,connectd_peer_disconnected,id,node_id,
9292
msgdata,connectd_peer_disconnected,counter,u64,
93+
msgdata,connectd_peer_disconnected,connected_time_nsec,u64,
9394

9495
# Connectd -> master: peer reconnected (disconnect & connect)
9596
msgtype,connectd_peer_reconnected,2010
@@ -101,6 +102,7 @@ msgdata,connectd_peer_reconnected,remote_addr,?wireaddr,
101102
msgdata,connectd_peer_reconnected,incoming,bool,
102103
msgdata,connectd_peer_reconnected,flen,u16,
103104
msgdata,connectd_peer_reconnected,features,u8,flen
105+
msgdata,connectd_peer_reconnected,connected_time_nsec,u64,
104106

105107
# Master -> connectd: make peer active immediately (we want to talk) (+ fd to subd).
106108
msgtype,connectd_peer_connect_subd,2004

connectd/handshake.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <ccan/endian/endian.h>
66
#include <ccan/io/io.h>
77
#include <ccan/mem/mem.h>
8+
#include <ccan/time/time.h>
89
#include <common/crypto_state.h>
910
#include <common/ecdh.h>
1011
#include <common/status.h>
@@ -178,13 +179,17 @@ struct handshake {
178179
/* Are we connected via a websocket? */
179180
enum is_websocket is_websocket;
180181

182+
/* Time they first connected */
183+
struct timemono starttime;
184+
181185
/* Function to call once handshake complete. */
182186
struct io_plan *(*cb)(struct io_conn *conn,
183187
const struct pubkey *their_id,
184188
const struct wireaddr_internal *wireaddr,
185189
struct crypto_state *cs,
186190
struct oneshot *timeout,
187191
enum is_websocket is_websocket,
192+
struct timemono starttime,
188193
void *cbarg);
189194
void *cbarg;
190195
};
@@ -357,12 +362,14 @@ static struct io_plan *handshake_succeeded(struct io_conn *conn,
357362
struct crypto_state *cs,
358363
struct oneshot *timeout,
359364
enum is_websocket is_websocket,
365+
struct timemono starttime,
360366
void *cbarg);
361367
void *cbarg;
362368
struct pubkey their_id;
363369
struct wireaddr_internal addr;
364370
struct oneshot *timeout;
365371
enum is_websocket is_websocket;
372+
struct timemono starttime;
366373

367374
/* BOLT #8:
368375
*
@@ -396,9 +403,10 @@ static struct io_plan *handshake_succeeded(struct io_conn *conn,
396403
addr = h->addr;
397404
timeout = h->timeout;
398405
is_websocket = h->is_websocket;
406+
starttime = h->starttime;
399407

400408
tal_free(h);
401-
return cb(conn, &their_id, &addr, &cs, timeout, is_websocket, cbarg);
409+
return cb(conn, &their_id, &addr, &cs, timeout, is_websocket, starttime, cbarg);
402410
}
403411

404412
static struct handshake *new_handshake(const tal_t *ctx,
@@ -983,12 +991,14 @@ struct io_plan *responder_handshake_(struct io_conn *conn,
983991
struct crypto_state *,
984992
struct oneshot *,
985993
enum is_websocket,
994+
struct timemono,
986995
void *cbarg),
987996
void *cbarg)
988997
{
989998
struct handshake *h = new_handshake(conn, my_id);
990999

9911000
h->side = RESPONDER;
1001+
h->starttime = time_mono();
9921002
h->my_id = *my_id;
9931003
h->addr = *addr;
9941004
h->cbarg = cbarg;
@@ -1011,12 +1021,14 @@ struct io_plan *initiator_handshake_(struct io_conn *conn,
10111021
struct crypto_state *,
10121022
struct oneshot *timeout,
10131023
enum is_websocket is_websocket,
1024+
struct timemono,
10141025
void *cbarg),
10151026
void *cbarg)
10161027
{
10171028
struct handshake *h = new_handshake(conn, their_id);
10181029

10191030
h->side = INITIATOR;
1031+
h->starttime = time_mono();
10201032
h->my_id = *my_id;
10211033
h->their_id = *their_id;
10221034
h->addr = *addr;

connectd/handshake.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ enum is_websocket {
2626
const struct wireaddr_internal *, \
2727
struct crypto_state *, \
2828
struct oneshot *, \
29-
enum is_websocket), \
29+
enum is_websocket, \
30+
struct timemono), \
3031
(cbarg))
3132

3233

@@ -42,6 +43,7 @@ struct io_plan *initiator_handshake_(struct io_conn *conn,
4243
struct crypto_state *,
4344
struct oneshot *timeout,
4445
enum is_websocket,
46+
struct timemono,
4547
void *cbarg),
4648
void *cbarg);
4749

@@ -55,7 +57,8 @@ struct io_plan *initiator_handshake_(struct io_conn *conn,
5557
const struct wireaddr_internal *, \
5658
struct crypto_state *, \
5759
struct oneshot *, \
58-
enum is_websocket), \
60+
enum is_websocket, \
61+
struct timemono), \
5962
(cbarg))
6063

6164
struct io_plan *responder_handshake_(struct io_conn *conn,
@@ -69,6 +72,7 @@ struct io_plan *responder_handshake_(struct io_conn *conn,
6972
struct crypto_state *,
7073
struct oneshot *,
7174
enum is_websocket,
75+
struct timemono,
7276
void *cbarg),
7377
void *cbarg);
7478
#endif /* LIGHTNING_CONNECTD_HANDSHAKE_H */

connectd/multiplex.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,9 +1392,10 @@ static void destroy_peer_conn(struct io_conn *peer_conn, struct peer *peer)
13921392
{
13931393
assert(peer->to_peer == peer_conn);
13941394

1395-
/* We are no longer connected. Tell lightningd & gossipd*/
1395+
/* We are no longer connected. Tell lightningd & gossipd */
13961396
peer->to_peer = NULL;
1397-
send_disconnected(peer->daemon, &peer->id, peer->counter);
1397+
send_disconnected(peer->daemon, &peer->id, peer->counter,
1398+
peer->connect_starttime);
13981399

13991400
/* Wake subds: give them 5 seconds to flush. */
14001401
for (size_t i = 0; i < tal_count(peer->subds); i++) {

connectd/peer_exchange_initmsg.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ struct early_peer {
3434

3535
/* Timeout in case it takes too long */
3636
struct oneshot *timeout;
37+
38+
/* We record time when we first accepted socket */
39+
struct timemono starttime;
3740
};
3841

3942
static bool contains_common_chain(struct bitcoin_blkid *chains)
@@ -152,6 +155,7 @@ static struct io_plan *peer_init_received(struct io_conn *conn,
152155
&peer->cs,
153156
take(features),
154157
peer->is_websocket,
158+
peer->starttime,
155159
peer->incoming);
156160
}
157161

@@ -206,6 +210,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
206210
const struct wireaddr_internal *addr,
207211
struct oneshot *timeout,
208212
enum is_websocket is_websocket,
213+
struct timemono starttime,
209214
bool incoming)
210215
{
211216
/* If conn is closed, forget peer */
@@ -220,6 +225,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
220225
peer->incoming = incoming;
221226
peer->is_websocket = is_websocket;
222227
peer->timeout = timeout;
228+
peer->starttime = starttime;
223229

224230
/* BOLT #1:
225231
*

connectd/peer_exchange_initmsg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
1919
const struct wireaddr_internal *addr,
2020
struct oneshot *timeout,
2121
enum is_websocket is_websocket,
22+
struct timemono starttime,
2223
bool incoming);
2324

2425
#endif /* LIGHTNING_CONNECTD_PEER_EXCHANGE_INITMSG_H */

connectd/test/run-initiator-success.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ static struct io_plan *success(struct io_conn *conn UNUSED,
186186
struct crypto_state *cs,
187187
struct oneshot *timeout UNUSED,
188188
enum is_websocket is_websocket UNUSED,
189+
struct timemono starttime UNUSED,
189190
void *unused UNUSED)
190191
{
191192
assert(pubkey_eq(them, &rs_pub));

connectd/test/run-responder-success.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ static struct io_plan *success(struct io_conn *conn UNUSED,
185185
struct crypto_state *cs,
186186
struct oneshot *timeout UNUSED,
187187
enum is_websocket is_websocket UNUSED,
188+
struct timemono starttime UNUSED,
188189
void *unused UNUSED)
189190
{
190191
assert(secret_eq_str(&cs->sk, expect_sk));

0 commit comments

Comments
 (0)