diff --git a/common/test/run-ip_port_parsing.c b/common/test/run-ip_port_parsing.c index fc8eae762..d99811c16 100644 --- a/common/test/run-ip_port_parsing.c +++ b/common/test/run-ip_port_parsing.c @@ -8,21 +8,36 @@ /* Generated stub for fromwire */ const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED) { fprintf(stderr, "fromwire called!\n"); abort(); } +/* Generated stub for fromwire_bool */ +bool fromwire_bool(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) +{ fprintf(stderr, "fromwire_bool called!\n"); abort(); } +/* Generated stub for fromwire_fail */ +const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) +{ fprintf(stderr, "fromwire_fail called!\n"); abort(); } /* Generated stub for fromwire_u16 */ u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u16 called!\n"); abort(); } /* Generated stub for fromwire_u8 */ u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u8 called!\n"); abort(); } +/* Generated stub for fromwire_u8_array */ +void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED) +{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); } /* Generated stub for towire */ void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) { fprintf(stderr, "towire called!\n"); abort(); } +/* Generated stub for towire_bool */ +void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) +{ fprintf(stderr, "towire_bool called!\n"); abort(); } /* Generated stub for towire_u16 */ void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED) { fprintf(stderr, "towire_u16 called!\n"); abort(); } /* Generated stub for towire_u8 */ void towire_u8(u8 **pptr UNNEEDED, u8 v UNNEEDED) { fprintf(stderr, "towire_u8 called!\n"); abort(); } +/* Generated stub for towire_u8_array */ +void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED) +{ fprintf(stderr, "towire_u8_array called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ int main(void) diff --git a/common/type_to_string.h b/common/type_to_string.h index bee4cbd67..83c485ed9 100644 --- a/common/type_to_string.h +++ b/common/type_to_string.h @@ -20,6 +20,7 @@ union printable_types { const struct preimage *preimage; const struct channel_oneside *channel_oneside; const struct wireaddr *wireaddr; + const struct wireaddr_internal *wireaddr_internal; const secp256k1_pubkey *secp256k1_pubkey; const struct channel_id *channel_id; const struct short_channel_id *short_channel_id; diff --git a/common/wireaddr.c b/common/wireaddr.c index f370bafaf..5b454d7f0 100644 --- a/common/wireaddr.c +++ b/common/wireaddr.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -8,6 +9,7 @@ #include #include #include +#include #include /* Returns false if we didn't parse it, and *cursor == NULL if malformed. */ @@ -53,6 +55,40 @@ void towire_addr_listen_announce(u8 **pptr, enum addr_listen_announce ala) towire_u8(pptr, ala); } +void towire_wireaddr_internal(u8 **pptr, const struct wireaddr_internal *addr) +{ + towire_u8(pptr, addr->itype); + switch (addr->itype) { + case ADDR_INTERNAL_SOCKNAME: + towire_u8_array(pptr, (const u8 *)addr->u.sockname, + sizeof(addr->u.sockname)); + return; + case ADDR_INTERNAL_WIREADDR: + towire_wireaddr(pptr, &addr->u.wireaddr); + return; + } + abort(); +} + +bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max, + struct wireaddr_internal *addr) +{ + addr->itype = fromwire_u8(cursor, max); + switch (addr->itype) { + case ADDR_INTERNAL_SOCKNAME: + fromwire_u8_array(cursor, max, (u8 *)addr->u.sockname, + sizeof(addr->u.sockname)); + /* Must be NUL terminated */ + if (!memchr(addr->u.sockname, 0, sizeof(addr->u.sockname))) + fromwire_fail(cursor, max); + return *cursor != NULL; + case ADDR_INTERNAL_WIREADDR: + return fromwire_wireaddr(cursor, max, &addr->u.wireaddr); + } + fromwire_fail(cursor, max); + return false; +} + char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a) { char addrstr[INET6_ADDRSTRLEN]; @@ -122,6 +158,19 @@ bool wireaddr_to_ipv6(const struct wireaddr *addr, struct sockaddr_in6 *s6) return true; } +char *fmt_wireaddr_internal(const tal_t *ctx, + const struct wireaddr_internal *a) +{ + switch (a->itype) { + case ADDR_INTERNAL_SOCKNAME: + return tal_fmt(ctx, "%s", a->u.sockname); + case ADDR_INTERNAL_WIREADDR: + return fmt_wireaddr(ctx, &a->u.wireaddr); + } + abort(); +} +REGISTER_TYPE_TO_STRING(wireaddr_internal, fmt_wireaddr_internal); + /* Valid forms: * * [anything]: @@ -247,3 +296,42 @@ finish: *err_msg = "Error parsing hostname"; return res; } + +bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr, u16 port, const char **err_msg) +{ + /* Addresses starting with '/' are local socket paths */ + if (arg[0] == '/') { + addr->itype = ADDR_INTERNAL_SOCKNAME; + + /* Check if the path is too long */ + if (strlen(arg) >= sizeof(addr->u.sockname)) { + if (err_msg) + *err_msg = "Socket name too long"; + return false; + } + strcpy(addr->u.sockname, arg); + return true; + } + + addr->itype = ADDR_INTERNAL_WIREADDR; + return parse_wireaddr(arg, &addr->u.wireaddr, port, err_msg); +} + +void wireaddr_from_sockname(struct wireaddr_internal *addr, + const char *sockname) +{ + addr->itype = ADDR_INTERNAL_SOCKNAME; + memset(addr->u.sockname, 0, sizeof(addr->u.sockname)); + strncpy(addr->u.sockname, sockname, sizeof(addr->u.sockname)-1); +} + +bool wireaddr_to_sockname(const struct wireaddr_internal *addr, + struct sockaddr_un *sun) +{ + if (addr->itype != ADDR_INTERNAL_SOCKNAME) + return false; + sun->sun_family = AF_LOCAL; + BUILD_ASSERT(sizeof(sun->sun_path) == sizeof(addr->u.sockname)); + memcpy(sun->sun_path, addr->u.sockname, sizeof(addr->u.sockname)); + return true; +} diff --git a/common/wireaddr.h b/common/wireaddr.h index e639b3482..3b202f9ae 100644 --- a/common/wireaddr.h +++ b/common/wireaddr.h @@ -10,6 +10,7 @@ struct in6_addr; struct in_addr; struct sockaddr_in6; struct sockaddr_in; +struct sockaddr_un; /* BOLT #7: * @@ -74,4 +75,30 @@ void wireaddr_from_ipv6(struct wireaddr *addr, bool wireaddr_to_ipv4(const struct wireaddr *addr, struct sockaddr_in *s4); bool wireaddr_to_ipv6(const struct wireaddr *addr, struct sockaddr_in6 *s6); +enum wireaddr_internal_type { + ADDR_INTERNAL_SOCKNAME, + ADDR_INTERNAL_WIREADDR, +}; + +/* For internal use, where we can also supply a local socket, wildcard. */ +struct wireaddr_internal { + enum wireaddr_internal_type itype; + union { + struct wireaddr wireaddr; + char sockname[108]; + } u; +}; +bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr, u16 port, const char **err_msg); + +void towire_wireaddr_internal(u8 **pptr, + const struct wireaddr_internal *addr); +bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max, + struct wireaddr_internal *addr); +char *fmt_wireaddr_internal(const tal_t *ctx, + const struct wireaddr_internal *a); + +void wireaddr_from_sockname(struct wireaddr_internal *addr, + const char *sockname); +bool wireaddr_to_sockname(const struct wireaddr_internal *addr, + struct sockaddr_un *sun); #endif /* LIGHTNING_COMMON_WIREADDR_H */