Peer sends an onion msg. */
| 37 | |
| 38 | /* Peer sends an onion msg. */ |
| 39 | void handle_onion_message(struct daemon *daemon, |
| 40 | struct peer *peer, const u8 *msg) |
| 41 | { |
| 42 | enum onion_wire badreason; |
| 43 | struct onionpacket *op; |
| 44 | struct pubkey blinding, ephemeral; |
| 45 | struct route_step *rs; |
| 46 | u8 *onion; |
| 47 | struct tlv_onionmsg_payload *om; |
| 48 | struct secret ss, onion_ss; |
| 49 | const u8 *cursor; |
| 50 | size_t max, maxlen; |
| 51 | |
| 52 | /* Ignore unless explicitly turned on. */ |
| 53 | if (!feature_offered(daemon->our_features->bits[NODE_ANNOUNCE_FEATURE], |
| 54 | OPT_ONION_MESSAGES)) |
| 55 | return; |
| 56 | |
| 57 | /* FIXME: ratelimit! */ |
| 58 | if (!fromwire_onion_message(msg, msg, &blinding, &onion)) { |
| 59 | inject_peer_msg(peer, |
| 60 | towire_warningfmt(NULL, NULL, |
| 61 | "Bad onion_message")); |
| 62 | return; |
| 63 | } |
| 64 | |
| 65 | /* We unwrap the onion now. */ |
| 66 | op = parse_onionpacket(tmpctx, onion, tal_bytelen(onion), &badreason); |
| 67 | if (!op) { |
| 68 | status_peer_debug(&peer->id, "onion msg: can't parse onionpacket: %s", |
| 69 | onion_wire_name(badreason)); |
| 70 | return; |
| 71 | } |
| 72 | |
| 73 | ephemeral = op->ephemeralkey; |
| 74 | if (!unblind_onion(&blinding, ecdh, &ephemeral, &ss)) { |
| 75 | status_peer_debug(&peer->id, "onion msg: can't unblind onionpacket"); |
| 76 | return; |
| 77 | } |
| 78 | |
| 79 | /* Now get onion shared secret and parse it. */ |
| 80 | ecdh(&ephemeral, &onion_ss); |
| 81 | rs = process_onionpacket(tmpctx, op, &onion_ss, NULL, 0, false); |
| 82 | if (!rs) { |
| 83 | status_peer_debug(&peer->id, |
| 84 | "onion msg: can't process onionpacket ss=%s", |
| 85 | type_to_string(tmpctx, struct secret, &onion_ss)); |
| 86 | return; |
| 87 | } |
| 88 | |
| 89 | /* The raw payload is prepended with length in the modern onion. */ |
| 90 | cursor = rs->raw_payload; |
| 91 | max = tal_bytelen(rs->raw_payload); |
| 92 | maxlen = fromwire_bigsize(&cursor, &max); |
| 93 | if (!cursor) { |
| 94 | status_peer_debug(&peer->id, "onion msg: Invalid hop payload %s", |
| 95 | tal_hex(tmpctx, rs->raw_payload)); |
| 96 | return; |
no test coverage detected