forked from ElementsProject/lightning
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconnectd.h
384 lines (300 loc) · 10.7 KB
/
connectd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
#ifndef LIGHTNING_CONNECTD_CONNECTD_H
#define LIGHTNING_CONNECTD_CONNECTD_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <bitcoin/short_channel_id.h>
#include <ccan/crypto/siphash24/siphash24.h>
#include <ccan/htable/htable_type.h>
#include <ccan/timer/timer.h>
#include <common/bigsize.h>
#include <common/channel_id.h>
#include <common/crypto_state.h>
#include <common/node_id.h>
#include <common/pseudorand.h>
#include <common/wireaddr.h>
#include <connectd/handshake.h>
struct io_conn;
struct connecting;
struct wireaddr_internal;
/*~ All the gossip_store related fields are kept together for convenience. */
struct gossip_state {
/* Is it active right now? */
bool active;
/* Except with dev override, this fires every 60 seconds */
struct oneshot *gossip_timer;
/* Timestamp filtering for gossip. */
u32 timestamp_min, timestamp_max;
/* I think this is called "echo cancellation" */
struct gossip_rcvd_filter *grf;
/* Offset within the gossip_store file */
struct gossmap_iter *iter;
/* Bytes sent in the last second. */
size_t bytes_this_second;
/* When that second starts */
struct timemono bytes_start_time;
};
/*~ We need to know if we were expecting a pong, and why */
enum pong_expect_type {
/* We weren't expecting a ping reply */
PONG_UNEXPECTED = 0,
/* We were expecting a ping reply due to ping command */
PONG_EXPECTED_COMMAND = 1,
/* We were expecting a ping reply due to ping timer */
PONG_EXPECTED_PROBING = 2,
};
/*~ We keep a hash table (ccan/htable) of peers, which tells us what peers are
* already connected (by peer->id). */
struct peer {
/* Main daemon */
struct daemon *daemon;
/* Are we connected via a websocket? */
enum is_websocket is_websocket;
/* The pubkey of the node */
struct node_id id;
/* Counters and keys for symmetric crypto */
struct crypto_state cs;
/* Connection to the peer */
struct io_conn *to_peer;
/* Counter to distinguish this connection from the next re-connection */
u64 counter;
/* Is this draining? If so, just keep writing until queue empty */
bool draining;
/* Connections to the subdaemons */
struct subd **subds;
/* When socket has Nagle overridden */
bool urgent;
/* Input buffer. */
u8 *peer_in;
/* Output buffer. */
struct msg_queue *peer_outq;
/* Peer sent buffer (for freeing after sending) */
const u8 *sent_to_peer;
/* We stream from the gossip_store for them, when idle */
struct gossip_state gs;
/* Are we expecting a pong? */
enum pong_expect_type expecting_pong;
/* Random ping timer, to detect dead connections. */
struct oneshot *ping_timer;
/* Last time we received traffic */
struct timeabs last_recv_time;
/* Ratelimits for onion messages. One token per msec. */
size_t onionmsg_incoming_tokens;
struct timemono onionmsg_last_incoming;
bool onionmsg_limit_warned;
bool dev_read_enabled;
/* If non-NULL, this counts down; 0 means disable */
u32 *dev_writes_enabled;
/* Are there outstanding responses for queries on short_channel_ids? */
const struct short_channel_id *scid_queries;
const bigsize_t *scid_query_flags;
size_t scid_query_idx;
/* Are there outstanding node_announcements from scid_queries? */
struct node_id *scid_query_nodes;
size_t scid_query_nodes_idx;
};
/* We gain one token per msec, and each msg uses 250 tokens. */
#define ONION_MSG_MSEC 250
#define ONION_MSG_TOKENS_MAX (4*ONION_MSG_MSEC)
/*~ The HTABLE_DEFINE_TYPE() macro needs a keyof() function to extract the key:
*/
static const struct node_id *peer_keyof(const struct peer *peer)
{
return &peer->id;
}
/*~ We reuse node_id_hash from common/node_id.h, which uses siphash
* and a per-run seed. */
/*~ We also define an equality function: is this element equal to this key? */
static bool peer_eq_node_id(const struct peer *peer,
const struct node_id *id)
{
return node_id_eq(&peer->id, id);
}
/*~ This defines 'struct peer_htable' which contains 'struct peer' pointers. */
HTABLE_DEFINE_NODUPS_TYPE(struct peer,
peer_keyof,
node_id_hash,
peer_eq_node_id,
peer_htable);
/* Node id, with any addresses we were explicitly given for it */
struct important_id {
struct daemon *daemon;
struct node_id id;
struct wireaddr_internal *addrs;
size_t reconnect_secs;
};
static const struct node_id *important_id_keyof(const struct important_id *imp)
{
return &imp->id;
}
static bool important_id_eq_node_id(const struct important_id *imp,
const struct node_id *id)
{
return node_id_eq(&imp->id, id);
}
/*~ This defines 'struct important_id_htable' */
HTABLE_DEFINE_NODUPS_TYPE(struct important_id,
important_id_keyof,
node_id_hash,
important_id_eq_node_id,
important_id_htable);
/*~ Peers we're trying to reach: we iterate through addrs until we succeed
* or fail. */
struct connecting {
struct daemon *daemon;
struct io_conn *conn;
/* The ID of the peer (not necessarily unique, in transit!) */
struct node_id id;
/* Are we queued waiting, to avoid too many connections at once? */
bool waiting;
/* We iterate through the tal_count(addrs) */
size_t addrnum;
struct wireaddr_internal *addrs;
/* How far did we get? */
const char *connstate;
/* Accumulated errors */
char *errors;
};
static const struct node_id *connecting_keyof(const struct connecting *connecting)
{
return &connecting->id;
}
static bool connecting_eq_node_id(const struct connecting *connecting,
const struct node_id *id)
{
return node_id_eq(&connecting->id, id);
}
/*~ This defines 'struct connecting_htable' which contains 'struct connecting'
* pointers. */
HTABLE_DEFINE_NODUPS_TYPE(struct connecting,
connecting_keyof,
node_id_hash,
connecting_eq_node_id,
connecting_htable);
struct scid_to_node_id {
struct short_channel_id scid;
struct node_id node_id;
};
static struct short_channel_id scid_to_node_id_keyof(const struct scid_to_node_id *scid_to_node_id)
{
return scid_to_node_id->scid;
}
static bool scid_to_node_id_eq_scid(const struct scid_to_node_id *scid_to_node_id,
const struct short_channel_id scid)
{
return short_channel_id_eq(scid_to_node_id->scid, scid);
}
/*~ This defines 'struct scid_htable' which maps short_channel_ids to peers:
* we use this to forward onion messages which specify the next hop by scid/dir. */
HTABLE_DEFINE_NODUPS_TYPE(struct scid_to_node_id,
scid_to_node_id_keyof,
short_channel_id_hash,
scid_to_node_id_eq_scid,
scid_htable);
/*~ This is the global state, like `struct lightningd *ld` in lightningd. */
struct daemon {
/* Who am I? */
struct node_id id;
/* --developer? */
bool developer;
/* pubkey equivalent. */
struct pubkey mykey;
/* Counter from which we derive connection identifiers. */
u64 connection_counter;
/* Base for timeout timers, and how long to wait for init msg */
struct timers timers;
u32 timeout_secs;
/* Peers that we've handed to `lightningd`, which it hasn't told us
* have disconnected. */
struct peer_htable *peers;
/* Peers we are trying to reach right now. */
struct connecting_htable *connecting;
/* Important (non-transient) peers we should reconnect to */
struct important_id_htable *important_ids;
/* Connection to main daemon. */
struct daemon_conn *master;
/* Connection to gossip daemon. */
struct daemon_conn *gossipd;
/* Map of short_channel_ids to peers */
struct scid_htable *scid_htable;
/* Any listening sockets we have. */
struct io_listener **listeners;
/* Allow localhost to be considered "public", only with --developer */
bool dev_allow_localhost;
/* How much to gossip allow a peer every 60 seconds (bytes) */
size_t gossip_stream_limit;
/* We support use of a SOCKS5 proxy (e.g. Tor) */
struct addrinfo *proxyaddr;
/* They can tell us we must use proxy even for non-Tor addresses. */
bool always_use_proxy;
/* There are DNS seeds we can use to look up node addresses as a last
* resort, but doing so leaks our address so can be disabled. */
bool use_dns;
/* The address that the broken response returns instead of
* NXDOMAIN. NULL if we have not detected a broken resolver. */
struct sockaddr *broken_resolver_response;
/* File descriptors to listen on once we're activated. */
const struct listen_fd **listen_fds;
/* Our features, as lightningd told us */
struct feature_set *our_features;
/* Subdaemon to proxy websocket requests. */
char *websocket_helper;
/* If non-zero, port to listen for websocket connections. */
u16 websocket_port;
/* The gossip store (access via get_gossmap!) */
struct gossmap *gossmap_raw;
/* Iterator which we keep at "recent" time */
u32 gossip_recent_time;
struct gossmap_iter *gossmap_iter_recent;
/* We only announce websocket addresses if !deprecated_apis */
bool announce_websocket;
/* Shutting down, don't send new stuff */
bool shutting_down;
/* What (even) custom messages we accept */
u16 *custom_msgs;
/* Timer which releases one pending connection per second. */
struct oneshot *connect_release_timer;
/* How many connection attempts do we allow at once
* (--dev-limit-connectsion-inflight sets this to 1 for testing). */
size_t max_connect_in_flight;
/* Hack to speed up gossip timer */
bool dev_fast_gossip;
/* Hack to avoid ping timeouts */
bool dev_no_ping_timer;
/* Hack to no longer send gossip */
bool dev_suppress_gossip;
/* dev_disconnect file */
int dev_disconnect_fd;
/* Did we exhaust fds? If so, skip dev_report_fds */
bool dev_exhausted_fds;
/* Allow connections in, but don't send anything */
bool dev_handshake_no_reply;
/* --dev-no-reconnect */
bool dev_no_reconnect;
/* --dev-fast-reconnect */
bool dev_fast_reconnect;
};
/* Called by io_tor_connect once it has a connection out. */
struct io_plan *connection_out(struct io_conn *conn, struct connecting *connect);
/* Get and refresh gossmap */
struct gossmap *get_gossmap(struct daemon *daemon);
/* Catch up with recent changes */
void update_recent_timestamp(struct daemon *daemon, struct gossmap *gossmap);
/* add erros to error list */
void add_errors_to_error_list(struct connecting *connect, const char *error);
/* Called by peer_exchange_initmsg if successful. */
struct io_plan *peer_connected(struct io_conn *conn,
struct daemon *daemon,
const struct node_id *id,
const struct wireaddr_internal *addr,
const struct wireaddr *remote_addr,
struct crypto_state *cs,
const u8 *their_features TAKES,
enum is_websocket is_websocket,
bool incoming);
/* Removes peer from hash table, tells gossipd and lightningd. */
void destroy_peer(struct peer *peer);
/* Remove a random connection, when under stress. */
void close_random_connection(struct daemon *daemon);
/* If connections are waiting to avoid flooding lightningd, release one now */
void release_one_waiting_connection(struct daemon *daemon, const char *why);
#endif /* LIGHTNING_CONNECTD_CONNECTD_H */