1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <netinet/ip.h> 17#include <stdio.h> 18#include <stdlib.h> 19#include <string.h> 20#include <time.h> 21#include <sys/socket.h> 22#include <bits/alltypes.h> 23#include <unistd.h> 24#include "test.h" 25 26const int SLEEP_TIME = 2; 27 28void sendsss(void) 29{ 30 int sockfd; 31 struct sockaddr_in addr; 32 struct mmsghdr msg[2]; 33 struct iovec msg1[2], msg2; 34 int retval; 35 36 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 37 if (sockfd == -1) { 38 t_error("recvmmsg_0100 socket error"); 39 exit(EXIT_FAILURE); 40 } 41 42 addr.sin_family = AF_INET; 43 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 44 addr.sin_port = htons(1234); 45 if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 46 t_error("recvmmsg_0100 connect error"); 47 exit(EXIT_FAILURE); 48 } 49 50 memset(msg1, 0, sizeof(msg1)); 51 msg1[0].iov_base = "one"; 52 msg1[0].iov_len = 3; 53 msg1[1].iov_base = "two"; 54 msg1[1].iov_len = 3; 55 56 memset(&msg2, 0, sizeof(msg2)); 57 msg2.iov_base = "three"; 58 msg2.iov_len = 5; 59 60 memset(msg, 0, sizeof(msg)); 61 msg[0].msg_hdr.msg_iov = msg1; 62 msg[0].msg_hdr.msg_iovlen = 2; 63 64 msg[1].msg_hdr.msg_iov = &msg2; 65 msg[1].msg_hdr.msg_iovlen = 1; 66 67 retval = sendmmsg(sockfd, msg, 2, 0); 68 if (retval == -1) 69 t_error("recvmmsg_0100 sendmmsg error"); 70} 71 72void recvsss(void) 73{ 74#define VLEN 10 75#define BUFSIZE 200 76#define TIMEOUT 1 77 int sockfd, retval; 78 struct sockaddr_in addr; 79 struct mmsghdr msgs[VLEN]; 80 struct iovec iovecs[VLEN]; 81 char bufs[VLEN][BUFSIZE + 1]; 82 struct timespec timeout; 83 84 sockfd = socket(AF_INET, SOCK_DGRAM, 0); 85 if (sockfd == -1) { 86 t_error("recvmmsg_0100 recv socket error"); 87 exit(EXIT_FAILURE); 88 } 89 90 addr.sin_family = AF_INET; 91 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 92 addr.sin_port = htons(1234); 93 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 94 t_error("recvmmsg_0100 recv bind error"); 95 exit(EXIT_FAILURE); 96 } 97 98 memset(msgs, 0, sizeof(msgs)); 99 for (int i = 0; i < VLEN; i++) { 100 iovecs[i].iov_base = bufs[i]; 101 iovecs[i].iov_len = BUFSIZE; 102 msgs[i].msg_hdr.msg_iov = &iovecs[i]; 103 msgs[i].msg_hdr.msg_iovlen = 1; 104 } 105 106 timeout.tv_sec = TIMEOUT; 107 timeout.tv_nsec = 0; 108 109 retval = recvmmsg(sockfd, msgs, VLEN, 0, &timeout); 110 if (retval == -1) { 111 t_error("recvmmsg_0100 recv recvmmsg error"); 112 exit(EXIT_FAILURE); 113 } 114} 115 116/** 117 * @tc.name : recvmmsg_0100 118 * @tc.desc : Test recvmmsg to recv messages through socket 119 * @tc.level : Level 0 120 */ 121int main(int argc, char *argv[]) 122{ 123 pid_t pid = fork(); 124 if (pid > 0) { 125 recvsss(); 126 } else if (pid == 0) { 127 sleep(SLEEP_TIME); 128 sendsss(); 129 } else { 130 t_error("recvmmsg_0100 fork error"); 131 } 132 return t_status; 133}