Files
shadowsocks-libev/tests/test_netutils.c
Max LvandClaude Opus 4.6 1c404eccf4 Modernize build: switch to CMake, add unit tests, fix man pages
Remove autotools (configure.ac, Makefile.am, m4/, autogen.sh) and make
CMake the sole build system. Enhance CMake with proper Find modules for
MbedTLS, libsodium, PCRE, and c-ares with version/feature detection.
Add support for connmarktos, nftables, stack protector, and MinGW.

Add 10 unit test suites (CTest) covering base64, buffer, cache, crypto,
jconf, json, netutils, ppbloom, rule, and utils modules. Add a Python
stress test measuring bandwidth per cipher with memory leak detection.

Fix man page typos ("Resovle" -> "Resolve"), document missing TCP buffer
options, fix ss-manager duplicate --executable entry, add example section
to ss-tunnel, and document --workdir and --nftables-sets options.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 16:40:27 +08:00

116 lines
3.2 KiB
C

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int verbose = 0;
#include "netutils.h"
static void
test_get_sockaddr_len(void)
{
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
struct sockaddr_storage unknown;
memset(&addr4, 0, sizeof(addr4));
addr4.sin_family = AF_INET;
assert(get_sockaddr_len((struct sockaddr *)&addr4) == sizeof(struct sockaddr_in));
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
assert(get_sockaddr_len((struct sockaddr *)&addr6) == sizeof(struct sockaddr_in6));
memset(&unknown, 0, sizeof(unknown));
unknown.ss_family = AF_UNSPEC;
assert(get_sockaddr_len((struct sockaddr *)&unknown) == 0);
}
static void
test_sockaddr_cmp(void)
{
struct sockaddr_storage a, b;
struct sockaddr_in *a4 = (struct sockaddr_in *)&a;
struct sockaddr_in *b4 = (struct sockaddr_in *)&b;
/* Same address and port */
memset(&a, 0, sizeof(a));
memset(&b, 0, sizeof(b));
a4->sin_family = AF_INET;
b4->sin_family = AF_INET;
a4->sin_port = htons(80);
b4->sin_port = htons(80);
inet_pton(AF_INET, "127.0.0.1", &a4->sin_addr);
inet_pton(AF_INET, "127.0.0.1", &b4->sin_addr);
assert(sockaddr_cmp(&a, &b, sizeof(struct sockaddr_in)) == 0);
/* Different port */
b4->sin_port = htons(81);
assert(sockaddr_cmp(&a, &b, sizeof(struct sockaddr_in)) != 0);
}
static void
test_sockaddr_cmp_addr(void)
{
struct sockaddr_storage a, b;
struct sockaddr_in *a4 = (struct sockaddr_in *)&a;
struct sockaddr_in *b4 = (struct sockaddr_in *)&b;
memset(&a, 0, sizeof(a));
memset(&b, 0, sizeof(b));
a4->sin_family = AF_INET;
b4->sin_family = AF_INET;
a4->sin_port = htons(80);
b4->sin_port = htons(443);
inet_pton(AF_INET, "10.0.0.1", &a4->sin_addr);
inet_pton(AF_INET, "10.0.0.1", &b4->sin_addr);
/* Same address, different port - should be equal */
assert(sockaddr_cmp_addr(&a, &b, sizeof(struct sockaddr_in)) == 0);
/* Different address */
inet_pton(AF_INET, "10.0.0.2", &b4->sin_addr);
assert(sockaddr_cmp_addr(&a, &b, sizeof(struct sockaddr_in)) != 0);
}
static void
test_validate_hostname(void)
{
/* Valid hostnames */
assert(validate_hostname("example.com", 11) == 1);
assert(validate_hostname("sub.example.com", 15) == 1);
assert(validate_hostname("a", 1) == 1);
assert(validate_hostname("a-b", 3) == 1);
assert(validate_hostname("123.456", 7) == 1);
/* Invalid hostnames */
assert(validate_hostname(NULL, 0) == 0);
assert(validate_hostname("", 0) == 0);
assert(validate_hostname(".example.com", 12) == 0); /* starts with dot */
assert(validate_hostname("-example.com", 12) == 0); /* label starts with hyphen */
assert(validate_hostname("example-.com", 12) == 0); /* label ends with hyphen */
/* Too long hostname (> 255) */
char long_name[260];
memset(long_name, 'a', 259);
long_name[259] = '\0';
assert(validate_hostname(long_name, 259) == 0);
}
int
main(void)
{
test_get_sockaddr_len();
test_sockaddr_cmp();
test_sockaddr_cmp_addr();
test_validate_hostname();
return 0;
}