diff --git a/lightningd/Makefile b/lightningd/Makefile index 69d6e0d65..2ed6c9fa9 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -75,6 +75,7 @@ LIGHTNINGD_SRC := \ lightningd/channel_control.c \ lightningd/closing_control.c \ lightningd/connect_control.c \ + lightningd/onion_message.c \ lightningd/gossip_control.c \ lightningd/gossip_msg.c \ lightningd/hsm_control.c \ diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index b9d88c8c9..01abc3303 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -319,11 +320,17 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNEL_SEND_ERROR_REPLY: handle_error_channel(sd->channel, msg); break; +#if EXPERIMENTAL_FEATURES case WIRE_GOT_ONIONMSG_TO_US: + handle_onionmsg_to_us(sd->channel, msg); + break; case WIRE_GOT_ONIONMSG_FORWARD: - /* FIXME */ + handle_onionmsg_forward(sd->channel, msg); break; - +#else + case WIRE_GOT_ONIONMSG_TO_US: + case WIRE_GOT_ONIONMSG_FORWARD: +#endif /* And we never get these from channeld. */ case WIRE_CHANNEL_INIT: case WIRE_CHANNEL_FUNDING_DEPTH: diff --git a/lightningd/onion_message.c b/lightningd/onion_message.c new file mode 100644 index 000000000..70ee619f1 --- /dev/null +++ b/lightningd/onion_message.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include + +#if EXPERIMENTAL_FEATURES +/* Returns false if we can't tell it */ +static bool make_peer_send(struct lightningd *ld, + struct channel *dst, const u8 *msg TAKES) +{ + /* Take ownership of msg (noop if it's taken) */ + msg = tal_dup_talarr(tmpctx, u8, msg); + + if (!dst) { + log_debug(ld->log, "Can't send %s: no channel", + channel_wire_type_name(fromwire_peektype(msg))); + return false; + } + + if (!dst->owner) { + log_debug(ld->log, "Can't send %s: not connected", + channel_wire_type_name(fromwire_peektype(msg))); + return false; + } + + /* FIXME: We should allow this for closingd too, and we should + * allow incoming via openingd!. */ + if (!streq(dst->owner->name, "channeld")) { + log_debug(ld->log, "Can't send %s: owned by %s", + channel_wire_type_name(fromwire_peektype(msg)), + dst->owner->name); + return false; + } + subd_send_msg(dst->owner, take(msg)); + return true; +} + +void handle_onionmsg_to_us(struct channel *channel, const u8 *msg) +{ + struct pubkey *reply_blinding; + struct onionmsg_path **reply_path; + + if (!fromwire_got_onionmsg_to_us(msg, msg, + &reply_blinding, &reply_path)) { + channel_internal_error(channel, "bad got_onionmsg_tous: %s", + tal_hex(tmpctx, msg)); + return; + } + + log_info(channel->log, "Got onionmsg%s%s", + reply_blinding ? " reply_blinding": "", + reply_path ? " reply_path": ""); +} + +void handle_onionmsg_forward(struct channel *channel, const u8 *msg) +{ + struct lightningd *ld = channel->peer->ld; + struct short_channel_id *next_scid; + struct node_id *next_node; + struct pubkey *next_blinding; + u8 onion[TOTAL_PACKET_SIZE]; + struct channel *outchan; + + if (!fromwire_got_onionmsg_forward(msg, msg, &next_scid, &next_node, + &next_blinding, onion)) { + channel_internal_error(channel, "bad got_onionmsg_forward: %s", + tal_hex(tmpctx, msg)); + return; + } + + if (next_scid) + outchan = active_channel_by_scid(ld, next_scid); + else if (next_node) { + struct peer *p = peer_by_id(ld, next_node); + if (p) + outchan = peer_active_channel(p); + else + outchan = NULL; + } else + outchan = NULL; + + make_peer_send(ld, outchan, + take(towire_send_onionmsg(NULL, onion, next_blinding))); +} +#endif /* EXPERIMENTAL_FEATURES */ diff --git a/lightningd/onion_message.h b/lightningd/onion_message.h new file mode 100644 index 000000000..c2a2099a8 --- /dev/null +++ b/lightningd/onion_message.h @@ -0,0 +1,11 @@ +#ifndef LIGHTNING_LIGHTNINGD_ONION_MESSAGE_H +#define LIGHTNING_LIGHTNINGD_ONION_MESSAGE_H +#include "config.h" +#include + +struct channel; + +void handle_onionmsg_to_us(struct channel *channel, const u8 *msg); +void handle_onionmsg_forward(struct channel *channel, const u8 *msg); + +#endif /* LIGHTNING_LIGHTNINGD_ONION_MESSAGE_H */