diff --git a/lightningd/new_connection.c b/lightningd/new_connection.c index c4a24f1b0..181504dee 100644 --- a/lightningd/new_connection.c +++ b/lightningd/new_connection.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -16,6 +17,9 @@ #include #include +const u8 supported_local_features[] = {0x03}; +const u8 supported_global_features[] = {0x00}; + /* Before we have identified the peer, we just have a connection object. */ struct connection { /* Lightning daemon, for when we're handed through callbacks. */ @@ -80,15 +84,35 @@ struct connection *new_connection(const tal_t *ctx, return c; } -static bool has_even_bit(const u8 *bitmap) +/** + * requires_unsupported_features - Check if we support what's being asked + * + * Given the features vector that the remote connection is expecting + * from us, we check to see if we support all even bit features, i.e., + * the required features. We do so by subtracting our own features in + * the provided positions and see if even bits remain. + * + * @bitmap: the features bitmap the peer is asking for + * @supportmap: what do we support + * @smlen: how long is our supportmap + */ +static bool requires_unsupported_features(const u8 *bitmap, + const u8 *supportmap, + size_t smlen) { size_t len = tal_count(bitmap); - - while (len) { - if (*bitmap & 0xAA) + u8 support; + for (size_t i=0; i smlen) { + support = 0x00; + } else { + support = supportmap[smlen-1]; + } + + /* Cancel out supported bits, check for even bits */ + if ((~support & bitmap[i]) & 0x55) return true; - len--; - bitmap++; } return false; } @@ -129,7 +153,9 @@ static bool handshake_succeeded(struct subd *handshaked, * MUST ignore the bit if the bit number is odd, and MUST fail * the connection if the bit number is even. */ - if (has_even_bit(globalfeatures)) { + if (requires_unsupported_features( + globalfeatures, supported_global_features, + ARRAY_SIZE(supported_global_features))) { connection_failed(c, handshaked->log, "peer %s: bad globalfeatures: %s", type_to_string(c, struct pubkey, id), @@ -137,7 +163,9 @@ static bool handshake_succeeded(struct subd *handshaked, return true; } - if (has_even_bit(localfeatures)) { + if (requires_unsupported_features( + localfeatures, supported_local_features, + ARRAY_SIZE(supported_local_features))) { connection_failed(c, handshaked->log, "peer %s: bad localfeatures: %s", type_to_string(c, struct pubkey, id),