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 					      &timestamp_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