Browse Source

common/base32: make this a simple tal-wrapper around ccan/base32.

And use it in wireaddr.

We fix up the double '.onion' in the test case, which seems like an error?

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
d5e4d52563
  1. 71
      common/base32.c
  2. 6
      common/base32.h
  3. 2
      common/test/run-ip_port_parsing.c
  4. 36
      common/wireaddr.c

71
common/base32.c

@ -1,63 +1,24 @@
#include <ccan/str/base32/base32.h>
#include <common/base32.h>
#include <sys/types.h>
/* This is a rework of what i found on the Net about base32
*
* so Orum (shallot) and Markus Gutschke (Google.inc) should be mentioned here
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* We want lower-case conversion please */
static const char base32_lower[] = "abcdefghijklmnopqrstuvwxyz234567=";
#define BASE32DATA "abcdefghijklmnopqrstuvwxyz234567"
char *b32_encode(char *dst, u8 * src, u8 ver)
char *b32_encode(const tal_t *ctx, const void *data, size_t len)
{
u16 byte = 0, poff = 0;
for (; byte < ((ver == 2) ? 16 : 56); poff += 5) {
if (poff > 7) {
poff -= 8;
src++;
}
dst[byte++] =
BASE32DATA[(htobe16(*(u16 *) src) >> (11 - poff)) & (u16)
0x001F];
}
dst[byte] = 0;
return dst;
}
char *str = tal_arr(ctx, char, base32_str_size(len));
//FIXME quiknditry
base32_chars = base32_lower;
base32_encode(data, len, str, tal_len(str));
return str;
}
void b32_decode(u8 * dst, u8 * src, u8 ver)
u8 *b32_decode(const tal_t *ctx, const char *str, size_t len)
{
int rem = 0;
int i;
u8 *p = src;
int buf;
u8 ch;
for (i = 0; i < ((ver == 2) ? 16 : 56); p++) {
ch = *p;
buf <<= 5;
if ((ch >= 'a' && ch <= 'z')) {
ch = (ch & 0x1F) - 1;
} else if (ch != '.') {
ch -= '2' - 0x1A;
} else return;
buf = buf | ch;
rem = rem + 5;
if (rem >= 8) {
dst[i++] = buf >> (rem - 8);
rem -= 8;
}
}
u8 *ret = tal_arr(ctx, u8, base32_data_size(str, len));
base32_chars = base32_lower;
if (!base32_decode(str, len, ret, tal_len(ret)))
return tal_free(ret);
return ret;
}

6
common/base32.h

@ -2,9 +2,9 @@
#define LIGHTNING_COMMON_BASE32_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
char *b32_encode(char *dst, u8 * src, u8 ver);
void b32_decode(u8 * dst, u8 * src, u8 ver);
char *b32_encode(const tal_t *ctx, const void *data, size_t len);
u8 *b32_decode(const tal_t *ctx, const char *str, size_t len);
#endif /* LIGHTNING_COMMON_BASE32_H */

2
common/test/run-ip_port_parsing.c

@ -113,7 +113,7 @@ int main(void)
assert(parse_wireaddr("odpzvneidqdf5hdq.onion:49150", &addr, 1, NULL));
assert(addr.port == 49150);
assert(parse_wireaddr("odpzvneidqdf5hdq.onion.onion", &addr, 1, NULL));
assert(parse_wireaddr("odpzvneidqdf5hdq.onion", &addr, 1, NULL));
assert(addr.port == 1);
tal_free(tmpctx);
return 0;

36
common/wireaddr.c

@ -181,8 +181,8 @@ REGISTER_TYPE_TO_STRING(wireaddr_internal, fmt_wireaddr_internal);
char *fmt_wireaddr_without_port(const tal_t * ctx, const struct wireaddr *a)
{
char addrstr[LARGEST_ADDRLEN];
char *ret, *hex;
char addrstr[LARGEST_ADDRLEN];
switch (a->type) {
case ADDR_TYPE_IPV4:
@ -194,11 +194,9 @@ char *fmt_wireaddr_without_port(const tal_t * ctx, const struct wireaddr *a)
return "Unprintable-ipv6-address";
return tal_fmt(ctx, "[%s]", addrstr);
case ADDR_TYPE_TOR_V2:
return tal_fmt(ctx, "%.16s.onion",
b32_encode(addrstr, (u8 *) a->addr, 2));
case ADDR_TYPE_TOR_V3:
return tal_fmt(ctx, "%.56s.onion",
b32_encode(addrstr, (u8 *) a->addr, 3));
return tal_fmt(ctx, "%s.onion",
b32_encode(tmpctx, a->addr, a->addrlen));
case ADDR_TYPE_PADDING:
break;
}
@ -271,26 +269,26 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
struct addrinfo *addrinfo;
struct addrinfo hints;
int gai_err;
u8 tor_dec_bytes[TOR_V3_ADDRLEN];
bool res = false;
/* Don't do lookup on onion addresses. */
if (strends(hostname, ".onion")) {
if (strlen(hostname) < 25) { //FIXME bool is_V2_or_V3_TOR(addr);
u8 *dec = b32_decode(tmpctx, hostname,
strlen(hostname) - strlen(".onion"));
if (tal_len(dec) == TOR_V2_ADDRLEN)
addr->type = ADDR_TYPE_TOR_V2;
addr->addrlen = TOR_V2_ADDRLEN;
addr->port = port;
b32_decode((u8 *) tor_dec_bytes, (u8 *)hostname, 2);
memcpy(&addr->addr, tor_dec_bytes, addr->addrlen);
return true;
} else {
addr->type = ADDR_TYPE_TOR_V3;
addr->addrlen = TOR_V3_ADDRLEN;
addr->port = port;
b32_decode((u8 *) tor_dec_bytes, (u8 *)hostname, 3);
memcpy(&addr->addr, tor_dec_bytes, addr->addrlen);
return true;
else if (tal_len(dec) == TOR_V3_ADDRLEN)
addr->type = ADDR_TYPE_TOR_V3;
else {
if (err_msg)
*err_msg = "Invalid Tor address";
return false;
}
addr->addrlen = tal_len(dec);
addr->port = port;
memcpy(&addr->addr, dec, tal_len(dec));
return true;
}
memset(&hints, 0, sizeof(hints));

Loading…
Cancel
Save