1/* SCTP kernel Implementation 2 * (C) Copyright IBM Corp. 2001, 2003 3 * Copyright (c) 1999-2000 Cisco, Inc. 4 * Copyright (c) 1999-2001 Motorola, Inc. 5 * Copyright (c) 2001 Intel Corp. 6 * Copyright (c) 2001 Nokia, Inc. 7 * 8 * The SCTP implementation is free software; 9 * you can redistribute it and/or modify it under the terms of 10 * the GNU General Public License as published by 11 * the Free Software Foundation; either version 2, or (at your option) 12 * any later version. 13 * 14 * The SCTP implementation is distributed in the hope that it 15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 16 * ************************ 17 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 * See the GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with GNU CC; see the file COPYING. If not, write to 22 * the Free Software Foundation, 59 Temple Place - Suite 330, 23 * Boston, MA 02111-1307, USA. 24 * 25 * Please send any bug reports or fixes you make to the 26 * email address(es): 27 * lksctp developers <lksctp-developers@lists.sourceforge.net> 28 * 29 * Or submit a bug report through the following website: 30 * http://www.sf.net/projects/lksctp 31 * 32 * Any bugs reported to us we will try to fix... any fixes shared will 33 * be incorporated into the next SCTP release. 34 * 35 * Written or modified by: 36 * Sridhar Samudrala <sri@us.ibm.com> 37 */ 38 39/* This is a Functional Test to verify autoclose functionality and the 40 * socket option SCTP_AUTOCLOSE that can be used to specify the duration in 41 * which an idle association is automatically closed. 42 */ 43 44#include <stdio.h> 45#include <unistd.h> 46#include <stdlib.h> 47#include <string.h> 48#include <sys/types.h> 49#include <sys/socket.h> 50#include <sys/uio.h> 51#include <netinet/in.h> 52#include <sys/errno.h> 53#include <errno.h> 54#include <netinet/sctp.h> 55#include <sctputil.h> 56#include "tst_kernel.h" 57 58char *TCID = __FILE__; 59int TST_TOTAL = 1; 60int TST_CNT = 0; 61 62int 63main(void) 64{ 65 int sk1, sk2; 66 sockaddr_storage_t loop1, loop2; 67 struct msghdr inmessage, outmessage; 68 struct iovec iov, out_iov; 69 int error; 70 char *big_buffer; 71 char *message = "hello, world!\n"; 72 uint32_t autoclose; 73 74 if (tst_check_driver("sctp")) 75 tst_brkm(TCONF, tst_exit, "sctp driver not available"); 76 77 /* Rather than fflush() throughout the code, set stdout to 78 * be unbuffered. 79 */ 80 setvbuf(stdout, NULL, _IONBF, 0); 81 82 loop1.v4.sin_family = AF_INET; 83 loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; 84 loop1.v4.sin_port = htons(SCTP_TESTPORT_1); 85 86 loop2.v4.sin_family = AF_INET; 87 loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; 88 loop2.v4.sin_port = htons(SCTP_TESTPORT_2); 89 90 /* Create the two endpoints which will talk to each other. */ 91 sk1 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); 92 sk2 = test_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); 93 94 /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ 95 test_enable_assoc_change(sk1); 96 test_enable_assoc_change(sk2); 97 98 /* Bind these sockets to the test ports. */ 99 test_bind(sk1, &loop1.sa, sizeof(loop1)); 100 test_bind(sk2, &loop2.sa, sizeof(loop2)); 101 102 /* Mark sk2 as being able to accept new associations. */ 103 test_listen(sk2, 1); 104 105 /* Set the autoclose duration for the associations created on sk1 106 * and sk2 to be 5 seconds. 107 */ 108 autoclose = 5; 109 test_setsockopt(sk1, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose)); 110 test_setsockopt(sk2, SCTP_AUTOCLOSE, &autoclose, sizeof(autoclose)); 111 112 /* Send the first message. This will create the association. */ 113 memset(&outmessage, 0, sizeof(outmessage)); 114 outmessage.msg_name = &loop2; 115 outmessage.msg_namelen = sizeof(loop2); 116 outmessage.msg_iov = &out_iov; 117 outmessage.msg_iovlen = 1; 118 outmessage.msg_iov->iov_base = message; 119 outmessage.msg_iov->iov_len = strlen(message) + 1; 120 121 test_sendmsg(sk1, &outmessage, 0, strlen(message)+1); 122 123 /* Initialize inmessage for all receives. */ 124 big_buffer = test_malloc(REALLY_BIG); 125 memset(&inmessage, 0, sizeof(inmessage)); 126 iov.iov_base = big_buffer; 127 iov.iov_len = REALLY_BIG; 128 inmessage.msg_iov = &iov; 129 inmessage.msg_iovlen = 1; 130 inmessage.msg_control = NULL; 131 132 /* Get the communication up message on sk2. */ 133 error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 134 test_check_msg_notification(&inmessage, error, 135 sizeof(struct sctp_assoc_change), 136 SCTP_ASSOC_CHANGE, SCTP_COMM_UP); 137 138 /* Get the communication up message on sk1. */ 139 error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); 140 test_check_msg_notification(&inmessage, error, 141 sizeof(struct sctp_assoc_change), 142 SCTP_ASSOC_CHANGE, SCTP_COMM_UP); 143 144 /* Get the first message which was sent. */ 145 error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 146 test_check_msg_data(&inmessage, error, strlen(message) + 1, 147 MSG_EOR|MSG_CTRUNC, 0, 0); 148 149 tst_resm(TINFO, "Waiting for the associations to close automatically " 150 "in 5 secs"); 151 152 /* Get the shutdown complete notification from sk1. */ 153 error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); 154 test_check_msg_notification(&inmessage, error, 155 sizeof(struct sctp_assoc_change), 156 SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); 157 158 /* Get the shutdown complete notification from sk2. */ 159 error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 160 test_check_msg_notification(&inmessage, error, 161 sizeof(struct sctp_assoc_change), 162 SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); 163 164 tst_resm(TPASS, "Autoclose of associations"); 165 166 /* Shut down the link. */ 167 close(sk1); 168 close(sk2); 169 170 /* Indicate successful completion. */ 171 return 0; 172} 173