diff options
author | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2009-09-02 19:43:05 +0000 |
---|---|---|
committer | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2009-09-02 19:43:05 +0000 |
commit | 163858a5390a5347c6b84a4a75956a646755cac4 (patch) | |
tree | 3cf2d57b4e97a850d1db0a16762bdadd8bfb839d | |
parent | bb101ba03fb9920cf3a55803a608501d2bc996ce (diff) | |
download | neon-163858a5390a5347c6b84a4a75956a646755cac4.tar.gz |
Merge r1709, r1710, r1711 from trunk:
* test/util-socks.c (read_socks_0string): Pass through context string.
(socks_server): Fail for v4 server without expected address.
Don't write "ok" message for v4 server without say_hello flag.
* src/ne_socket.c (ne_iaddr_parse): New function.
* test/socket.c (check_is_raw127): Factored out from addr_make_v4.
(parse_v4): New function.
(addr_make_v6): Test ne_iaddr_parse for IPv6 addresses.
(socks_proxy): Fix for non-v6-enabled builds.
* src/ne_socket.c (ne_iaddr_parse) [!USE_GETADDRINFO]: Fail for IPv6
addresses.
* test/socket.c (addr_make_v6) [!TEST_IPV6]: Test for failure.
Also:
* src/neon.vers: Add ne_iaddr_parse.
git-svn-id: http://svn.webdav.org/repos/projects/neon/branches/0.29.x@1712 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
-rw-r--r-- | src/ne_socket.c | 26 | ||||
-rw-r--r-- | src/ne_socket.h | 10 | ||||
-rw-r--r-- | src/neon.vers | 1 | ||||
-rw-r--r-- | test/socket.c | 56 | ||||
-rw-r--r-- | test/util-socks.c | 18 |
5 files changed, 96 insertions, 15 deletions
diff --git a/src/ne_socket.c b/src/ne_socket.c index 8ab4906..32bc7e7 100644 --- a/src/ne_socket.c +++ b/src/ne_socket.c @@ -1067,6 +1067,32 @@ unsigned char *ne_iaddr_raw(const ne_inet_addr *ia, unsigned char *buf) #endif } +ne_inet_addr *ne_iaddr_parse(const char *addr, ne_iaddr_type type) +{ +#if defined(USE_GETADDRINFO) + char dst[sizeof(struct in6_addr)]; + int af = type == ne_iaddr_ipv6 ? AF_INET6 : AF_INET; + + if (inet_pton(af, addr, dst) != 1) { + return NULL; + } + + return ne_iaddr_make(type, (unsigned char *)dst); +#else + struct in_addr a; + + if (type == ne_iaddr_ipv6) { + return NULL; + } + + if (inet_aton(addr, &a) == 0) { + return NULL; + } + + return ne_iaddr_make(ne_iaddr_ipv4, (unsigned char *)&a.s_addr); +#endif +} + int ne_iaddr_reverse(const ne_inet_addr *ia, char *buf, size_t bufsiz) { #ifdef USE_GETADDRINFO diff --git a/src/ne_socket.h b/src/ne_socket.h index 613f444..fd6f571 100644 --- a/src/ne_socket.h +++ b/src/ne_socket.h @@ -1,6 +1,6 @@ /* socket handling interface - Copyright (C) 1999-2008, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 1999-2009, Joe Orton <joe@manyfish.co.uk> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -125,7 +125,13 @@ unsigned char *ne_iaddr_raw(const ne_inet_addr *ia, unsigned char *buffer); * successful. Returns zero on success, or non-zero on error. */ int ne_iaddr_reverse(const ne_inet_addr *ia, char *buf, size_t bufsiz); -/* Destroy a network address object created using ne_iaddr_make. */ +/* Convert network address string 'addr' (for example, "127.0.0.1") + * into a network address object. Returns NULL on parse error. If + * non-NULL, return value must be freed using ne_iaddr_free. */ +ne_inet_addr *ne_iaddr_parse(const char *addr, ne_iaddr_type type); + +/* Destroy a network address object created using ne_iaddr_make or + * ne_iaddr_parse. */ void ne_iaddr_free(ne_inet_addr *addr); /* Create a socket object; returns NULL on error. */ diff --git a/src/neon.vers b/src/neon.vers index 391cb24..e482b5e 100644 --- a/src/neon.vers +++ b/src/neon.vers @@ -12,4 +12,5 @@ NEON_0_29 { ne_acl3744_set; ne_buffer_qappend; ne_strnqdup; + ne_iaddr_parse; }; diff --git a/test/socket.c b/test/socket.c index 54f969a..f461a88 100644 --- a/test/socket.c +++ b/test/socket.c @@ -1,6 +1,6 @@ /* Socket handling tests - Copyright (C) 2002-2008, Joe Orton <joe@manyfish.co.uk> + Copyright (C) 2002-2009, Joe Orton <joe@manyfish.co.uk> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -222,11 +222,24 @@ raw6_cafe[16] = /* feed::cafe */ "\xfe\xed\0\0\0\0\0\0\0\0\0\0\0\0\xca\xfe", raw6_babe[16] = /* cafe:babe:: */ "\xca\xfe\xba\xbe\0\0\0\0\0\0\0\0\0\0\0\0"; #endif +/* Check the given inet addr is 127.0.0.1. */ +static int check_is_raw127(const ne_inet_addr *ia) +{ + unsigned char raw[5]; + + raw[4] = 'Z'; + ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv4); + ONN("ne_iaddr_raw gave bad retval", ne_iaddr_raw(ia, raw) != raw); + ONN("raw address mismatch", memcmp(raw, raw_127, 4) != 0); + ONN("ne_iaddr_raw buffer overflow", raw[4] != 'Z'); + + return OK; +} + static int addr_make_v4(void) { ne_inet_addr *ia; char pr[50]; - unsigned char raw[5]; ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); ONN("ne_iaddr_make returned NULL", ia == NULL); @@ -234,14 +247,24 @@ static int addr_make_v4(void) ne_iaddr_print(ia, pr, sizeof pr); ONV(strcmp(pr, "127.0.0.1"), ("address was %s not 127.0.0.1", pr)); - ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv4); + CALL(check_is_raw127(ia)); + + ne_iaddr_free(ia); - raw[4] = 'Z'; - ONN("ne_iaddr_raw gave bad retval", ne_iaddr_raw(ia, raw) != raw); - ONN("raw address mismatch", memcmp(raw, raw_127, 4) != 0); - ONN("ne_iaddr_raw buffer overflow", raw[4] != 'Z'); + return OK; +} + +static int parse_v4(void) +{ + ne_inet_addr *ia; + + ia = ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv4); + ONN("parse failed", ia == NULL); + + CALL(check_is_raw127(ia)); ne_iaddr_free(ia); + return OK; } @@ -277,15 +300,25 @@ static int addr_make_v6(void) ONN("ne_iaddr_raw gave bad retval", ne_iaddr_raw(ia, raw) != raw); ONN("raw address mismatch", memcmp(raw, as[n].addr, 4) != 0); ONN("ne_iaddr_raw buffer overflow", raw[16] != 'Z'); - + ne_iaddr_free(ia); - } + + ia = ne_iaddr_parse(as[n].rep, ne_iaddr_ipv6); + ONV(ia == NULL, ("ne_iaddr_parse failed for %s", as[n].rep)); + ONN("bogus ne_iaddr_typeof return", ne_iaddr_typeof(ia) != ne_iaddr_ipv6); + ONN("ne_iaddr_raw gave bad retval", ne_iaddr_raw(ia, raw) != raw); + ONN("raw address mismatch", memcmp(raw, as[n].addr, 4) != 0); + ONN("ne_iaddr_raw buffer overflow", raw[16] != 'Z'); + + ne_iaddr_free(ia); + } return OK; #else /* should fail when lacking IPv6 support. */ ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv6, raw6_nuls); ONN("ne_iaddr_make did not return NULL", ia != NULL); + ONN("ne_iaddr_parse did not return NULL", ne_iaddr_parse("127.0.0.1", ne_iaddr_ipv6)); #endif return OK; } @@ -1279,7 +1312,9 @@ static int socks_proxy(void) { NE_SOCK_SOCKSV4A, 0, "www.example.com", 55555, NULL, NULL }, { NE_SOCK_SOCKSV5, 0, "www.example.com", 55555, NULL, NULL }, { NE_SOCK_SOCKSV5, 4, NULL, 55555, NULL, NULL }, +#ifdef TEST_IPV6 { NE_SOCK_SOCKSV5, 6, NULL, 55555, NULL, NULL }, +#endif { NE_SOCK_SOCKSV5, 0, "www.example.com", 55555, "norman", "foobar" } }; unsigned n; @@ -1293,8 +1328,10 @@ static int socks_proxy(void) arg.expect_port = ts[n].port; if (ts[n].addr == 4) arg.expect_addr = ne_iaddr_make(ne_iaddr_ipv4, raw_127); +#ifdef TEST_IPV6 else if (ts[n].addr == 6) arg.expect_addr = ne_iaddr_make(ne_iaddr_ipv4, raw6_cafe); +#endif else arg.expect_fqdn = ts[n].fqdn; arg.username = ts[n].username; @@ -1392,6 +1429,7 @@ ne_test tests[] = { T_LEAKY(init_ssl), #endif T(addr_make_v4), + T(parse_v4), T(addr_make_v6), T(addr_compare), T(addr_reverse), diff --git a/test/util-socks.c b/test/util-socks.c index a055bf5..0734460 100644 --- a/test/util-socks.c +++ b/test/util-socks.c @@ -90,7 +90,7 @@ static int read_socks_0string(ne_socket *sock, const char *ctx, unsigned char *end = buf + *len, *p = buf; while (p < end) { - CALL(read_socks_byte(sock, "NUL-terminated string read", p)); + CALL(read_socks_byte(sock, ctx, p)); if (*p == '\0') break; @@ -131,6 +131,9 @@ int socks_server(ne_socket *sock, void *userdata) srv->version == NE_SOCK_SOCKSV4A && srv->expect_addr == NULL && memcmp(buf + 2, "\0\0\0", 3) != 0 && buf[6] != 0); + ONN("v4 server with no expected address! fail", + srv->version == NE_SOCK_SOCKSV4 && srv->expect_addr == NULL); + if (srv->expect_addr) { ONN("v4 address mismatch", memcmp(ne_iaddr_raw(srv->expect_addr, raw), buf + 2, 4) != 0); @@ -156,9 +159,16 @@ int socks_server(ne_socket *sock, void *userdata) ("bad v4A hostname: %s not %s", buf, srv->expect_fqdn)); } - CALL(full_write(sock, "\x00\x5A" - "\x00\x00" "\x00\x00\x00\x00" - "ok!\n", 12)); + { + static const char msg[] = "\x00\x5A" + "\x00\x00" "\x00\x00\x00\x00" + "ok!\n"; + + if (srv->say_hello) + CALL(full_write(sock, msg, 12)); + else + CALL(full_write(sock, msg, 8)); + } return srv->server(sock, srv->userdata); } |