1c520d61bSMaxim Sobolev /*- 2c520d61bSMaxim Sobolev * Copyright (c) 2005 Maxim Sobolev 3c520d61bSMaxim Sobolev * All rights reserved. 4c520d61bSMaxim Sobolev * 5c520d61bSMaxim Sobolev * Redistribution and use in source and binary forms, with or without 6c520d61bSMaxim Sobolev * modification, are permitted provided that the following conditions 7c520d61bSMaxim Sobolev * are met: 8c520d61bSMaxim Sobolev * 1. Redistributions of source code must retain the above copyright 9c520d61bSMaxim Sobolev * notice, this list of conditions and the following disclaimer. 10c520d61bSMaxim Sobolev * 2. Redistributions in binary form must reproduce the above copyright 11c520d61bSMaxim Sobolev * notice, this list of conditions and the following disclaimer in the 12c520d61bSMaxim Sobolev * documentation and/or other materials provided with the distribution. 13c520d61bSMaxim Sobolev * 14c520d61bSMaxim Sobolev * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15c520d61bSMaxim Sobolev * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16c520d61bSMaxim Sobolev * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17c520d61bSMaxim Sobolev * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18c520d61bSMaxim Sobolev * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19c520d61bSMaxim Sobolev * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20c520d61bSMaxim Sobolev * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21c520d61bSMaxim Sobolev * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22c520d61bSMaxim Sobolev * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23c520d61bSMaxim Sobolev * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24c520d61bSMaxim Sobolev * SUCH DAMAGE. 25c520d61bSMaxim Sobolev * 26c520d61bSMaxim Sobolev * $FreeBSD$ 27c520d61bSMaxim Sobolev */ 28c520d61bSMaxim Sobolev 29c520d61bSMaxim Sobolev /* 30c520d61bSMaxim Sobolev * The reconnect regression test is designed to catch kernel bug that may 31c520d61bSMaxim Sobolev * prevent changing association of already associated datagram unix domain 32c520d61bSMaxim Sobolev * socket when server side of connection has been closed. 33c520d61bSMaxim Sobolev */ 34c520d61bSMaxim Sobolev 35c520d61bSMaxim Sobolev #include <sys/types.h> 36c520d61bSMaxim Sobolev #include <sys/socket.h> 37c520d61bSMaxim Sobolev #include <sys/uio.h> 38c520d61bSMaxim Sobolev #include <sys/un.h> 39c520d61bSMaxim Sobolev #include <err.h> 40c520d61bSMaxim Sobolev #include <errno.h> 41c520d61bSMaxim Sobolev #include <fcntl.h> 42c520d61bSMaxim Sobolev #include <stdio.h> 43c520d61bSMaxim Sobolev #include <stdlib.h> 44c520d61bSMaxim Sobolev #include <signal.h> 45c520d61bSMaxim Sobolev #include <string.h> 46c520d61bSMaxim Sobolev #include <unistd.h> 47c520d61bSMaxim Sobolev 48c520d61bSMaxim Sobolev static char *uds_name1 = NULL; 49c520d61bSMaxim Sobolev static char *uds_name2 = NULL; 50c520d61bSMaxim Sobolev 51c520d61bSMaxim Sobolev #define sstosa(ss) ((struct sockaddr *)(ss)) 52c520d61bSMaxim Sobolev 53c520d61bSMaxim Sobolev void 54c520d61bSMaxim Sobolev prepare_ifsun(struct sockaddr_un *ifsun, const char *path) 55c520d61bSMaxim Sobolev { 56c520d61bSMaxim Sobolev 57c520d61bSMaxim Sobolev memset(ifsun, '\0', sizeof(*ifsun)); 58c520d61bSMaxim Sobolev #if !defined(__linux__) && !defined(__solaris__) 59c520d61bSMaxim Sobolev ifsun->sun_len = strlen(path); 60c520d61bSMaxim Sobolev #endif 61c520d61bSMaxim Sobolev ifsun->sun_family = AF_LOCAL; 62c520d61bSMaxim Sobolev strcpy(ifsun->sun_path, path); 63c520d61bSMaxim Sobolev } 64c520d61bSMaxim Sobolev 65c520d61bSMaxim Sobolev int 66c520d61bSMaxim Sobolev create_uds_server(const char *path) 67c520d61bSMaxim Sobolev { 68c520d61bSMaxim Sobolev struct sockaddr_un ifsun; 69c520d61bSMaxim Sobolev int sock; 70c520d61bSMaxim Sobolev 71c520d61bSMaxim Sobolev prepare_ifsun(&ifsun, path); 72c520d61bSMaxim Sobolev 73c520d61bSMaxim Sobolev unlink(ifsun.sun_path); 74c520d61bSMaxim Sobolev 75c520d61bSMaxim Sobolev sock = socket(PF_LOCAL, SOCK_DGRAM, 0); 76c520d61bSMaxim Sobolev if (sock == -1) 77c520d61bSMaxim Sobolev err(1, "can't create socket"); 78c520d61bSMaxim Sobolev setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sock, sizeof(sock)); 79c520d61bSMaxim Sobolev if (bind(sock, sstosa(&ifsun), sizeof(ifsun)) < 0) 80c520d61bSMaxim Sobolev err(1, "can't bind to a socket"); 81c520d61bSMaxim Sobolev 82c520d61bSMaxim Sobolev return sock; 83c520d61bSMaxim Sobolev } 84c520d61bSMaxim Sobolev 85c520d61bSMaxim Sobolev void 86c520d61bSMaxim Sobolev connect_uds_server(int sock, const char *path) 87c520d61bSMaxim Sobolev { 88c520d61bSMaxim Sobolev struct sockaddr_un ifsun; 89c520d61bSMaxim Sobolev int e; 90c520d61bSMaxim Sobolev 91c520d61bSMaxim Sobolev prepare_ifsun(&ifsun, path); 92c520d61bSMaxim Sobolev 93c520d61bSMaxim Sobolev e = connect(sock, sstosa(&ifsun), sizeof(ifsun)); 94c520d61bSMaxim Sobolev if (e < 0) 95c520d61bSMaxim Sobolev err(1, "can't connect to a socket"); 96c520d61bSMaxim Sobolev } 97c520d61bSMaxim Sobolev 98c520d61bSMaxim Sobolev void 99c520d61bSMaxim Sobolev cleanup(void) 100c520d61bSMaxim Sobolev { 101c520d61bSMaxim Sobolev 102c520d61bSMaxim Sobolev if (uds_name1 != NULL) 103c520d61bSMaxim Sobolev unlink(uds_name1); 104c520d61bSMaxim Sobolev if (uds_name2 != NULL) 105c520d61bSMaxim Sobolev unlink(uds_name2); 106c520d61bSMaxim Sobolev } 107c520d61bSMaxim Sobolev 108c520d61bSMaxim Sobolev int 109c520d61bSMaxim Sobolev main() 110c520d61bSMaxim Sobolev { 111c520d61bSMaxim Sobolev int s_sock1, s_sock2, c_sock; 112c520d61bSMaxim Sobolev 113c520d61bSMaxim Sobolev atexit(cleanup); 114c520d61bSMaxim Sobolev 115c520d61bSMaxim Sobolev uds_name1 = strdup("/tmp/reconnect.XXXXXX"); 116c520d61bSMaxim Sobolev if (uds_name1 == NULL) 117c520d61bSMaxim Sobolev err(1, "can't allocate memory"); 118c520d61bSMaxim Sobolev uds_name1 = mktemp(uds_name1); 119c520d61bSMaxim Sobolev if (uds_name1 == NULL) 120c520d61bSMaxim Sobolev err(1, "mktemp(3) failed"); 121c520d61bSMaxim Sobolev s_sock1 = create_uds_server(uds_name1); 122c520d61bSMaxim Sobolev 123c520d61bSMaxim Sobolev uds_name2 = strdup("/tmp/reconnect.XXXXXX"); 124c520d61bSMaxim Sobolev if (uds_name2 == NULL) 125c520d61bSMaxim Sobolev err(1, "can't allocate memory"); 126c520d61bSMaxim Sobolev uds_name2 = mktemp(uds_name2); 127c520d61bSMaxim Sobolev if (uds_name2 == NULL) 128c520d61bSMaxim Sobolev err(1, "mktemp(3) failed"); 129c520d61bSMaxim Sobolev s_sock2 = create_uds_server(uds_name2); 130c520d61bSMaxim Sobolev 131c520d61bSMaxim Sobolev c_sock = socket(PF_LOCAL, SOCK_DGRAM, 0); 132c520d61bSMaxim Sobolev if (c_sock < 0) 133c520d61bSMaxim Sobolev err(1, "can't create socket"); 134c520d61bSMaxim Sobolev 135c520d61bSMaxim Sobolev connect_uds_server(c_sock, uds_name1); 136c520d61bSMaxim Sobolev close(s_sock1); 137c520d61bSMaxim Sobolev connect_uds_server(c_sock, uds_name2); 138c520d61bSMaxim Sobolev 139c520d61bSMaxim Sobolev exit (0); 140c520d61bSMaxim Sobolev } 141