1140109Ssobomax/*- 2140109Ssobomax * Copyright (c) 2005 Maxim Sobolev 3140109Ssobomax * All rights reserved. 4140109Ssobomax * 5140109Ssobomax * Redistribution and use in source and binary forms, with or without 6140109Ssobomax * modification, are permitted provided that the following conditions 7140109Ssobomax * are met: 8140109Ssobomax * 1. Redistributions of source code must retain the above copyright 9140109Ssobomax * notice, this list of conditions and the following disclaimer. 10140109Ssobomax * 2. Redistributions in binary form must reproduce the above copyright 11140109Ssobomax * notice, this list of conditions and the following disclaimer in the 12140109Ssobomax * documentation and/or other materials provided with the distribution. 13140109Ssobomax * 14140109Ssobomax * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15140109Ssobomax * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16140109Ssobomax * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17140109Ssobomax * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18140109Ssobomax * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19140109Ssobomax * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20140109Ssobomax * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21140109Ssobomax * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22140109Ssobomax * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23140109Ssobomax * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24140109Ssobomax * SUCH DAMAGE. 25140109Ssobomax * 26140109Ssobomax * $FreeBSD: releng/10.3/tools/regression/sockets/reconnect/reconnect.c 294486 2016-01-21 05:59:33Z ngie $ 27140109Ssobomax */ 28140109Ssobomax 29140109Ssobomax/* 30140109Ssobomax * The reconnect regression test is designed to catch kernel bug that may 31140109Ssobomax * prevent changing association of already associated datagram unix domain 32140109Ssobomax * socket when server side of connection has been closed. 33140109Ssobomax */ 34140109Ssobomax 35140109Ssobomax#include <sys/types.h> 36140109Ssobomax#include <sys/socket.h> 37140109Ssobomax#include <sys/uio.h> 38140109Ssobomax#include <sys/un.h> 39140109Ssobomax#include <err.h> 40140109Ssobomax#include <errno.h> 41140109Ssobomax#include <fcntl.h> 42140109Ssobomax#include <stdio.h> 43140109Ssobomax#include <stdlib.h> 44140109Ssobomax#include <signal.h> 45140109Ssobomax#include <string.h> 46140109Ssobomax#include <unistd.h> 47140109Ssobomax 48281974Sngiestatic char uds_name1[] = "reconnect.XXXXXXXX"; 49281974Sngiestatic char uds_name2[] = "reconnect.XXXXXXXX"; 50140109Ssobomax 51140109Ssobomax#define sstosa(ss) ((struct sockaddr *)(ss)) 52140109Ssobomax 53281974Sngiestatic void 54140109Ssobomaxprepare_ifsun(struct sockaddr_un *ifsun, const char *path) 55140109Ssobomax{ 56140109Ssobomax 57140109Ssobomax memset(ifsun, '\0', sizeof(*ifsun)); 58140109Ssobomax#if !defined(__linux__) && !defined(__solaris__) 59140109Ssobomax ifsun->sun_len = strlen(path); 60140109Ssobomax#endif 61140109Ssobomax ifsun->sun_family = AF_LOCAL; 62140109Ssobomax strcpy(ifsun->sun_path, path); 63140109Ssobomax} 64140109Ssobomax 65281974Sngiestatic int 66140109Ssobomaxcreate_uds_server(const char *path) 67140109Ssobomax{ 68140109Ssobomax struct sockaddr_un ifsun; 69140109Ssobomax int sock; 70140109Ssobomax 71140109Ssobomax prepare_ifsun(&ifsun, path); 72140109Ssobomax 73140109Ssobomax unlink(ifsun.sun_path); 74140109Ssobomax 75140109Ssobomax sock = socket(PF_LOCAL, SOCK_DGRAM, 0); 76140109Ssobomax if (sock == -1) 77140109Ssobomax err(1, "can't create socket"); 78140109Ssobomax setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sock, sizeof(sock)); 79140109Ssobomax if (bind(sock, sstosa(&ifsun), sizeof(ifsun)) < 0) 80140109Ssobomax err(1, "can't bind to a socket"); 81140109Ssobomax 82140109Ssobomax return sock; 83140109Ssobomax} 84140109Ssobomax 85281974Sngiestatic void 86140109Ssobomaxconnect_uds_server(int sock, const char *path) 87140109Ssobomax{ 88140109Ssobomax struct sockaddr_un ifsun; 89140109Ssobomax int e; 90140109Ssobomax 91140109Ssobomax prepare_ifsun(&ifsun, path); 92140109Ssobomax 93140109Ssobomax e = connect(sock, sstosa(&ifsun), sizeof(ifsun)); 94140109Ssobomax if (e < 0) 95140109Ssobomax err(1, "can't connect to a socket"); 96140109Ssobomax} 97140109Ssobomax 98281974Sngiestatic void 99140109Ssobomaxcleanup(void) 100140109Ssobomax{ 101140109Ssobomax 102281974Sngie unlink(uds_name1); 103281974Sngie unlink(uds_name2); 104140109Ssobomax} 105140109Ssobomax 106140109Ssobomaxint 107294486Sngiemain(void) 108140109Ssobomax{ 109140109Ssobomax int s_sock1, s_sock2, c_sock; 110140109Ssobomax 111140109Ssobomax atexit(cleanup); 112140109Ssobomax 113281974Sngie if (mkstemp(uds_name1) == -1) 114281974Sngie err(1, "mkstemp"); 115281974Sngie unlink(uds_name1); 116140109Ssobomax s_sock1 = create_uds_server(uds_name1); 117140109Ssobomax 118281974Sngie if (mkstemp(uds_name2) == -1) 119281974Sngie err(1, "mkstemp"); 120281974Sngie unlink(uds_name2); 121140109Ssobomax s_sock2 = create_uds_server(uds_name2); 122140109Ssobomax 123140109Ssobomax c_sock = socket(PF_LOCAL, SOCK_DGRAM, 0); 124140109Ssobomax if (c_sock < 0) 125140109Ssobomax err(1, "can't create socket"); 126140109Ssobomax 127140109Ssobomax connect_uds_server(c_sock, uds_name1); 128140109Ssobomax close(s_sock1); 129140109Ssobomax connect_uds_server(c_sock, uds_name2); 130294486Sngie close(s_sock2); 131140109Ssobomax 132140109Ssobomax exit (0); 133140109Ssobomax} 134