summaryrefslogtreecommitdiff
path: root/minix/tests/test80.c
blob: 99e65376b1201ac5267b42562788ac4ff12c75cd (plain)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * test80: use the functions originally written for test56 to test TCP
 */

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>

#include "common.h"
#include "common-socket.h"

#define PORT1	4321
#define PORT2	4322

static void callback_check_sockaddr(const struct sockaddr *sockaddr,
	socklen_t sockaddrlen, const char *callname, int addridx) {
	char buf[256];
	int port;
	const struct sockaddr_in *sockaddr_in =
		(const struct sockaddr_in *) sockaddr;

	switch (addridx) {
	case 1: port = PORT1; break;
	case 2: port = PORT2; break;
	default:
		fprintf(stderr, "error: invalid addridx %d in "
			"callback_check_sockaddr\n", addridx);
		abort();
	}

	if (sockaddr_in->sin_family != AF_INET ||
		sockaddr_in->sin_port != htons(port)) {
		snprintf(buf, sizeof(buf), "%s() didn't return the right addr",
			callname);
		test_fail(buf);

		memset(buf, 0, sizeof(buf));
		inet_ntop(sockaddr_in->sin_family, &sockaddr_in->sin_addr,
			buf, sizeof(buf));
		fprintf(stderr, "exp: localhost:%d | got: %s:%d\n", port, buf,
			ntohs(sockaddr_in->sin_port));
	}
}

static void callback_cleanup(void) {
	/* nothing to do */
}

int main(int argc, char *argv[])
{
	struct sockaddr_in clientaddr = {
		.sin_family = AF_INET,
		.sin_port = htons(PORT1),
		.sin_addr = { .s_addr = htonl(INADDR_LOOPBACK) },
	};
	struct sockaddr_in clientaddr2 = {
		.sin_family = AF_INET,
		.sin_port = htons(PORT2),
		.sin_addr = { .s_addr = htonl(INADDR_LOOPBACK) },
	};
	struct sockaddr_in serveraddr = {
		.sin_family = AF_INET,
		.sin_port = htons(PORT1),
		.sin_addr = { .s_addr = htonl(INADDR_ANY) },
	};
	struct sockaddr_in serveraddr2 = {
		.sin_family = AF_INET,
		.sin_port = htons(PORT2),
		.sin_addr = { .s_addr = htonl(INADDR_ANY) },
	};
	const struct socket_test_info info = {
		.clientaddr                = (struct sockaddr *) &clientaddr,
		.clientaddrlen             = sizeof(clientaddr),
		.clientaddr2               = (struct sockaddr *) &clientaddr2,
		.clientaddr2len            = sizeof(clientaddr2),
		.clientaddrsym             = (struct sockaddr *) &clientaddr,
		.clientaddrsymlen          = sizeof(clientaddr),
		.domain                    = PF_INET,
		.expected_rcvbuf           = -1,
		.expected_sndbuf           = -1,
		.serveraddr                = (struct sockaddr *) &serveraddr,
		.serveraddrlen             = sizeof(serveraddr),
		.serveraddr2               = (struct sockaddr *) &serveraddr2,
		.serveraddr2len            = sizeof(serveraddr2),
		.type                      = SOCK_STREAM,
		.types                     = &info.type,
		.typecount                 = 1,

		/*
		 * Maintainer's note: common-socket was adapted from test56 in
		 * a time that UDS's LOCAL_CONNWAIT was the default.  Due to
		 * this as well as inherent behavioral differences between TCP
		 * and UDS, these exceptions basically work around the fact
		 * that common-socket was not designed for its current task.
		 */
		.ignore_accept_delay       = 1,
		.ignore_connect_unaccepted = 1,
		.ignore_connect_delay      = 1,
		.ignore_select_delay       = 1,
		.ignore_send_waiting       = 1,
		.ignore_write_conn_reset   = 1,

		.callback_check_sockaddr   = callback_check_sockaddr,
		.callback_cleanup          = callback_cleanup,
		.callback_xfer_prepclient  = NULL,
		.callback_xfer_peercred    = NULL,
	};

	debug("entering main()");

	start(80);

	test_socket(&info);
	test_bind(&info);
	test_listen(&info);
	test_getsockname(&info);
	test_shutdown(&info);
	test_close(&info);
	test_dup(&info);
	test_dup2(&info);
	test_shutdown(&info);
	test_read(&info);
	test_write(&info);
	test_sockopts(&info);
	test_xfer(&info);
	test_simple_client_server(&info, info.type);
	test_abort_client_server(&info, 1);
	test_abort_client_server(&info, 2);
	test_nonblock(&info);
	test_connect_nb(&info);
	test_intr(&info);
	test_connect_close(&info);
	/* test_listen_close(&info); -- not suitable for TCP */
	test_listen_close_nb(&info);

	quit();

	return -1;	/* we should never get here */
}