File: test_netutils.c

package info (click to toggle)
shadowsocks-libev 3.3.6%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,192 kB
  • sloc: ansic: 15,474; sh: 3,518; python: 452; makefile: 25
file content (115 lines) | stat: -rw-r--r-- 3,300 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#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;
}