Browse Source

protocol: pkt_reconnect becomes pkt_init, and always send.

Make this always the first packet after auth.  That means there's no
reliance on whether a node remembers an aborted connection.

It also gives us a place to put version bits.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
ec64e7756e
  1. 10
      daemon/packets.c
  2. 2
      daemon/packets.h
  3. 166
      daemon/peer.c
  4. 72
      lightning.pb-c.c
  5. 54
      lightning.pb-c.h
  6. 6
      lightning.proto

10
daemon/packets.c

@ -236,12 +236,12 @@ Pkt *pkt_err(struct peer *peer, const char *msg, ...)
return make_pkt(peer, PKT__PKT_ERROR, e);
}
Pkt *pkt_reconnect(struct peer *peer, u64 ack)
Pkt *pkt_init(struct peer *peer, u64 ack)
{
Reconnect *r = tal(peer, Reconnect);
reconnect__init(r);
r->ack = ack;
return make_pkt(peer, PKT__PKT_RECONNECT, r);
Init *i = tal(peer, Init);
init__init(i);
i->ack = ack;
return make_pkt(peer, PKT__PKT_INIT, i);
}
void queue_pkt_err(struct peer *peer, Pkt *err)

2
daemon/packets.h

@ -26,7 +26,7 @@ void queue_pkt_close_shutdown(struct peer *peer);
void queue_pkt_close_signature(struct peer *peer);
Pkt *pkt_err(struct peer *peer, const char *msg, ...);
Pkt *pkt_reconnect(struct peer *peer, u64 ack);
Pkt *pkt_init(struct peer *peer, u64 ack);
void queue_pkt_err(struct peer *peer, Pkt *err);
Pkt *pkt_err_unexpected(struct peer *peer, const Pkt *pkt);

166
daemon/peer.c

@ -2091,6 +2091,86 @@ static void peer_has_connected(struct peer *peer)
}
}
static struct io_plan *init_pkt_in(struct io_conn *conn, struct peer *peer)
{
if (peer->inpkt->pkt_case != PKT__PKT_INIT) {
peer_received_unexpected_pkt(peer, peer->inpkt, __func__);
return pkt_out(conn, peer);
}
/* They might have missed the error, tell them before hanging up */
if (state_is_error(peer->state)) {
queue_pkt_err(peer, pkt_err(peer, "In error state %s",
state_name(peer->state)));
return pkt_out(conn, peer);
}
/* Send any packets they missed. */
retransmit_pkts(peer, peer->inpkt->init->ack);
/* We let the conversation go this far in case they missed the
* close packets. But now we can close if we're done. */
if (!state_can_io(peer->state)) {
log_debug(peer->log, "State %s, closing immediately",
state_name(peer->state));
return pkt_out(conn, peer);
}
/* Back into normal mode. */
peer_has_connected(peer);
return io_duplex(conn,
peer_read_packet(conn, peer, pkt_in),
pkt_out(conn, peer));
}
static struct io_plan *read_init_pkt(struct io_conn *conn,
struct peer *peer)
{
return peer_read_packet(conn, peer, init_pkt_in);
}
static u64 peer_commitsigs_received(struct peer *peer)
{
return peer->their_commitsigs;
}
static u64 peer_revocations_received(struct peer *peer)
{
/* How many preimages we've received. */
return -peer->their_preimages.min_index;
}
static struct io_plan *peer_send_init(struct io_conn *conn, struct peer *peer)
{
u64 sigs, revokes, shutdown, closing;
sigs = peer_commitsigs_received(peer);
revokes = peer_revocations_received(peer);
shutdown = peer->closing.their_script ? 1 : 0;
closing = peer->closing.sigs_in;
log_debug(peer->log,
"Init with ack %"PRIu64" sigs + %"PRIu64" revokes"
" + %"PRIu64" shutdown + %"PRIu64" closing",
sigs, revokes, shutdown, closing);
/* BOLT #2:
*
* A node reconnecting after receiving or sending an `open_channel`
* message SHOULD send a `reconnect` message on the new connection
* immediately after it has validated the `authenticate` message. */
/* BOLT #2:
*
* A node MUST set the `ack` field in the `reconnect` message to the
* the sum of previously-processed messages of types
* `open_commit_sig`, `update_commit`, `update_revocation`,
* `close_shutdown` and `close_signature`. */
return peer_write_packet(conn, peer,
pkt_init(peer, sigs + revokes
+ shutdown + closing),
read_init_pkt);
}
/* Crypto is on, we are live. */
static struct io_plan *peer_crypto_on(struct io_conn *conn, struct peer *peer)
{
@ -2107,10 +2187,7 @@ static struct io_plan *peer_crypto_on(struct io_conn *conn, struct peer *peer)
state_event(peer, peer->local.offer_anchor, NULL);
peer_has_connected(peer);
return io_duplex(conn,
peer_read_packet(conn, peer, pkt_in),
pkt_out(conn, peer));
return peer_send_init(conn,peer);
}
static void destroy_peer(struct peer *peer)
@ -2484,17 +2561,6 @@ static bool peer_first_connected(struct peer *peer,
return true;
}
static u64 peer_commitsigs_received(struct peer *peer)
{
return peer->their_commitsigs;
}
static u64 peer_revocations_received(struct peer *peer)
{
/* How many preimages we've received. */
return -peer->their_preimages.min_index;
}
static void htlc_destroy(struct htlc *htlc)
{
if (!htlc_map_del(&htlc->peer->htlcs, htlc))
@ -2540,48 +2606,6 @@ struct htlc *peer_new_htlc(struct peer *peer,
return h;
}
static struct io_plan *reconnect_pkt_in(struct io_conn *conn, struct peer *peer)
{
if (peer->inpkt->pkt_case != PKT__PKT_RECONNECT) {
peer_received_unexpected_pkt(peer, peer->inpkt, __func__);
return pkt_out(conn, peer);
}
/* We need to eliminate queue now. */
clear_output_queue(peer);
/* They might have missed the error, tell them before hanging up */
if (state_is_error(peer->state)) {
queue_pkt_err(peer, pkt_err(peer, "In error state %s",
state_name(peer->state)));
return pkt_out(conn, peer);
}
/* Send any packets they missed. */
retransmit_pkts(peer, peer->inpkt->reconnect->ack);
/* We let the conversation go this far in case they missed the
* close packets. But now we can close if we're done. */
if (!state_can_io(peer->state)) {
log_debug(peer->log, "State %s, closing immediately",
state_name(peer->state));
return pkt_out(conn, peer);
}
/* Back into normal mode. */
peer_has_connected(peer);
return io_duplex(conn,
peer_read_packet(conn, peer, pkt_in),
pkt_out(conn, peer));
}
static struct io_plan *read_reconnect_pkt(struct io_conn *conn,
struct peer *peer)
{
return peer_read_packet(conn, peer, reconnect_pkt_in);
}
static struct io_plan *crypto_on_reconnect(struct io_conn *conn,
struct lightningd_state *dstate,
struct io_data *iod,
@ -2589,37 +2613,15 @@ static struct io_plan *crypto_on_reconnect(struct io_conn *conn,
struct peer *peer,
bool we_connected)
{
u64 sigs, revokes, shutdown, closing;
/* Setup peer->conn and peer->io_data */
if (!peer_reconnected(peer, conn, SOCK_STREAM, IPPROTO_TCP,
iod, id, we_connected))
return io_close(conn);
sigs = peer_commitsigs_received(peer);
revokes = peer_revocations_received(peer);
shutdown = peer->closing.their_script ? 1 : 0;
closing = peer->closing.sigs_in;
log_debug(peer->log,
"Reconnecting with ack %"PRIu64" sigs + %"PRIu64" revokes"
" + %"PRIu64" shutdown + %"PRIu64" closing",
sigs, revokes, shutdown, closing);
/* BOLT #2:
*
* A node reconnecting after receiving or sending an `open_channel`
* message SHOULD send a `reconnect` message on the new connection
* immediately after it has validated the `authenticate` message. */
/* We need to eliminate queue now. */
clear_output_queue(peer);
/* BOLT #2:
*
* A node MUST set the `ack` field in the `reconnect` message to the
* the sum of previously-processed messages of types
* `open_commit_sig`, `update_commit`, `update_revocation`,
* `close_shutdown` and `close_signature`. */
return peer_write_packet(conn, peer,
pkt_reconnect(peer, sigs + revokes
+ shutdown + closing),
read_reconnect_pkt);
return peer_send_init(conn, peer);
}
static struct io_plan *crypto_on_reconnect_in(struct io_conn *conn,

72
lightning.pb-c.c

@ -308,47 +308,47 @@ void authenticate__free_unpacked
assert(message->base.descriptor == &authenticate__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void reconnect__init
(Reconnect *message)
void init__init
(Init *message)
{
static Reconnect init_value = RECONNECT__INIT;
static Init init_value = INIT__INIT;
*message = init_value;
}
size_t reconnect__get_packed_size
(const Reconnect *message)
size_t init__get_packed_size
(const Init *message)
{
assert(message->base.descriptor == &reconnect__descriptor);
assert(message->base.descriptor == &init__descriptor);
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t reconnect__pack
(const Reconnect *message,
size_t init__pack
(const Init *message,
uint8_t *out)
{
assert(message->base.descriptor == &reconnect__descriptor);
assert(message->base.descriptor == &init__descriptor);
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t reconnect__pack_to_buffer
(const Reconnect *message,
size_t init__pack_to_buffer
(const Init *message,
ProtobufCBuffer *buffer)
{
assert(message->base.descriptor == &reconnect__descriptor);
assert(message->base.descriptor == &init__descriptor);
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
Reconnect *
reconnect__unpack
Init *
init__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data)
{
return (Reconnect *)
protobuf_c_message_unpack (&reconnect__descriptor,
return (Init *)
protobuf_c_message_unpack (&init__descriptor,
allocator, len, data);
}
void reconnect__free_unpacked
(Reconnect *message,
void init__free_unpacked
(Init *message,
ProtobufCAllocator *allocator)
{
assert(message->base.descriptor == &reconnect__descriptor);
assert(message->base.descriptor == &init__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void open_channel__init
@ -1644,7 +1644,7 @@ const ProtobufCMessageDescriptor authenticate__descriptor =
(ProtobufCMessageInit) authenticate__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor reconnect__field_descriptors[1] =
static const ProtobufCFieldDescriptor init__field_descriptors[1] =
{
{
"ack",
@ -1652,34 +1652,34 @@ static const ProtobufCFieldDescriptor reconnect__field_descriptors[1] =
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_UINT64,
0, /* quantifier_offset */
offsetof(Reconnect, ack),
offsetof(Init, ack),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
};
static const unsigned reconnect__field_indices_by_name[] = {
static const unsigned init__field_indices_by_name[] = {
0, /* field[0] = ack */
};
static const ProtobufCIntRange reconnect__number_ranges[1 + 1] =
static const ProtobufCIntRange init__number_ranges[1 + 1] =
{
{ 1, 0 },
{ 0, 1 }
};
const ProtobufCMessageDescriptor reconnect__descriptor =
const ProtobufCMessageDescriptor init__descriptor =
{
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"reconnect",
"Reconnect",
"Reconnect",
"init",
"Init",
"Init",
"",
sizeof(Reconnect),
sizeof(Init),
1,
reconnect__field_descriptors,
reconnect__field_indices_by_name,
1, reconnect__number_ranges,
(ProtobufCMessageInit) reconnect__init,
init__field_descriptors,
init__field_indices_by_name,
1, init__number_ranges,
(ProtobufCMessageInit) init__init,
NULL,NULL,NULL /* reserved[123] */
};
static const ProtobufCEnumValue open_channel__anchor_offer__enum_values_by_number[2] =
@ -2840,13 +2840,13 @@ static const ProtobufCFieldDescriptor pkt__field_descriptors[15] =
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
"reconnect",
"init",
51,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE,
offsetof(Pkt, pkt_case),
offsetof(Pkt, reconnect),
&reconnect__descriptor,
offsetof(Pkt, init),
&init__descriptor,
NULL,
0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
@ -2857,11 +2857,11 @@ static const unsigned pkt__field_indices_by_name[] = {
10, /* field[10] = close_shutdown */
11, /* field[11] = close_signature */
12, /* field[12] = error */
14, /* field[14] = init */
6, /* field[6] = open */
7, /* field[7] = open_anchor */
8, /* field[8] = open_commit_sig */
9, /* field[9] = open_complete */
14, /* field[14] = reconnect */
0, /* field[0] = update_add_htlc */
4, /* field[4] = update_commit */
2, /* field[2] = update_fail_htlc */

54
lightning.pb-c.h

@ -10,7 +10,7 @@ PROTOBUF_C__BEGIN_DECLS
#if PROTOBUF_C_VERSION_NUMBER < 1000000
# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
#elif 1001001 < PROTOBUF_C_MIN_COMPILER_VERSION
#elif 1002001 < PROTOBUF_C_MIN_COMPILER_VERSION
# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
#endif
@ -22,7 +22,7 @@ typedef struct _Locktime Locktime;
typedef struct _BitcoinPubkey BitcoinPubkey;
typedef struct _Funding Funding;
typedef struct _Authenticate Authenticate;
typedef struct _Reconnect Reconnect;
typedef struct _Init Init;
typedef struct _OpenChannel OpenChannel;
typedef struct _OpenAnchor OpenAnchor;
typedef struct _OpenCommitSig OpenCommitSig;
@ -123,7 +123,7 @@ struct _Locktime
};
#define LOCKTIME__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&locktime__descriptor) \
, LOCKTIME__LOCKTIME__NOT_SET, {} }
, LOCKTIME__LOCKTIME__NOT_SET, {0} }
/*
@ -185,9 +185,9 @@ struct _Authenticate
/*
* We're reconnecting, here's what we've received already.
* We're authenticated. Here's what we've received already.
*/
struct _Reconnect
struct _Init
{
ProtobufCMessage base;
/*
@ -195,8 +195,8 @@ struct _Reconnect
*/
uint64_t ack;
};
#define RECONNECT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&reconnect__descriptor) \
#define INIT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&init__descriptor) \
, 0 }
@ -328,7 +328,7 @@ struct _RouteStep
};
#define ROUTE_STEP__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&route_step__descriptor) \
, 0, ROUTE_STEP__NEXT__NOT_SET, {} }
, 0, ROUTE_STEP__NEXT__NOT_SET, {0} }
struct _Route
@ -544,7 +544,7 @@ struct _Error
typedef enum {
PKT__PKT__NOT_SET = 0,
PKT__PKT_AUTH = 50,
PKT__PKT_RECONNECT = 51,
PKT__PKT_INIT = 51,
PKT__PKT_OPEN = 20,
PKT__PKT_OPEN_ANCHOR = 21,
PKT__PKT_OPEN_COMMIT_SIG = 22,
@ -572,7 +572,7 @@ struct _Pkt
* Start of connection
*/
Authenticate *auth;
Reconnect *reconnect;
Init *init;
/*
* Opening
*/
@ -602,7 +602,7 @@ struct _Pkt
};
#define PKT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&pkt__descriptor) \
, PKT__PKT__NOT_SET, {} }
, PKT__PKT__NOT_SET, {0} }
/* Sha256Hash methods */
@ -738,24 +738,24 @@ Authenticate *
void authenticate__free_unpacked
(Authenticate *message,
ProtobufCAllocator *allocator);
/* Reconnect methods */
void reconnect__init
(Reconnect *message);
size_t reconnect__get_packed_size
(const Reconnect *message);
size_t reconnect__pack
(const Reconnect *message,
/* Init methods */
void init__init
(Init *message);
size_t init__get_packed_size
(const Init *message);
size_t init__pack
(const Init *message,
uint8_t *out);
size_t reconnect__pack_to_buffer
(const Reconnect *message,
size_t init__pack_to_buffer
(const Init *message,
ProtobufCBuffer *buffer);
Reconnect *
reconnect__unpack
Init *
init__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void reconnect__free_unpacked
(Reconnect *message,
void init__free_unpacked
(Init *message,
ProtobufCAllocator *allocator);
/* OpenChannel methods */
void open_channel__init
@ -1141,8 +1141,8 @@ typedef void (*Funding_Closure)
typedef void (*Authenticate_Closure)
(const Authenticate *message,
void *closure_data);
typedef void (*Reconnect_Closure)
(const Reconnect *message,
typedef void (*Init_Closure)
(const Init *message,
void *closure_data);
typedef void (*OpenChannel_Closure)
(const OpenChannel *message,
@ -1214,7 +1214,7 @@ extern const ProtobufCMessageDescriptor locktime__descriptor;
extern const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor;
extern const ProtobufCMessageDescriptor funding__descriptor;
extern const ProtobufCMessageDescriptor authenticate__descriptor;
extern const ProtobufCMessageDescriptor reconnect__descriptor;
extern const ProtobufCMessageDescriptor init__descriptor;
extern const ProtobufCMessageDescriptor open_channel__descriptor;
extern const ProtobufCEnumDescriptor open_channel__anchor_offer__descriptor;
extern const ProtobufCMessageDescriptor open_anchor__descriptor;

6
lightning.proto

@ -66,8 +66,8 @@ message authenticate {
required signature session_sig = 2;
};
// We're reconnecting, here's what we've received already.
message reconnect {
// We're authenticated. Here's what we've received already.
message init {
// How many update_commit and update_revocation messages already received
required uint64 ack = 1;
};
@ -226,7 +226,7 @@ message pkt {
oneof pkt {
// Start of connection
authenticate auth = 50;
reconnect reconnect = 51;
init init = 51;
// Opening
open_channel open = 20;

Loading…
Cancel
Save