gossipd: pass addr of peer though handshake.

We need to derive this from the fd when they connect in, but we already
know it if we're connecting out.

We want this so we can tell (in next few patches) master the peer's address.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-10-23 14:42:38 +10:30
parent 3f84ca1052
commit 33bfc2326a
5 changed files with 83 additions and 25 deletions

View File

@ -1,3 +1,4 @@
#include <ccan/build_assert/build_assert.h>
#include <ccan/container_of/container_of.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/endian/endian.h>
@ -81,6 +82,9 @@ struct reaching {
/* The ID of the peer (not necessarily unique, in transit!) */
struct pubkey id;
/* Where I'm reaching to. */
struct ipaddr addr;
/* Did we succeed? */
bool succeeded;
};
@ -94,6 +98,9 @@ struct peer {
/* The ID of the peer (not necessarily unique, in transit!) */
struct pubkey id;
/* Where it's connected to. */
struct ipaddr addr;
/* Feature bitmaps. */
u8 *gfeatures, *lfeatures;
@ -332,6 +339,7 @@ static struct io_plan *read_init(struct io_conn *conn, struct peer *peer)
* we have the features. */
static struct io_plan *init_new_peer(struct io_conn *conn,
const struct pubkey *their_id,
const struct ipaddr *addr,
const struct crypto_state *cs,
struct daemon *daemon)
{
@ -339,6 +347,7 @@ static struct io_plan *init_new_peer(struct io_conn *conn,
u8 *initmsg;
peer->fd = io_conn_fd(conn);
peer->addr = *addr;
/* BOLT #1:
*
@ -935,8 +944,38 @@ fail:
static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon)
{
struct ipaddr addr;
struct sockaddr_storage s;
socklen_t len = sizeof(s);
if (getpeername(io_conn_fd(conn), (struct sockaddr *)&s, &len) != 0) {
status_trace("Failed to get peername for incoming conn");
return io_close(conn);
}
if (s.ss_family == AF_INET6) {
struct sockaddr_in6 *s6 = (void *)&s;
addr.type = ADDR_TYPE_IPV6;
addr.addrlen = sizeof(s6->sin6_addr);
BUILD_ASSERT(sizeof(s6->sin6_addr) <= sizeof(addr.addr));
memcpy(addr.addr, &s6->sin6_addr, addr.addrlen);
addr.port = ntohs(s6->sin6_port);
} else if (s.ss_family == AF_INET) {
struct sockaddr_in *s4 = (void *)&s;
addr.type = ADDR_TYPE_IPV4;
addr.addrlen = sizeof(s4->sin_addr);
BUILD_ASSERT(sizeof(s4->sin_addr) <= sizeof(addr.addr));
memcpy(addr.addr, &s4->sin_addr, addr.addrlen);
addr.port = ntohs(s4->sin_port);
} else {
status_trace("Unknown socket type %i for incoming conn",
s.ss_family);
return io_close(conn);
}
/* FIXME: Timeout */
return responder_handshake(conn, &daemon->id, init_new_peer, daemon);
return responder_handshake(conn, &daemon->id, &addr,
init_new_peer, daemon);
}
static void setup_listeners(struct daemon *daemon, u16 portnum)
@ -1068,10 +1107,11 @@ static void handle_forwarded_msg(struct io_conn *conn, struct daemon *daemon, co
static struct io_plan *handshake_out_success(struct io_conn *conn,
const struct pubkey *id,
const struct ipaddr *addr,
const struct crypto_state *cs,
struct reaching *reach)
{
return init_new_peer(conn, id, cs, reach->daemon);
return init_new_peer(conn, id, addr, cs, reach->daemon);
}
@ -1083,6 +1123,7 @@ static struct io_plan *connection_out(struct io_conn *conn,
type_to_string(trc, struct pubkey, &reach->id));
return initiator_handshake(conn, &reach->daemon->id, &reach->id,
&reach->addr,
handshake_out_success, reach);
}
@ -1099,14 +1140,8 @@ static void connect_failed(struct io_conn *conn, struct reaching *reach)
try_connect, reach);
}
struct reach_addr {
struct reaching *reach;
struct ipaddr addr;
};
static struct io_plan *conn_init(struct io_conn *conn, struct reach_addr *r)
static struct io_plan *conn_init(struct io_conn *conn, struct reaching *reach)
{
struct reaching *reach = r->reach;
struct addrinfo ai;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
@ -1118,12 +1153,12 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reach_addr *r)
ai.ai_canonname = NULL;
ai.ai_next = NULL;
switch (r->addr.type) {
switch (reach->addr.type) {
case ADDR_TYPE_IPV4:
ai.ai_family = AF_INET;
sin.sin_family = AF_INET;
sin.sin_port = htons(r->addr.port);
memcpy(&sin.sin_addr, r->addr.addr, sizeof(sin.sin_addr));
sin.sin_port = htons(reach->addr.port);
memcpy(&sin.sin_addr, reach->addr.addr, sizeof(sin.sin_addr));
ai.ai_addrlen = sizeof(sin);
ai.ai_addr = (struct sockaddr *)&sin;
break;
@ -1131,8 +1166,8 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reach_addr *r)
ai.ai_family = AF_INET6;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(r->addr.port);
memcpy(&sin6.sin6_addr, r->addr.addr, sizeof(sin6.sin6_addr));
sin6.sin6_port = htons(reach->addr.port);
memcpy(&sin6.sin6_addr, reach->addr.addr, sizeof(sin6.sin6_addr));
ai.ai_addrlen = sizeof(sin6);
ai.ai_addr = (struct sockaddr *)&sin6;
break;
@ -1148,7 +1183,6 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reach_addr *r)
static void try_connect(struct reaching *reach)
{
struct addrhint *a;
struct reach_addr r;
int fd;
/* Already succeeded somehow? */
@ -1192,9 +1226,8 @@ static void try_connect(struct reaching *reach)
return;
}
r.reach = reach;
r.addr = a->addr;
io_new_conn(reach, fd, conn_init, &r);
reach->addr = a->addr;
io_new_conn(reach, fd, conn_init, reach);
}
static void try_reach_peer(struct daemon *daemon, const struct pubkey *id)

View File

@ -19,6 +19,7 @@
#include <sodium/randombytes.h>
#include <stdio.h>
#include <unistd.h>
#include <wire/wire.h>
#define HSM_FD 3
@ -169,6 +170,9 @@ struct handshake {
struct act_two act2;
struct act_three act3;
/* Where is connection from/to */
struct ipaddr addr;
/* Who we are */
struct pubkey my_id;
/* Who they are: set already if we're initiator. */
@ -180,6 +184,7 @@ struct handshake {
/* Function to call once handshake complete. */
struct io_plan *(*cb)(struct io_conn *conn,
const struct pubkey *their_id,
const struct ipaddr *ipaddr,
const struct crypto_state *cs,
void *cbarg);
void *cbarg;
@ -348,10 +353,12 @@ static struct io_plan *handshake_succeeded(struct io_conn *conn,
struct crypto_state cs;
struct io_plan *(*cb)(struct io_conn *conn,
const struct pubkey *their_id,
const struct ipaddr *addr,
const struct crypto_state *cs,
void *cbarg);
void *cbarg;
struct pubkey their_id;
struct ipaddr addr;
/* BOLT #8:
*
@ -376,9 +383,10 @@ static struct io_plan *handshake_succeeded(struct io_conn *conn,
cb = h->cb;
cbarg = h->cbarg;
their_id = h->their_id;
addr = h->addr;
tal_free(h);
return cb(conn, &their_id, &cs, cbarg);
return cb(conn, &their_id, &addr, &cs, cbarg);
}
static struct handshake *new_handshake(const tal_t *ctx,
@ -953,8 +961,10 @@ static struct io_plan *act_one_responder(struct io_conn *conn,
struct io_plan *responder_handshake_(struct io_conn *conn,
const struct pubkey *my_id,
const struct ipaddr *addr,
struct io_plan *(*cb)(struct io_conn *,
const struct pubkey *,
const struct ipaddr *,
const struct crypto_state *,
void *cbarg),
void *cbarg)
@ -963,6 +973,7 @@ struct io_plan *responder_handshake_(struct io_conn *conn,
h->side = RESPONDER;
h->my_id = *my_id;
h->addr = *addr;
h->cbarg = cbarg;
h->cb = cb;
@ -972,8 +983,10 @@ struct io_plan *responder_handshake_(struct io_conn *conn,
struct io_plan *initiator_handshake_(struct io_conn *conn,
const struct pubkey *my_id,
const struct pubkey *their_id,
const struct ipaddr *addr,
struct io_plan *(*cb)(struct io_conn *,
const struct pubkey *,
const struct ipaddr *,
const struct crypto_state *,
void *cbarg),
void *cbarg)
@ -983,6 +996,7 @@ struct io_plan *initiator_handshake_(struct io_conn *conn,
h->side = INITIATOR;
h->my_id = *my_id;
h->their_id = *their_id;
h->addr = *addr;
h->cbarg = cbarg;
h->cb = cb;

View File

@ -5,14 +5,16 @@
struct crypto_state;
struct io_conn;
struct ipaddr;
struct pubkey;
#define initiator_handshake(conn, my_id, their_id, cb, cbarg) \
initiator_handshake_((conn), (my_id), (their_id), \
#define initiator_handshake(conn, my_id, their_id, addr, cb, cbarg) \
initiator_handshake_((conn), (my_id), (their_id), (addr), \
typesafe_cb_preargs(struct io_plan *, void *, \
(cb), (cbarg), \
struct io_conn *, \
const struct pubkey *, \
const struct ipaddr *, \
const struct crypto_state *), \
(cbarg))
@ -20,26 +22,31 @@ struct pubkey;
struct io_plan *initiator_handshake_(struct io_conn *conn,
const struct pubkey *my_id,
const struct pubkey *their_id,
const struct ipaddr *addr,
struct io_plan *(*cb)(struct io_conn *,
const struct pubkey *,
const struct ipaddr *,
const struct crypto_state *,
void *cbarg),
void *cbarg);
#define responder_handshake(conn, my_id, cb, cbarg) \
responder_handshake_((conn), (my_id), \
#define responder_handshake(conn, my_id, addr, cb, cbarg) \
responder_handshake_((conn), (my_id), (addr), \
typesafe_cb_preargs(struct io_plan *, void *, \
(cb), (cbarg), \
struct io_conn *, \
const struct pubkey *, \
const struct ipaddr *, \
const struct crypto_state *), \
(cbarg))
struct io_plan *responder_handshake_(struct io_conn *conn,
const struct pubkey *my_id,
const struct ipaddr *addr,
struct io_plan *(*cb)(struct io_conn *,
const struct pubkey *,
const struct ipaddr *,
const struct crypto_state *,
void *cbarg),
void *cbarg);

View File

@ -176,6 +176,7 @@ static struct io_plan *test_read(struct io_conn *conn,
static struct io_plan *success(struct io_conn *conn,
const struct pubkey *them,
const struct ipaddr *addr,
const struct crypto_state *cs,
void *ctx)
{
@ -199,6 +200,7 @@ bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point)
int main(void)
{
tal_t *ctx = tal_tmpctx(NULL);
struct ipaddr dummy;
trc = tal_tmpctx(ctx);
@ -221,7 +223,7 @@ int main(void)
e_priv = privkey("1212121212121212121212121212121212121212121212121212121212121212");
e_pub = pubkey("036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7");
initiator_handshake(ctx, &ls_pub, &rs_pub, success, ctx);
initiator_handshake(ctx, &ls_pub, &rs_pub, &dummy, success, ctx);
/* Should not exit! */
abort();
}

View File

@ -176,6 +176,7 @@ static struct io_plan *test_read(struct io_conn *conn,
static struct io_plan *success(struct io_conn *conn,
const struct pubkey *them,
const struct ipaddr *addr,
const struct crypto_state *cs,
void *ctx)
{
@ -197,6 +198,7 @@ bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point)
int main(void)
{
tal_t *ctx = tal_tmpctx(NULL);
struct ipaddr dummy;
trc = tal_tmpctx(ctx);
@ -217,7 +219,7 @@ int main(void)
e_priv = privkey("2222222222222222222222222222222222222222222222222222222222222222");
e_pub = pubkey("02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27");
responder_handshake(ctx, &ls_pub, success, ctx);
responder_handshake(ctx, &ls_pub, &dummy, success, ctx);
/* Should not exit! */
abort();
}