| 266 | } |
| 267 | |
| 268 | static struct command_result *onion_message_recv(struct command *cmd, |
| 269 | const char *buf, |
| 270 | const jsmntok_t *params) |
| 271 | { |
| 272 | const jsmntok_t *om, *secrettok, *replytok, *invreqtok, *invtok; |
| 273 | struct blinded_path *reply_path = NULL; |
| 274 | struct secret *secret; |
| 275 | |
| 276 | om = json_get_member(buf, params, "onion_message"); |
| 277 | secrettok = json_get_member(buf, om, "pathsecret"); |
| 278 | if (secrettok) { |
| 279 | secret = tal(tmpctx, struct secret); |
| 280 | json_to_secret(buf, secrettok, secret); |
| 281 | } else |
| 282 | secret = NULL; |
| 283 | |
| 284 | /* Might be reply for fetchinvoice (which always has a secret, |
| 285 | * so we can tell it's a response). */ |
| 286 | if (secret) { |
| 287 | struct command_result *res; |
| 288 | res = handle_invoice_onion_message(cmd, buf, om, secret); |
| 289 | if (res) |
| 290 | return res; |
| 291 | } |
| 292 | |
| 293 | /* BOLT #4: |
| 294 | * - otherwise (it is the final node): |
| 295 | * - if `path_id` is set and corresponds to a path the reader has previously published in a `reply_path`: |
| 296 | * - if the onion message is not a reply to that previous onion: |
| 297 | * - MUST ignore the onion message |
| 298 | * - otherwise (unknown or unset `path_id`): |
| 299 | * - if the onion message is a reply to an onion message which contained a `path_id`: |
| 300 | * - MUST respond (or not respond) exactly as if it did not send the initial onion message. |
| 301 | */ |
| 302 | /* FIXME: Technically, we don't meet the first half of this: we |
| 303 | * always do parsing and sanity checking before checking the |
| 304 | * secret (thus the path_id). But we ignore it *after* that. |
| 305 | */ |
| 306 | replytok = json_get_member(buf, om, "reply_blindedpath"); |
| 307 | if (replytok) { |
| 308 | reply_path = json_to_blinded_path(cmd, buf, replytok); |
| 309 | if (!reply_path) |
| 310 | plugin_err(cmd->plugin, "Invalid reply path %.*s?", |
| 311 | json_tok_full_len(replytok), |
| 312 | json_tok_full(buf, replytok)); |
| 313 | } |
| 314 | |
| 315 | invreqtok = json_get_member(buf, om, "invoice_request"); |
| 316 | if (invreqtok) { |
| 317 | const u8 *invreqbin = json_tok_bin_from_hex(tmpctx, buf, invreqtok); |
| 318 | return handle_invoice_request(cmd, |
| 319 | invreqbin, |
| 320 | reply_path, secret); |
| 321 | } |
| 322 | |
| 323 | invtok = json_get_member(buf, om, "invoice"); |
| 324 | if (invtok) { |
| 325 | const u8 *invbin = json_tok_bin_from_hex(tmpctx, buf, invtok); |
nothing calls this directly
no test coverage detected