Subversion Repositories HelenOS

Rev

Rev 4743 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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