Ignore:
Timestamp:
2010-03-15T19:35:25Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6092b56e
Parents:
92307f1 (diff), 4684368 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from bzr://bzr.helenos.org/head.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/app/nettest1/nettest1.c

    r92307f1 r858fc90  
    4848#include "../../err.h"
    4949
     50#include "../nettest.h"
    5051#include "../parse.h"
    5152#include "../print_error.h"
     
    6566 *  @returns EOK on success.
    6667 */
    67 int             main( int argc, char * argv[] );
     68int main(int argc, char * argv[]);
    6869
    6970/** Prints the application help.
    7071 */
    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 );
     72void nettest1_print_help(void);
    8673
    8774/** Refreshes the data.
     
    9077 *  @param[in] size The data block size in bytes.
    9178 */
    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 ){
     79void nettest1_refresh_data(char * data, size_t size);
     80
     81int 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
     383void nettest1_print_help(void){
    176384        printf(
    177385                "Network Networking test 1 aplication - sockets\n" \
     
    201409}
    202410
    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;
     411void nettest1_refresh_data(char * data, size_t size){
     412        size_t length;
    223413
    224414        // fill the data
    225415        length = 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';
     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';
    232422}
    233423
    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;
    610 }
    611 
    612424/** @}
    613425 */
Note: See TracChangeset for help on using the changeset viewer.