Changes in uspace/srv/net/app/nettest1/nettest1.c [3be62bc:9d28b9c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/app/nettest1/nettest1.c
r3be62bc r9d28b9c 48 48 #include "../../err.h" 49 49 50 #include "../nettest.h"51 50 #include "../parse.h" 52 51 #include "../print_error.h" … … 66 65 * @returns EOK on success. 67 66 */ 68 int main(int argc, char * argv[]);67 int main( int argc, char * argv[] ); 69 68 70 69 /** Prints the application help. 71 70 */ 72 void nettest1_print_help(void); 71 void print_help( void ); 72 73 /** Translates the character string to the protocol family number. 74 * @param[in] name The protocol family name. 75 * @returns The corresponding protocol family number. 76 * @returns EPFNOSUPPORTED if the protocol family is not supported. 77 */ 78 int parse_protocol_family( const char * name ); 79 80 /** Translates the character string to the socket type number. 81 * @param[in] name The socket type name. 82 * @returns The corresponding socket type number. 83 * @returns ESOCKNOSUPPORTED if the socket type is not supported. 84 */ 85 int parse_socket_type( const char * name ); 73 86 74 87 /** Refreshes the data. … … 77 90 * @param[in] size The data block size in bytes. 78 91 */ 79 void nettest1_refresh_data(char * data, size_t size); 80 81 int main(int argc, char * argv[]){ 82 ERROR_DECLARE; 83 84 size_t size = 27; 85 int verbose = 0; 86 sock_type_t type = SOCK_DGRAM; 87 int sockets = 10; 88 int messages = 10; 89 int family = PF_INET; 90 uint16_t port = 7; 91 92 socklen_t max_length = sizeof(struct sockaddr_in6); 93 uint8_t address_data[max_length]; 94 struct sockaddr * address = (struct sockaddr *) address_data; 95 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 96 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 97 socklen_t addrlen; 98 // char address_string[INET6_ADDRSTRLEN]; 99 uint8_t * address_start; 100 101 int * socket_ids; 102 char * data; 103 int value; 104 int index; 105 struct timeval time_before; 106 struct timeval time_after; 107 108 // print the program label 109 printf("Task %d - ", task_get_id()); 110 printf("%s\n", NAME); 111 112 // parse the command line arguments 113 // stop before the last argument if it does not start with the minus sign ('-') 114 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 115 // options should start with the minus sign ('-') 116 if(argv[index][0] == '-'){ 117 switch(argv[index][1]){ 118 // short options with only one letter 119 case 'f': 120 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family)); 121 break; 122 case 'h': 123 nettest1_print_help(); 124 return EOK; 125 break; 126 case 'm': 127 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 0)); 128 break; 129 case 'n': 130 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 0)); 131 break; 132 case 'p': 133 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 0)); 134 port = (uint16_t) value; 135 break; 136 case 's': 137 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "packet size", 0)); 138 size = (value >= 0) ? (size_t) value : 0; 139 break; 140 case 't': 141 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type)); 142 type = (sock_type_t) value; 143 break; 144 case 'v': 145 verbose = 1; 146 break; 147 // long options with the double minus sign ('-') 148 case '-': 149 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 150 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family)); 151 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 152 nettest1_print_help(); 153 return EOK; 154 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ 155 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &messages, "message count", 8)); 156 }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){ 157 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &sockets, "socket count", 8)); 158 }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){ 159 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &value, "port number", 7)); 160 port = (uint16_t) value; 161 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 162 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type)); 163 type = (sock_type_t) value; 164 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ 165 verbose = 1; 166 }else{ 167 print_unrecognized(index, argv[index] + 2); 168 nettest1_print_help(); 169 return EINVAL; 170 } 171 break; 172 default: 173 print_unrecognized(index, argv[index] + 1); 174 nettest1_print_help(); 175 return EINVAL; 176 } 177 }else{ 178 print_unrecognized(index, argv[index]); 179 nettest1_print_help(); 180 return EINVAL; 181 } 182 } 183 184 // if not before the last argument containing the address 185 if(index >= argc){ 186 printf("Command line error: missing address\n"); 187 nettest1_print_help(); 188 return EINVAL; 189 } 190 191 // prepare the address buffer 192 bzero(address_data, max_length); 193 switch(family){ 194 case PF_INET: 195 address_in->sin_family = AF_INET; 196 address_in->sin_port = htons(port); 197 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 198 addrlen = sizeof(struct sockaddr_in); 199 break; 200 case PF_INET6: 201 address_in6->sin6_family = AF_INET6; 202 address_in6->sin6_port = htons(port); 203 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 204 addrlen = sizeof(struct sockaddr_in6); 205 break; 206 default: 207 fprintf(stderr, "Address family is not supported\n"); 208 return EAFNOSUPPORT; 209 } 210 211 // parse the last argument which should contain the address 212 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 213 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); 214 return ERROR_CODE; 215 } 216 217 // check the buffer size 218 if(size <= 0){ 219 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 220 size = 1024; 221 } 222 223 // prepare the buffer 224 // size plus the terminating null (\0) 225 data = (char *) malloc(size + 1); 226 if(! data){ 227 fprintf(stderr, "Failed to allocate data buffer.\n"); 228 return ENOMEM; 229 } 230 nettest1_refresh_data(data, size); 231 232 // check the socket count 233 if(sockets <= 0){ 234 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 235 sockets = 2; 236 } 237 238 // prepare the socket buffer 239 // count plus the terminating null (\0) 240 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 241 if(! socket_ids){ 242 fprintf(stderr, "Failed to allocate receive buffer.\n"); 243 return ENOMEM; 244 } 245 socket_ids[sockets] = NULL; 246 247 if(verbose){ 248 printf("Starting tests\n"); 249 } 250 251 if(verbose){ 252 printf("1 socket, 1 message\n"); 253 } 254 255 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 256 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 257 return ERROR_CODE; 258 } 259 260 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 261 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 262 if(verbose){ 263 printf("\tOK\n"); 264 } 265 266 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 267 if(type == SOCK_STREAM){ 268 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 269 } 270 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1)); 271 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 272 if(verbose){ 273 printf("\tOK\n"); 274 } 275 276 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 277 if(type == SOCK_STREAM){ 278 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 279 } 280 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, 1)); 281 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1)); 282 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 283 if(verbose){ 284 printf("\tOK\n"); 285 } 286 287 if(verbose){ 288 printf("1 socket, %d messages\n", messages); 289 } 290 291 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 292 if(type == SOCK_STREAM){ 293 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 294 } 295 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages)); 296 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 297 if(verbose){ 298 printf("\tOK\n"); 299 } 300 301 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 302 if(type == SOCK_STREAM){ 303 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 304 } 305 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, messages)); 306 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages)); 307 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 308 if(verbose){ 309 printf("\tOK\n"); 310 } 311 312 if(verbose){ 313 printf("%d sockets, 1 message\n", sockets); 314 } 315 316 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 317 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 318 if(verbose){ 319 printf("\tOK\n"); 320 } 321 322 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 323 if(type == SOCK_STREAM){ 324 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 325 } 326 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1)); 327 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 328 if(verbose){ 329 printf("\tOK\n"); 330 } 331 332 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 333 if(type == SOCK_STREAM){ 334 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 335 } 336 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, 1)); 337 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1)); 338 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 339 if(verbose){ 340 printf("\tOK\n"); 341 } 342 343 if(verbose){ 344 printf("%d sockets, %d messages\n", sockets, messages); 345 } 346 347 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 348 if(type == SOCK_STREAM){ 349 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 350 } 351 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 352 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 353 if(verbose){ 354 printf("\tOK\n"); 355 } 356 357 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 358 if(type == SOCK_STREAM){ 359 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 360 } 361 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages)); 362 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 363 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 364 365 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 366 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 367 return ERROR_CODE; 368 } 369 370 if(verbose){ 371 printf("\tOK\n"); 372 } 373 374 printf("Tested in %d microseconds\n", tv_sub(&time_after, &time_before)); 375 376 if(verbose){ 377 printf("Exiting\n"); 378 } 379 380 return EOK; 381 } 382 383 void nettest1_print_help(void){ 92 void refresh_data( char * data, size_t size ); 93 94 /** Creates new sockets. 95 * @param[in] verbose A value indicating whether to print out verbose information. 96 * @param[out] socket_ids A field to store the socket identifiers. 97 * @param[in] sockets The number of sockets to create. Should be at most the size of the field. 98 * @param[in] family The socket address family. 99 * @param[in] type The socket type. 100 * @returns EOK on success. 101 * @returns Other error codes as defined for the socket() function. 102 */ 103 int sockets_create( int verbose, int * socket_ids, int sockets, int family, sock_type_t type ); 104 105 /** Closes sockets. 106 * @param[in] verbose A value indicating whether to print out verbose information. 107 * @param[in] socket_ids A field of stored socket identifiers. 108 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 109 * @returns EOK on success. 110 * @returns Other error codes as defined for the closesocket() function. 111 */ 112 int sockets_close( int verbose, int * socket_ids, int sockets ); 113 114 /** Connects sockets. 115 * @param[in] verbose A value indicating whether to print out verbose information. 116 * @param[in] socket_ids A field of stored socket identifiers. 117 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 118 * @param[in] address The destination host address to connect to. 119 * @param[in] addrlen The length of the destination address in bytes. 120 * @returns EOK on success. 121 * @returns Other error codes as defined for the connect() function. 122 */ 123 int sockets_connect( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen ); 124 125 /** Sends data via sockets. 126 * @param[in] verbose A value indicating whether to print out verbose information. 127 * @param[in] socket_ids A field of stored socket identifiers. 128 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 129 * @param[in] address The destination host address to send data to. 130 * @param[in] addrlen The length of the destination address in bytes. 131 * @param[in] data The data to be sent. 132 * @param[in] size The data size in bytes. 133 * @param[in] messages The number of datagrams per socket to be sent. 134 * @returns EOK on success. 135 * @returns Other error codes as defined for the sendto() function. 136 */ 137 int sockets_sendto( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages ); 138 139 /** Receives data via sockets. 140 * @param[in] verbose A value indicating whether to print out verbose information. 141 * @param[in] socket_ids A field of stored socket identifiers. 142 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 143 * @param[in] address The source host address of received datagrams. 144 * @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead. 145 * @param[out] data The received data. 146 * @param[in] size The maximum data size in bytes. 147 * @param[in] messages The number of datagrams per socket to be received. 148 * @returns EOK on success. 149 * @returns Other error codes as defined for the recvfrom() function. 150 */ 151 int sockets_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ); 152 153 /** Sends and receives data via sockets. 154 * Each datagram is sent and a reply read consequently. 155 * The next datagram is sent after the reply is received. 156 * @param[in] verbose A value indicating whether to print out verbose information. 157 * @param[in] socket_ids A field of stored socket identifiers. 158 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 159 * @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead. 160 * @param[in] addrlen The length of the destination address in bytes. 161 * @param[in,out] data The data to be sent. The received data are set instead. 162 * @param[in] size The data size in bytes. 163 * @param[in] messages The number of datagrams per socket to be received. 164 * @returns EOK on success. 165 * @returns Other error codes as defined for the recvfrom() function. 166 */ 167 int sockets_sendto_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ); 168 169 /** Prints a mark. 170 * If the index is a multiple of ten, a different mark is printed. 171 * @param[in] index The index of the mark to be printed. 172 */ 173 void print_mark( int index ); 174 175 void print_help( void ){ 384 176 printf( 385 177 "Network Networking test 1 aplication - sockets\n" \ … … 409 201 } 410 202 411 void nettest1_refresh_data(char * data, size_t size){ 412 size_t length; 203 int parse_protocol_family( const char * name ){ 204 if( str_lcmp( name, "PF_INET", 7 ) == 0 ){ 205 return PF_INET; 206 }else if( str_lcmp( name, "PF_INET6", 8 ) == 0 ){ 207 return PF_INET6; 208 } 209 return EPFNOSUPPORT; 210 } 211 212 int parse_socket_type( const char * name ){ 213 if( str_lcmp( name, "SOCK_DGRAM", 11 ) == 0 ){ 214 return SOCK_DGRAM; 215 }else if( str_lcmp( name, "SOCK_STREAM", 12 ) == 0 ){ 216 return SOCK_STREAM; 217 } 218 return ESOCKTNOSUPPORT; 219 } 220 221 void refresh_data( char * data, size_t size ){ 222 size_t length; 413 223 414 224 // fill the data 415 225 length = 0; 416 while(size > length + sizeof(NETTEST1_TEXT) - 1){ 417 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1); 418 length += sizeof(NETTEST1_TEXT) - 1; 419 } 420 memcpy(data + length, NETTEST1_TEXT, size - length); 421 data[size] = '\0'; 226 while( size > length + sizeof( NETTEST1_TEXT ) - 1 ){ 227 memcpy( data + length, NETTEST1_TEXT, sizeof( NETTEST1_TEXT ) - 1 ); 228 length += sizeof( NETTEST1_TEXT ) - 1; 229 } 230 memcpy( data + length, NETTEST1_TEXT, size - length ); 231 data[ size ] = '\0'; 232 } 233 234 int sockets_create( int verbose, int * socket_ids, int sockets, int family, sock_type_t type ){ 235 int index; 236 237 if( verbose ) printf( "Create\t" ); 238 fflush( stdout ); 239 for( index = 0; index < sockets; ++ index ){ 240 socket_ids[ index ] = socket( family, type, 0 ); 241 if( socket_ids[ index ] < 0 ){ 242 printf( "Socket %d (%d) error:\n", index, socket_ids[ index ] ); 243 socket_print_error( stderr, socket_ids[ index ], "Socket create: ", "\n" ); 244 return socket_ids[ index ]; 245 } 246 if( verbose ){ 247 print_mark( index ); 248 } 249 } 250 return EOK; 251 } 252 253 int sockets_close( int verbose, int * socket_ids, int sockets ){ 254 ERROR_DECLARE; 255 256 int index; 257 258 if( verbose ) printf( "\tClose\t" ); 259 fflush( stdout ); 260 for( index = 0; index < sockets; ++ index ){ 261 if( ERROR_OCCURRED( closesocket( socket_ids[ index ] ))){ 262 printf( "Socket %d (%d) error:\n", index, socket_ids[ index ] ); 263 socket_print_error( stderr, ERROR_CODE, "Socket close: ", "\n" ); 264 return ERROR_CODE; 265 } 266 if( verbose ) print_mark( index ); 267 } 268 return EOK; 269 } 270 271 int sockets_connect( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen ){ 272 ERROR_DECLARE; 273 274 int index; 275 276 if( verbose ) printf( "\tConnect\t" ); 277 fflush( stdout ); 278 for( index = 0; index < sockets; ++ index ){ 279 if( ERROR_OCCURRED( connect( socket_ids[ index ], address, addrlen ))){ 280 socket_print_error( stderr, ERROR_CODE, "Socket connect: ", "\n" ); 281 return ERROR_CODE; 282 } 283 if( verbose ) print_mark( index ); 284 } 285 return EOK; 286 } 287 288 int sockets_sendto( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages ){ 289 ERROR_DECLARE; 290 291 int index; 292 int message; 293 294 if( verbose ) printf( "\tSendto\t" ); 295 fflush( stdout ); 296 for( index = 0; index < sockets; ++ index ){ 297 for( message = 0; message < messages; ++ message ){ 298 if( ERROR_OCCURRED( sendto( socket_ids[ index ], data, size, 0, address, addrlen ))){ 299 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message ); 300 socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" ); 301 return ERROR_CODE; 302 } 303 } 304 if( verbose ) print_mark( index ); 305 } 306 return EOK; 307 } 308 309 int sockets_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ){ 310 int value; 311 int index; 312 int message; 313 314 if( verbose ) printf( "\tRecvfrom\t" ); 315 fflush( stdout ); 316 for( index = 0; index < sockets; ++ index ){ 317 for( message = 0; message < messages; ++ message ){ 318 value = recvfrom( socket_ids[ index ], data, size, 0, address, addrlen ); 319 if( value < 0 ){ 320 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message ); 321 socket_print_error( stderr, value, "Socket receive: ", "\n" ); 322 return value; 323 } 324 } 325 if( verbose ) print_mark( index ); 326 } 327 return EOK; 328 } 329 330 int sockets_sendto_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ){ 331 ERROR_DECLARE; 332 333 int value; 334 int index; 335 int message; 336 337 if( verbose ) printf( "\tSendto and recvfrom\t" ); 338 fflush( stdout ); 339 for( index = 0; index < sockets; ++ index ){ 340 for( message = 0; message < messages; ++ message ){ 341 if( ERROR_OCCURRED( sendto( socket_ids[ index ], data, size, 0, address, * addrlen ))){ 342 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message ); 343 socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" ); 344 return ERROR_CODE; 345 } 346 value = recvfrom( socket_ids[ index ], data, size, 0, address, addrlen ); 347 if( value < 0 ){ 348 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message ); 349 socket_print_error( stderr, value, "Socket receive: ", "\n" ); 350 return value; 351 } 352 } 353 if( verbose ) print_mark( index ); 354 } 355 return EOK; 356 } 357 358 void print_mark( int index ){ 359 if(( index + 1 ) % 10 ){ 360 printf( "*" ); 361 }else{ 362 printf( "|" ); 363 } 364 fflush( stdout ); 365 } 366 367 int main( int argc, char * argv[] ){ 368 ERROR_DECLARE; 369 370 size_t size = 27; 371 int verbose = 0; 372 sock_type_t type = SOCK_DGRAM; 373 int sockets = 10; 374 int messages = 10; 375 int family = PF_INET; 376 uint16_t port = 7; 377 378 socklen_t max_length = sizeof( struct sockaddr_in6 ); 379 uint8_t address_data[ max_length ]; 380 struct sockaddr * address = ( struct sockaddr * ) address_data; 381 struct sockaddr_in * address_in = ( struct sockaddr_in * ) address; 382 struct sockaddr_in6 * address_in6 = ( struct sockaddr_in6 * ) address; 383 socklen_t addrlen; 384 // char address_string[ INET6_ADDRSTRLEN ]; 385 uint8_t * address_start; 386 387 int * socket_ids; 388 char * data; 389 int value; 390 int index; 391 struct timeval time_before; 392 struct timeval time_after; 393 394 printf( "Task %d - ", task_get_id()); 395 printf( "%s\n", NAME ); 396 397 if( argc <= 1 ){ 398 print_help(); 399 return EINVAL; 400 } 401 402 for( index = 1; ( index < argc - 1 ) || (( index == argc ) && ( argv[ index ][ 0 ] == '-' )); ++ index ){ 403 if( argv[ index ][ 0 ] == '-' ){ 404 switch( argv[ index ][ 1 ] ){ 405 case 'f': ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 0, parse_protocol_family )); 406 break; 407 case 'h': print_help(); 408 return EOK; 409 break; 410 case 'm': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & messages, "message count", 0 )); 411 break; 412 case 'n': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & sockets, "socket count", 0 )); 413 break; 414 case 'p': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 0 )); 415 port = ( uint16_t ) value; 416 break; 417 case 's': ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 0 )); 418 size = (value >= 0 ) ? ( size_t ) value : 0; 419 break; 420 case 't': ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 0, parse_socket_type )); 421 type = ( sock_type_t ) value; 422 break; 423 case 'v': verbose = 1; 424 break; 425 case '-': if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){ 426 ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 9, parse_protocol_family )); 427 }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){ 428 print_help(); 429 return EOK; 430 }else if( str_lcmp( argv[ index ] + 2, "messages=", 6 ) == 0 ){ 431 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & messages, "message count", 8 )); 432 }else if( str_lcmp( argv[ index ] + 2, "sockets=", 6 ) == 0 ){ 433 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & sockets, "socket count", 8 )); 434 }else if( str_lcmp( argv[ index ] + 2, "port=", 5 ) == 0 ){ 435 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 7 )); 436 port = ( uint16_t ) value; 437 }else if( str_lcmp( argv[ index ] + 2, "type=", 5 ) == 0 ){ 438 ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 7, parse_socket_type )); 439 type = ( sock_type_t ) value; 440 }else if( str_lcmp( argv[ index ] + 2, "verbose", 8 ) == 0 ){ 441 verbose = 1; 442 }else{ 443 print_unrecognized( index, argv[ index ] + 2 ); 444 print_help(); 445 return EINVAL; 446 } 447 break; 448 default: 449 print_unrecognized( index, argv[ index ] + 1 ); 450 print_help(); 451 return EINVAL; 452 } 453 }else{ 454 print_unrecognized( index, argv[ index ] ); 455 print_help(); 456 return EINVAL; 457 } 458 } 459 460 bzero( address_data, max_length ); 461 switch( family ){ 462 case PF_INET: 463 address_in->sin_family = AF_INET; 464 address_in->sin_port = htons( port ); 465 address_start = ( uint8_t * ) & address_in->sin_addr.s_addr; 466 addrlen = sizeof( struct sockaddr_in ); 467 break; 468 case PF_INET6: 469 address_in6->sin6_family = AF_INET6; 470 address_in6->sin6_port = htons( port ); 471 address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr; 472 addrlen = sizeof( struct sockaddr_in6 ); 473 break; 474 default: 475 fprintf( stderr, "Address family is not supported\n" ); 476 return EAFNOSUPPORT; 477 } 478 479 if( ERROR_OCCURRED( inet_pton( family, argv[ argc - 1 ], address_start ))){ 480 fprintf( stderr, "Address parse error %d\n", ERROR_CODE ); 481 return ERROR_CODE; 482 } 483 484 if( size <= 0 ){ 485 fprintf( stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size ); 486 size = 1024; 487 } 488 // size plus terminating null (\0) 489 data = ( char * ) malloc( size + 1 ); 490 if( ! data ){ 491 fprintf( stderr, "Failed to allocate data buffer.\n" ); 492 return ENOMEM; 493 } 494 refresh_data( data, size ); 495 496 if( sockets <= 0 ){ 497 fprintf( stderr, "Socket count too small (%d). Using 2 instead.\n", sockets ); 498 sockets = 2; 499 } 500 // count plus terminating null (\0) 501 socket_ids = ( int * ) malloc( sizeof( int ) * ( sockets + 1 )); 502 if( ! socket_ids ){ 503 fprintf( stderr, "Failed to allocate receive buffer.\n" ); 504 return ENOMEM; 505 } 506 socket_ids[ sockets ] = NULL; 507 508 if( verbose ) printf( "Starting tests\n" ); 509 510 if( verbose ) printf( "1 socket, 1 message\n" ); 511 512 if( ERROR_OCCURRED( gettimeofday( & time_before, NULL ))){ 513 fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); 514 return ERROR_CODE; 515 } 516 517 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type )); 518 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 )); 519 if( verbose ) printf( "\tOK\n" ); 520 521 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type )); 522 if( type == SOCK_STREAM ){ 523 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, addrlen )); 524 } 525 ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, 1 )); 526 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 )); 527 if( verbose ) printf( "\tOK\n" ); 528 529 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type )); 530 if( type == SOCK_STREAM ){ 531 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, addrlen )); 532 } 533 ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, 1, address, addrlen, data, size, 1 )); 534 ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, 1 )); 535 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 )); 536 if( verbose ) printf( "\tOK\n" ); 537 538 if( verbose ) printf( "1 socket, %d messages\n", messages ); 539 540 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type )); 541 if( type == SOCK_STREAM ){ 542 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, addrlen )); 543 } 544 ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, messages )); 545 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 )); 546 if( verbose ) printf( "\tOK\n" ); 547 548 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type )); 549 if( type == SOCK_STREAM ){ 550 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, addrlen )); 551 } 552 ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, 1, address, addrlen, data, size, messages )); 553 ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, messages )); 554 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 )); 555 if( verbose ) printf( "\tOK\n" ); 556 557 if( verbose ) printf( "%d sockets, 1 message\n", sockets ); 558 559 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type )); 560 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets )); 561 if( verbose ) printf( "\tOK\n" ); 562 563 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type )); 564 if( type == SOCK_STREAM ){ 565 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, addrlen )); 566 } 567 ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, 1 )); 568 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets )); 569 if( verbose ) printf( "\tOK\n" ); 570 571 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type )); 572 if( type == SOCK_STREAM ){ 573 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, addrlen )); 574 } 575 ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, sockets, address, addrlen, data, size, 1 )); 576 ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, 1 )); 577 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets )); 578 if( verbose ) printf( "\tOK\n" ); 579 580 if( verbose ) printf( "%d sockets, %d messages\n", sockets, messages ); 581 582 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type )); 583 if( type == SOCK_STREAM ){ 584 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, addrlen )); 585 } 586 ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, messages )); 587 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets )); 588 if( verbose ) printf( "\tOK\n" ); 589 590 ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type )); 591 if( type == SOCK_STREAM ){ 592 ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, addrlen )); 593 } 594 ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, sockets, address, addrlen, data, size, messages )); 595 ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, messages )); 596 ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets )); 597 598 if( ERROR_OCCURRED( gettimeofday( & time_after, NULL ))){ 599 fprintf( stderr, "Get time of day error %d\n", ERROR_CODE ); 600 return ERROR_CODE; 601 } 602 603 if( verbose ) printf( "\tOK\n" ); 604 605 printf( "Tested in %d microseconds\n", tv_sub( & time_after, & time_before )); 606 607 if( verbose ) printf( "Exiting\n" ); 608 609 return EOK; 422 610 } 423 611
Note:
See TracChangeset
for help on using the changeset viewer.