1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <arpa/inet.h> 4 #include <error.h> 5 #include <errno.h> 6 #include <unistd.h> 7 8 int main(void) 9 { 10 int fd1, fd2, one = 1; 11 struct sockaddr_in6 bind_addr = { 12 .sin6_family = AF_INET6, 13 .sin6_port = htons(20000), 14 .sin6_flowinfo = htonl(0), 15 .sin6_addr = {}, 16 .sin6_scope_id = 0, 17 }; 18 19 inet_pton(AF_INET6, "::", &bind_addr.sin6_addr); 20 21 fd1 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); 22 if (fd1 < 0) { 23 error(1, errno, "socket fd1"); 24 return -1; 25 } 26 27 if (setsockopt(fd1, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { 28 error(1, errno, "setsockopt(SO_REUSEADDR) fd1"); 29 goto out_err1; 30 } 31 32 if (bind(fd1, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) { 33 error(1, errno, "bind fd1"); 34 goto out_err1; 35 } 36 37 if (sendto(fd1, NULL, 0, MSG_FASTOPEN, (struct sockaddr *)&bind_addr, 38 sizeof(bind_addr))) { 39 error(1, errno, "sendto fd1"); 40 goto out_err1; 41 } 42 43 fd2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); 44 if (fd2 < 0) { 45 error(1, errno, "socket fd2"); 46 goto out_err1; 47 } 48 49 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { 50 error(1, errno, "setsockopt(SO_REUSEADDR) fd2"); 51 goto out_err2; 52 } 53 54 if (bind(fd2, (struct sockaddr *)&bind_addr, sizeof(bind_addr))) { 55 error(1, errno, "bind fd2"); 56 goto out_err2; 57 } 58 59 if (sendto(fd2, NULL, 0, MSG_FASTOPEN, (struct sockaddr *)&bind_addr, 60 sizeof(bind_addr)) != -1) { 61 error(1, errno, "sendto fd2"); 62 goto out_err2; 63 } 64 65 if (listen(fd2, 0)) { 66 error(1, errno, "listen"); 67 goto out_err2; 68 } 69 70 close(fd2); 71 close(fd1); 72 return 0; 73 74 out_err2: 75 close(fd2); 76 77 out_err1: 78 close(fd1); 79 return -1; 80 } 81