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