1 #include <assert.h>
2 #include <ccan/breakpoint/breakpoint.h>
3 #include <ccan/tal/str/str.h>
4 #include <common/crypto_sync.h>
5 #include <common/peer_billboard.h>
6 #include <common/peer_failed.h>
7 #include <common/peer_status_wiregen.h>
8 #include <common/status.h>
9 #include <common/status_wiregen.h>
10 #include <common/wire_error.h>
11 
12 /* Fatal error here, return peer control to lightningd */
13 static void NORETURN
peer_fatal_continue(const u8 * msg TAKES,const struct per_peer_state * pps)14 peer_fatal_continue(const u8 *msg TAKES, const struct per_peer_state *pps)
15 {
16  	int reason = fromwire_peektype(msg);
17  	breakpoint();
18  	status_send(msg);
19 
20 	status_send_fd(pps->peer_fd);
21 	status_send_fd(pps->gossip_fd);
22 	status_send_fd(pps->gossip_store_fd);
23 	exit(0x80 | (reason & 0xFF));
24 }
25 
26 /* We only support one channel per peer anyway */
27 static void NORETURN
peer_failed(struct per_peer_state * pps,bool warn,const struct channel_id * channel_id,const char * desc)28 peer_failed(struct per_peer_state *pps,
29 	    bool warn,
30 	    const struct channel_id *channel_id,
31 	    const char *desc)
32 {
33 	u8 *msg;
34 
35 	if (warn) {
36 		msg = towire_warningfmt(desc, channel_id, "%s", desc);
37 	} else {
38 		msg = towire_errorfmt(desc, channel_id, "%s", desc);
39 	}
40 	sync_crypto_write(pps, msg);
41 
42 	/* Tell master the error so it can re-xmit. */
43 	msg = towire_status_peer_error(NULL, channel_id,
44 				       desc,
45 				       warn,
46 				       pps,
47 				       msg);
48 	peer_billboard(true, desc);
49 	peer_fatal_continue(take(msg), pps);
50 }
51 
peer_failed_warn(struct per_peer_state * pps,const struct channel_id * channel_id,const char * fmt,...)52 void peer_failed_warn(struct per_peer_state *pps,
53 		      const struct channel_id *channel_id,
54 		      const char *fmt, ...)
55 {
56 	va_list ap;
57 	const char *desc;
58 
59  	va_start(ap, fmt);
60 	desc = tal_vfmt(tmpctx, fmt, ap);
61 	va_end(ap);
62 
63 	peer_failed(pps, true, channel_id, desc);
64 }
65 
peer_failed_err(struct per_peer_state * pps,const struct channel_id * channel_id,const char * fmt,...)66 void peer_failed_err(struct per_peer_state *pps,
67 		     const struct channel_id *channel_id,
68 		     const char *fmt, ...)
69 {
70 	va_list ap;
71 	const char *desc;
72 
73 	assert(channel_id);
74  	va_start(ap, fmt);
75 	desc = tal_vfmt(tmpctx, fmt, ap);
76 	va_end(ap);
77 
78 	peer_failed(pps, false, channel_id, desc);
79 }
80 
81 /* We're failing because peer sent us an error/warning message */
peer_failed_received_errmsg(struct per_peer_state * pps,const char * desc,const struct channel_id * channel_id,bool warning)82 void peer_failed_received_errmsg(struct per_peer_state *pps,
83 				 const char *desc,
84 				 const struct channel_id *channel_id,
85 				 bool warning)
86 {
87 	u8 *msg;
88 
89 	msg = towire_status_peer_error(NULL, channel_id, desc, warning, pps,
90 				       NULL);
91 	peer_billboard(true, "Received %s", desc);
92 	peer_fatal_continue(take(msg), pps);
93 }
94 
peer_failed_connection_lost(void)95 void peer_failed_connection_lost(void)
96 {
97 	status_send_fatal(take(towire_status_peer_connection_lost(NULL)));
98 }
99