1f08c3bdfSopenharmony_ci/* SCTP kernel Implementation 2f08c3bdfSopenharmony_ci * (C) Copyright IBM Corp. 2003 3f08c3bdfSopenharmony_ci * Copyright (c) 2003 Intel Corp. 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * The SCTP implementation is free software; 6f08c3bdfSopenharmony_ci * you can redistribute it and/or modify it under the terms of 7f08c3bdfSopenharmony_ci * the GNU General Public License as published by 8f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2, or (at your option) 9f08c3bdfSopenharmony_ci * any later version. 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * The SCTP implementation is distributed in the hope that it 12f08c3bdfSopenharmony_ci * will be useful, but WITHOUT ANY WARRANTY; without even the implied 13f08c3bdfSopenharmony_ci * ************************ 14f08c3bdfSopenharmony_ci * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15f08c3bdfSopenharmony_ci * See the GNU General Public License for more details. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 18f08c3bdfSopenharmony_ci * along with GNU CC; see the file COPYING. If not, write to 19f08c3bdfSopenharmony_ci * the Free Software Foundation, 59 Temple Place - Suite 330, 20f08c3bdfSopenharmony_ci * Boston, MA 02111-1307, USA. 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * Please send any bug reports or fixes you make to the 23f08c3bdfSopenharmony_ci * email address(es): 24f08c3bdfSopenharmony_ci * lksctp developers <lksctp-developers@lists.sourceforge.net> 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * Or submit a bug report through the following website: 27f08c3bdfSopenharmony_ci * http://www.sf.net/projects/lksctp 28f08c3bdfSopenharmony_ci * 29f08c3bdfSopenharmony_ci * Any bugs reported to us we will try to fix... any fixes shared will 30f08c3bdfSopenharmony_ci * be incorporated into the next SCTP release. 31f08c3bdfSopenharmony_ci * 32f08c3bdfSopenharmony_ci * Written or modified by: 33f08c3bdfSopenharmony_ci * To compile the v6 version, set the symbol TEST_V6 to 1. 34f08c3bdfSopenharmony_ci * 35f08c3bdfSopenharmony_ci * Written or modified by: 36f08c3bdfSopenharmony_ci * Ardelle Fan <ardelle.fan@intel.com> 37f08c3bdfSopenharmony_ci * Sridhar Samudrala <sri@us.ibm.com> 38f08c3bdfSopenharmony_ci */ 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci/* This is a basic functional test for the SCTP new library APIs 41f08c3bdfSopenharmony_ci * sctp_sendmsg() and sctp_recvmsg(). test_timetolive.c is rewritten using 42f08c3bdfSopenharmony_ci * these new APIs. 43f08c3bdfSopenharmony_ci */ 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_ci#include <stdio.h> 46f08c3bdfSopenharmony_ci#include <unistd.h> 47f08c3bdfSopenharmony_ci#include <stdlib.h> 48f08c3bdfSopenharmony_ci#include <string.h> 49f08c3bdfSopenharmony_ci#include <sys/types.h> 50f08c3bdfSopenharmony_ci#include <sys/socket.h> 51f08c3bdfSopenharmony_ci#include <sys/uio.h> 52f08c3bdfSopenharmony_ci#include <netinet/in.h> 53f08c3bdfSopenharmony_ci#include <sys/errno.h> 54f08c3bdfSopenharmony_ci#include <errno.h> 55f08c3bdfSopenharmony_ci#include <netinet/sctp.h> 56f08c3bdfSopenharmony_ci#include <sctputil.h> 57f08c3bdfSopenharmony_ci#include "tst_kernel.h" 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_cichar *TCID = __FILE__; 60f08c3bdfSopenharmony_ciint TST_TOTAL = 10; 61f08c3bdfSopenharmony_ciint TST_CNT = 0; 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_ci/* RCVBUF value, and indirectly RWND*2 */ 64f08c3bdfSopenharmony_ci#define SMALL_RCVBUF 3000 65f08c3bdfSopenharmony_ci#define SMALL_MAXSEG 500 66f08c3bdfSopenharmony_ci/* This is extra data length to ensure rwnd closes */ 67f08c3bdfSopenharmony_ci#define RWND_SLOP 100 68f08c3bdfSopenharmony_cistatic char *fillmsg = NULL; 69f08c3bdfSopenharmony_cistatic char *ttlmsg = "This should time out!\n"; 70f08c3bdfSopenharmony_cistatic char *nottlmsg = "This should NOT time out!\n"; 71f08c3bdfSopenharmony_cistatic char ttlfrag[SMALL_MAXSEG*3] = {0}; 72f08c3bdfSopenharmony_cistatic char *message = "Hello world\n"; 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ciint main(void) 75f08c3bdfSopenharmony_ci{ 76f08c3bdfSopenharmony_ci int sk1, sk2; 77f08c3bdfSopenharmony_ci sockaddr_storage_t loop1; 78f08c3bdfSopenharmony_ci sockaddr_storage_t loop2; 79f08c3bdfSopenharmony_ci sockaddr_storage_t msgname; 80f08c3bdfSopenharmony_ci int error; 81f08c3bdfSopenharmony_ci int pf_class; 82f08c3bdfSopenharmony_ci uint32_t ppid; 83f08c3bdfSopenharmony_ci uint32_t stream; 84f08c3bdfSopenharmony_ci struct sctp_event_subscribe subscribe; 85f08c3bdfSopenharmony_ci char *big_buffer; 86f08c3bdfSopenharmony_ci int offset, msg_flags; 87f08c3bdfSopenharmony_ci socklen_t msgname_len; 88f08c3bdfSopenharmony_ci size_t buflen; 89f08c3bdfSopenharmony_ci struct sctp_send_failed *ssf; 90f08c3bdfSopenharmony_ci struct sctp_sndrcvinfo sinfo; 91f08c3bdfSopenharmony_ci struct sctp_sndrcvinfo snd_sinfo; 92f08c3bdfSopenharmony_ci sctp_assoc_t associd1; 93f08c3bdfSopenharmony_ci socklen_t len, oldlen; 94f08c3bdfSopenharmony_ci struct sctp_status gstatus; 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ci if (tst_check_driver("sctp")) 97f08c3bdfSopenharmony_ci tst_brkm(TCONF, tst_exit, "sctp driver not available"); 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci /* Rather than fflush() throughout the code, set stdout to 100f08c3bdfSopenharmony_ci * be unbuffered. 101f08c3bdfSopenharmony_ci */ 102f08c3bdfSopenharmony_ci setvbuf(stdout, NULL, _IONBF, 0); 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci /* Set some basic values which depend on the address family. */ 105f08c3bdfSopenharmony_ci#if TEST_V6 106f08c3bdfSopenharmony_ci pf_class = PF_INET6; 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_ci loop1.v6.sin6_family = AF_INET6; 109f08c3bdfSopenharmony_ci loop1.v6.sin6_addr = in6addr_loopback; 110f08c3bdfSopenharmony_ci loop1.v6.sin6_port = htons(SCTP_TESTPORT_1); 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ci loop2.v6.sin6_family = AF_INET6; 113f08c3bdfSopenharmony_ci loop2.v6.sin6_addr = in6addr_loopback; 114f08c3bdfSopenharmony_ci loop2.v6.sin6_port = htons(SCTP_TESTPORT_2); 115f08c3bdfSopenharmony_ci#else 116f08c3bdfSopenharmony_ci pf_class = PF_INET; 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci loop1.v4.sin_family = AF_INET; 119f08c3bdfSopenharmony_ci loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; 120f08c3bdfSopenharmony_ci loop1.v4.sin_port = htons(SCTP_TESTPORT_1); 121f08c3bdfSopenharmony_ci 122f08c3bdfSopenharmony_ci loop2.v4.sin_family = AF_INET; 123f08c3bdfSopenharmony_ci loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; 124f08c3bdfSopenharmony_ci loop2.v4.sin_port = htons(SCTP_TESTPORT_2); 125f08c3bdfSopenharmony_ci#endif /* TEST_V6 */ 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci /* Create the two endpoints which will talk to each other. */ 128f08c3bdfSopenharmony_ci sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); 129f08c3bdfSopenharmony_ci sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci /* Set the MAXSEG to something smallish. */ 132f08c3bdfSopenharmony_ci { 133f08c3bdfSopenharmony_ci int val = SMALL_MAXSEG; 134f08c3bdfSopenharmony_ci test_setsockopt(sk1, SCTP_MAXSEG, &val, sizeof(val)); 135f08c3bdfSopenharmony_ci } 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_ci memset(&subscribe, 0, sizeof(subscribe)); 138f08c3bdfSopenharmony_ci subscribe.sctp_data_io_event = 1; 139f08c3bdfSopenharmony_ci subscribe.sctp_association_event = 1; 140f08c3bdfSopenharmony_ci subscribe.sctp_send_failure_event = 1; 141f08c3bdfSopenharmony_ci test_setsockopt(sk1, SCTP_EVENTS, &subscribe, sizeof(subscribe)); 142f08c3bdfSopenharmony_ci test_setsockopt(sk2, SCTP_EVENTS, &subscribe, sizeof(subscribe)); 143f08c3bdfSopenharmony_ci 144f08c3bdfSopenharmony_ci /* Bind these sockets to the test ports. */ 145f08c3bdfSopenharmony_ci test_bind(sk1, &loop1.sa, sizeof(loop1)); 146f08c3bdfSopenharmony_ci test_bind(sk2, &loop2.sa, sizeof(loop2)); 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci /* 149f08c3bdfSopenharmony_ci * Set the RWND small so we can fill it up easily. 150f08c3bdfSopenharmony_ci * then reset RCVBUF to avoid frame droppage 151f08c3bdfSopenharmony_ci */ 152f08c3bdfSopenharmony_ci len = sizeof(int); 153f08c3bdfSopenharmony_ci error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &oldlen, &len); 154f08c3bdfSopenharmony_ci 155f08c3bdfSopenharmony_ci if (error) 156f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "can't get rcvbuf size: %s", 157f08c3bdfSopenharmony_ci strerror(errno)); 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci len = SMALL_RCVBUF; /* Really becomes 2xlen when set. */ 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_ci error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len)); 162f08c3bdfSopenharmony_ci if (error) 163f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s", 164f08c3bdfSopenharmony_ci strerror(errno)); 165f08c3bdfSopenharmony_ci 166f08c3bdfSopenharmony_ci /* Mark sk2 as being able to accept new associations. */ 167f08c3bdfSopenharmony_ci test_listen(sk2, 1); 168f08c3bdfSopenharmony_ci 169f08c3bdfSopenharmony_ci /* Send the first message. This will create the association. */ 170f08c3bdfSopenharmony_ci ppid = rand(); 171f08c3bdfSopenharmony_ci stream = 1; 172f08c3bdfSopenharmony_ci test_sctp_sendmsg(sk1, message, strlen(message) + 1, 173f08c3bdfSopenharmony_ci (struct sockaddr *)&loop2, sizeof(loop2), 174f08c3bdfSopenharmony_ci ppid, 0, stream, 0, 0); 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_sendmsg"); 177f08c3bdfSopenharmony_ci 178f08c3bdfSopenharmony_ci /* Get the communication up message on sk2. */ 179f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 180f08c3bdfSopenharmony_ci big_buffer = test_malloc(buflen); 181f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 182f08c3bdfSopenharmony_ci msg_flags = 0; 183f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk2, big_buffer, buflen, 184f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 185f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 186f08c3bdfSopenharmony_ci#if 0 187f08c3bdfSopenharmony_ci associd2 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id; 188f08c3bdfSopenharmony_ci#endif 189f08c3bdfSopenharmony_ci test_check_buf_notification(big_buffer, error, msg_flags, 190f08c3bdfSopenharmony_ci sizeof(struct sctp_assoc_change), 191f08c3bdfSopenharmony_ci SCTP_ASSOC_CHANGE, SCTP_COMM_UP); 192f08c3bdfSopenharmony_ci 193f08c3bdfSopenharmony_ci 194f08c3bdfSopenharmony_ci /* restore the rcvbuffer size for the receiving socket */ 195f08c3bdfSopenharmony_ci error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &oldlen, 196f08c3bdfSopenharmony_ci sizeof(oldlen)); 197f08c3bdfSopenharmony_ci 198f08c3bdfSopenharmony_ci if (error) 199f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "setsockopt(SO_RCVBUF): %s", 200f08c3bdfSopenharmony_ci strerror(errno)); 201f08c3bdfSopenharmony_ci 202f08c3bdfSopenharmony_ci /* Get the communication up message on sk1. */ 203f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 204f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 205f08c3bdfSopenharmony_ci msg_flags = 0; 206f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk1, big_buffer, buflen, 207f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 208f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 209f08c3bdfSopenharmony_ci associd1 = ((struct sctp_assoc_change *)big_buffer)->sac_assoc_id; 210f08c3bdfSopenharmony_ci test_check_buf_notification(big_buffer, error, msg_flags, 211f08c3bdfSopenharmony_ci sizeof(struct sctp_assoc_change), 212f08c3bdfSopenharmony_ci SCTP_ASSOC_CHANGE, SCTP_COMM_UP); 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_recvmsg SCTP_COMM_UP notification"); 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci /* Get the first message which was sent. */ 217f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 218f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 219f08c3bdfSopenharmony_ci msg_flags = 0; 220f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk2, big_buffer, buflen, 221f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 222f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 223f08c3bdfSopenharmony_ci test_check_buf_data(big_buffer, error, msg_flags, &sinfo, 224f08c3bdfSopenharmony_ci strlen(message) + 1, MSG_EOR, stream, ppid); 225f08c3bdfSopenharmony_ci 226f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_recvmsg data"); 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci /* Figure out how big to make our fillmsg */ 229f08c3bdfSopenharmony_ci len = sizeof(struct sctp_status); 230f08c3bdfSopenharmony_ci memset(&gstatus,0,sizeof(struct sctp_status)); 231f08c3bdfSopenharmony_ci gstatus.sstat_assoc_id = associd1; 232f08c3bdfSopenharmony_ci error = getsockopt(sk1, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len); 233f08c3bdfSopenharmony_ci 234f08c3bdfSopenharmony_ci if (error) 235f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "can't get rwnd size: %s", 236f08c3bdfSopenharmony_ci strerror(errno)); 237f08c3bdfSopenharmony_ci tst_resm(TINFO, "creating a fillmsg of size %d", 238f08c3bdfSopenharmony_ci gstatus.sstat_rwnd+RWND_SLOP); 239f08c3bdfSopenharmony_ci fillmsg = malloc(gstatus.sstat_rwnd+RWND_SLOP); 240f08c3bdfSopenharmony_ci 241f08c3bdfSopenharmony_ci /* Send a fillmsg */ 242f08c3bdfSopenharmony_ci memset(fillmsg, 'X', gstatus.sstat_rwnd+RWND_SLOP); 243f08c3bdfSopenharmony_ci fillmsg[gstatus.sstat_rwnd+RWND_SLOP-1] = '\0'; 244f08c3bdfSopenharmony_ci ppid++; 245f08c3bdfSopenharmony_ci stream++; 246f08c3bdfSopenharmony_ci test_sctp_sendmsg(sk1, fillmsg, gstatus.sstat_rwnd+RWND_SLOP, 247f08c3bdfSopenharmony_ci (struct sockaddr *)&loop2, sizeof(loop2), 248f08c3bdfSopenharmony_ci ppid, 0, stream, 0, 0); 249f08c3bdfSopenharmony_ci 250f08c3bdfSopenharmony_ci /* Now send a message that will timeout. */ 251f08c3bdfSopenharmony_ci test_sctp_sendmsg(sk1, ttlmsg, strlen(ttlmsg) + 1, 252f08c3bdfSopenharmony_ci (struct sockaddr *)&loop2, sizeof(loop2), 253f08c3bdfSopenharmony_ci ppid, 0, stream, 2000, 0); 254f08c3bdfSopenharmony_ci 255f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_sendmsg with ttl"); 256f08c3bdfSopenharmony_ci 257f08c3bdfSopenharmony_ci /* Next send a message that won't time out. */ 258f08c3bdfSopenharmony_ci test_sctp_sendmsg(sk1, nottlmsg, strlen(nottlmsg) + 1, 259f08c3bdfSopenharmony_ci (struct sockaddr *)&loop2, sizeof(loop2), 260f08c3bdfSopenharmony_ci ppid, 0, stream, 0, 0); 261f08c3bdfSopenharmony_ci 262f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_sendmsg with zero ttl"); 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci /* And finally a fragmented message that will time out. */ 265f08c3bdfSopenharmony_ci memset(ttlfrag, '0', sizeof(ttlfrag)); 266f08c3bdfSopenharmony_ci ttlfrag[sizeof(ttlfrag)-1] = '\0'; 267f08c3bdfSopenharmony_ci test_sctp_sendmsg(sk1, ttlfrag, sizeof(ttlfrag), 268f08c3bdfSopenharmony_ci (struct sockaddr *)&loop2, sizeof(loop2), 269f08c3bdfSopenharmony_ci ppid, 0, stream, 2000, 0); 270f08c3bdfSopenharmony_ci 271f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_sendmsg fragmented msg with ttl"); 272f08c3bdfSopenharmony_ci 273f08c3bdfSopenharmony_ci /* Sleep waiting for the message to time out. */ 274f08c3bdfSopenharmony_ci tst_resm(TINFO, "** SLEEPING for 3 seconds **"); 275f08c3bdfSopenharmony_ci sleep(3); 276f08c3bdfSopenharmony_ci 277f08c3bdfSopenharmony_ci /* Get the fillmsg. */ 278f08c3bdfSopenharmony_ci do { 279f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 280f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 281f08c3bdfSopenharmony_ci msg_flags = 0; 282f08c3bdfSopenharmony_ci test_sctp_recvmsg(sk2, big_buffer, buflen, 283f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 284f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 285f08c3bdfSopenharmony_ci } while (!(msg_flags & MSG_EOR)); 286f08c3bdfSopenharmony_ci 287f08c3bdfSopenharmony_ci /* Get the message that did NOT time out. */ 288f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 289f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 290f08c3bdfSopenharmony_ci msg_flags = 0; 291f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk2, big_buffer, buflen, 292f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 293f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 294f08c3bdfSopenharmony_ci test_check_buf_data(big_buffer, error, msg_flags, &sinfo, 295f08c3bdfSopenharmony_ci strlen(nottlmsg) + 1, MSG_EOR, stream, ppid); 296f08c3bdfSopenharmony_ci if (0 != strncmp(big_buffer, nottlmsg, strlen(nottlmsg))) 297f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "sctp_recvmsg: Wrong Message !!!"); 298f08c3bdfSopenharmony_ci 299f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_recvmsg msg with zero ttl"); 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci /* Get the SEND_FAILED notification for the message that DID 302f08c3bdfSopenharmony_ci * time out. 303f08c3bdfSopenharmony_ci */ 304f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 305f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 306f08c3bdfSopenharmony_ci msg_flags = 0; 307f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk1, big_buffer, buflen, 308f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 309f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 310f08c3bdfSopenharmony_ci test_check_buf_notification(big_buffer, error, msg_flags, 311f08c3bdfSopenharmony_ci sizeof(struct sctp_send_failed) + 312f08c3bdfSopenharmony_ci strlen(ttlmsg) + 1, 313f08c3bdfSopenharmony_ci SCTP_SEND_FAILED, 0); 314f08c3bdfSopenharmony_ci ssf = (struct sctp_send_failed *)big_buffer; 315f08c3bdfSopenharmony_ci if (0 != strncmp(ttlmsg, (char *)ssf->ssf_data, strlen(ttlmsg) + 1)) 316f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch"); 317f08c3bdfSopenharmony_ci 318f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for message with ttl"); 319f08c3bdfSopenharmony_ci 320f08c3bdfSopenharmony_ci offset = 0; 321f08c3bdfSopenharmony_ci 322f08c3bdfSopenharmony_ci /* Get the SEND_FAILED notifications for the fragmented message that 323f08c3bdfSopenharmony_ci * timed out. 324f08c3bdfSopenharmony_ci */ 325f08c3bdfSopenharmony_ci do { 326f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 327f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 328f08c3bdfSopenharmony_ci msg_flags = 0; 329f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk1, big_buffer, buflen, 330f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 331f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 332f08c3bdfSopenharmony_ci test_check_buf_notification(big_buffer, error, msg_flags, 333f08c3bdfSopenharmony_ci sizeof(struct sctp_send_failed) + 334f08c3bdfSopenharmony_ci SMALL_MAXSEG, 335f08c3bdfSopenharmony_ci SCTP_SEND_FAILED, 0); 336f08c3bdfSopenharmony_ci ssf = (struct sctp_send_failed *)big_buffer; 337f08c3bdfSopenharmony_ci if (0 != strncmp(&ttlfrag[offset], (char *)ssf->ssf_data, 338f08c3bdfSopenharmony_ci SMALL_MAXSEG)) 339f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "SEND_FAILED data mismatch"); 340f08c3bdfSopenharmony_ci offset += SMALL_MAXSEG; 341f08c3bdfSopenharmony_ci } while (!(ssf->ssf_info.sinfo_flags & 0x01)); /* LAST FRAG */ 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_recvmsg SEND_FAILED for fragmented message with " 344f08c3bdfSopenharmony_ci "ttl"); 345f08c3bdfSopenharmony_ci 346f08c3bdfSopenharmony_ci snd_sinfo.sinfo_ppid = rand(); 347f08c3bdfSopenharmony_ci snd_sinfo.sinfo_flags = 0; 348f08c3bdfSopenharmony_ci snd_sinfo.sinfo_stream = 2; 349f08c3bdfSopenharmony_ci snd_sinfo.sinfo_timetolive = 0; 350f08c3bdfSopenharmony_ci snd_sinfo.sinfo_assoc_id = associd1; 351f08c3bdfSopenharmony_ci test_sctp_send(sk1, message, strlen(message) + 1, &snd_sinfo, 352f08c3bdfSopenharmony_ci MSG_NOSIGNAL); 353f08c3bdfSopenharmony_ci 354f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 355f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 356f08c3bdfSopenharmony_ci msg_flags = 0; 357f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk2, big_buffer, buflen, 358f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 359f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 360f08c3bdfSopenharmony_ci test_check_buf_data(big_buffer, error, msg_flags, &sinfo, 361f08c3bdfSopenharmony_ci strlen(message) + 1, MSG_EOR, snd_sinfo.sinfo_stream, 362f08c3bdfSopenharmony_ci snd_sinfo.sinfo_ppid); 363f08c3bdfSopenharmony_ci 364f08c3bdfSopenharmony_ci tst_resm(TPASS, "sctp_send"); 365f08c3bdfSopenharmony_ci 366f08c3bdfSopenharmony_ci /* Shut down the link. */ 367f08c3bdfSopenharmony_ci close(sk1); 368f08c3bdfSopenharmony_ci 369f08c3bdfSopenharmony_ci /* Get the shutdown complete notification. */ 370f08c3bdfSopenharmony_ci buflen = REALLY_BIG; 371f08c3bdfSopenharmony_ci msgname_len = sizeof(msgname); 372f08c3bdfSopenharmony_ci msg_flags = 0; 373f08c3bdfSopenharmony_ci error = test_sctp_recvmsg(sk2, big_buffer, buflen, 374f08c3bdfSopenharmony_ci (struct sockaddr *)&msgname, &msgname_len, 375f08c3bdfSopenharmony_ci &sinfo, &msg_flags); 376f08c3bdfSopenharmony_ci test_check_buf_notification(big_buffer, error, msg_flags, 377f08c3bdfSopenharmony_ci sizeof(struct sctp_assoc_change), 378f08c3bdfSopenharmony_ci SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); 379f08c3bdfSopenharmony_ci 380f08c3bdfSopenharmony_ci close(sk2); 381f08c3bdfSopenharmony_ci 382f08c3bdfSopenharmony_ci /* Indicate successful completion. */ 383f08c3bdfSopenharmony_ci return 0; 384f08c3bdfSopenharmony_ci} 385