lightningd: get connection direction from connectd.

This matters: if we connected, the address is probably usable for future connections.
But if they connected, the port is probably not (but the IP address may be).

Changelog-Added: JSON-RPC: `connect` returns "direction" ("in": they iniatated, or "out": we initiated)
Changelog-Added: plugins: `peer_connected` hook and `connect` notifications have "direction" field.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2021-03-25 14:23:31 +10:30
parent b689d33e97
commit b0d6996ed6
17 changed files with 79 additions and 46 deletions

View File

@@ -513,7 +513,8 @@ struct io_plan *peer_connected(struct io_conn *conn,
return io_close(conn);
/* Create message to tell master peer has connected. */
msg = towire_connectd_peer_connected(NULL, id, addr, pps, their_features);
msg = towire_connectd_peer_connected(NULL, id, addr, incoming,
pps, their_features);
/*~ daemon_conn is a message queue for inter-daemon communication: we
* queue up the `connect_peer_connected` message to tell lightningd

View File

@@ -56,6 +56,7 @@ msgdata,connectd_connect_failed,addrhint,?wireaddr_internal,
msgtype,connectd_peer_connected,2002
msgdata,connectd_peer_connected,id,node_id,
msgdata,connectd_peer_connected,addr,wireaddr_internal,
msgdata,connectd_peer_connected,incoming,bool,
msgdata,connectd_peer_connected,pps,per_peer_state,
msgdata,connectd_peer_connected,flen,u16,
msgdata,connectd_peer_connected,features,u8,flen
1 #include <common/cryptomsg.h>
56 msgdata,connectd_peer_disconnected,id,node_id, msgtype,connectd_peer_disconnected,2015
57 # master -> connectd: do you have a memleak? msgdata,connectd_peer_disconnected,id,node_id,
58 msgtype,connectd_dev_memleak,2033 # master -> connectd: do you have a memleak?
59 msgtype,connectd_dev_memleak,2033
60 msgtype,connectd_dev_memleak_reply,2133
61 msgdata,connectd_dev_memleak_reply,leak,bool,
62

View File

@@ -311,7 +311,7 @@ bool fromwire_connectd_connect_failed(const tal_t *ctx, const void *p, struct no
/* WIRE: CONNECTD_PEER_CONNECTED */
/* Connectd -> master: we got a peer. Three fds: peer */
u8 *towire_connectd_peer_connected(const tal_t *ctx, const struct node_id *id, const struct wireaddr_internal *addr, const struct per_peer_state *pps, const u8 *features)
u8 *towire_connectd_peer_connected(const tal_t *ctx, const struct node_id *id, const struct wireaddr_internal *addr, bool incoming, const struct per_peer_state *pps, const u8 *features)
{
u16 flen = tal_count(features);
u8 *p = tal_arr(ctx, u8, 0);
@@ -319,13 +319,14 @@ u8 *towire_connectd_peer_connected(const tal_t *ctx, const struct node_id *id, c
towire_u16(&p, WIRE_CONNECTD_PEER_CONNECTED);
towire_node_id(&p, id);
towire_wireaddr_internal(&p, addr);
towire_bool(&p, incoming);
towire_per_peer_state(&p, pps);
towire_u16(&p, flen);
towire_u8_array(&p, features, flen);
return memcheck(p, tal_count(p));
}
bool fromwire_connectd_peer_connected(const tal_t *ctx, const void *p, struct node_id *id, struct wireaddr_internal *addr, struct per_peer_state **pps, u8 **features)
bool fromwire_connectd_peer_connected(const tal_t *ctx, const void *p, struct node_id *id, struct wireaddr_internal *addr, bool *incoming, struct per_peer_state **pps, u8 **features)
{
u16 flen;
@@ -336,6 +337,7 @@ bool fromwire_connectd_peer_connected(const tal_t *ctx, const void *p, struct no
return false;
fromwire_node_id(&cursor, &plen, id);
fromwire_wireaddr_internal(&cursor, &plen, addr);
*incoming = fromwire_bool(&cursor, &plen);
*pps = fromwire_per_peer_state(ctx, &cursor, &plen);
flen = fromwire_u16(&cursor, &plen);
// 2nd case features
@@ -406,4 +408,4 @@ bool fromwire_connectd_dev_memleak_reply(const void *p, bool *leak)
*leak = fromwire_bool(&cursor, &plen);
return cursor != NULL;
}
// SHA256STAMP:f8dfca9dd140207a71bbc264cce4a86015529ec753f1a61a672800662ed7ee75
// SHA256STAMP:9bbb0b97a226bd5c85a21bafde42c7fd438b8107d6d30b7c7b17c16a6cbd3557

View File

@@ -84,8 +84,8 @@ bool fromwire_connectd_connect_failed(const tal_t *ctx, const void *p, struct no
/* WIRE: CONNECTD_PEER_CONNECTED */
/* Connectd -> master: we got a peer. Three fds: peer */
u8 *towire_connectd_peer_connected(const tal_t *ctx, const struct node_id *id, const struct wireaddr_internal *addr, const struct per_peer_state *pps, const u8 *features);
bool fromwire_connectd_peer_connected(const tal_t *ctx, const void *p, struct node_id *id, struct wireaddr_internal *addr, struct per_peer_state **pps, u8 **features);
u8 *towire_connectd_peer_connected(const tal_t *ctx, const struct node_id *id, const struct wireaddr_internal *addr, bool incoming, const struct per_peer_state *pps, const u8 *features);
bool fromwire_connectd_peer_connected(const tal_t *ctx, const void *p, struct node_id *id, struct wireaddr_internal *addr, bool *incoming, struct per_peer_state **pps, u8 **features);
/* WIRE: CONNECTD_PEER_DISCONNECTED */
/* master -> connectd: peer has disconnected. */
@@ -103,4 +103,4 @@ bool fromwire_connectd_dev_memleak_reply(const void *p, bool *leak);
#endif /* LIGHTNING_CONNECTD_CONNECTD_WIREGEN_H */
// SHA256STAMP:f8dfca9dd140207a71bbc264cce4a86015529ec753f1a61a672800662ed7ee75
// SHA256STAMP:9bbb0b97a226bd5c85a21bafde42c7fd438b8107d6d30b7c7b17c16a6cbd3557

View File

@@ -398,12 +398,13 @@ remote peer, but we have been offline.
### `connect`
A notification for topic `connect` is sent every time a new connection
to a peer is established.
to a peer is established. `direction` is either `"in"` or `"out"`.
```json
{
"id": "02f6725f9c1c40333b67faea92fd211c183050f28df32cac3f9d69685fe9665432",
"address": "1.2.3.4"
"direction": "in",
"address": "1.2.3.4:1234"
}
```
@@ -796,6 +797,7 @@ the cryptographic handshake. The parameters have the following structure:
{
"peer": {
"id": "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f",
"direction": "in",
"addr": "34.239.230.56:9735",
"features": ""
}
@@ -803,11 +805,11 @@ the cryptographic handshake. The parameters have the following structure:
```
The hook is sparse on information, since the plugin can use the JSON-RPC
`listpeers` command to get additional details should they be required. The
`addr` field shows the address that we are connected to ourselves, not the
gossiped list of known addresses. In particular this means that the port for
incoming connections is an ephemeral port, that may not be available for
reconnections.
`listpeers` command to get additional details should they be required.
`direction` is either `"in"` or `"out"`. The `addr` field shows the address
that we are connected to ourselves, not the gossiped list of known
addresses. In particular this means that the port for incoming connections is
an ephemeral port, that may not be available for reconnections.
The returned result must contain a `result` member which is either
the string `disconnect` or `continue`. If `disconnect` and

View File

@@ -42,8 +42,11 @@ another node\. Once the peer is connected a channel can be opened with
.SH RETURN VALUE
On success the peer \fIid\fR is returned, as well as a hexidecimal \fIfeatures\fR
bitmap and an \fIaddress\fR object as per \fBlightning-listnodes\fR(7)\.
On success the peer \fIid\fR is returned, as well as a hexidecimal
\fIfeatures\fR bitmap, a \fIdirection\fR ("in" if they connected to us, "out"
if we connected to them") and an \fIaddress\fR object as per
\fBlightning-listnodes\fR(7)\. Note that \fIaddress\fR will be less useful if
"direction" is "in", especially if a proxy is in use\.
.SH ERRORS
@@ -94,4 +97,4 @@ Felix \fI<fixone@gmail.com\fR> is the original author of this manpage\.
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
\" SHA256STAMP:336c35e791dc6439115e25a2f58ffb9dc68989c96d51b6c39cb3de6d40328ae5
\" SHA256STAMP:a392b6683fad5fe218e7a985e1eaf5d7439f38d7c74212c275cfa64db284efc0

View File

@@ -39,8 +39,11 @@ lightning-fundchannel(7).
RETURN VALUE
------------
On success the peer *id* is returned, as well as a hexidecimal *features*
bitmap and an *address* object as per lightning-listnodes(7).
On success the peer *id* is returned, as well as a hexidecimal
*features* bitmap, a *direction* ("in" if they connected to us, "out"
if we connected to them") and an *address* object as per
lightning-listnodes(7). Note that *address* will be less useful if
"direction" is "in", especially if a proxy is in use.
ERRORS
------

View File

@@ -69,11 +69,13 @@ static struct connect *find_connect(struct lightningd *ld,
static struct command_result *connect_cmd_succeed(struct command *cmd,
const struct peer *peer,
bool incoming,
const struct wireaddr_internal *addr)
{
struct json_stream *response = json_stream_success(cmd);
json_add_node_id(response, "id", &peer->id);
json_add_hex_talarr(response, "features", peer->their_features);
json_add_string(response, "direction", incoming ? "in" : "out");
json_add_address_internal(response, "address", addr);
return command_success(cmd, response);
}
@@ -147,7 +149,8 @@ static struct command_result *json_connect(struct command *cmd,
|| (channel && channel->connected)) {
log_debug(cmd->ld->log, "Already connected via %s",
type_to_string(tmpctx, struct wireaddr_internal, &peer->addr));
return connect_cmd_succeed(cmd, peer, &peer->addr);
/* FIXME: Save connection direction! */
return connect_cmd_succeed(cmd, peer, false, &peer->addr);
}
}
@@ -265,6 +268,7 @@ static void connect_failed(struct lightningd *ld, const u8 *msg)
}
void connect_succeeded(struct lightningd *ld, const struct peer *peer,
bool incoming,
const struct wireaddr_internal *addr)
{
struct connect *c;
@@ -272,7 +276,7 @@ void connect_succeeded(struct lightningd *ld, const struct peer *peer,
/* We can have multiple connect commands: fail them all */
while ((c = find_connect(ld, &peer->id)) != NULL) {
/* They delete themselves from list */
connect_cmd_succeed(c->cmd, peer, addr);
connect_cmd_succeed(c->cmd, peer, incoming, addr);
}
}

View File

@@ -13,6 +13,7 @@ void connectd_activate(struct lightningd *ld);
void delay_then_reconnect(struct channel *channel, u32 seconds_delay,
const struct wireaddr_internal *addrhint TAKES);
void connect_succeeded(struct lightningd *ld, const struct peer *peer,
bool incoming,
const struct wireaddr_internal *addr);
void gossip_connect_result(struct lightningd *ld, const u8 *msg);

View File

@@ -28,26 +28,31 @@ bool notifications_have_topic(const char *topic)
}
static void connect_notification_serialize(struct json_stream *stream,
struct node_id *nodeid,
struct wireaddr_internal *addr)
const struct node_id *nodeid,
bool incoming,
const struct wireaddr_internal *addr)
{
json_add_node_id(stream, "id", nodeid);
json_add_string(stream, "direction", incoming ? "in" : "out");
json_add_address_internal(stream, "address", addr);
}
REGISTER_NOTIFICATION(connect,
connect_notification_serialize);
void notify_connect(struct lightningd *ld, struct node_id *nodeid,
struct wireaddr_internal *addr)
void notify_connect(struct lightningd *ld,
const struct node_id *nodeid,
bool incoming,
const struct wireaddr_internal *addr)
{
void (*serialize)(struct json_stream *,
struct node_id *,
struct wireaddr_internal *) = connect_notification_gen.serialize;
const struct node_id *,
bool,
const struct wireaddr_internal *) = connect_notification_gen.serialize;
struct jsonrpc_notification *n
= jsonrpc_notification_start(NULL, connect_notification_gen.topic);
serialize(n->stream, nodeid, addr);
serialize(n->stream, nodeid, incoming, addr);
jsonrpc_notification_end(n);
plugins_notify(ld->plugins, take(n));
}

View File

@@ -43,8 +43,10 @@ AUTODATA_TYPE(notifications, struct notification);
}; \
AUTODATA(notifications, &topic##_notification_gen);
void notify_connect(struct lightningd *ld, struct node_id *nodeid,
struct wireaddr_internal *addr);
void notify_connect(struct lightningd *ld,
const struct node_id *nodeid,
bool incoming,
const struct wireaddr_internal *addr);
void notify_disconnect(struct lightningd *ld, struct node_id *nodeid);
void notify_warning(struct lightningd *ld, struct log_entry *l);

View File

@@ -981,6 +981,7 @@ struct peer_connected_hook_payload {
struct lightningd *ld;
struct channel *channel;
struct wireaddr_internal addr;
bool incoming;
struct peer *peer;
struct per_peer_state *pps;
u8 *error;
@@ -993,6 +994,7 @@ peer_connected_serialize(struct peer_connected_hook_payload *payload,
const struct peer *p = payload->peer;
json_object_start(stream, "peer");
json_add_node_id(stream, "id", &p->id);
json_add_string(stream, "direction", payload->incoming ? "in" : "out");
json_add_string(
stream, "addr",
type_to_string(stream, struct wireaddr_internal, &payload->addr));
@@ -1079,7 +1081,7 @@ static void peer_connected_hook_final(struct peer_connected_hook_payload *payloa
abort();
}
notify_connect(ld, &peer->id, &addr);
notify_connect(ld, &peer->id, payload->incoming, &addr);
/* No err, all good. */
error = NULL;
@@ -1167,9 +1169,10 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
hook_payload->ld = ld;
hook_payload->error = NULL;
if (!fromwire_connectd_peer_connected(hook_payload, msg,
&id, &hook_payload->addr,
&hook_payload->pps,
&their_features))
&id, &hook_payload->addr,
&hook_payload->incoming,
&hook_payload->pps,
&their_features))
fatal("Connectd gave bad CONNECT_PEER_CONNECTED message %s",
tal_hex(msg, msg));
@@ -1188,7 +1191,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
peer_update_features(peer, their_features);
/* Complete any outstanding connect commands. */
connect_succeeded(ld, peer, &hook_payload->addr);
connect_succeeded(ld, peer, hook_payload->incoming, &hook_payload->addr);
/* Can't be opening, since we wouldn't have sent peer_disconnected. */
assert(!peer->uncommitted_channel);

View File

@@ -143,6 +143,7 @@ struct command_result *command_success(struct command *cmd UNNEEDED,
{ fprintf(stderr, "command_success called!\n"); abort(); }
/* Generated stub for connect_succeeded */
void connect_succeeded(struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED,
bool incoming UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "connect_succeeded called!\n"); abort(); }
/* Generated stub for delay_then_reconnect */
@@ -190,7 +191,7 @@ void fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_dev_memleak_reply called!\n"); abort(); }
/* Generated stub for fromwire_connectd_peer_connected */
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **features UNNEEDED)
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, bool *incoming UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **features UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
/* Generated stub for fromwire_gossipd_get_incoming_channels_reply */
bool fromwire_gossipd_get_incoming_channels_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct route_info **public_route_info UNNEEDED, bool **public_deadends UNNEEDED, struct route_info **private_route_info UNNEEDED, bool **private_deadends UNNEEDED)
@@ -421,8 +422,10 @@ int node_id_cmp(const struct node_id *a UNNEEDED, const struct node_id *b UNNEED
char *node_id_to_hexstr(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED)
{ fprintf(stderr, "node_id_to_hexstr 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)
void notify_connect(struct lightningd *ld UNNEEDED,
const struct node_id *nodeid UNNEEDED,
bool incoming UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "notify_connect called!\n"); abort(); }
/* Generated stub for notify_disconnect */
void notify_disconnect(struct lightningd *ld UNNEEDED, struct node_id *nodeid UNNEEDED)

View File

@@ -1888,4 +1888,4 @@ struct db_query db_postgres_queries[] = {
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
// SHA256STAMP:3004e6442db61cf4afb9a7e0ce3600b32e27a4cd5cac0aff02cefd3ddbdac209
// SHA256STAMP:08adbcdb1d190901ae39605a2c1cb0d4639f6d88ddff2f1cd370e1fdc9663a2d

View File

@@ -1888,4 +1888,4 @@ struct db_query db_sqlite3_queries[] = {
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
// SHA256STAMP:3004e6442db61cf4afb9a7e0ce3600b32e27a4cd5cac0aff02cefd3ddbdac209
// SHA256STAMP:08adbcdb1d190901ae39605a2c1cb0d4639f6d88ddff2f1cd370e1fdc9663a2d

View File

@@ -1238,11 +1238,11 @@ msgstr ""
msgid "not a valid SQL statement"
msgstr ""
#: wallet/test/run-wallet.c:1442
#: wallet/test/run-wallet.c:1445
msgid "SELECT COUNT(1) FROM channel_funding_inflights WHERE channel_id = ?;"
msgstr ""
#: wallet/test/run-wallet.c:1640
#: wallet/test/run-wallet.c:1643
msgid "INSERT INTO channels (id) VALUES (1);"
msgstr ""
# SHA256STAMP:ae37c982463dfe567d7b4ff13d238e20987f67496778b413d6212e24ebddee68
# SHA256STAMP:b110e3333958e18759ec9a2cf17840a3ded609edbdd6001962888a0152ac879c

View File

@@ -90,6 +90,7 @@ struct command_result *command_success(struct command *cmd UNNEEDED,
{ fprintf(stderr, "command_success called!\n"); abort(); }
/* Generated stub for connect_succeeded */
void connect_succeeded(struct lightningd *ld UNNEEDED, const struct peer *peer UNNEEDED,
bool incoming UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "connect_succeeded called!\n"); abort(); }
/* Generated stub for create_onionreply */
@@ -139,7 +140,7 @@ bool fromwire_channeld_offer_htlc_reply(const tal_t *ctx UNNEEDED, const void *p
bool fromwire_channeld_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct penalty_base **pbase UNNEEDED, struct fee_states **fee_states UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_signature *commit_sig UNNEEDED, struct bitcoin_signature **htlc_sigs UNNEEDED)
{ fprintf(stderr, "fromwire_channeld_sending_commitsig called!\n"); abort(); }
/* Generated stub for fromwire_connectd_peer_connected */
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **features UNNEEDED)
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, bool *incoming UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **features UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
/* Generated stub for fromwire_custommsg_in */
bool fromwire_custommsg_in(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **msg UNNEEDED)
@@ -490,8 +491,10 @@ void notify_channel_state_changed(struct lightningd *ld UNNEEDED,
char *message UNNEEDED)
{ fprintf(stderr, "notify_channel_state_changed 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)
void notify_connect(struct lightningd *ld UNNEEDED,
const struct node_id *nodeid UNNEEDED,
bool incoming UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "notify_connect called!\n"); abort(); }
/* Generated stub for notify_disconnect */
void notify_disconnect(struct lightningd *ld UNNEEDED, struct node_id *nodeid UNNEEDED)