1 #include "config.h"
2 #include <assert.h>
3 #include <bitcoin/chainparams.h>
4 #include <common/crypto_sync.h>
5 #include <common/gossip_rcvd_filter.h>
6 #include <common/gossip_store.h>
7 #include <common/peer_failed.h>
8 #include <common/per_peer_state.h>
9 #include <common/ping.h>
10 #include <common/read_peer_msg.h>
11 #include <common/status.h>
12 #include <common/wire_error.h>
13 #include <errno.h>
14 #include <wire/peer_wire.h>
15 #include <wire/wire_sync.h>
16
peer_or_gossip_sync_read(const tal_t * ctx,struct per_peer_state * pps,bool * from_gossipd)17 u8 *peer_or_gossip_sync_read(const tal_t *ctx,
18 struct per_peer_state *pps,
19 bool *from_gossipd)
20 {
21 fd_set readfds;
22 u8 *msg;
23
24 for (;;) {
25 struct timeval tv, *tptr;
26 struct timerel trel;
27
28 if (time_to_next_gossip(pps, &trel)) {
29 tv = timerel_to_timeval(trel);
30 tptr = &tv;
31 } else
32 tptr = NULL;
33
34 FD_ZERO(&readfds);
35 FD_SET(pps->peer_fd, &readfds);
36 FD_SET(pps->gossip_fd, &readfds);
37
38 if (select(pps->peer_fd > pps->gossip_fd
39 ? pps->peer_fd + 1 : pps->gossip_fd + 1,
40 &readfds, NULL, NULL, tptr) != 0)
41 break;
42
43 /* We timed out; look in gossip_store. Failure resets timer. */
44 msg = gossip_store_next(tmpctx, pps);
45 if (msg) {
46 *from_gossipd = true;
47 return msg;
48 }
49 }
50
51 if (FD_ISSET(pps->peer_fd, &readfds)) {
52 msg = sync_crypto_read(ctx, pps);
53 *from_gossipd = false;
54 return msg;
55 }
56
57 msg = wire_sync_read(ctx, pps->gossip_fd);
58 if (!msg)
59 status_failed(STATUS_FAIL_GOSSIP_IO,
60 "Error reading gossip msg: %s",
61 strerror(errno));
62 *from_gossipd = true;
63 return msg;
64 }
65
is_peer_error(const tal_t * ctx,const u8 * msg,const struct channel_id * channel_id,char ** desc,bool * warning)66 bool is_peer_error(const tal_t *ctx, const u8 *msg,
67 const struct channel_id *channel_id,
68 char **desc, bool *warning)
69 {
70 struct channel_id err_chanid;
71
72 if (fromwire_peektype(msg) == WIRE_ERROR)
73 *warning = false;
74 else if (fromwire_peektype(msg) == WIRE_WARNING)
75 *warning = true;
76 else
77 return false;
78
79 *desc = sanitize_error(ctx, msg, &err_chanid);
80
81 /* BOLT #1:
82 *
83 * The channel is referred to by `channel_id`, unless `channel_id` is
84 * 0 (i.e. all bytes are 0), in which case it refers to all channels.
85 * ...
86 * The receiving node:
87 * - upon receiving `error`:
88 * - MUST fail the channel referred to by the error message, if that
89 * channel is with the sending node.
90 * - if no existing channel is referred to by the message:
91 * - MUST ignore the message.
92 */
93 /* FIXME: The spec changed, so for *errors* all 0 is not special.
94 * But old gossipd would send these, so we turn them into warnings */
95 if (channel_id_is_all(&err_chanid))
96 *warning = true;
97 else if (!channel_id_eq(&err_chanid, channel_id))
98 *desc = tal_free(*desc);
99
100 return true;
101 }
102
is_wrong_channel(const u8 * msg,const struct channel_id * expected,struct channel_id * actual)103 bool is_wrong_channel(const u8 *msg, const struct channel_id *expected,
104 struct channel_id *actual)
105 {
106 if (!extract_channel_id(msg, actual))
107 return false;
108
109 return !channel_id_eq(expected, actual);
110 }
111
handle_gossip_msg(struct per_peer_state * pps,const u8 * msg TAKES)112 void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES)
113 {
114 u8 *gossip;
115
116 /* It's a raw gossip msg: this copies or takes() */
117 gossip = tal_dup_talarr(tmpctx, u8, msg);
118
119 /* Gossipd can send us gossip messages, OR warnings */
120 if (fromwire_peektype(gossip) == WIRE_WARNING) {
121 sync_crypto_write(pps, gossip);
122 peer_failed_connection_lost();
123 } else {
124 sync_crypto_write(pps, gossip);
125 }
126 }
127
128 /* takes iff returns true */
handle_timestamp_filter(struct per_peer_state * pps,const u8 * msg TAKES)129 bool handle_timestamp_filter(struct per_peer_state *pps, const u8 *msg TAKES)
130 {
131 struct bitcoin_blkid chain_hash;
132 u32 first_timestamp, timestamp_range;
133
134 if (!fromwire_gossip_timestamp_filter(msg, &chain_hash,
135 &first_timestamp,
136 ×tamp_range)) {
137 return false;
138 }
139
140 if (!bitcoin_blkid_eq(&chainparams->genesis_blockhash, &chain_hash)) {
141 sync_crypto_write(pps,
142 take(towire_warningfmt(NULL, NULL,
143 "gossip_timestamp_filter"
144 " for bad chain: %s",
145 tal_hex(tmpctx, take(msg)))));
146 return true;
147 }
148
149 gossip_setup_timestamp_filter(pps, first_timestamp, timestamp_range);
150 return true;
151 }
152
handle_peer_gossip_or_error(struct per_peer_state * pps,const struct channel_id * channel_id,bool soft_error,const u8 * msg TAKES)153 bool handle_peer_gossip_or_error(struct per_peer_state *pps,
154 const struct channel_id *channel_id,
155 bool soft_error,
156 const u8 *msg TAKES)
157 {
158 char *err;
159 bool warning;
160 u8 *pong;
161
162 #if DEVELOPER
163 /* Any odd-typed unknown message is handled by the caller, so if we
164 * find one here it's an error. */
165 assert(!is_unknown_msg_discardable(msg));
166 #else
167 /* BOLT #1:
168 *
169 * A receiving node:
170 * - upon receiving a message of _odd_, unknown type:
171 * - MUST ignore the received message.
172 */
173 if (is_unknown_msg_discardable(msg))
174 goto handled;
175 #endif
176
177 if (handle_timestamp_filter(pps, msg))
178 return true;
179 else if (check_ping_make_pong(NULL, msg, &pong)) {
180 if (pong)
181 sync_crypto_write(pps, take(pong));
182 return true;
183 } else if (is_msg_for_gossipd(msg)) {
184 gossip_rcvd_filter_add(pps->grf, msg);
185 wire_sync_write(pps->gossip_fd, msg);
186 /* wire_sync_write takes, so don't take again. */
187 return true;
188 }
189
190 if (is_peer_error(tmpctx, msg, channel_id, &err, &warning)) {
191 /* Ignore unknown channel errors. */
192 if (!err)
193 goto handled;
194
195 /* We hang up when a warning is received. */
196 peer_failed_received_errmsg(pps, err, channel_id,
197 soft_error || warning);
198
199 goto handled;
200 }
201
202 return false;
203
204 handled:
205 if (taken(msg))
206 tal_free(msg);
207 return true;
208 }
209