1 //
2 // Copyright (C) 2015 Aaron Ball <nullspoon@iohq.net>
3 //
4 // Cnetbench is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Cnetbench is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with cnetbench. If not, see <http://www.gnu.org/licenses/>.
16 //
17 #include "test.h"
18
19 #ifndef cnetbench_test
20 #define cnetbench_test
21
22 #define test_default_amount 64
23 #define test_default_streams 1
24
25 void new_test(t_test *test) {
26 test->amount = test_default_amount;
27 test->streams = test_default_streams;
28 }
29
30
31 //
32 // Performs a benchmark test on the specified destination/port, sending the
33 // specified amount of data.
34 //
35 // @param amount Megabytes to send
36 // @param dest Destination host to send data to
37 // @param port Destination port to send the data on
38 //
39 // @return int Succcess (0) or failure (1) of data send
40 //
41 int test_execute(t_test* test) {
42 int socket_desc;
43 // This is 1 megabyte
44 long size = 1048576;
45 char *message = calloc(size, 1);
46
47 // AF_INET: ipv4 (AF_INET6 would be ipv6)
48 // SOCK_STREAM: TCP
49 // 0: Protocol 0 (IP)
50 socket_desc = socket(AF_INET, SOCK_STREAM, 0);
51
52 if(socket_desc == -1) {
53 printf("Error creating socket\n");
54 return 1;
55 }
56
57 // Set socket values
58 struct sockaddr_in server;
59 server.sin_addr.s_addr = inet_addr(test->server);
60 server.sin_family = AF_INET;
61 server.sin_port = htons(test->port);
62
63 if(connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) {
64 printf("Connection error\n");
65 return -1;
66 }
67 printf("Connected\n");
68
69 // Send some data
70 long i = 0;
71 while(i < test->amount) {
72 if(send(socket_desc, message, size, 0) < 0) {
73 return -1;
74 }
75 i++;
76 }
77
78 free(message);
79 return 0;
80 }
81
82
83 //
84 // Forks sub-processes off stream_count times, to test bandwidth to the
85 // specified destination host/port, sending the specified amount of data.
86 //
87 // Note that start_times and exit_times are two arrays that will receive start
88 // and exit timestamps for each pid for timing purposes.
89 //
90 // @param amount Amount of data in megabytes to send
91 // @param stream_count Number of data streams to test concurrently
92 // @param dest Destination host to send data to
93 // @param port Destination port to send data over
94 // @param start_times Output array of timeval start time timestamps
95 // @param exit_times Output array of timeval exit time timestamps
96 //
97 // @return int Success (0) or failure(1)
98 //
99 //int spawn_tests(int amount,
100 // int stream_count,
101 // char* dest,
102 // int port,
103 // struct timeval *start_times,
104 // struct timeval *exit_times) {
105 int test_start_all(t_test *test_def,
106 struct timeval *start_times,
107 struct timeval *exit_times) {
108 pid_t pids[test_def->streams];
109
110 pid_t pid;
111 int i = 0;
112 while(i < test_def->streams) {
113 // Fork
114 pid = fork();
115
116 if(pid == 0) {
117 // Execute the test
118 printf("Fork %d starting\n", i);
119 test_execute(test_def);
120 exit(0);
121 } else if(pid > 0) {
122 // parent
123 pids[i] = pid;
124 // Set start time
125 gettimeofday(&start_times[i], NULL);
126 i++;
127 } else {
128 // failure
129 printf("%d: Failure\n", i);
130 return 1;
131 }
132 }
133
134 // Wait for all children to exit, and clock their exit time
135 time_pids(pids, test_def->streams, exit_times);
136
137 printf("Fin!\n");
138 return 0;
139 }
140
141 #endif
|