phunix/minix/tests/test81.c
Erik van der Kouwe 294d159017 Add new tests 80 (TCP) and 81 (UDP)
These new tests are largely based on the code from test 56 (UDS). Common code
is moved into a separate file common-socket.c. In some instances the tests
are too strict for TCP/UDP sockets, which may not always react instantly to
whatever happens on the other side (even locally). For these cases, the
ignore_* fields in struct socket_test_info indicate that there needs to be
an exception. There are also tests where it seems the functionality of inet
is either incorrect or incomplete with regard to the POSIX standard. In these
cases, the bug_* fields are used to document the issues while avoiding
failure of the test.

Change-Id: Ia860deb4559d42608790451936b1aade866faebc
2015-07-08 09:46:56 +02:00

135 lines
3.7 KiB
C

/*
* test81: use the functions originally written for test56 to test UDP
*/
#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[])
{
int i;
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_DGRAM,
.types = &info.type,
.typecount = 1,
.bug_bind_in_use = 1,
.bug_bind_null = 1,
.bug_connect_after_close = 1,
.bug_shutdown = 1, /* UDP only problem */
.bug_shutdown_not_conn = 1,
.bug_shutdown_read = 1,
.bug_sockopt_rcvbuf = 1, /* UDP only problem */
.bug_sockopt_sndbuf = 1, /* UDP only problem */
.ignore_accept_delay = 1,
.ignore_connect_unaccepted = 1,
.ignore_connect_delay = 1,
.ignore_read_conn_reset = 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(81);
test_socket(&info);
test_bind(&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_simple_client_server(&info, info.type);
quit();
return -1; /* we should never get here */
}