Browse Source

gossipd: don't handle multiple connect requests, combine them in lightningd.

Christian points out that this is the pattern used elsewhere, for example.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
83e847575c
  1. 35
      gossipd/gossip.c
  2. 12
      lightningd/connect_control.c

35
gossipd/gossip.c

@ -149,8 +149,8 @@ struct reaching {
/* FIXME: Support multiple address. */ /* FIXME: Support multiple address. */
struct wireaddr addr; struct wireaddr addr;
/* How many (if any) connect commands are waiting for the result. */ /* Whether connect command is waiting for the result. */
size_t num_master_responses; bool master_needs_response;
/* How far did we get? */ /* How far did we get? */
const char *connstate; const char *connstate;
@ -362,10 +362,12 @@ static void reached_peer(struct peer *peer, struct io_conn *conn)
/* Don't free conn with reach */ /* Don't free conn with reach */
tal_steal(peer->daemon, conn); tal_steal(peer->daemon, conn);
/* Tell any connect commands what happened. */ /* Tell any connect command what happened. */
msg = towire_gossipctl_connect_to_peer_result(r, &r->id, true, ""); if (r->master_needs_response) {
for (size_t i = 0; i < r->num_master_responses; i++) msg = towire_gossipctl_connect_to_peer_result(NULL, &r->id,
daemon_conn_send(&peer->daemon->master, msg); true, "");
daemon_conn_send(&peer->daemon->master, take(msg));
}
tal_free(r); tal_free(r);
} }
@ -1713,11 +1715,12 @@ static void connect_failed(struct io_conn *conn, struct reaching *reach)
reach->connstate, reach->connstate,
strerror(errno)); strerror(errno));
/* Tell any connect commands what happened. */ /* Tell any connect command what happened. */
msg = towire_gossipctl_connect_to_peer_result(reach, &reach->id, if (reach->master_needs_response) {
msg = towire_gossipctl_connect_to_peer_result(NULL, &reach->id,
false, err); false, err);
for (size_t i = 0; i < reach->num_master_responses; i++) daemon_conn_send(&reach->daemon->master, take(msg));
daemon_conn_send(&reach->daemon->master, msg); }
status_trace("Failed connected out for %s", status_trace("Failed connected out for %s",
type_to_string(tmpctx, struct pubkey, &reach->id)); type_to_string(tmpctx, struct pubkey, &reach->id));
@ -1832,9 +1835,13 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
/* If we're trying to reach it right now, that's OK. */ /* If we're trying to reach it right now, that's OK. */
reach = find_reaching(daemon, id); reach = find_reaching(daemon, id);
if (reach) { if (reach) {
/* Please tell us too. */ /* Please tell us too. Master should not ask twice (we'll
if (master_needs_response) * only respond once, and so one request will get stuck) */
reach->num_master_responses++; if (reach->master_needs_response)
status_failed(STATUS_FAIL_MASTER_IO,
"Already reaching %s",
type_to_string(tmpctx, struct pubkey, id));
reach->master_needs_response = true;
return; return;
} }
@ -1889,7 +1896,7 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
reach->daemon = daemon; reach->daemon = daemon;
reach->id = *id; reach->id = *id;
reach->addr = a->addr; reach->addr = a->addr;
reach->num_master_responses = master_needs_response; reach->master_needs_response = master_needs_response;
reach->connstate = "Connection establishment"; reach->connstate = "Connection establishment";
list_add_tail(&daemon->reaching, &reach->list); list_add_tail(&daemon->reaching, &reach->list);
tal_add_destructor(reach, destroy_reaching); tal_add_destructor(reach, destroy_reaching);

12
lightningd/connect_control.c

@ -61,9 +61,8 @@ void gossip_connect_result(struct lightningd *ld, const u8 *msg)
tal_hex(msg, msg)); tal_hex(msg, msg));
c = find_connect(ld, &id); /* We can have multiple connect commands: complete them all */
assert(c); while ((c = find_connect(ld, &id)) != NULL) {
if (connected) { if (connected) {
struct json_result *response = new_json_result(c->cmd); struct json_result *response = new_json_result(c->cmd);
json_object_start(response, NULL); json_object_start(response, NULL);
@ -73,6 +72,8 @@ void gossip_connect_result(struct lightningd *ld, const u8 *msg)
} else { } else {
command_fail(c->cmd, "%s", err); command_fail(c->cmd, "%s", err);
} }
/* They delete themselves from list */
}
} }
static void json_connect(struct command *cmd, static void json_connect(struct command *cmd,
@ -162,10 +163,11 @@ static void json_connect(struct command *cmd,
subd_send_msg(cmd->ld->gossip, take(msg)); subd_send_msg(cmd->ld->gossip, take(msg));
} }
/* Now tell it to try reaching it. */ /* If there isn't already a connect command, tell gossipd */
if (!find_connect(cmd->ld, &id)) {
msg = towire_gossipctl_connect_to_peer(NULL, &id); msg = towire_gossipctl_connect_to_peer(NULL, &id);
subd_send_msg(cmd->ld->gossip, take(msg)); subd_send_msg(cmd->ld->gossip, take(msg));
}
/* Leave this here for gossip_connect_result */ /* Leave this here for gossip_connect_result */
new_connect(cmd->ld, &id, cmd); new_connect(cmd->ld, &id, cmd);
command_still_pending(cmd); command_still_pending(cmd);

Loading…
Cancel
Save