Subversion Repositories HelenOS

Rev

Rev 4743 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2009 Lukas Mejdrech
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup echo
  30.  *  @{
  31.  */
  32.  
  33. /** @file
  34.  *  Networking test 1 application - UDP sockets.
  35.  */
  36.  
  37. #include <malloc.h>
  38. #include <stdio.h>
  39. #include <string.h>
  40. #include <task.h>
  41.  
  42. #include "../../include/in.h"
  43. #include "../../include/in6.h"
  44. #include "../../include/inet.h"
  45. #include "../../include/socket.h"
  46.  
  47. #include "../../err.h"
  48.  
  49. #include "../parse.h"
  50. #include "../print_error.h"
  51.  
  52. /** Echo module name.
  53.  */
  54. #define NAME    "Nettest1"
  55.  
  56. /** Packet data pattern.
  57.  */
  58. #define NETTEST1_TEXT   "Networking test 1 - UDP sockets"
  59.  
  60. /** Module entry point.
  61.  *  Starts testing.
  62.  *  @param argc The number of command line parameters. Input parameter.
  63.  *  @param argv The command line parameters. Input parameter.
  64.  *  @returns EOK on success.
  65.  */
  66. int     main( int argc, char * argv[] );
  67.  
  68. /** Prints the application help.
  69.  */
  70. void    print_help( void );
  71.  
  72. /** Translates the character string to the protocol family number.
  73.  *  @param name The protocol family name. Input parameter.
  74.  *  @returns The corresponding protocol family number.
  75.  *  @returns EPFNOSUPPORTED if the protocol family is not supported.
  76.  */
  77. int     parse_protocol_family( const char * name );
  78.  
  79. /** Translates the character string to the socket type number.
  80.  *  @param name The socket type name. Input parameter.
  81.  *  @returns The corresponding socket type number.
  82.  *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
  83.  */
  84. int     parse_socket_type( const char * name );
  85.  
  86. void    refresh_data( char * data, int size );
  87. int sockets_create( int verbose, int * socket_ids, int sockets, int family, sock_type_t type );
  88. int sockets_close( int verbose, int * socket_ids, int sockets );
  89. int sockets_bind( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen );
  90. int sockets_sendto( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages );
  91. int sockets_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages );
  92. int sockets_sendto_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages );
  93. void    print_mark( int index );
  94.  
  95. void print_help( void ){
  96.     printf(
  97.         "Network Networking test 1 aplication - UDP sockets\n" \
  98.         "Usage: echo [options] numeric_address\n" \
  99.         "Where options are:\n" \
  100.         "-f protocol_family | --family=protocol_family\n" \
  101.         "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
  102.         "\n" \
  103.         "-h | --help\n" \
  104.         "\tShow this application help.\n"
  105.         "\n" \
  106.         "-m count | --messages=count\n" \
  107.         "\tThe number of messages to send and receive per socket. The default is 100.\n" \
  108.         "\n" \
  109.         "-n sockets | --sockets=count\n" \
  110.         "\tThe number of sockets to use. The default is 100.\n" \
  111.         "\n" \
  112.         "-p port_number | --port=port_number\n" \
  113.         "\tThe port number the application should send messages to. The default is 7.\n" \
  114.         "\n" \
  115.         "-s packet_size | --size=packet_size\n" \
  116.         "\tThe packet data size the application sends. The default is 38 bytes.\n" \
  117.         "\n" \
  118.         "-v | --verbose\n" \
  119.         "\tShow all output messages.\n"
  120.     );
  121. }
  122.  
  123. int parse_protocol_family( const char * name ){
  124.     if( str_lcmp( name, "PF_INET", 7 ) == 0 ){
  125.         return PF_INET;
  126.     }else if( str_lcmp( name, "PF_INET6", 8 ) == 0 ){
  127.         return PF_INET6;
  128.     }
  129.     return EPFNOSUPPORT;
  130. }
  131.  
  132. int parse_socket_type( const char * name ){
  133.     if( str_lcmp( name, "SOCK_DGRAM", 11 ) == 0 ){
  134.         return SOCK_DGRAM;
  135.     }else if( str_lcmp( name, "SOCK_STREAM", 12 ) == 0 ){
  136.         return SOCK_STREAM;
  137.     }
  138.     return ESOCKTNOSUPPORT;
  139. }
  140.  
  141. void refresh_data( char * data, int size ){
  142.     int length;
  143.  
  144.     // fill the data
  145.     length = 0;
  146.     while( size > length + sizeof( NETTEST1_TEXT )){
  147.         memcpy( data + length, NETTEST1_TEXT, sizeof( NETTEST1_TEXT ));
  148.         length += sizeof( NETTEST1_TEXT );
  149.     }
  150.     memcpy( data + length, NETTEST1_TEXT, size - length );
  151. }
  152.  
  153. int sockets_create( int verbose, int * socket_ids, int sockets, int family, sock_type_t type ){
  154.     int index;
  155.  
  156.     if( verbose ) printf( "Create\t" );
  157.     fflush( stdout );
  158.     for( index = 0; index < sockets; ++ index ){
  159.         socket_ids[ index ] = socket( family, type, 0 );
  160.         if( socket_ids[ index ] < 0 ){
  161.             printf( "Socket %d (%d) error:\n", index, socket_ids[ index ] );
  162.             socket_print_error( stderr, socket_ids[ index ], "Socket create: ", "\n" );
  163.             return socket_ids[ index ];
  164.         }
  165.         if( verbose ) print_mark( index );
  166.     }
  167.     return EOK;
  168. }
  169.  
  170. int sockets_close( int verbose, int * socket_ids, int sockets ){
  171.     ERROR_DECLARE;
  172.  
  173.     int index;
  174.  
  175.     if( verbose ) printf( "\tClose\t" );
  176.     fflush( stdout );
  177.     for( index = 0; index < sockets; ++ index ){
  178.         if( ERROR_OCCURRED( closesocket( socket_ids[ index ] ))){
  179.             printf( "Socket %d (%d) error:\n", index, socket_ids[ index ] );
  180.             socket_print_error( stderr, ERROR_CODE, "Socket close: ", "\n" );
  181.             return ERROR_CODE;
  182.         }
  183.         if( verbose ) print_mark( index );
  184.     }
  185.     return EOK;
  186. }
  187.  
  188. int sockets_bind( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen ){
  189.     ERROR_DECLARE;
  190.  
  191.     int index;
  192.  
  193.     if( verbose ) printf( "\tBind\t" );
  194.     fflush( stdout );
  195.     for( index = 0; index < sockets; ++ index ){
  196.         if( ERROR_OCCURRED( bind( socket_ids[ index ], address, addrlen ))){
  197.             printf( "Socket %d (%d) error:\n", index, socket_ids[ index ] );
  198.             socket_print_error( stderr, ERROR_CODE, "Socket bind: ", "\n" );
  199.             return ERROR_CODE;
  200.         }
  201.         if( verbose ) print_mark( index );
  202.     }
  203.     return EOK;
  204. }
  205.  
  206. int sockets_sendto( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages ){
  207.     ERROR_DECLARE;
  208.  
  209.     int index;
  210.     int message;
  211.  
  212.     if( verbose ) printf( "\tSendto\t" );
  213.     fflush( stdout );
  214.     for( index = 0; index < sockets; ++ index ){
  215.         for( message = 0; message < messages; ++ message ){
  216.             if( ERROR_OCCURRED( sendto( socket_ids[ index ], data, size, 0, address, addrlen ))){
  217.                 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
  218.                 socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
  219.                 return ERROR_CODE;
  220.             }
  221.         }
  222.         if( verbose ) print_mark( index );
  223.     }
  224.     return EOK;
  225. }
  226.  
  227. int sockets_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ){
  228.     int value;
  229.     int index;
  230.     int message;
  231.  
  232.     if( verbose ) printf( "\tRecvfrom\t" );
  233.     fflush( stdout );
  234.     for( index = 0; index < sockets; ++ index ){
  235.         for( message = 0; message < messages; ++ message ){
  236.             value = recvfrom( socket_ids[ index ], data, size, 0, address, addrlen );
  237.             if( value < 0 ){
  238.                 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
  239.                 socket_print_error( stderr, value, "Socket receive: ", "\n" );
  240.                 return value;
  241.             }
  242.         }
  243.         if( verbose ) print_mark( index );
  244.     }
  245.     return EOK;
  246. }
  247.  
  248. int sockets_sendto_recvfrom( int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages ){
  249.     ERROR_DECLARE;
  250.  
  251.     int value;
  252.     int index;
  253.     int message;
  254.  
  255.     if( verbose ) printf( "\tSendto and recvfrom\t" );
  256.     fflush( stdout );
  257.     for( index = 0; index < sockets; ++ index ){
  258.         for( message = 0; message < messages; ++ message ){
  259.             if( ERROR_OCCURRED( sendto( socket_ids[ index ], data, size, 0, address, * addrlen ))){
  260.                 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
  261.                 socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
  262.                 return ERROR_CODE;
  263.             }
  264.             value = recvfrom( socket_ids[ index ], data, size, 0, address, addrlen );
  265.             if( value < 0 ){
  266.                 printf( "Socket %d (%d), message %d error:\n", index, socket_ids[ index ], message );
  267.                 socket_print_error( stderr, value, "Socket receive: ", "\n" );
  268.                 return value;
  269.             }
  270.         }
  271.         if( verbose ) print_mark( index );
  272.     }
  273.     return EOK;
  274. }
  275.  
  276. void print_mark( int index ){
  277.     if(( index + 1 ) % 10 ){
  278.         printf( "*" );
  279.     }else{
  280.         printf( "|" );
  281.     }
  282.     fflush( stdout );
  283. }
  284.  
  285. int main( int argc, char * argv[] ){
  286.     ERROR_DECLARE;
  287.  
  288.     size_t              size            = 38;
  289.     int                 verbose         = 0;
  290.     sock_type_t         type            = SOCK_DGRAM;
  291.     int                 sockets         = 10;
  292.     int                 messages        = 10;
  293.     int                 family          = PF_INET;
  294.     uint16_t            port            = 7;
  295.  
  296.     socklen_t           max_length      = sizeof( struct sockaddr_in6 );
  297.     uint8_t             address_data[ max_length ];
  298.     struct sockaddr *       address     = ( struct sockaddr * ) address_data;
  299.     struct sockaddr_in *    address_in      = ( struct sockaddr_in * ) address;
  300.     struct sockaddr_in6 *   address_in6 = ( struct sockaddr_in6 * ) address;
  301.     socklen_t           addrlen;
  302. //  char                address_string[ INET6_ADDRSTRLEN ];
  303.     uint8_t *           address_start;
  304.  
  305.     int *               socket_ids;
  306.     char *              data;
  307.     int                 value;
  308.     int                 index;
  309.  
  310.     printf( "Task %d - ", task_get_id());
  311.     printf( "%s\n", NAME );
  312.  
  313.     if( argc <= 1 ){
  314.         print_help();
  315.         return EINVAL;
  316.     }
  317.  
  318.     for( index = 1; ( index < argc - 1 ) || (( index == argc ) && ( argv[ index ][ 0 ] == '-' )); ++ index ){
  319.         if( argv[ index ][ 0 ] == '-' ){
  320.             switch( argv[ index ][ 1 ] ){
  321.                 case 'f':   ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 0, parse_protocol_family ));
  322.                             break;
  323.                 case 'h':   print_help();
  324.                             return EOK;
  325.                             break;
  326.                 case 'm':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & messages, "message count", 0 ));
  327.                             break;
  328.                 case 'n':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & sockets, "socket count", 0 ));
  329.                             break;
  330.                 case 'p':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 0 ));
  331.                             port = ( uint16_t ) value;
  332.                             break;
  333.                 case 's':   ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "packet size", 0 ));
  334.                             size = (value >= 0 ) ? ( size_t ) value : 0;
  335.                             break;
  336.                 case 't':   ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 0, parse_socket_type ));
  337.                             type = ( sock_type_t ) value;
  338.                             break;
  339.                 case 'v':   verbose = 1;
  340.                             break;
  341.                 case '-':   if( str_lcmp( argv[ index ] + 2, "family=", 7 ) == 0 ){
  342.                                 ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & family, "protocol family", 9, parse_protocol_family ));
  343.                             }else if( str_lcmp( argv[ index ] + 2, "help", 5 ) == 0 ){
  344.                                 print_help();
  345.                                 return EOK;
  346.                             }else if( str_lcmp( argv[ index ] + 2, "messages=", 6 ) == 0 ){
  347.                                 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & messages, "message count", 8 ));
  348.                             }else if( str_lcmp( argv[ index ] + 2, "sockets=", 6 ) == 0 ){
  349.                                 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & sockets, "socket count", 8 ));
  350.                             }else if( str_lcmp( argv[ index ] + 2, "port=", 5 ) == 0 ){
  351.                                 ERROR_PROPAGATE( parse_parameter_int( argc, argv, & index, & value, "port number", 7 ));
  352.                                 port = ( uint16_t ) value;
  353.                             }else if( str_lcmp( argv[ index ] + 2, "type=", 5 ) == 0 ){
  354.                                 ERROR_PROPAGATE( parse_parameter_name_int( argc, argv, & index, & value, "socket type", 7, parse_socket_type ));
  355.                                 type = ( sock_type_t ) value;
  356.                             }else if( str_lcmp( argv[ index ] + 2, "verbose", 8 ) == 0 ){
  357.                                 verbose = 1;
  358.                             }else{
  359.                                 print_unrecognized( index, argv[ index ] + 2 );
  360.                                 print_help();
  361.                                 return EINVAL;
  362.                             }
  363.                             break;
  364.                 default:
  365.                     print_unrecognized( index, argv[ index ] + 1 );
  366.                     print_help();
  367.                     return EINVAL;
  368.             }
  369.         }else{
  370.             print_unrecognized( index, argv[ index ] );
  371.             print_help();
  372.             return EINVAL;
  373.         }
  374.     }
  375.  
  376.     bzero( address_data, max_length );
  377.     switch( family ){
  378.         case PF_INET:
  379.             address_in->sin_family = AF_INET;
  380.             address_in->sin_port = htons( port );
  381.             address_start = ( uint8_t * ) & address_in->sin_addr.s_addr;
  382.             addrlen = sizeof( struct sockaddr_in );
  383.             break;
  384.         case PF_INET6:
  385.             address_in6->sin6_family = AF_INET6;
  386.             address_in6->sin6_port = htons( port );
  387.             address_start = ( uint8_t * ) & address_in6->sin6_addr.s6_addr;
  388.             addrlen = sizeof( struct sockaddr_in6 );
  389.             break;
  390.         default:
  391.             fprintf( stderr, "Address family is not supported\n" );
  392.             return EAFNOSUPPORT;
  393.     }
  394.  
  395.     if( ERROR_OCCURRED( inet_pton( family, argv[ argc - 1 ], address_start ))){
  396.         fprintf( stderr, "Address parse error %d\n", ERROR_CODE );
  397.         return ERROR_CODE;
  398.     }
  399.  
  400.     if( size <= 0 ){
  401.         fprintf( stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size );
  402.         size = 1024;
  403.     }
  404.     // size plus terminating null (\0)
  405.     data = ( char * ) malloc( size + 1 );
  406.     if( ! data ){
  407.         fprintf( stderr, "Failed to allocate data buffer.\n" );
  408.         return ENOMEM;
  409.     }
  410.     refresh_data( data, size );
  411.  
  412.     if( sockets <= 0 ){
  413.         fprintf( stderr, "Socket count too small (%d). Using 2 instead.\n", sockets );
  414.         sockets = 2;
  415.     }
  416.     // count plus terminating null (\0)
  417.     socket_ids = ( int * ) malloc( sizeof( int ) * ( sockets + 1 ));
  418.     if( ! socket_ids ){
  419.         fprintf( stderr, "Failed to allocate receive buffer.\n" );
  420.         return ENOMEM;
  421.     }
  422.     socket_ids[ sockets ] = NULL;
  423.  
  424.     if( verbose ) printf( "Starting tests\n" );
  425.  
  426.     if( verbose ) printf( "1 socket, 1 message\n" );
  427.  
  428.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type ));
  429.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 ));
  430.     if( verbose ) printf( "\tOK\n" );
  431.  
  432.     if( type == SOCK_DGRAM ){
  433. /*  ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1 ));
  434.     ERROR_PROPAGATE( sockets_bind( verbose, socket_ids, 1, address, addrlen ));
  435.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 ));
  436. */
  437.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type ));
  438. /*  if( type == SOCK_STREAM ){
  439.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, & addrlen ));
  440.     }
  441. */  ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, 1 ));
  442.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 ));
  443.     if( verbose ) printf( "\tOK\n" );
  444.  
  445.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type ));
  446. /*  if( type == SOCK_STREAM ){
  447.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, & addrlen ));
  448.     }
  449. */  ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, 1, address, addrlen, data, size, 1 ));
  450.     ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, 1 ));
  451.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 ));
  452.     if( verbose ) printf( "\tOK\n" );
  453.  
  454.     if( verbose ) printf( "1 socket, %d messages\n", messages );
  455.  
  456.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type ));
  457. /*  if( type == SOCK_STREAM ){
  458.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, & addrlen ));
  459.     }
  460. */  ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, messages ));
  461.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 ));
  462.     if( verbose ) printf( "\tOK\n" );
  463.  
  464.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, 1, family, type ));
  465. /*  if( type == SOCK_STREAM ){
  466.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, 1, address, & addrlen ));
  467.     }
  468. */  ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, 1, address, addrlen, data, size, messages ));
  469.     ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, 1, address, & addrlen, data, size, messages ));
  470.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, 1 ));
  471.     if( verbose ) printf( "\tOK\n" );
  472.  
  473.     if( verbose ) printf( "%d sockets, 1 message\n", sockets );
  474.  
  475.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type ));
  476.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets ));
  477.     if( verbose ) printf( "\tOK\n" );
  478.  
  479. /*  ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets ));
  480.     ERROR_PROPAGATE( sockets_bind( verbose, socket_ids, sockets, address, addrlen ));
  481.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets ));
  482. */
  483.  
  484.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type ));
  485. /*  if( type == SOCK_STREAM ){
  486.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, & addrlen ));
  487.     }
  488. */  ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, 1 ));
  489.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets ));
  490.     if( verbose ) printf( "\tOK\n" );
  491.  
  492.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type ));
  493. /*  if( type == SOCK_STREAM ){
  494.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, & addrlen ));
  495.     }
  496. */  ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, sockets, address, addrlen, data, size, 1 ));
  497.     ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, 1 ));
  498.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets ));
  499.     if( verbose ) printf( "\tOK\n" );
  500.  
  501.     if( verbose ) printf( "%d sockets, %d messages\n", sockets, messages );
  502.  
  503.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type ));
  504. /*  if( type == SOCK_STREAM ){
  505.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, & addrlen ));
  506.     }
  507. */  ERROR_PROPAGATE( sockets_sendto_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, messages ));
  508.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets ));
  509.     if( verbose ) printf( "\tOK\n" );
  510.  
  511.     ERROR_PROPAGATE( sockets_create( verbose, socket_ids, sockets, family, type ));
  512. /*  if( type == SOCK_STREAM ){
  513.         ERROR_PROPAGATE( sockets_connect( verbose, socket_ids, sockets, address, & addrlen ));
  514.     }
  515. */  ERROR_PROPAGATE( sockets_sendto( verbose, socket_ids, sockets, address, addrlen, data, size, messages ));
  516.     ERROR_PROPAGATE( sockets_recvfrom( verbose, socket_ids, sockets, address, & addrlen, data, size, messages ));
  517.     ERROR_PROPAGATE( sockets_close( verbose, socket_ids, sockets ));
  518.     if( verbose ) printf( "\tOK\n" );
  519.     }
  520. /*
  521.     if( type == SOCK_STREAM ){
  522.         // TODO remove tests
  523.         address_in->sin_addr.s_addr = 0x3f26b75a;
  524.         address_in->sin_port = htons( 80 );
  525.         if( ERROR_OCCURRED( connect( listening_id, address, sizeof( struct sockaddr_in )))){
  526.             socket_print_error( stderr, ERROR_CODE, "Socket connect: ", "\n" );
  527.             return ERROR_CODE;
  528.         }
  529.         if( ERROR_OCCURRED( send( listening_id, "ahoj nekdo", 10, 0 ))){
  530.             socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
  531.             return ERROR_CODE;
  532.         }
  533.         value = recv( socket_id, data, size, 0 );
  534.         fprintf( stderr, "Socket receive: %d\n", value );
  535.         if( ERROR_OCCURRED( send( listening_id, "ahoj nekdo", 10, 0 ))){
  536.             socket_print_error( stderr, ERROR_CODE, "Socket send: ", "\n" );
  537.             return ERROR_CODE;
  538.         }
  539.         value = recvfrom( socket_id, data, size, 0, address, & addrlen );
  540.         fprintf( stderr, "Socket receive: %d\n", value );
  541.  
  542.         if( ERROR_OCCURRED( closesocket( listening_id ))){
  543.             socket_print_error( stderr, ERROR_CODE, "Close socket: ", "\n" );
  544.             return ERROR_CODE;
  545.         }
  546.         listening_id = socket( family, type, 0 );
  547.         if( listening_id < 0 ){
  548.             socket_print_error( stderr, listening_id, "Socket create: ", "\n" );
  549.             return listening_id;
  550.         }
  551.  
  552.         if( ERROR_OCCURRED( listen( listening_id, 3 ))){
  553.             socket_print_error( stderr, ERROR_CODE, "Socket listen: ", "\n" );
  554.             return ERROR_CODE;
  555.         }
  556.     }else{
  557.         socket_id = listening_id;
  558.     }
  559.     if( ERROR_OCCURRED( bind( listening_id, address, addrlen ))){
  560.         socket_print_error( stderr, ERROR_CODE, "Socket bind: ", "\n" );
  561.         return ERROR_CODE;
  562.     }
  563. */
  564.     if( verbose ) printf( "Exiting\n" );
  565.  
  566.     return EOK;
  567. }
  568.  
  569. /** @}
  570.  */
  571.