Changeset ede63e4 in mainline


Ignore:
Timestamp:
2010-01-04T23:25:48Z (15 years ago)
Author:
Lukas Mejdrech <lukasmejdrech@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
eac9722
Parents:
1a0fb3f8
Message:
  • socket identifier generation moved to libsocket, + data fragment size fix and enhancement, + [ICMP|TCP|UDP]_HEADER_SIZE definition, + int_map_update() function to alter item key
Location:
uspace/srv/net
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/socket/socket_client.c

    r1a0fb3f8 rede63e4  
    4040#include <async.h>
    4141#include <fibril_synch.h>
     42#include <limits.h>
     43#include <stdlib.h>
    4244
    4345#include <ipc/services.h>
     
    7476 */
    7577#define SOCKET_CONNECT_TIMEOUT  ( 1 * 1000 * 1000 )
     78
     79/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
     80 */
     81#define SOCKET_ID_TRIES                                 100
    7682
    7783/** Type definition of the socket specific data.
     
    155161         */
    156162        int     udp_phone;
     163//      /** The last socket identifier.
     164//       */
     165//      int last_id;
    157166        /** Active sockets.
    158167         */
     
    168177        .tcp_phone = -1,
    169178        .udp_phone = -1,
     179//      .last_id = 0,
    170180        .sockets = NULL,
    171181        .lock = {
     
    199209 */
    200210static sockets_ref      socket_get_sockets( void );
     211
     212/** Tries to find a new free socket identifier.
     213 *      @returns The new socket identifier.
     214 *  @returns ELIMIT if there is no socket identifier available.
     215 */
     216static int      socket_generate_new_id( void );
    201217
    202218/** Default thread for new connections.
     
    288304                        socket_globals.sockets = NULL;
    289305                }
     306                srand( task_get_id());
    290307        }
    291308        return socket_globals.sockets;
     309}
     310
     311static int socket_generate_new_id( void ){
     312        sockets_ref     sockets;
     313        int                     socket_id;
     314        int                     count;
     315
     316        sockets = socket_get_sockets();
     317        count = 0;
     318//      socket_id = socket_globals.last_id;
     319        do{
     320                if( count < SOCKET_ID_TRIES ){
     321                        socket_id = rand() % INT_MAX;
     322                        ++ count;
     323                }else if( count == SOCKET_ID_TRIES ){
     324                        socket_id = 1;
     325                        ++ count;
     326                // only this branch for last_id
     327                }else{
     328                        if( socket_id < INT_MAX ){
     329                                ++ socket_id;
     330/*                      }else if( socket_globals.last_id ){
     331*                               socket_globals.last_id = 0;
     332*                               socket_id = 1;
     333*/                      }else{
     334                                return ELIMIT;
     335                        }
     336                }
     337        }while( sockets_find( sockets, socket_id ));
     338//      last_id = socket_id
     339        return socket_id;
    292340}
    293341
     
    311359        ipc_call_t              call;
    312360        socket_ref              socket;
    313         socket_ref              new_socket;
    314361
    315362        while( true ){
     
    318365                switch( IPC_GET_METHOD( call )){
    319366                        case NET_SOCKET_RECEIVED:
    320                                 fibril_rwlock_read_lock( & socket_globals.lock );
    321                                 // find the socket
    322                                 socket = sockets_find( socket_get_sockets(), SOCKET_GET_SOCKET_ID( call ));
    323                                 if( ! socket ){
    324                                         ERROR_CODE = ENOTSOCK;
    325                                 }else{
    326                                         fibril_mutex_lock( & socket->receive_lock );
    327                                         // push the number of received packet fragments
    328                                         if( ! ERROR_OCCURRED( dyn_fifo_push( & socket->received, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_MAX_RECEIVED_SIZE ))){
    329                                                 // signal the received packet
    330                                                 fibril_condvar_signal( & socket->receive_signal );
    331                                         }
    332                                         fibril_mutex_unlock( & socket->receive_lock );
    333                                 }
    334                                 fibril_rwlock_read_unlock( & socket_globals.lock );
    335                                 break;
    336367                        case NET_SOCKET_ACCEPTED:
    337                                 fibril_rwlock_read_lock( & socket_globals.lock );
    338                                 // find the socket
    339                                 socket = sockets_find( socket_get_sockets(), SOCKET_GET_SOCKET_ID( call ));
    340                                 if( ! socket ){
    341                                         ERROR_CODE = ENOTSOCK;
    342                                 }else{
    343                                         // create a new scoket
    344                                         new_socket = ( socket_ref ) malloc( sizeof( socket_t ));
    345                                         if( ! new_socket ){
    346                                                 ERROR_CODE = ENOMEM;
    347                                         }else{
    348                                                 bzero( new_socket, sizeof( * new_socket ));
    349                                                 socket_initialize( new_socket, SOCKET_GET_NEW_SOCKET_ID( call ), socket->phone, socket->service );
    350                                                 ERROR_CODE = sockets_add( socket_get_sockets(), new_socket->socket_id, new_socket );
    351                                                 if( ERROR_CODE < 0 ){
    352                                                         free( new_socket );
    353                                                 }else{
    354                                                         // push the new socket identifier
    355                                                         fibril_mutex_lock( & socket->accept_lock );
    356                                                         if( ERROR_OCCURRED( dyn_fifo_push( & socket->accepted, new_socket->socket_id, SOCKET_MAX_ACCEPTED_SIZE ))){
    357                                                                 sockets_exclude( socket_get_sockets(), new_socket->socket_id );
    358                                                         }else{
    359                                                                 // signal the accepted socket
    360                                                                 fibril_condvar_signal( & socket->accept_signal );
    361                                                         }
    362                                                         fibril_mutex_unlock( & socket->accept_lock );
    363                                                         ERROR_CODE = EOK;
    364                                                 }
    365                                         }
    366                                 }
    367                                 fibril_rwlock_read_unlock( & socket_globals.lock );
    368                                 break;
    369368                        case NET_SOCKET_DATA_FRAGMENT_SIZE:
    370369                                fibril_rwlock_read_lock( & socket_globals.lock );
     
    374373                                        ERROR_CODE = ENOTSOCK;
    375374                                }else{
    376                                         fibril_rwlock_write_lock( & socket->sending_lock );
    377                                         // set the data fragment size
    378                                         socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( call );
    379                                         fibril_rwlock_write_unlock( & socket->sending_lock );
    380                                         ERROR_CODE = EOK;
     375                                        switch( IPC_GET_METHOD( call )){
     376                                                case NET_SOCKET_RECEIVED:
     377                                                        fibril_mutex_lock( & socket->receive_lock );
     378                                                        // push the number of received packet fragments
     379                                                        if( ! ERROR_OCCURRED( dyn_fifo_push( & socket->received, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_MAX_RECEIVED_SIZE ))){
     380                                                                // signal the received packet
     381                                                                fibril_condvar_signal( & socket->receive_signal );
     382                                                        }
     383                                                        fibril_mutex_unlock( & socket->receive_lock );
     384                                                        break;
     385                                                case NET_SOCKET_ACCEPTED:
     386                                                        // push the new socket identifier
     387                                                        fibril_mutex_lock( & socket->accept_lock );
     388                                                        if( ERROR_OCCURRED( dyn_fifo_push( & socket->accepted, SOCKET_GET_NEW_SOCKET_ID( call ), SOCKET_MAX_ACCEPTED_SIZE ))){
     389                                                                sockets_exclude( socket_get_sockets(), SOCKET_GET_NEW_SOCKET_ID( call ));
     390                                                        }else{
     391                                                                // signal the accepted socket
     392                                                                fibril_condvar_signal( & socket->accept_signal );
     393                                                        }
     394                                                        fibril_mutex_unlock( & socket->accept_lock );
     395                                                        break;
     396                                                default:
     397                                                        ERROR_CODE = ENOTSUP;
     398                                        }
     399                                        if(( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) > 0 )
     400                                        && ( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) != socket->data_fragment_size )){
     401                                                fibril_rwlock_write_lock( & socket->sending_lock );
     402                                                // set the data fragment size
     403                                                socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( call );
     404                                                fibril_rwlock_write_unlock( & socket->sending_lock );
     405                                        }
    381406                                }
    382407                                fibril_rwlock_read_unlock( & socket_globals.lock );
    383                                 break;
    384408                        default:
    385409                                ERROR_CODE = ENOTSUP;
     
    396420        int                     socket_id;
    397421        services_t      service;
     422        int                     count;
    398423
    399424        // find the appropriate service
     
    437462        if( ! socket ) return ENOMEM;
    438463        bzero( socket, sizeof( * socket ));
     464        count = 0;
     465        fibril_rwlock_write_lock( & socket_globals.lock );
    439466        // request a new socket
    440         if( ERROR_OCCURRED(( int ) async_req_3_3( phone, NET_SOCKET, 0, 0, service, ( ipcarg_t * ) & socket_id, ( ipcarg_t * ) & socket->data_fragment_size, ( ipcarg_t * ) & socket->header_size ))){
     467        socket_id = socket_generate_new_id();
     468        if( socket_id <= 0 ){
     469                fibril_rwlock_write_unlock( & socket_globals.lock );
     470                free( socket );
     471                return socket_id;
     472        }
     473        if( ERROR_OCCURRED(( int ) async_req_3_3( phone, NET_SOCKET, socket_id, 0, service, NULL, ( ipcarg_t * ) & socket->data_fragment_size, ( ipcarg_t * ) & socket->header_size ))){
     474                fibril_rwlock_write_unlock( & socket_globals.lock );
    441475                free( socket );
    442476                return ERROR_CODE;
     
    445479        socket_initialize( socket, socket_id, phone, service );
    446480        // store the new socket
    447         fibril_rwlock_write_lock( & socket_globals.lock );
    448481        ERROR_CODE = sockets_add( socket_get_sockets(), socket_id, socket );
    449482        fibril_rwlock_write_unlock( & socket_globals.lock );
     
    509542int accept( int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen ){
    510543        socket_ref              socket;
     544        socket_ref              new_socket;
    511545        aid_t                   message_id;
    512546        int                             result;
     
    515549        if(( ! cliaddr ) || ( ! addrlen )) return EBADMEM;
    516550
    517         fibril_rwlock_read_lock( & socket_globals.lock );
     551        fibril_rwlock_write_lock( & socket_globals.lock );
    518552        // find the socket
    519553        socket = sockets_find( socket_get_sockets(), socket_id );
    520554        if( ! socket ){
    521                 fibril_rwlock_read_unlock( & socket_globals.lock );
     555                fibril_rwlock_write_unlock( & socket_globals.lock );
    522556                return ENOTSOCK;
    523557        }
     
    526560        ++ socket->blocked;
    527561        while( dyn_fifo_value( & socket->accepted ) <= 0 ){
    528                 fibril_rwlock_read_unlock( & socket_globals.lock );
     562                fibril_rwlock_write_unlock( & socket_globals.lock );
    529563                fibril_condvar_wait( & socket->accept_signal, & socket->accept_lock );
    530                 fibril_rwlock_read_lock( & socket_globals.lock );
     564                fibril_rwlock_write_lock( & socket_globals.lock );
    531565        }
    532566        -- socket->blocked;
     567
     568        // create a new scoket
     569        new_socket = ( socket_ref ) malloc( sizeof( socket_t ));
     570        if( ! new_socket ){
     571                fibril_mutex_unlock( & socket->accept_lock );
     572                fibril_rwlock_write_unlock( & socket_globals.lock );
     573                return ENOMEM;
     574        }
     575        bzero( new_socket, sizeof( * new_socket ));
     576        socket_id = socket_generate_new_id();
     577        if( socket_id <= 0 ){
     578                fibril_mutex_unlock( & socket->accept_lock );
     579                fibril_rwlock_write_unlock( & socket_globals.lock );
     580                free( new_socket );
     581                return socket_id;
     582        }
     583        socket_initialize( new_socket, socket_id, socket->phone, socket->service );
     584        result = sockets_add( socket_get_sockets(), new_socket->socket_id, new_socket );
     585        if( result < 0 ){
     586                fibril_mutex_unlock( & socket->accept_lock );
     587                fibril_rwlock_write_unlock( & socket_globals.lock );
     588                free( new_socket );
     589                return result;
     590        }
     591
    533592        // request accept
    534         message_id = async_send_3( socket->phone, NET_SOCKET_ACCEPT, ( ipcarg_t ) socket->socket_id, 0, socket->service, & answer );
     593        message_id = async_send_5( socket->phone, NET_SOCKET_ACCEPT, ( ipcarg_t ) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, & answer );
    535594        // read address
    536         async_data_read_start( socket->phone, cliaddr, * addrlen );
    537         fibril_rwlock_read_unlock( & socket_globals.lock );
     595        ipc_data_read_start( socket->phone, cliaddr, * addrlen );
     596        fibril_rwlock_write_unlock( & socket_globals.lock );
    538597        async_wait_for( message_id, ( ipcarg_t * ) & result );
    539598        if( result > 0 ){
     599                if( result != socket_id ){
     600                        result = EINVAL;
     601                }
    540602                // dequeue the accepted socket if successful
    541603                dyn_fifo_pop( & socket->accepted );
    542604                // set address length
    543605                * addrlen = SOCKET_GET_ADDRESS_LENGTH( answer );
     606                new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer );
    544607        }else if( result == ENOTSOCK ){
    545608                // empty the queue if no accepted sockets
     
    609672        ipcarg_t                result;
    610673        size_t                  fragments;
     674        ipc_call_t              answer;
    611675
    612676        if( ! data ) return EBADMEM;
     
    621685        fibril_rwlock_read_lock( & socket->sending_lock );
    622686        // compute data fragment count
    623         fragments = ( datalength + socket->header_size ) / socket->data_fragment_size;
    624         if(( datalength + socket->header_size ) % socket->data_fragment_size ) ++ fragments;
     687        if( socket->data_fragment_size > 0 ){
     688                fragments = ( datalength + socket->header_size ) / socket->data_fragment_size;
     689                if(( datalength + socket->header_size ) % socket->data_fragment_size ) ++ fragments;
     690        }else{
     691                fragments = 1;
     692        }
    625693        // request send
    626         message_id = async_send_5( socket->phone, message, ( ipcarg_t ) socket->socket_id, socket->data_fragment_size, socket->service, ( ipcarg_t ) flags, fragments, NULL );
     694        message_id = async_send_5( socket->phone, message, ( ipcarg_t ) socket->socket_id, ( fragments == 1 ? datalength : socket->data_fragment_size ), socket->service, ( ipcarg_t ) flags, fragments, & answer );
    627695        // send the address if given
    628696        if(( ! toaddr ) || ( async_data_write_start( socket->phone, toaddr, addrlen ) == EOK )){
     
    643711                }
    644712        }
     713        async_wait_for( message_id, & result );
     714        if(( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) > 0 )
     715        && ( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) != socket->data_fragment_size )){
     716                // set the data fragment size
     717                socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer );
     718        }
    645719        fibril_rwlock_read_unlock( & socket->sending_lock );
    646720        fibril_rwlock_read_unlock( & socket_globals.lock );
    647         async_wait_for( message_id, & result );
    648721        return ( int ) result;
    649722}
  • uspace/srv/net/socket/socket_core.c

    r1a0fb3f8 rede63e4  
    3535 */
    3636
     37#include <limits.h>
     38#include <stdlib.h>
     39
    3740#include "../err.h"
    3841
     
    5154
    5255#include "socket_core.h"
     56
     57/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
     58 */
     59#define SOCKET_ID_TRIES                                 100
    5360
    5461/** Bound port sockets.
     
    94101 */
    95102int     socket_port_add_core( socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length );
     103
     104/** Tries to find a new free socket identifier.
     105 *  @param[in] local_sockets The local sockets to be searched.
     106 *  @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false.
     107 *      @returns The new socket identifier.
     108 *  @returns ELIMIT if there is no socket identifier available.
     109 */
     110static int      socket_generate_new_id( socket_cores_ref local_sockets, int positive );
    96111
    97112INT_MAP_IMPLEMENT( socket_cores, socket_core_t );
     
    230245}
    231246
     247
     248static int socket_generate_new_id( socket_cores_ref local_sockets, int positive ){
     249        int                     socket_id;
     250        int                     count;
     251
     252        count = 0;
     253//      socket_id = socket_globals.last_id;
     254        do{
     255                if( count < SOCKET_ID_TRIES ){
     256                        socket_id = rand() % INT_MAX;
     257                        ++ count;
     258                }else if( count == SOCKET_ID_TRIES ){
     259                        socket_id = 1;
     260                        ++ count;
     261                // only this branch for last_id
     262                }else{
     263                        if( socket_id < INT_MAX ){
     264                                ++ socket_id;
     265/*                      }else if( socket_globals.last_id ){
     266*                               socket_globals.last_id = 0;
     267*                               socket_id = 1;
     268*/                      }else{
     269                                return ELIMIT;
     270                        }
     271                }
     272        }while( socket_cores_find( local_sockets, (( positive ? 1 : -1 ) * socket_id )));
     273//      last_id = socket_id
     274        return socket_id;
     275}
     276
    232277int socket_create( socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id ){
    233278        ERROR_DECLARE;
     
    235280        socket_core_ref socket;
    236281        int                             res;
    237 
    238         if( ! socket_id ) return EBADMEM;
     282        int                             positive;
     283
     284        if( ! socket_id ) return EINVAL;
     285        // store the socket
     286        if( * socket_id <= 0 ){
     287                positive = ( * socket_id == 0 );
     288                * socket_id = socket_generate_new_id( local_sockets, positive );
     289                if( * socket_id <= 0 ){
     290                        return * socket_id;
     291                }
     292                if( ! positive ){
     293                        * socket_id *= -1;
     294                }
     295        }else if( socket_cores_find( local_sockets, * socket_id )){
     296                return EEXIST;
     297        }
    239298        socket = ( socket_core_ref ) malloc( sizeof( * socket ));
    240299        if( ! socket ) return ENOMEM;
     
    254313                return ERROR_CODE;
    255314        }
    256         // get a next free socket number
    257         socket->socket_id = socket_cores_count( local_sockets ) + 1;
    258         // store the socket
     315        socket->socket_id = * socket_id;
    259316        res = socket_cores_add( local_sockets, socket->socket_id, socket );
    260317        if( res < 0 ){
     
    264321                return res;
    265322        }
    266         // return the socket identifier
    267         * socket_id = socket->socket_id;
    268323        return EOK;
    269324}
  • uspace/srv/net/socket/socket_core.h

    r1a0fb3f8 rede63e4  
    177177 *  @param[in] app_phone The application phone.
    178178 *  @param[in] specific_data The socket specific data.
    179  *  @param[out] socket_id The new socket identifier.
    180  *  @returns EOK on success.
    181  *  @returns EBADMEM if the socket_id parameter is NULL.
     179 *  @param[in,out] socket_id The new socket identifier. A new identifier is chosen if set to zero (0) or negative. A negative identifier is chosen if set to negative.
     180 *  @returns EOK on success.
     181 *  @returns EINVAL if the socket_id parameter is NULL.
    182182 *  @returns ENOMEM if there is not enough memory left.
    183183 */
  • uspace/srv/net/socket/socket_messages.h

    r1a0fb3f8 rede63e4  
    142142#define SOCKET_GET_OPT_LEVEL( call )                    ( int ) IPC_GET_ARG2( call )
    143143
    144 /** Sets the address length in the message answer.
    145  *  @param[out] answer The message answer structure.
    146  */
    147 #define SOCKET_SET_ADDRESS_LENGTH( answer )             ( socklen_t * ) & IPC_GET_ARG2( answer )
    148 
    149 /** Returns the address length message parameter.
    150  *  @param[in] call The message call structure.
    151  */
    152 #define SOCKET_GET_ADDRESS_LENGTH( call )               ( socklen_t ) IPC_GET_ARG2( call )
    153 
    154144/** Returns the data fragment size message parameter.
    155145 *  @param[in] call The message call structure.
     
    161151 */
    162152#define SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) ( size_t * ) & IPC_GET_ARG2( answer )
     153
     154/** Sets the address length in the message answer.
     155 *  @param[out] answer The message answer structure.
     156 */
     157#define SOCKET_SET_ADDRESS_LENGTH( answer )             ( socklen_t * ) & IPC_GET_ARG3( answer )
     158
     159/** Returns the address length message parameter.
     160 *  @param[in] call The message call structure.
     161 */
     162#define SOCKET_GET_ADDRESS_LENGTH( call )               ( socklen_t ) IPC_GET_ARG3( call )
    163163
    164164/** Sets the header size in the message answer.
  • uspace/srv/net/structures/int_map.h

    r1a0fb3f8 rede63e4  
    8282void    name##_exclude_index( name##_ref map, int index );                                              \
    8383type *  name##_find( name##_ref map, int key );                                                                 \
     84int             name##_update( name##_ref map, int key, int new_key );                                  \
    8485type *  name##_get_index( name##_ref map, int index );                                                  \
    8586int             name##_initialize( name##_ref map );                                                                    \
     
    178179        }                                                                                                                                                       \
    179180        return NULL;                                                                                                                            \
     181}                                                                                                                                                               \
     182                                                                                                                                                                \
     183int name##_update( name##_ref map, int key, int new_key ){                                              \
     184        if( name##_is_valid( map )){                                                                                            \
     185                int     index;                                                                                                                          \
     186                                                                                                                                                                \
     187                for( index = 0; index < map->next; ++ index ){                                                  \
     188                        if( name##_item_is_valid( &( map->items[ index ] ))){                           \
     189                                if( map->items[ index ].key == new_key ){                                               \
     190                                        return EEXIST;                                                                                          \
     191                                }else if( map->items[ index ].key == key ){                                             \
     192                                        map->items[ index ].key = new_key;                                                      \
     193                                        return EOK;                                                                                                     \
     194                                }                                                                                                                               \
     195                        }                                                                                                                                       \
     196                }                                                                                                                                               \
     197        }                                                                                                                                                       \
     198        return ENOENT;                                                                                                                          \
    180199}                                                                                                                                                               \
    181200                                                                                                                                                                \
  • uspace/srv/net/tl/icmp/icmp.c

    r1a0fb3f8 rede63e4  
    350350        // TODO do not ask all the time
    351351        ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.addr_len, & icmp_globals.prefix, & icmp_globals.content, & icmp_globals.suffix ));
    352         packet = packet_get_4( icmp_globals.net_phone, size, icmp_globals.addr_len, sizeof( icmp_header_t ) + icmp_globals.prefix, icmp_globals.suffix );
     352        packet = packet_get_4( icmp_globals.net_phone, size, icmp_globals.addr_len, ICMP_HEADER_SIZE + icmp_globals.prefix, icmp_globals.suffix );
    353353        if( ! packet ) return ENOMEM;
    354354
     
    548548        }
    549549        ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.addr_len, & icmp_globals.prefix, & icmp_globals.content, & icmp_globals.suffix ));
    550         icmp_globals.prefix += sizeof( icmp_header_t );
    551         icmp_globals.content -= sizeof( icmp_header_t );
     550        icmp_globals.prefix += ICMP_HEADER_SIZE;
     551        icmp_globals.content -= ICMP_HEADER_SIZE;
    552552        // get configuration
    553553        icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING;
     
    610610        length = packet_get_data_length( packet );
    611611        if( length <= 0 ) return EINVAL;
    612         if( length < sizeof( icmp_header_t )) return EINVAL;
     612        if( length < ICMP_HEADER_SIZE) return EINVAL;
    613613        data = packet_get_data( packet );
    614614        if( ! data ) return EINVAL;
  • uspace/srv/net/tl/icmp/icmp_header.h

    r1a0fb3f8 rede63e4  
    4343#include "../../include/in.h"
    4444#include "../../include/icmp_codes.h"
     45
     46/** ICMP header size in bytes.
     47 */
     48#define ICMP_HEADER_SIZE                        sizeof( icmp_header_t )
    4549
    4650/** Type definition of the echo specific data.
  • uspace/srv/net/tl/tcp/tcp.c

    r1a0fb3f8 rede63e4  
    205205int     tcp_connect_message( socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen );
    206206int     tcp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen );
    207 int     tcp_send_message( socket_cores_ref local_sockets, int socket_id, int fragments, size_t data_fragment_size, int flags );
    208 int     tcp_accept_message( socket_cores_ref local_sockets, int socket_id, size_t * addrlen );
     207int     tcp_send_message( socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags );
     208int     tcp_accept_message( socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen );
    209209int tcp_close_message( socket_cores_ref local_sockets, int socket_id );
    210210
     
    298298                return tcp_release_and_return( packet, EINVAL );
    299299        }
    300         if( length < sizeof( tcp_header_t ) + offset ){
     300        if( length < TCP_HEADER_SIZE + offset ){
    301301                return tcp_release_and_return( packet, NO_DATA );
    302302        }
     
    668668        ERROR_DECLARE;
    669669
     670        packet_dimension_ref    packet_dimension;
     671
    670672        assert( socket );
    671673        assert( socket_data );
     
    676678
    677679        // queue the received packet
    678         if( ERROR_OCCURRED( dyn_fifo_push( & socket->received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){
     680        if( ERROR_OCCURRED( dyn_fifo_push( & socket->received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))
     681        || ERROR_OCCURRED( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension ))){
    679682                return tcp_release_and_return( packet, ERROR_CODE );
    680683        }
     
    684687
    685688        // notify the destination socket
    686         async_msg_5( socket->phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) socket->socket_id, 0, 0, 0, ( ipcarg_t ) fragments );
     689        async_msg_5( socket->phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) socket->socket_id, (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size ), 0, 0, ( ipcarg_t ) fragments );
    687690        return EOK;
    688691}
     
    783786//                      printf( "addr %p\n", socket_data->addr, socket_data->addrlen );
    784787                        // create a socket
     788                        socket_id = -1;
    785789                        if( ERROR_OCCURRED( socket_create( socket_data->local_sockets, listening_socket->phone, socket_data, & socket_id ))){
    786790                                free( socket_data->addr );
     
    789793                        }
    790794
     795                        socket_id *= -1;
    791796                        printf("new_sock %d\n", socket_id);
    792797                        socket_data->pseudo_header = listening_socket_data->pseudo_header;
     
    901906                        if( ! ERROR_OCCURRED( dyn_fifo_push( & listening_socket->accepted, socket->socket_id, listening_socket_data->backlog ))){
    902907                                // notify the destination socket
    903                                 async_msg_5( socket->phone, NET_SOCKET_ACCEPTED, ( ipcarg_t ) listening_socket->socket_id, 0, 0, 0, ( ipcarg_t ) socket->socket_id );
     908                                async_msg_5( socket->phone, NET_SOCKET_ACCEPTED, ( ipcarg_t ) listening_socket->socket_id, socket_data->data_fragment_size, TCP_HEADER_SIZE, 0, ( ipcarg_t ) socket->socket_id );
    904909                                fibril_rwlock_write_unlock( socket_data->local_lock );
    905910                                return EOK;
     
    10351040        bzero( socket_data, sizeof( * socket_data ));
    10361041        socket_data->state = TCP_SOCKET_INITIAL;
    1037         socket_data->device_id = -1;
     1042        socket_data->device_id = DEVICE_INVALID_ID;
    10381043        socket_data->window = NET_DEFAULT_TCP_WINDOW;
    10391044        socket_data->treshold = socket_data->window;
     
    10511056        fibril_mutex_initialize( & socket_data->operation.mutex );
    10521057        fibril_condvar_initialize( & socket_data->operation.condvar );
     1058        socket_data->data_fragment_size = MAX_TCP_FRAGMENT_SIZE;
    10531059}
    10541060
     
    10651071        tcp_socket_data_ref             socket_data;
    10661072        socket_core_ref                 socket;
     1073        packet_dimension_ref    packet_dimension;
    10671074
    10681075        /*
     
    10961103                                        socket_data->local_sockets = & local_sockets;
    10971104                                        fibril_rwlock_write_lock( & lock );
     1105                                        * SOCKET_SET_SOCKET_ID( answer ) = SOCKET_GET_SOCKET_ID( call );
    10981106                                        res = socket_create( & local_sockets, app_phone, socket_data, SOCKET_SET_SOCKET_ID( answer ));
    10991107                                        fibril_rwlock_write_unlock( & lock );
    11001108                                        if( res == EOK ){
    1101                                                 * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( tcp_header_t );
    1102                                                 * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_TCP_FRAGMENT_SIZE;
     1109                                                if( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, DEVICE_INVALID_ID, & packet_dimension ) == EOK ){
     1110                                                        * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size );
     1111                                                }
     1112//                                              * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_TCP_FRAGMENT_SIZE;
     1113                                                * SOCKET_SET_HEADER_SIZE( answer ) = TCP_HEADER_SIZE;
    11031114                                                answer_count = 3;
    11041115                                        }else{
     
    11381149                                res = data_receive(( void ** ) & addr, & addrlen );
    11391150                                if( res == EOK ){
    1140                                         // the global lock may released in the tcp_connect_message() function
     1151                                        // the global lock may be released in the tcp_connect_message() function
    11411152                                        fibril_rwlock_write_lock( & tcp_globals.lock );
    11421153                                        fibril_rwlock_write_lock( & lock );
     
    11521163                                fibril_rwlock_read_lock( & tcp_globals.lock );
    11531164                                fibril_rwlock_write_lock( & lock );
    1154                                 res = tcp_accept_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), & addrlen );
     1165                                res = tcp_accept_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_NEW_SOCKET_ID( call ), SOCKET_SET_DATA_FRAGMENT_SIZE( answer ), & addrlen );
    11551166                                fibril_rwlock_write_unlock( & lock );
    11561167                                fibril_rwlock_read_unlock( & tcp_globals.lock );
     
    11581169                                        * SOCKET_SET_SOCKET_ID( answer ) = res;
    11591170                                        * SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen;
    1160                                         answer_count = 2;
     1171                                        answer_count = 3;
    11611172                                }
    11621173                                break;
     
    11641175                                fibril_rwlock_read_lock( & tcp_globals.lock );
    11651176                                fibril_rwlock_write_lock( & lock );
    1166                                 res = tcp_send_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_DATA_FRAGMENT_SIZE( call ), SOCKET_GET_FLAGS( call ));
     1177                                res = tcp_send_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_SET_DATA_FRAGMENT_SIZE( answer ), SOCKET_GET_FLAGS( call ));
    11671178                                if( res != EOK ){
    11681179                                        fibril_rwlock_write_unlock( & lock );
    11691180                                        fibril_rwlock_read_unlock( & tcp_globals.lock );
     1181                                }else{
     1182                                        answer_count = 2;
    11701183                                }
    11711184                                break;
     
    11751188                                        fibril_rwlock_read_lock( & tcp_globals.lock );
    11761189                                        fibril_rwlock_write_lock( & lock );
    1177                                         res = tcp_send_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_DATA_FRAGMENT_SIZE( call ), SOCKET_GET_FLAGS( call ));
     1190                                        res = tcp_send_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_SET_DATA_FRAGMENT_SIZE( answer ), SOCKET_GET_FLAGS( call ));
    11781191                                        if( res != EOK ){
    11791192                                                fibril_rwlock_write_unlock( & lock );
    11801193                                                fibril_rwlock_read_unlock( & tcp_globals.lock );
     1194                                        }else{
     1195                                                answer_count = 2;
    11811196                                        }
    11821197                                        free( addr );
     
    12041219                                        * SOCKET_SET_READ_DATA_LENGTH( answer ) = res;
    12051220                                        * SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen;
    1206                                         answer_count = 2;
     1221                                        answer_count = 3;
    12071222                                        res = EOK;
    12081223                                }
     
    17251740}
    17261741
    1727 int tcp_send_message( socket_cores_ref local_sockets, int socket_id, int fragments, size_t data_fragment_size, int flags ){
     1742int tcp_send_message( socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags ){
    17281743        ERROR_DECLARE;
    17291744
     
    17381753
    17391754        assert( local_sockets );
     1755        assert( data_fragment_size );
    17401756
    17411757        // find the socket
     
    17531769        ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension ));
    17541770
    1755         // TODO return the device_id + data_fragment_size if different - the client should send it again
    1756         // ( two messages are better than ip fragmentation )
     1771        * data_fragment_size = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size );
    17571772
    17581773        for( index = 0; index < fragments; ++ index ){
    17591774                // read the data fragment
    1760                 result = tl_socket_read_packet_data( tcp_globals.net_phone, & packet, sizeof( tcp_header_t ), packet_dimension, socket_data->addr, socket_data->addrlen );
     1775                result = tl_socket_read_packet_data( tcp_globals.net_phone, & packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen );
    17611776                if( result < 0 ) return result;
    17621777                total_length = ( size_t ) result;
     
    18441859        ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension ));
    18451860        // get a new packet
    1846         * packet = packet_get_4( tcp_globals.net_phone, sizeof( tcp_header_t ), packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix );
     1861        * packet = packet_get_4( tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix );
    18471862        if( ! * packet ) return ENOMEM;
    18481863        // allocate space in the packet
     
    18561871}
    18571872
    1858 int tcp_accept_message( socket_cores_ref local_sockets, int socket_id, size_t * addrlen ){
     1873int tcp_accept_message( socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen ){
    18591874        ERROR_DECLARE;
    18601875
     
    18621877        socket_core_ref         socket;
    18631878        tcp_socket_data_ref     socket_data;
     1879        packet_dimension_ref    packet_dimension;
    18641880
    18651881        assert( local_sockets );
     1882        assert( data_fragment_size );
    18661883        assert( addrlen );
    18671884
     
    18871904                socket_data = ( tcp_socket_data_ref ) accepted->specific_data;
    18881905                assert( socket_data );
     1906                // TODO can it be in another state?
    18891907                if( socket_data->state == TCP_SOCKET_ESTABLISHED ){
    18901908                        ERROR_PROPAGATE( data_reply( socket_data->addr, socket_data->addrlen ));
     1909                        ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension ));
    18911910                        * addrlen = socket_data->addrlen;
     1911                        * data_fragment_size = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size );
     1912                        if( new_socket_id > 0 ){
     1913                                ERROR_PROPAGATE( socket_cores_update( local_sockets, accepted->socket_id, new_socket_id ));
     1914                                accepted->socket_id = new_socket_id;
     1915                        }
    18921916                }
    18931917                dyn_fifo_pop( & socket->accepted );
  • uspace/srv/net/tl/tcp/tcp_header.h

    r1a0fb3f8 rede63e4  
    4141#include <sys/types.h>
    4242
     43/** TCP header size in bytes.
     44 */
     45#define TCP_HEADER_SIZE                 sizeof( tcp_header_t )
     46
    4347/** Returns the actual TCP header length in bytes.
    4448 *  @param[in] header The TCP packet header.
  • uspace/srv/net/tl/udp/udp.c

    r1a0fb3f8 rede63e4  
    9797 *  Is used as an entry point from the underlying IP module.
    9898 *  Locks the global lock and calls udp_process_packet() function.
    99  *  @param device_id The device identifier. Ignored parameter.
     99 *  @param[in] device_id The receiving device identifier.
    100100 *  @param[in,out] packet The received packet queue.
    101101 *  @param receiver The target service. Ignored parameter.
     
    109109 *  Notifies the destination socket application.
    110110 *  Releases the packet on error or sends an ICMP error notification..
     111 *  @param[in] device_id The receiving device identifier.
    111112 *  @param[in,out] packet The received packet queue.
    112113 *  @param[in] error The packet error reporting service. Prefixes the received packet.
     
    120121 *  @returns Other error codes as defined for the ip_client_process_packet() function.
    121122 */
    122 int udp_process_packet( packet_t packet, services_t error );
     123int udp_process_packet( device_id_t device_id, packet_t packet, services_t error );
    123124
    124125/** Releases the packet and returns the result.
     
    151152 *  @param[in] addrlen The address length.
    152153 *  @param[in] fragments The number of data fragments.
    153  *  @param[in] data_fragment_size The data fragment size in bytes.
     154 *  @param[out] data_fragment_size The data fragment size in bytes.
    154155 *  @param[in] flags Various send flags.
    155156 *  @returns EOK on success.
     
    163164 *  @returns Other error codes as defined for the ip_send_msg() function.
    164165 */
    165 int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t data_fragment_size, int flags );
     166int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t * data_fragment_size, int flags );
    166167
    167168/** Receives data to the socket.
     
    235236
    236237        fibril_rwlock_write_lock( & udp_globals.lock );
    237         result = udp_process_packet( packet, error );
     238        result = udp_process_packet( device_id, packet, error );
    238239        if( result != EOK ){
    239240                fibril_rwlock_write_unlock( & udp_globals.lock );
     
    243244}
    244245
    245 int udp_process_packet( packet_t packet, services_t error ){
     246int udp_process_packet( device_id_t device_id, packet_t packet, services_t error ){
    246247        ERROR_DECLARE;
    247248
     
    261262        struct sockaddr *               src;
    262263        struct sockaddr *               dest;
     264        packet_dimension_ref    packet_dimension;
    263265
    264266        if( error ){
     
    292294                return udp_release_and_return( packet, EINVAL );
    293295        }
    294         if( length < sizeof( udp_header_t ) + offset ){
     296        if( length < UDP_HEADER_SIZE + offset ){
    295297                return udp_release_and_return( packet, NO_DATA );
    296298        }
     
    380382
    381383        // queue the received packet
    382         if( ERROR_OCCURRED( dyn_fifo_push( & socket->received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))){
     384        if( ERROR_OCCURRED( dyn_fifo_push( & socket->received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE ))
     385        || ERROR_OCCURRED( tl_get_ip_packet_dimension( udp_globals.ip_phone, & udp_globals.dimensions, device_id, & packet_dimension ))){
    383386                return udp_release_and_return( packet, ERROR_CODE );
    384387        }
     
    386389        // notify the destination socket
    387390        fibril_rwlock_write_unlock( & udp_globals.lock );
     391        async_msg_5( socket->phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) socket->socket_id, packet_dimension->content, 0, 0, ( ipcarg_t ) fragments );
     392/*      fibril_rwlock_write_unlock( & udp_globals.lock );
    388393        async_msg_5( socket->phone, NET_SOCKET_RECEIVED, ( ipcarg_t ) socket->socket_id, 0, 0, 0, ( ipcarg_t ) fragments );
    389         return EOK;
     394*/      return EOK;
    390395}
    391396
     
    418423        ipc_call_t                              answer;
    419424        int                                             answer_count;
     425        packet_dimension_ref    packet_dimension;
    420426
    421427        /*
     
    444450                        case NET_SOCKET:
    445451                                fibril_rwlock_write_lock( & lock );
     452                                * SOCKET_SET_SOCKET_ID( answer ) = SOCKET_GET_SOCKET_ID( call );
    446453                                res = socket_create( & local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID( answer ));
    447454                                fibril_rwlock_write_unlock( & lock );
    448                                 // TODO max fragment size
    449                                 * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE;
    450                                 * SOCKET_SET_HEADER_SIZE( answer ) = sizeof( udp_header_t );
    451                                 answer_count = 3;
     455                                if( res == EOK ){
     456                                        if( tl_get_ip_packet_dimension( udp_globals.ip_phone, & udp_globals.dimensions, DEVICE_INVALID_ID, & packet_dimension ) == EOK ){
     457                                                * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = packet_dimension->content;
     458                                        }
     459//                                      * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_UDP_FRAGMENT_SIZE;
     460                                        * SOCKET_SET_HEADER_SIZE( answer ) = UDP_HEADER_SIZE;
     461                                        answer_count = 3;
     462                                }
    452463                                break;
    453464                        case NET_SOCKET_BIND:
     
    467478                                        fibril_rwlock_read_lock( & lock );
    468479                                        fibril_rwlock_write_lock( & udp_globals.lock );
    469                                         res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_GET_DATA_FRAGMENT_SIZE( call ), SOCKET_GET_FLAGS( call ));
     480                                        res = udp_sendto_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_SET_DATA_FRAGMENT_SIZE( answer ), SOCKET_GET_FLAGS( call ));
    470481                                        if( res != EOK ){
    471482                                                fibril_rwlock_write_unlock( & udp_globals.lock );
     483                                        }else{
     484                                                answer_count = 2;
    472485                                        }
    473486                                        fibril_rwlock_read_unlock( & lock );
     
    484497                                        * SOCKET_SET_READ_DATA_LENGTH( answer ) = res;
    485498                                        * SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen;
    486                                         answer_count = 2;
     499                                        answer_count = 3;
    487500                                        res = EOK;
    488501                                }
     
    513526}
    514527
    515 int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t data_fragment_size, int flags ){
     528int udp_sendto_message( socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t * data_fragment_size, int flags ){
    516529        ERROR_DECLARE;
    517530
     
    571584
    572585        // read the first packet fragment
    573         result = tl_socket_read_packet_data( udp_globals.net_phone, & packet, sizeof( udp_header_t ), packet_dimension, addr, addrlen );
     586        result = tl_socket_read_packet_data( udp_globals.net_phone, & packet, UDP_HEADER_SIZE, packet_dimension, addr, addrlen );
    574587        if( result < 0 ) return result;
    575588        total_length = ( size_t ) result;
     
    606619//                      return udp_release_and_return( packet, ERROR_CODE );
    607620//              }
    608                 if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( ip_header, headerlen, total_length + sizeof( udp_header_t )))){
     621                if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( ip_header, headerlen, total_length + UDP_HEADER_SIZE))){
    609622                        free( ip_header );
    610623                        return udp_release_and_return( packet, ERROR_CODE );
     
    615628                free( ip_header );
    616629        }else{
    617                 device_id = -1;
     630                device_id = DEVICE_INVALID_ID;
    618631        }
    619632        // prepare the first packet fragment
     
    665678
    666679        // trim the header
    667         ERROR_PROPAGATE( packet_trim( packet, sizeof( udp_header_t ), 0 ));
     680        ERROR_PROPAGATE( packet_trim( packet, UDP_HEADER_SIZE, 0 ));
    668681
    669682        // reply the packets
  • uspace/srv/net/tl/udp/udp_header.h

    r1a0fb3f8 rede63e4  
    4141#include <sys/types.h>
    4242
     43/** UDP header size in bytes.
     44 */
     45#define UDP_HEADER_SIZE                 sizeof( udp_header_t )
     46
    4347/** Type definition of the user datagram header.
    4448 *  @see udp_header
Note: See TracChangeset for help on using the changeset viewer.