Changeset ca2d142 in mainline for uspace/srv/net/tl/icmp/icmp.c


Ignore:
Timestamp:
2010-02-18T10:00:30Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e326edc
Parents:
b8da2a3 (diff), 91478aa (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from the networking branch.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/icmp/icmp.c

    rb8da2a3 rca2d142  
    115115#define ICMP_GET_REPLY_KEY( id, sequence )      ((( id ) << 16 ) | ( sequence & 0xFFFF ))
    116116
    117 /** Type definition of the ICMP reply timeout.
    118  *  @see icmp_reply_timeout
    119  */
    120 typedef struct icmp_reply_timeout       icmp_reply_timeout_t;
    121 
    122 /** Type definition of the ICMP reply timeout pointer.
    123  *  @see icmp_reply_timeout
    124  */
    125 typedef icmp_reply_timeout_t *  icmp_reply_timeout_ref;
    126 
    127 /** ICMP reply timeout data.
    128  *  Used as a timeouting fibril argument.
    129  *  @see icmp_timeout_for_reply()
    130  */
    131 struct icmp_reply_timeout{
    132         /** Reply data key.
    133          */
    134         int                     reply_key;
    135         /** Timeout in microseconds.
    136          */
    137         suseconds_t     timeout;
    138 };
    139 
    140117/** Processes the received ICMP packet.
    141118 *  Is used as an entry point from the underlying IP module.
     
    255232int     icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code );
    256233
    257 /** Tries to set the pending reply result as timeouted.
    258  *  Sleeps the timeout period of time and then tries to obtain and set the pending reply result as timeouted and signals the reply result.
    259  *  If the reply data are still present, the reply timeouted and the parent fibril is awaken.
    260  *  The global lock is not released in this case to be reused by the parent fibril.
    261  *  Should run in a searate fibril.
    262  *  @param[in] data The icmp_reply_timeout structure.
    263  *  @returns EOK on success.
    264  *  @returns EINVAL if the data parameter is NULL.
    265  */
    266 int     icmp_timeout_for_reply( void * data );
    267 
    268234/** Assigns a new identifier for the connection.
    269235 *  Fills the echo data parameter with the assigned values.
     
    304270}
    305271
    306 int icmp_timeout_for_reply( void * data ){
    307         icmp_reply_ref                  reply;
    308         icmp_reply_timeout_ref  timeout = data;
    309 
    310         if( ! timeout ){
    311                 return EINVAL;
    312         }
    313         // sleep the given timeout
    314         async_usleep( timeout->timeout );
    315         // lock the globals
    316         fibril_rwlock_write_lock( & icmp_globals.lock );
    317         // find the pending reply
    318         reply = icmp_replies_find( & icmp_globals.replies, timeout->reply_key );
    319         if( reply ){
    320                 // set the timeout result
    321                 reply->result = ETIMEOUT;
    322                 // notify the main fibril
    323                 fibril_condvar_signal( & reply->condvar );
    324         }else{
    325                 // unlock only if no reply
    326                 fibril_rwlock_write_unlock( & icmp_globals.lock );
    327         }
    328         // release the timeout structure
    329         free( timeout );
    330         return EOK;
    331 }
    332 
    333272int icmp_echo( icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen ){
    334273        ERROR_DECLARE;
     
    339278        uint8_t *               data;
    340279        icmp_reply_ref                  reply;
    341         icmp_reply_timeout_ref  reply_timeout;
     280        int                             reply_key;
    342281        int                             result;
    343282        int                             index;
    344         fid_t                   fibril;
    345283
    346284        if( addrlen <= 0 ){
     
    349287        length = ( size_t ) addrlen;
    350288        // TODO do not ask all the time
    351         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, ICMP_HEADER_SIZE + icmp_globals.prefix, icmp_globals.suffix );
     289        ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.packet_dimension ));
     290        packet = packet_get_4( icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix );
    353291        if( ! packet ) return ENOMEM;
    354292
     
    379317        header->un.echo.sequence_number = sequence;
    380318
    381         // prepare the reply and the reply timeout structures
    382         reply_timeout = malloc( sizeof( * reply_timeout ));
    383         if( ! reply_timeout ){
    384                 return icmp_release_and_return( packet, ENOMEM );
    385         }
     319        // prepare the reply structure
    386320        reply = malloc( sizeof( * reply ));
    387321        if( ! reply ){
    388                 free( reply_timeout );
    389322                return icmp_release_and_return( packet, ENOMEM );
    390323        }
    391         // prepare the timeouting thread
    392         fibril = fibril_create( icmp_timeout_for_reply, reply_timeout );
    393         if( ! fibril ){
    394                 free( reply );
    395                 free( reply_timeout );
    396                 return icmp_release_and_return( packet, EPARTY );
    397         }
    398         reply_timeout->reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number );
    399         // timeout in microseconds
    400         reply_timeout->timeout = timeout * 1000;
    401324        fibril_mutex_initialize( & reply->mutex );
    402325        fibril_mutex_lock( & reply->mutex );
    403326        fibril_condvar_initialize( & reply->condvar );
    404         // start the timeouting fibril
    405         fibril_add_ready( fibril );
    406         index = icmp_replies_add( & icmp_globals.replies, reply_timeout->reply_key, reply );
     327        reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number );
     328        index = icmp_replies_add( & icmp_globals.replies, reply_key, reply );
    407329        if( index < 0 ){
    408330                free( reply );
     
    417339
    418340        // wait for a reply
    419         fibril_condvar_wait( & reply->condvar, & reply->mutex );
    420 
    421         // read the result
    422         result = reply->result;
     341        // timeout in microseconds
     342        if( ERROR_OCCURRED( fibril_condvar_wait_timeout( & reply->condvar, & reply->mutex, timeout * 1000 ))){
     343                result = ERROR_CODE;
     344
     345                // lock the globals again and clean up
     346                fibril_rwlock_write_lock( & icmp_globals.lock );
     347        }else{
     348                // read the result
     349                result = reply->result;
     350
     351                // release the reply structure
     352                fibril_mutex_unlock( & reply->mutex );
     353        }
    423354
    424355        // destroy the reply structure
    425         fibril_mutex_unlock( & reply->mutex );
    426356        icmp_replies_exclude_index( & icmp_globals.replies, index );
    427357        return result;
     
    547477                return icmp_globals.ip_phone;
    548478        }
    549         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 += ICMP_HEADER_SIZE;
    551         icmp_globals.content -= ICMP_HEADER_SIZE;
     479        ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.packet_dimension ));
     480        icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE;
     481        icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE;
    552482        // get configuration
    553483        icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING;
Note: See TracChangeset for help on using the changeset viewer.