Ignore:
File:
1 edited

Legend:

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

    raadf01e r3be62bc  
    5555#define NAME    "Echo"
    5656
     57/** Prints the application help.
     58 */
     59void echo_print_help(void);
     60
    5761/** Module entry point.
    5862 *  Reads command line parameters and starts listenning.
     
    6266 */
    6367int main(int argc, char * argv[]);
    64 
    65 /** Prints the application help.
    66  */
    67 void echo_print_help(void);
    68 
    69 /** Translates the character string to the protocol family number.
    70  *  @param[in] name The protocol family name.
    71  *  @returns The corresponding protocol family number.
    72  *  @returns EPFNOSUPPORTED if the protocol family is not supported.
    73  */
    74 int echo_parse_protocol_family(const char * name);
    75 
    76 /** Translates the character string to the socket type number.
    77  *  @param[in] name The socket type name.
    78  *  @returns The corresponding socket type number.
    79  *  @returns ESOCKNOSUPPORTED if the socket type is not supported.
    80  */
    81 int echo_parse_socket_type(const char * name);
    8268
    8369void echo_print_help(void){
     
    115101}
    116102
    117 int echo_parse_protocol_family(const char * name){
    118         if(str_lcmp(name, "PF_INET", 7) == 0){
    119                 return PF_INET;
    120         }else if(str_lcmp(name, "PF_INET6", 8) == 0){
    121                 return PF_INET6;
    122         }
    123         return EPFNOSUPPORT;
    124 }
    125 
    126 int echo_parse_socket_type(const char * name){
    127         if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){
    128                 return SOCK_DGRAM;
    129         }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){
    130                 return SOCK_STREAM;
    131         }
    132         return ESOCKTNOSUPPORT;
    133 }
    134 
    135103int main(int argc, char * argv[]){
    136104        ERROR_DECLARE;
     
    138106        size_t size                     = 1024;
    139107        int verbose                     = 0;
    140         char * reply                    = NULL;
    141         sock_type_t type                        = SOCK_DGRAM;
     108        char * reply            = NULL;
     109        sock_type_t type        = SOCK_DGRAM;
    142110        int count                       = -1;
    143111        int family                      = PF_INET;
    144         uint16_t port                   = 7;
     112        uint16_t port           = 7;
    145113        int backlog                     = 3;
    146114
    147         socklen_t max_length            = sizeof(struct sockaddr_in6);
     115        socklen_t max_length                            = sizeof(struct sockaddr_in6);
    148116        uint8_t address_data[max_length];
    149         struct sockaddr * address               = (struct sockaddr *) address_data;
     117        struct sockaddr * address                       = (struct sockaddr *) address_data;
    150118        struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    151119        struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     
    155123        int socket_id;
    156124        int listening_id;
    157         char *                          data;
     125        char * data;
    158126        size_t length;
    159127        int index;
     
    161129        int value;
    162130
     131        // print the program label
    163132        printf("Task %d - ", task_get_id());
    164133        printf("%s\n", NAME);
    165134
     135        // parse the command line arguments
    166136        for(index = 1; index < argc; ++ index){
    167137                if(argv[index][0] == '-'){
     
    174144                                        break;
    175145                                case 'f':
    176                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, echo_parse_protocol_family));
     146                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family));
    177147                                        break;
    178148                                case 'h':
     
    192162                                        break;
    193163                                case 't':
    194                                         ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, echo_parse_socket_type));
     164                                        ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type));
    195165                                        type = (sock_type_t) value;
    196166                                        break;
     
    198168                                        verbose = 1;
    199169                                        break;
     170                                // long options with the double minus sign ('-')
    200171                                case '-':
    201172                                        if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
     
    204175                                                ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8));
    205176                                        }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    206                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, echo_parse_protocol_family));
     177                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family));
    207178                                        }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    208179                                                echo_print_help();
     
    217188                                                size = (value >= 0) ? (size_t) value : 0;
    218189                                        }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    219                                                 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, echo_parse_socket_type));
     190                                                ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type));
    220191                                                type = (sock_type_t) value;
    221192                                        }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
     
    239210        }
    240211
     212        // check the buffer size
    241213        if(size <= 0){
    242214                fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
    243215                size = 1024;
    244216        }
    245         // size plus terminating null (\0)
     217        // size plus the terminating null (\0)
    246218        data = (char *) malloc(size + 1);
    247219        if(! data){
     
    250222        }
    251223
     224        // set the reply size if set
    252225        reply_length = reply ? str_length(reply) : 0;
    253226
    254         listening_id = socket(family, type, 0);
    255         if(listening_id < 0){
    256                 socket_print_error(stderr, listening_id, "Socket create: ", "\n");
    257                 return listening_id;
    258         }
    259 
     227        // prepare the address buffer
    260228        bzero(address_data, max_length);
    261229        switch(family){
     
    275243        }
    276244
     245        // get a listening socket
    277246        listening_id = socket(family, type, 0);
    278247        if(listening_id < 0){
     
    281250        }
    282251
     252        // if the stream socket is used
    283253        if(type == SOCK_STREAM){
     254                // check the backlog
    284255                if(backlog <= 0){
    285256                        fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
    286257                        backlog = 3;
    287258                }
     259                // set the backlog
    288260                if(ERROR_OCCURRED(listen(listening_id, backlog))){
    289261                        socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
     
    292264        }
    293265
     266        // bind the listenning socket
    294267        if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
    295268                socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
     
    303276        socket_id = listening_id;
    304277
     278        // do count times
     279        // or indefinitely if set to a negative value
    305280        while(count){
     281
    306282                addrlen = max_length;
    307283                if(type == SOCK_STREAM){
     284                        // acceept a socket if the stream socket is used
    308285                        socket_id = accept(listening_id, address, &addrlen);
    309286                        if(socket_id <= 0){
     
    315292                        }
    316293                }
     294
     295                // if the datagram socket is used or the stream socked was accepted
    317296                if(socket_id > 0){
     297
     298                        // receive an echo request
    318299                        value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    319300                        if(value < 0){
     
    322303                                length = (size_t) value;
    323304                                if(verbose){
     305                                        // print the header
     306
     307                                        // get the source port and prepare the address buffer
    324308                                        address_start = NULL;
    325309                                        switch(address->sa_family){
     
    335319                                                        fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
    336320                                        }
     321                                        // parse the source address
    337322                                        if(address_start){
    338323                                                if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
     
    344329                                        }
    345330                                }
     331
     332                                // answer the request either with the static reply or the original data
    346333                                if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
    347334                                        socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    348335                                }
    349                         }
     336
     337                        }
     338
     339                        // close the accepted stream socket
    350340                        if(type == SOCK_STREAM){
    351341                                if(ERROR_OCCURRED(closesocket(socket_id))){
     
    353343                                }
    354344                        }
    355                 }
     345
     346                }
     347
     348                // decrease the count if positive
    356349                if(count > 0){
    357350                        -- count;
     
    366359        }
    367360
     361        // close the listenning socket
    368362        if(ERROR_OCCURRED(closesocket(listening_id))){
    369363                socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
Note: See TracChangeset for help on using the changeset viewer.