diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 0b00fcfa2..843d0c00d 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -705,6 +705,10 @@ static void json_connect(struct command *cmd, { jsmntok_t *hosttok, *porttok, *idtok; struct pubkey id; + char *id_str; + char *atptr; + char *ataddr = NULL; + int atidx; const char *name; struct wireaddr addr; u8 *msg; @@ -717,6 +721,17 @@ static void json_connect(struct command *cmd, return; } + /* Check for id@addrport form */ + id_str = tal_strndup(cmd, buffer + idtok->start, + idtok->end - idtok->start); + atptr = strchr(id_str, '@'); + if (atptr) { + atidx = atptr - id_str; + ataddr = tal_strdup(cmd, atptr + 1); + /* Cut id. */ + idtok->end = idtok->start + atidx; + } + if (!json_tok_pubkey(buffer, idtok, &id)) { command_fail(cmd, "id %.*s not valid", idtok->end - idtok->start, @@ -724,14 +739,31 @@ static void json_connect(struct command *cmd, return; } - if (porttok && !hosttok) { + if (hosttok && ataddr) { + command_fail(cmd, + "Can't specify host as both xxx@yyy " + "and separate argument"); + return; + } + + /* Get parseable host if provided somehow */ + if (hosttok) + name = tal_strndup(cmd, buffer + hosttok->start, + hosttok->end - hosttok->start); + else if (ataddr) + name = ataddr; + else + name = NULL; + + /* Port without host name? */ + if (porttok && !name) { command_fail(cmd, "Can't specify port without host"); return; } - if (hosttok) { - name = tal_strndup(cmd, buffer + hosttok->start, - hosttok->end - hosttok->start); + /* Was there parseable host name? */ + if (name) { + /* Is there a port? */ if (porttok) { u32 port; if (!json_tok_number(buffer, porttok, &port)) { @@ -767,7 +799,8 @@ static void json_connect(struct command *cmd, static const struct json_command connect_command = { "connect", json_connect, - "Connect to {id} at {host} (which can end in ':port' if not default)" + "Connect to {id} at {host} (which can end in ':port' if not default). " + "{id} can also be of the form id@host" }; AUTODATA(json_command, &connect_command); diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index fd31f7ff2..1455eab17 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -453,6 +453,25 @@ class LightningDTests(BaseLightningDTests): assert len(l1.rpc.listpeers()) == 1 assert len(l2.rpc.listpeers()) == 1 + def test_connect_standard_addr(self): + """Test standard node@host:port address + """ + l1 = self.node_factory.get_node() + l2 = self.node_factory.get_node() + l3 = self.node_factory.get_node() + + # node@host + ret = l1.rpc.connect("{}@{}".format(l2.info['id'], 'localhost'), port=l2.info['port']) + assert ret['id'] == l2.info['id'] + + # node@host:port + ret = l1.rpc.connect("{}@localhost:{}".format(l3.info['id'], l3.info['port'])) + assert ret['id'] == l3.info['id'] + + # node@[ipv6]:port --- not supported by our CI + # ret = l1.rpc.connect("{}@[::1]:{}".format(l3.info['id'], l3.info['port'])) + # assert ret['id'] == l3.info['id'] + def test_balance(self): l1, l2 = self.connect()