0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #define _GNU_SOURCE
0015
0016 #include <arpa/inet.h>
0017 #include <errno.h>
0018 #include <error.h>
0019 #include <linux/in.h>
0020 #include <linux/unistd.h>
0021 #include <stdio.h>
0022 #include <stdlib.h>
0023 #include <string.h>
0024 #include <sys/epoll.h>
0025 #include <sys/types.h>
0026 #include <sys/socket.h>
0027 #include <unistd.h>
0028
0029 static const int PORT = 8888;
0030
0031 static void build_rcv_fd(int family, int proto, int *rcv_fds, int count)
0032 {
0033 struct sockaddr_storage addr;
0034 struct sockaddr_in *addr4;
0035 struct sockaddr_in6 *addr6;
0036 int opt, i;
0037
0038 switch (family) {
0039 case AF_INET:
0040 addr4 = (struct sockaddr_in *)&addr;
0041 addr4->sin_family = AF_INET;
0042 addr4->sin_addr.s_addr = htonl(INADDR_ANY);
0043 addr4->sin_port = htons(PORT);
0044 break;
0045 case AF_INET6:
0046 addr6 = (struct sockaddr_in6 *)&addr;
0047 addr6->sin6_family = AF_INET6;
0048 addr6->sin6_addr = in6addr_any;
0049 addr6->sin6_port = htons(PORT);
0050 break;
0051 default:
0052 error(1, 0, "Unsupported family %d", family);
0053 }
0054
0055 for (i = 0; i < count; ++i) {
0056 rcv_fds[i] = socket(family, proto, 0);
0057 if (rcv_fds[i] < 0)
0058 error(1, errno, "failed to create receive socket");
0059
0060 opt = 1;
0061 if (setsockopt(rcv_fds[i], SOL_SOCKET, SO_REUSEPORT, &opt,
0062 sizeof(opt)))
0063 error(1, errno, "failed to set SO_REUSEPORT");
0064
0065 if (bind(rcv_fds[i], (struct sockaddr *)&addr, sizeof(addr)))
0066 error(1, errno, "failed to bind receive socket");
0067
0068 if (proto == SOCK_STREAM && listen(rcv_fds[i], 10))
0069 error(1, errno, "failed to listen on receive port");
0070 }
0071 }
0072
0073 static void send_from_v4(int proto)
0074 {
0075 struct sockaddr_in saddr, daddr;
0076 int fd;
0077
0078 saddr.sin_family = AF_INET;
0079 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
0080 saddr.sin_port = 0;
0081
0082 daddr.sin_family = AF_INET;
0083 daddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
0084 daddr.sin_port = htons(PORT);
0085
0086 fd = socket(AF_INET, proto, 0);
0087 if (fd < 0)
0088 error(1, errno, "failed to create send socket");
0089
0090 if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)))
0091 error(1, errno, "failed to bind send socket");
0092
0093 if (connect(fd, (struct sockaddr *)&daddr, sizeof(daddr)))
0094 error(1, errno, "failed to connect send socket");
0095
0096 if (send(fd, "a", 1, 0) < 0)
0097 error(1, errno, "failed to send message");
0098
0099 close(fd);
0100 }
0101
0102 static int receive_once(int epfd, int proto)
0103 {
0104 struct epoll_event ev;
0105 int i, fd;
0106 char buf[8];
0107
0108 i = epoll_wait(epfd, &ev, 1, -1);
0109 if (i < 0)
0110 error(1, errno, "epoll_wait failed");
0111
0112 if (proto == SOCK_STREAM) {
0113 fd = accept(ev.data.fd, NULL, NULL);
0114 if (fd < 0)
0115 error(1, errno, "failed to accept");
0116 i = recv(fd, buf, sizeof(buf), 0);
0117 close(fd);
0118 } else {
0119 i = recv(ev.data.fd, buf, sizeof(buf), 0);
0120 }
0121
0122 if (i < 0)
0123 error(1, errno, "failed to recv");
0124
0125 return ev.data.fd;
0126 }
0127
0128 static void test(int *rcv_fds, int count, int proto)
0129 {
0130 struct epoll_event ev;
0131 int epfd, i, test_fd;
0132 int test_family;
0133 socklen_t len;
0134
0135 epfd = epoll_create(1);
0136 if (epfd < 0)
0137 error(1, errno, "failed to create epoll");
0138
0139 ev.events = EPOLLIN;
0140 for (i = 0; i < count; ++i) {
0141 ev.data.fd = rcv_fds[i];
0142 if (epoll_ctl(epfd, EPOLL_CTL_ADD, rcv_fds[i], &ev))
0143 error(1, errno, "failed to register sock epoll");
0144 }
0145
0146 send_from_v4(proto);
0147
0148 test_fd = receive_once(epfd, proto);
0149 len = sizeof(test_family);
0150 if (getsockopt(test_fd, SOL_SOCKET, SO_DOMAIN, &test_family, &len))
0151 error(1, errno, "failed to read socket domain");
0152 if (test_family != AF_INET)
0153 error(1, 0, "expected to receive on v4 socket but got v6 (%d)",
0154 test_family);
0155
0156 close(epfd);
0157 }
0158
0159 int main(void)
0160 {
0161 int rcv_fds[32], i;
0162
0163 fprintf(stderr, "---- UDP IPv4 created before IPv6 ----\n");
0164 build_rcv_fd(AF_INET, SOCK_DGRAM, rcv_fds, 5);
0165 build_rcv_fd(AF_INET6, SOCK_DGRAM, &(rcv_fds[5]), 5);
0166 test(rcv_fds, 10, SOCK_DGRAM);
0167 for (i = 0; i < 10; ++i)
0168 close(rcv_fds[i]);
0169
0170 fprintf(stderr, "---- UDP IPv6 created before IPv4 ----\n");
0171 build_rcv_fd(AF_INET6, SOCK_DGRAM, rcv_fds, 5);
0172 build_rcv_fd(AF_INET, SOCK_DGRAM, &(rcv_fds[5]), 5);
0173 test(rcv_fds, 10, SOCK_DGRAM);
0174 for (i = 0; i < 10; ++i)
0175 close(rcv_fds[i]);
0176
0177
0178
0179
0180 fprintf(stderr, "---- UDP IPv4 created before IPv6 (large) ----\n");
0181 build_rcv_fd(AF_INET, SOCK_DGRAM, rcv_fds, 16);
0182 build_rcv_fd(AF_INET6, SOCK_DGRAM, &(rcv_fds[16]), 16);
0183 test(rcv_fds, 32, SOCK_DGRAM);
0184 for (i = 0; i < 32; ++i)
0185 close(rcv_fds[i]);
0186
0187 fprintf(stderr, "---- UDP IPv6 created before IPv4 (large) ----\n");
0188 build_rcv_fd(AF_INET6, SOCK_DGRAM, rcv_fds, 16);
0189 build_rcv_fd(AF_INET, SOCK_DGRAM, &(rcv_fds[16]), 16);
0190 test(rcv_fds, 32, SOCK_DGRAM);
0191 for (i = 0; i < 32; ++i)
0192 close(rcv_fds[i]);
0193
0194 fprintf(stderr, "---- TCP IPv4 created before IPv6 ----\n");
0195 build_rcv_fd(AF_INET, SOCK_STREAM, rcv_fds, 5);
0196 build_rcv_fd(AF_INET6, SOCK_STREAM, &(rcv_fds[5]), 5);
0197 test(rcv_fds, 10, SOCK_STREAM);
0198 for (i = 0; i < 10; ++i)
0199 close(rcv_fds[i]);
0200
0201 fprintf(stderr, "---- TCP IPv6 created before IPv4 ----\n");
0202 build_rcv_fd(AF_INET6, SOCK_STREAM, rcv_fds, 5);
0203 build_rcv_fd(AF_INET, SOCK_STREAM, &(rcv_fds[5]), 5);
0204 test(rcv_fds, 10, SOCK_STREAM);
0205 for (i = 0; i < 10; ++i)
0206 close(rcv_fds[i]);
0207
0208 fprintf(stderr, "SUCCESS\n");
0209 return 0;
0210 }