1// SPDX-License-Identifier: GPL-2.0 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6#include <unistd.h> 7#include <arpa/inet.h> 8 9int main(int argc, char *argv[]) 10{ 11 struct sockaddr_in saddr = {}, daddr = {}; 12 int sd, ret, len = sizeof(daddr); 13 struct timeval tv = {25, 0}; 14 char buf[] = "hello"; 15 16 if (argc != 6 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) { 17 printf("%s <server|client> <LOCAL_IP> <LOCAL_PORT> <REMOTE_IP> <REMOTE_PORT>\n", 18 argv[0]); 19 return -1; 20 } 21 22 sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); 23 if (sd < 0) { 24 printf("Failed to create sd\n"); 25 return -1; 26 } 27 28 saddr.sin_family = AF_INET; 29 saddr.sin_addr.s_addr = inet_addr(argv[2]); 30 saddr.sin_port = htons(atoi(argv[3])); 31 32 ret = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr)); 33 if (ret < 0) { 34 printf("Failed to bind to address\n"); 35 goto out; 36 } 37 38 ret = listen(sd, 5); 39 if (ret < 0) { 40 printf("Failed to listen on port\n"); 41 goto out; 42 } 43 44 daddr.sin_family = AF_INET; 45 daddr.sin_addr.s_addr = inet_addr(argv[4]); 46 daddr.sin_port = htons(atoi(argv[5])); 47 48 /* make test shorter than 25s */ 49 ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); 50 if (ret < 0) { 51 printf("Failed to setsockopt SO_RCVTIMEO\n"); 52 goto out; 53 } 54 55 if (!strcmp(argv[1], "server")) { 56 sleep(1); /* wait a bit for client's INIT */ 57 ret = connect(sd, (struct sockaddr *)&daddr, len); 58 if (ret < 0) { 59 printf("Failed to connect to peer\n"); 60 goto out; 61 } 62 ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); 63 if (ret < 0) { 64 printf("Failed to recv msg %d\n", ret); 65 goto out; 66 } 67 ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); 68 if (ret < 0) { 69 printf("Failed to send msg %d\n", ret); 70 goto out; 71 } 72 printf("Server: sent! %d\n", ret); 73 } 74 75 if (!strcmp(argv[1], "client")) { 76 usleep(300000); /* wait a bit for server's listening */ 77 ret = connect(sd, (struct sockaddr *)&daddr, len); 78 if (ret < 0) { 79 printf("Failed to connect to peer\n"); 80 goto out; 81 } 82 sleep(1); /* wait a bit for server's delayed INIT_ACK to reproduce the issue */ 83 ret = sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr *)&daddr, len); 84 if (ret < 0) { 85 printf("Failed to send msg %d\n", ret); 86 goto out; 87 } 88 ret = recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr *)&daddr, &len); 89 if (ret < 0) { 90 printf("Failed to recv msg %d\n", ret); 91 goto out; 92 } 93 printf("Client: rcvd! %d\n", ret); 94 } 95 ret = 0; 96out: 97 close(sd); 98 return ret; 99} 100