Changeset aadf01e in mainline for uspace/srv/net/tl
- Timestamp:
- 2010-03-07T15:13:28Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 936835e
- Parents:
- aa85487
- Location:
- uspace/srv/net/tl
- Files:
-
- 22 edited
-
icmp/icmp.c (modified) (28 diffs)
-
icmp/icmp.h (modified) (4 diffs)
-
icmp/icmp_api.c (modified) (1 diff)
-
icmp/icmp_client.c (modified) (1 diff)
-
icmp/icmp_common.c (modified) (1 diff)
-
icmp/icmp_header.h (modified) (6 diffs)
-
icmp/icmp_messages.h (modified) (1 diff)
-
icmp/icmp_module.c (modified) (5 diffs)
-
icmp/icmp_module.h (modified) (2 diffs)
-
icmp/icmp_remote.c (modified) (1 diff)
-
tcp/tcp.c (modified) (42 diffs)
-
tcp/tcp.h (modified) (7 diffs)
-
tcp/tcp_header.h (modified) (8 diffs)
-
tcp/tcp_module.c (modified) (5 diffs)
-
tcp/tcp_module.h (modified) (2 diffs)
-
tl_common.c (modified) (5 diffs)
-
tl_common.h (modified) (7 diffs)
-
udp/udp.c (modified) (17 diffs)
-
udp/udp.h (modified) (1 diff)
-
udp/udp_header.h (modified) (3 diffs)
-
udp/udp_module.c (modified) (5 diffs)
-
udp/udp_module.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/icmp/icmp.c
raa85487 raadf01e 102 102 * @returns The computed checksum. 103 103 */ 104 #define ICMP_CHECKSUM( header, length ) htons( ip_checksum(( uint8_t * ) ( header ), ( length)))104 #define ICMP_CHECKSUM(header, length) htons(ip_checksum((uint8_t *) (header), (length))) 105 105 106 106 /** An echo request datagrams pattern. … … 113 113 * @returns The computed ICMP reply data key. 114 114 */ 115 #define ICMP_GET_REPLY_KEY( id, sequence ) ((( id ) << 16 ) | ( sequence & 0xFFFF))115 #define ICMP_GET_REPLY_KEY(id, sequence) (((id) << 16) | (sequence &0xFFFF)) 116 116 117 117 /** Processes the received ICMP packet. … … 125 125 * @returns Other error codes as defined for the icmp_process_packet() function. 126 126 */ 127 int icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error);127 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error); 128 128 129 129 /** Processes the received ICMP packet. … … 140 140 * @returns Other error codes as defined for the ip_client_process_packet() function. 141 141 */ 142 int icmp_process_packet( packet_t packet, services_t error);142 int icmp_process_packet(packet_t packet, services_t error); 143 143 144 144 /** Processes the client messages. … … 151 151 * @see icmp_api.h 152 152 */ 153 int icmp_process_client_messages( ipc_callid_t callid, ipc_call_t call);153 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 154 154 155 155 /** Processes the generic client messages. … … 164 164 * @see icmp_interface.h 165 165 */ 166 int icmp_process_message( ipc_call_t * call);166 int icmp_process_message(ipc_call_t * call); 167 167 168 168 /** Releases the packet and returns the result. … … 171 171 * @returns The result parameter. 172 172 */ 173 int icmp_release_and_return( packet_t packet, int result);173 int icmp_release_and_return(packet_t packet, int result); 174 174 175 175 /** Requests an echo message. … … 192 192 * @returns EPARTY if there was an internal error. 193 193 */ 194 int 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);194 int 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); 195 195 196 196 /** Prepares the ICMP error packet. … … 201 201 * @returns NULL on errors. 202 202 */ 203 icmp_header_ref icmp_prepare_packet( packet_t packet);203 icmp_header_ref icmp_prepare_packet(packet_t packet); 204 204 205 205 /** Sends the ICMP message. … … 218 218 * @returns EPERM if the error message is not allowed. 219 219 */ 220 int icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment);220 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment); 221 221 222 222 /** Tries to set the pending reply result as the received message type. … … 230 230 * @returns EOK. 231 231 */ 232 int icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code);232 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code); 233 233 234 234 /** Assigns a new identifier for the connection. … … 239 239 * @returns ENOTCONN if no free identifier have been found. 240 240 */ 241 int icmp_bind_free_id( icmp_echo_ref echo_data);241 int icmp_bind_free_id(icmp_echo_ref echo_data); 242 242 243 243 /** ICMP global data. … … 245 245 icmp_globals_t icmp_globals; 246 246 247 INT_MAP_IMPLEMENT( icmp_replies, icmp_reply_t);248 249 INT_MAP_IMPLEMENT( icmp_echo_data, icmp_echo_t);250 251 int icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){252 icmp_echo_ref echo_data;253 int res;254 255 fibril_rwlock_write_lock( & icmp_globals.lock);247 INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t); 248 249 INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t); 250 251 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ 252 icmp_echo_ref echo_data; 253 int res; 254 255 fibril_rwlock_write_lock(&icmp_globals.lock); 256 256 // use the phone as the echo data index 257 echo_data = icmp_echo_data_find( & icmp_globals.echo_data, icmp_phone);258 if( ! echo_data){257 echo_data = icmp_echo_data_find(&icmp_globals.echo_data, icmp_phone); 258 if(! echo_data){ 259 259 res = ENOENT; 260 260 }else{ 261 res = icmp_echo( echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen);262 if( echo_data->sequence_number < MAX_UINT16){261 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen); 262 if(echo_data->sequence_number < MAX_UINT16){ 263 263 ++ echo_data->sequence_number; 264 264 }else{ … … 266 266 } 267 267 } 268 fibril_rwlock_write_unlock( & icmp_globals.lock);268 fibril_rwlock_write_unlock(&icmp_globals.lock); 269 269 return res; 270 270 } 271 271 272 int 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){272 int 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){ 273 273 ERROR_DECLARE; 274 274 275 icmp_header_ref header;276 packet_t packet;277 size_t length;278 uint8_t * data;279 icmp_reply_ref reply;280 int reply_key;281 int result;282 int index;283 284 if( addrlen <= 0){275 icmp_header_ref header; 276 packet_t packet; 277 size_t length; 278 uint8_t * data; 279 icmp_reply_ref reply; 280 int reply_key; 281 int result; 282 int index; 283 284 if(addrlen <= 0){ 285 285 return EINVAL; 286 286 } 287 length = ( size_t) addrlen;287 length = (size_t) addrlen; 288 288 // TODO do not ask all the time 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 ); 291 if( ! packet ) return ENOMEM; 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); 291 if(! packet){ 292 return ENOMEM; 293 } 292 294 293 295 // prepare the requesting packet 294 296 // set the destination address 295 if( ERROR_OCCURRED( packet_set_addr( packet, NULL, ( const uint8_t * ) addr, length))){296 return icmp_release_and_return( packet, ERROR_CODE);297 if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (const uint8_t *) addr, length))){ 298 return icmp_release_and_return(packet, ERROR_CODE); 297 299 } 298 300 // allocate space in the packet 299 data = ( uint8_t * ) packet_suffix( packet, size);300 if( ! data){301 return icmp_release_and_return( packet, ENOMEM);301 data = (uint8_t *) packet_suffix(packet, size); 302 if(! data){ 303 return icmp_release_and_return(packet, ENOMEM); 302 304 } 303 305 // fill the data 304 306 length = 0; 305 while( size > length + sizeof( ICMP_ECHO_TEXT)){306 memcpy( data + length, ICMP_ECHO_TEXT, sizeof( ICMP_ECHO_TEXT));307 length += sizeof( ICMP_ECHO_TEXT);308 } 309 memcpy( data + length, ICMP_ECHO_TEXT, size - length);307 while(size > length + sizeof(ICMP_ECHO_TEXT)){ 308 memcpy(data + length, ICMP_ECHO_TEXT, sizeof(ICMP_ECHO_TEXT)); 309 length += sizeof(ICMP_ECHO_TEXT); 310 } 311 memcpy(data + length, ICMP_ECHO_TEXT, size - length); 310 312 // prefix the header 311 header = PACKET_PREFIX( packet, icmp_header_t);312 if( ! header){313 return icmp_release_and_return( packet, ENOMEM);314 } 315 bzero( header, sizeof( * header));313 header = PACKET_PREFIX(packet, icmp_header_t); 314 if(! header){ 315 return icmp_release_and_return(packet, ENOMEM); 316 } 317 bzero(header, sizeof(*header)); 316 318 header->un.echo.identifier = id; 317 319 header->un.echo.sequence_number = sequence; 318 320 319 321 // prepare the reply structure 320 reply = malloc( sizeof( * reply));321 if( ! reply){322 return icmp_release_and_return( packet, ENOMEM);323 } 324 fibril_mutex_initialize( & reply->mutex);325 fibril_mutex_lock( & reply->mutex);326 fibril_condvar_initialize( & reply->condvar);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);329 if( index < 0){330 free( reply);331 return icmp_release_and_return( packet, index);322 reply = malloc(sizeof(*reply)); 323 if(! reply){ 324 return icmp_release_and_return(packet, ENOMEM); 325 } 326 fibril_mutex_initialize(&reply->mutex); 327 fibril_mutex_lock(&reply->mutex); 328 fibril_condvar_initialize(&reply->condvar); 329 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number); 330 index = icmp_replies_add(&icmp_globals.replies, reply_key, reply); 331 if(index < 0){ 332 free(reply); 333 return icmp_release_and_return(packet, index); 332 334 } 333 335 334 336 // unlock the globals and wait for a reply 335 fibril_rwlock_write_unlock( & icmp_globals.lock);337 fibril_rwlock_write_unlock(&icmp_globals.lock); 336 338 337 339 // send the request 338 icmp_send_packet( ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment);340 icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment); 339 341 340 342 // wait for a reply 341 343 // timeout in microseconds 342 if( ERROR_OCCURRED( fibril_condvar_wait_timeout( & reply->condvar, & reply->mutex, timeout * 1000))){344 if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){ 343 345 result = ERROR_CODE; 344 346 345 347 // lock the globals again and clean up 346 fibril_rwlock_write_lock( & icmp_globals.lock);348 fibril_rwlock_write_lock(&icmp_globals.lock); 347 349 }else{ 348 350 // read the result … … 350 352 351 353 // release the reply structure 352 fibril_mutex_unlock( & reply->mutex);354 fibril_mutex_unlock(&reply->mutex); 353 355 } 354 356 355 357 // destroy the reply structure 356 icmp_replies_exclude_index( & icmp_globals.replies, index);358 icmp_replies_exclude_index(&icmp_globals.replies, index); 357 359 return result; 358 360 } 359 361 360 int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){361 icmp_header_ref header;362 363 header = icmp_prepare_packet( packet);364 if( ! header){365 return icmp_release_and_return( packet, ENOMEM);366 } 367 if( mtu){362 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){ 363 icmp_header_ref header; 364 365 header = icmp_prepare_packet(packet); 366 if(! header){ 367 return icmp_release_and_return(packet, ENOMEM); 368 } 369 if(mtu){ 368 370 header->un.frag.mtu = mtu; 369 371 } 370 return icmp_send_packet( ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0);371 } 372 373 int icmp_source_quench_msg( int icmp_phone, packet_t packet){374 icmp_header_ref header;375 376 header = icmp_prepare_packet( packet);377 if( ! header){378 return icmp_release_and_return( packet, ENOMEM);379 } 380 return icmp_send_packet( ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0);381 } 382 383 int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet){384 icmp_header_ref header;385 386 header = icmp_prepare_packet( packet);387 if( ! header){388 return icmp_release_and_return( packet, ENOMEM);389 } 390 return icmp_send_packet( ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0);391 } 392 393 int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){394 icmp_header_ref header;395 396 header = icmp_prepare_packet( packet);397 if( ! header){398 return icmp_release_and_return( packet, ENOMEM);372 return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0); 373 } 374 375 int icmp_source_quench_msg(int icmp_phone, packet_t packet){ 376 icmp_header_ref header; 377 378 header = icmp_prepare_packet(packet); 379 if(! header){ 380 return icmp_release_and_return(packet, ENOMEM); 381 } 382 return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0); 383 } 384 385 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t packet){ 386 icmp_header_ref header; 387 388 header = icmp_prepare_packet(packet); 389 if(! header){ 390 return icmp_release_and_return(packet, ENOMEM); 391 } 392 return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0); 393 } 394 395 int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){ 396 icmp_header_ref header; 397 398 header = icmp_prepare_packet(packet); 399 if(! header){ 400 return icmp_release_and_return(packet, ENOMEM); 399 401 } 400 402 header->un.param.pointer = pointer; 401 return icmp_send_packet( ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0 ); 402 } 403 404 icmp_header_ref icmp_prepare_packet( packet_t packet ){ 405 icmp_header_ref header; 406 size_t header_length; 407 size_t total_length; 408 409 total_length = packet_get_data_length( packet ); 410 if( total_length <= 0 ) return NULL; 411 header_length = ip_client_header_length( packet ); 412 if( header_length <= 0 ) return NULL; 403 return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0); 404 } 405 406 icmp_header_ref icmp_prepare_packet(packet_t packet){ 407 icmp_header_ref header; 408 size_t header_length; 409 size_t total_length; 410 411 total_length = packet_get_data_length(packet); 412 if(total_length <= 0){ 413 return NULL; 414 } 415 header_length = ip_client_header_length(packet); 416 if(header_length <= 0){ 417 return NULL; 418 } 413 419 // truncate if longer than 64 bits (without the IP header) 414 if(( total_length > header_length + ICMP_KEEP_LENGTH)415 && ( packet_trim( packet, 0, total_length - header_length - ICMP_KEEP_LENGTH ) != EOK)){420 if((total_length > header_length + ICMP_KEEP_LENGTH) 421 && (packet_trim(packet, 0, total_length - header_length - ICMP_KEEP_LENGTH) != EOK)){ 416 422 return NULL; 417 423 } 418 header = PACKET_PREFIX( packet, icmp_header_t ); 419 if( ! header ) return NULL; 420 bzero( header, sizeof( * header )); 424 header = PACKET_PREFIX(packet, icmp_header_t); 425 if(! header){ 426 return NULL; 427 } 428 bzero(header, sizeof(*header)); 421 429 return header; 422 430 } 423 431 424 int icmp_send_packet( icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment){432 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment){ 425 433 ERROR_DECLARE; 426 434 427 435 // do not send an error if disabled 428 if( error && ( ! icmp_globals.error_reporting)){429 return icmp_release_and_return( packet, EPERM);436 if(error && (! icmp_globals.error_reporting)){ 437 return icmp_release_and_return(packet, EPERM); 430 438 } 431 439 header->type = type; 432 440 header->code = code; 433 441 header->checksum = 0; 434 header->checksum = ICMP_CHECKSUM( header, packet_get_data_length( packet )); 435 if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0 ))){ 436 return icmp_release_and_return( packet, ERROR_CODE ); 437 } 438 return ip_send_msg( icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error ); 439 } 440 441 int icmp_connect_module( services_t service, suseconds_t timeout ){ 442 icmp_echo_ref echo_data; 443 icmp_param_t id; 444 int index; 445 446 echo_data = ( icmp_echo_ref ) malloc( sizeof( * echo_data )); 447 if( ! echo_data ) return ENOMEM; 442 header->checksum = ICMP_CHECKSUM(header, packet_get_data_length(packet)); 443 if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0))){ 444 return icmp_release_and_return(packet, ERROR_CODE); 445 } 446 return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error); 447 } 448 449 int icmp_connect_module(services_t service, suseconds_t timeout){ 450 icmp_echo_ref echo_data; 451 icmp_param_t id; 452 int index; 453 454 echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data)); 455 if(! echo_data){ 456 return ENOMEM; 457 } 448 458 // assign a new identifier 449 fibril_rwlock_write_lock( & icmp_globals.lock);450 index = icmp_bind_free_id( echo_data);451 if( index < 0){452 free( echo_data);453 fibril_rwlock_write_unlock( & icmp_globals.lock);459 fibril_rwlock_write_lock(&icmp_globals.lock); 460 index = icmp_bind_free_id(echo_data); 461 if(index < 0){ 462 free(echo_data); 463 fibril_rwlock_write_unlock(&icmp_globals.lock); 454 464 return index; 455 465 }else{ 456 466 id = echo_data->identifier; 457 fibril_rwlock_write_unlock( & icmp_globals.lock);467 fibril_rwlock_write_unlock(&icmp_globals.lock); 458 468 // return the echo data identifier as the ICMP phone 459 469 return id; … … 461 471 } 462 472 463 int icmp_initialize( async_client_conn_t client_connection){473 int icmp_initialize(async_client_conn_t client_connection){ 464 474 ERROR_DECLARE; 465 475 466 measured_string_t names[] = {{ str_dup("ICMP_ERROR_REPORTING"), 20 }, { str_dup("ICMP_ECHO_REPLYING"), 18}};467 measured_string_ref configuration;468 size_t count = sizeof( names ) / sizeof( measured_string_t);469 char * data;470 471 fibril_rwlock_initialize( & icmp_globals.lock);472 fibril_rwlock_write_lock( & icmp_globals.lock);473 icmp_replies_initialize( & icmp_globals.replies);474 icmp_echo_data_initialize( & icmp_globals.echo_data);475 icmp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg);476 if( icmp_globals.ip_phone < 0){476 measured_string_t names[] = {{str_dup("ICMP_ERROR_REPORTING"), 20}, {str_dup("ICMP_ECHO_REPLYING"), 18}}; 477 measured_string_ref configuration; 478 size_t count = sizeof(names) / sizeof(measured_string_t); 479 char * data; 480 481 fibril_rwlock_initialize(&icmp_globals.lock); 482 fibril_rwlock_write_lock(&icmp_globals.lock); 483 icmp_replies_initialize(&icmp_globals.replies); 484 icmp_echo_data_initialize(&icmp_globals.echo_data); 485 icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg); 486 if(icmp_globals.ip_phone < 0){ 477 487 return icmp_globals.ip_phone; 478 488 } 479 ERROR_PROPAGATE( ip_packet_size_req( icmp_globals.ip_phone, -1, & icmp_globals.packet_dimension));489 ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension)); 480 490 icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE; 481 491 icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE; … … 483 493 icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING; 484 494 icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING; 485 configuration = & names[ 0];486 ERROR_PROPAGATE( net_get_conf_req( icmp_globals.net_phone, & configuration, count, & data));487 if( configuration){488 if( configuration[ 0 ].value){489 icmp_globals.error_reporting = ( configuration[ 0 ].value[ 0 ] == 'y');495 configuration = &names[0]; 496 ERROR_PROPAGATE(net_get_conf_req(icmp_globals.net_phone, &configuration, count, &data)); 497 if(configuration){ 498 if(configuration[0].value){ 499 icmp_globals.error_reporting = (configuration[0].value[0] == 'y'); 490 500 } 491 if( configuration[ 1 ].value){492 icmp_globals.echo_replying = ( configuration[ 1 ].value[ 0 ] == 'y');501 if(configuration[1].value){ 502 icmp_globals.echo_replying = (configuration[1].value[0] == 'y'); 493 503 } 494 net_free_settings( configuration, data);495 } 496 fibril_rwlock_write_unlock( & icmp_globals.lock);504 net_free_settings(configuration, data); 505 } 506 fibril_rwlock_write_unlock(&icmp_globals.lock); 497 507 return EOK; 498 508 } 499 509 500 int icmp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error){510 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){ 501 511 ERROR_DECLARE; 502 512 503 if( ERROR_OCCURRED( icmp_process_packet( packet, error))){504 return icmp_release_and_return( packet, ERROR_CODE);513 if(ERROR_OCCURRED(icmp_process_packet(packet, error))){ 514 return icmp_release_and_return(packet, ERROR_CODE); 505 515 } 506 516 … … 508 518 } 509 519 510 int icmp_process_packet( packet_t packet, services_t error){520 int icmp_process_packet(packet_t packet, services_t error){ 511 521 ERROR_DECLARE; 512 522 513 size_t length;514 uint8_t * src;515 int addrlen;516 int result;517 void * data;518 icmp_header_ref header;519 icmp_type_t type;520 icmp_code_t code;521 522 if( error){523 switch( error){523 size_t length; 524 uint8_t * src; 525 int addrlen; 526 int result; 527 void * data; 528 icmp_header_ref header; 529 icmp_type_t type; 530 icmp_code_t code; 531 532 if(error){ 533 switch(error){ 524 534 case SERVICE_ICMP: 525 535 // process error 526 result = icmp_client_process_packet( packet, & type, & code, NULL, NULL ); 527 if( result < 0 ) return result; 528 length = ( size_t ) result; 536 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 537 if(result < 0){ 538 return result; 539 } 540 length = (size_t) result; 529 541 // remove the error header 530 ERROR_PROPAGATE( packet_trim( packet, length, 0));542 ERROR_PROPAGATE(packet_trim(packet, length, 0)); 531 543 break; 532 544 default: … … 535 547 } 536 548 // get rid of the ip header 537 length = ip_client_header_length( packet ); 538 ERROR_PROPAGATE( packet_trim( packet, length, 0 )); 539 540 length = packet_get_data_length( packet ); 541 if( length <= 0 ) return EINVAL; 542 if( length < ICMP_HEADER_SIZE) return EINVAL; 543 data = packet_get_data( packet ); 544 if( ! data ) return EINVAL; 549 length = ip_client_header_length(packet); 550 ERROR_PROPAGATE(packet_trim(packet, length, 0)); 551 552 length = packet_get_data_length(packet); 553 if(length <= 0){ 554 return EINVAL; 555 } 556 if(length < ICMP_HEADER_SIZE){ 557 return EINVAL; 558 } 559 data = packet_get_data(packet); 560 if(! data){ 561 return EINVAL; 562 } 545 563 // get icmp header 546 header = ( icmp_header_ref) data;564 header = (icmp_header_ref) data; 547 565 // checksum 548 if( header->checksum){549 while( ICMP_CHECKSUM( header, length ) != IP_CHECKSUM_ZERO){566 if(header->checksum){ 567 while(ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO){ 550 568 // set the original message type on error notification 551 569 // type swap observed in Qemu 552 if( error){553 switch( header->type){570 if(error){ 571 switch(header->type){ 554 572 case ICMP_ECHOREPLY: 555 573 header->type = ICMP_ECHO; … … 560 578 } 561 579 } 562 switch( header->type){580 switch(header->type){ 563 581 case ICMP_ECHOREPLY: 564 if( error){565 return icmp_process_echo_reply( packet, header, type, code);582 if(error){ 583 return icmp_process_echo_reply(packet, header, type, code); 566 584 }else{ 567 return icmp_process_echo_reply( packet, header, ICMP_ECHO, 0);585 return icmp_process_echo_reply(packet, header, ICMP_ECHO, 0); 568 586 } 569 587 case ICMP_ECHO: 570 if( error){571 return icmp_process_echo_reply( packet, header, type, code);588 if(error){ 589 return icmp_process_echo_reply(packet, header, type, code); 572 590 // do not send a reply if disabled 573 }else if( icmp_globals.echo_replying){574 addrlen = packet_get_addr( packet, & src, NULL);575 if(( addrlen > 0)591 }else if(icmp_globals.echo_replying){ 592 addrlen = packet_get_addr(packet, &src, NULL); 593 if((addrlen > 0) 576 594 // set both addresses to the source one (avoids the source address deletion before setting the destination one) 577 && ( packet_set_addr( packet, src, src, ( size_t ) addrlen ) == EOK)){595 && (packet_set_addr(packet, src, src, (size_t) addrlen) == EOK)){ 578 596 // send the reply 579 icmp_send_packet( ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0);597 icmp_send_packet(ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0); 580 598 return EOK; 581 599 }else{ … … 597 615 case ICMP_SKIP: 598 616 case ICMP_PHOTURIS: 599 ip_received_error_msg( icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP);617 ip_received_error_msg(icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP); 600 618 return EOK; 601 619 default: … … 604 622 } 605 623 606 int icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code){607 int reply_key;608 icmp_reply_ref reply;624 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code){ 625 int reply_key; 626 icmp_reply_ref reply; 609 627 610 628 // compute the reply key 611 reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number);612 pq_release( icmp_globals.net_phone, packet_get_id( packet));629 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number); 630 pq_release(icmp_globals.net_phone, packet_get_id(packet)); 613 631 // lock the globals 614 fibril_rwlock_write_lock( & icmp_globals.lock);632 fibril_rwlock_write_lock(&icmp_globals.lock); 615 633 // find the pending reply 616 reply = icmp_replies_find( & icmp_globals.replies, reply_key);617 if( reply){634 reply = icmp_replies_find(&icmp_globals.replies, reply_key); 635 if(reply){ 618 636 // set the result 619 637 reply->result = type; 620 638 // notify the main fibril 621 fibril_condvar_signal( & reply->condvar);639 fibril_condvar_signal(&reply->condvar); 622 640 }else{ 623 641 // unlock only if no reply 624 fibril_rwlock_write_unlock( & icmp_globals.lock);642 fibril_rwlock_write_unlock(&icmp_globals.lock); 625 643 } 626 644 return EOK; 627 645 } 628 646 629 int icmp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){647 int icmp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 630 648 ERROR_DECLARE; 631 649 632 packet_t packet;633 634 * answer_count = 0;635 switch( IPC_GET_METHOD( * call)){650 packet_t packet; 651 652 *answer_count = 0; 653 switch(IPC_GET_METHOD(*call)){ 636 654 case NET_TL_RECEIVED: 637 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){638 ERROR_CODE = icmp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_ICMP, IPC_GET_ERROR( call));655 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 656 ERROR_CODE = icmp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_ICMP, IPC_GET_ERROR(call)); 639 657 } 640 658 return ERROR_CODE; 641 659 case NET_ICMP_INIT: 642 return icmp_process_client_messages( callid, * call);660 return icmp_process_client_messages(callid, * call); 643 661 default: 644 return icmp_process_message( call);662 return icmp_process_message(call); 645 663 } 646 664 return ENOTSUP; 647 665 } 648 666 649 int icmp_process_client_messages( ipc_callid_t callid, ipc_call_t call){667 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call){ 650 668 ERROR_DECLARE; 651 669 652 bool keep_on_going = true;670 bool keep_on_going = true; 653 671 // fibril_rwlock_t lock; 654 ipc_call_t answer;655 int answer_count;656 size_t length;657 struct sockaddr * addr;658 ipc_callid_t data_callid;659 icmp_echo_ref echo_data;660 int res;672 ipc_call_t answer; 673 int answer_count; 674 size_t length; 675 struct sockaddr * addr; 676 ipc_callid_t data_callid; 677 icmp_echo_ref echo_data; 678 int res; 661 679 662 680 /* … … 667 685 answer_count = 0; 668 686 669 // fibril_rwlock_initialize( & lock ); 670 671 echo_data = ( icmp_echo_ref ) malloc( sizeof( * echo_data )); 672 if( ! echo_data ) return ENOMEM; 687 // fibril_rwlock_initialize(&lock); 688 689 echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data)); 690 if(! echo_data){ 691 return ENOMEM; 692 } 673 693 674 694 // assign a new identifier 675 fibril_rwlock_write_lock( & icmp_globals.lock);676 res = icmp_bind_free_id( echo_data);677 fibril_rwlock_write_unlock( & icmp_globals.lock);678 if( res < 0){679 free( echo_data);695 fibril_rwlock_write_lock(&icmp_globals.lock); 696 res = icmp_bind_free_id(echo_data); 697 fibril_rwlock_write_unlock(&icmp_globals.lock); 698 if(res < 0){ 699 free(echo_data); 680 700 return res; 681 701 } 682 702 683 while( keep_on_going){703 while(keep_on_going){ 684 704 685 705 // answer the call 686 answer_call( callid, res, & answer, answer_count);706 answer_call(callid, res, &answer, answer_count); 687 707 688 708 // refresh data 689 refresh_answer( & answer, & answer_count);709 refresh_answer(&answer, &answer_count); 690 710 691 711 // get the next call 692 callid = async_get_call( & call);712 callid = async_get_call(&call); 693 713 694 714 // process the call 695 switch( IPC_GET_METHOD( call)){715 switch(IPC_GET_METHOD(call)){ 696 716 case IPC_M_PHONE_HUNGUP: 697 717 keep_on_going = false; … … 699 719 break; 700 720 case NET_ICMP_ECHO: 701 // fibril_rwlock_write_lock( & lock);702 if( ! async_data_write_receive( & data_callid, & length)){721 // fibril_rwlock_write_lock(&lock); 722 if(! async_data_write_receive(&data_callid, &length)){ 703 723 res = EINVAL; 704 724 }else{ 705 addr = malloc( length);706 if( ! addr){725 addr = malloc(length); 726 if(! addr){ 707 727 res = ENOMEM; 708 728 }else{ 709 if( ! ERROR_OCCURRED( async_data_write_finalize( data_callid, addr, length))){710 fibril_rwlock_write_lock( & icmp_globals.lock);711 res = icmp_echo( echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE( call ), ICMP_GET_TIMEOUT( call ), ICMP_GET_TTL( call ), ICMP_GET_TOS( call ), ICMP_GET_DONT_FRAGMENT( call ), addr, ( socklen_t ) length);712 fibril_rwlock_write_unlock( & icmp_globals.lock);713 free( addr);714 if( echo_data->sequence_number < MAX_UINT16){729 if(! ERROR_OCCURRED(async_data_write_finalize(data_callid, addr, length))){ 730 fibril_rwlock_write_lock(&icmp_globals.lock); 731 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE(call), ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call), ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call), addr, (socklen_t) length); 732 fibril_rwlock_write_unlock(&icmp_globals.lock); 733 free(addr); 734 if(echo_data->sequence_number < MAX_UINT16){ 715 735 ++ echo_data->sequence_number; 716 736 }else{ … … 722 742 } 723 743 } 724 // fibril_rwlock_write_unlock( & lock);744 // fibril_rwlock_write_unlock(&lock); 725 745 break; 726 746 default: 727 res = icmp_process_message( & call);747 res = icmp_process_message(&call); 728 748 } 729 749 } 730 750 731 751 // release the identifier 732 fibril_rwlock_write_lock( & icmp_globals.lock);733 icmp_echo_data_exclude( & icmp_globals.echo_data, echo_data->identifier);734 fibril_rwlock_write_unlock( & icmp_globals.lock);752 fibril_rwlock_write_lock(&icmp_globals.lock); 753 icmp_echo_data_exclude(&icmp_globals.echo_data, echo_data->identifier); 754 fibril_rwlock_write_unlock(&icmp_globals.lock); 735 755 return res; 736 756 } 737 757 738 int icmp_process_message( ipc_call_t * call){758 int icmp_process_message(ipc_call_t * call){ 739 759 ERROR_DECLARE; 740 760 741 packet_t packet;742 743 switch( IPC_GET_METHOD( * call)){761 packet_t packet; 762 763 switch(IPC_GET_METHOD(*call)){ 744 764 case NET_ICMP_DEST_UNREACH: 745 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){746 ERROR_CODE = icmp_destination_unreachable_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_MTU( call ), packet);765 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 766 ERROR_CODE = icmp_destination_unreachable_msg(0, ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet); 747 767 } 748 768 return ERROR_CODE; 749 769 case NET_ICMP_SOURCE_QUENCH: 750 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){751 ERROR_CODE = icmp_source_quench_msg( 0, packet);770 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 771 ERROR_CODE = icmp_source_quench_msg(0, packet); 752 772 } 753 773 return ERROR_CODE; 754 774 case NET_ICMP_TIME_EXCEEDED: 755 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){756 ERROR_CODE = icmp_time_exceeded_msg( 0, ICMP_GET_CODE( call ), packet);775 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 776 ERROR_CODE = icmp_time_exceeded_msg(0, ICMP_GET_CODE(call), packet); 757 777 } 758 778 return ERROR_CODE; 759 779 case NET_ICMP_PARAMETERPROB: 760 if( ! ERROR_OCCURRED( packet_translate( icmp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){761 ERROR_CODE = icmp_parameter_problem_msg( 0, ICMP_GET_CODE( call ), ICMP_GET_POINTER( call ), packet);780 if(! ERROR_OCCURRED(packet_translate(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 781 ERROR_CODE = icmp_parameter_problem_msg(0, ICMP_GET_CODE(call), ICMP_GET_POINTER(call), packet); 762 782 } 763 783 return ERROR_CODE; … … 767 787 } 768 788 769 int icmp_release_and_return( packet_t packet, int result){770 pq_release( icmp_globals.net_phone, packet_get_id( packet));789 int icmp_release_and_return(packet_t packet, int result){ 790 pq_release(icmp_globals.net_phone, packet_get_id(packet)); 771 791 return result; 772 792 } 773 793 774 int icmp_bind_free_id( icmp_echo_ref echo_data ){ 775 icmp_param_t index; 776 777 if( ! echo_data ) return EBADMEM; 794 int icmp_bind_free_id(icmp_echo_ref echo_data){ 795 icmp_param_t index; 796 797 if(! echo_data){ 798 return EBADMEM; 799 } 778 800 // from the last used one 779 801 index = icmp_globals.last_used_id; … … 781 803 ++ index; 782 804 // til the range end 783 if( index >= ICMP_FREE_IDS_END){805 if(index >= ICMP_FREE_IDS_END){ 784 806 // start from the range beginning 785 807 index = ICMP_FREE_IDS_START - 1; … … 787 809 ++ index; 788 810 // til the last used one 789 if( index >= icmp_globals.last_used_id){811 if(index >= icmp_globals.last_used_id){ 790 812 // none found 791 813 return ENOTCONN; 792 814 } 793 }while( icmp_echo_data_find( & icmp_globals.echo_data, index ) != NULL);815 }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL); 794 816 // found, break immediately 795 817 break; 796 818 } 797 }while( icmp_echo_data_find( & icmp_globals.echo_data, index ) != NULL);819 }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL); 798 820 echo_data->identifier = index; 799 821 echo_data->sequence_number = 0; 800 return icmp_echo_data_add( & icmp_globals.echo_data, index, echo_data);822 return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data); 801 823 } 802 824 -
uspace/srv/net/tl/icmp/icmp.h
raa85487 raadf01e 66 66 * Receiving fibril sets the associated reply with the return value and signals the event. 67 67 */ 68 INT_MAP_DECLARE( icmp_replies, icmp_reply_t);68 INT_MAP_DECLARE(icmp_replies, icmp_reply_t); 69 69 70 70 /** Echo specific data map. … … 72 72 * The identifier is used in the future semi-remote calls instead of the ICMP phone. 73 73 */ 74 INT_MAP_DECLARE( icmp_echo_data, icmp_echo_t);74 INT_MAP_DECLARE(icmp_echo_data, icmp_echo_t); 75 75 76 76 /** ICMP reply data. … … 79 79 /** Reply result. 80 80 */ 81 int result;81 int result; 82 82 /** Safety lock. 83 83 */ 84 fibril_mutex_t mutex;84 fibril_mutex_t mutex; 85 85 /** Received or timeouted reply signaling. 86 86 */ 87 fibril_condvar_t condvar;87 fibril_condvar_t condvar; 88 88 }; 89 89 … … 93 93 /** IP module phone. 94 94 */ 95 int ip_phone;95 int ip_phone; 96 96 /** Packet dimension. 97 97 */ 98 packet_dimension_t packet_dimension;98 packet_dimension_t packet_dimension; 99 99 /** Networking module phone. 100 100 */ 101 int net_phone;101 int net_phone; 102 102 /** Indicates whether ICMP error reporting is enabled. 103 103 */ 104 int error_reporting;104 int error_reporting; 105 105 /** Indicates whether ICMP echo replying (ping) is enabled. 106 106 */ 107 int echo_replying;107 int echo_replying; 108 108 /** The last used identifier number. 109 109 */ 110 icmp_param_t last_used_id;110 icmp_param_t last_used_id; 111 111 /** The budled modules assigned echo specific data. 112 112 */ 113 icmp_echo_data_t echo_data;113 icmp_echo_data_t echo_data; 114 114 /** Echo timeout locks. 115 115 */ 116 icmp_replies_t replies;116 icmp_replies_t replies; 117 117 /** Safety lock. 118 118 */ 119 fibril_rwlock_t lock;119 fibril_rwlock_t lock; 120 120 }; 121 121 -
uspace/srv/net/tl/icmp/icmp_api.c
raa85487 raadf01e 52 52 #include "icmp_messages.h" 53 53 54 int icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){55 aid_t message_id;56 ipcarg_t result;54 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ 55 aid_t message_id; 56 ipcarg_t result; 57 57 58 if( addrlen <= 0){58 if(addrlen <= 0){ 59 59 return EINVAL; 60 60 } 61 message_id = async_send_5( icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, tos, ( ipcarg_t ) dont_fragment, NULL);61 message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, tos, (ipcarg_t) dont_fragment, NULL); 62 62 // send the address 63 async_data_write_start( icmp_phone, addr, ( size_t ) addrlen);63 async_data_write_start(icmp_phone, addr, (size_t) addrlen); 64 64 // timeout version may cause inconsistency - there is also an inner timer 65 // return async_wait_timeout( message_id, & result, timeout);66 async_wait_for( message_id, & result);67 return ( int) result;65 // return async_wait_timeout(message_id, &result, timeout); 66 async_wait_for(message_id, &result); 67 return (int) result; 68 68 } 69 69 -
uspace/srv/net/tl/icmp/icmp_client.c
raa85487 raadf01e 49 49 #include "icmp_header.h" 50 50 51 int icmp_client_process_packet( packet_t packet, icmp_type_t * type, icmp_code_t * code, icmp_param_t * pointer, icmp_param_t * mtu){52 icmp_header_ref header;51 int icmp_client_process_packet(packet_t packet, icmp_type_t * type, icmp_code_t * code, icmp_param_t * pointer, icmp_param_t * mtu){ 52 icmp_header_ref header; 53 53 54 header = ( icmp_header_ref ) packet_get_data( packet);55 if(( ! header)56 || ( packet_get_data_length( packet ) < sizeof( icmp_header_t))){54 header = (icmp_header_ref) packet_get_data(packet); 55 if((! header) 56 || (packet_get_data_length(packet) < sizeof(icmp_header_t))){ 57 57 return 0; 58 58 } 59 if( type ) * type = header->type; 60 if( code ) * code = header->code; 61 if( pointer ) * pointer = header->un.param.pointer; 62 if( mtu ) * mtu = header->un.frag.mtu; 59 if(type){ 60 *type = header->type; 61 } 62 if(code){ 63 *code = header->code; 64 } 65 if(pointer){ 66 *pointer = header->un.param.pointer; 67 } 68 if(mtu){ 69 *mtu = header->un.frag.mtu; 70 } 63 71 // remove debug dump 64 // printf( "ICMP error %d (%d) in packet %d\n", header->type, header->code, packet_get_id( packet));65 return sizeof( icmp_header_t);72 // printf("ICMP error %d (%d) in packet %d\n", header->type, header->code, packet_get_id(packet)); 73 return sizeof(icmp_header_t); 66 74 } 67 75 68 size_t icmp_client_header_length( packet_t packet){69 if( packet_get_data_length( packet ) < sizeof( icmp_header_t)){76 size_t icmp_client_header_length(packet_t packet){ 77 if(packet_get_data_length(packet) < sizeof(icmp_header_t)){ 70 78 return 0; 71 79 } 72 return sizeof( icmp_header_t);80 return sizeof(icmp_header_t); 73 81 } 74 82 -
uspace/srv/net/tl/icmp/icmp_common.c
raa85487 raadf01e 45 45 #include "icmp_messages.h" 46 46 47 int icmp_connect_module( services_t service, suseconds_t timeout){48 int phone;47 int icmp_connect_module(services_t service, suseconds_t timeout){ 48 int phone; 49 49 50 phone = connect_to_service_timeout( SERVICE_ICMP, timeout);51 if( phone >= 0){52 async_req_0_0( phone, NET_ICMP_INIT);50 phone = connect_to_service_timeout(SERVICE_ICMP, timeout); 51 if(phone >= 0){ 52 async_req_0_0(phone, NET_ICMP_INIT); 53 53 } 54 54 return phone; -
uspace/srv/net/tl/icmp/icmp_header.h
raa85487 raadf01e 46 46 /** ICMP header size in bytes. 47 47 */ 48 #define ICMP_HEADER_SIZE sizeof( icmp_header_t)48 #define ICMP_HEADER_SIZE sizeof(icmp_header_t) 49 49 50 50 /** Type definition of the echo specific data. … … 63 63 /** Message idintifier. 64 64 */ 65 icmp_param_t identifier;65 icmp_param_t identifier; 66 66 /** Message sequence number. 67 67 */ 68 icmp_param_t sequence_number;68 icmp_param_t sequence_number; 69 69 } __attribute__ ((packed)); 70 70 … … 84 84 /** The type of the message. 85 85 */ 86 uint8_t type;86 uint8_t type; 87 87 /** The error code for the datagram reported by the ICMP message. 88 88 * The interpretation is dependent on the message type. 89 89 */ 90 uint8_t code;90 uint8_t code; 91 91 /** The checksum is the 16-bit ones's complement of the one's complement sum of the ICMP message starting with the ICMP Type. 92 92 * For computing the checksum, the checksum field should be zero. 93 93 * If the checksum does not match the contents, the datagram is discarded. 94 94 */ 95 uint16_t checksum;95 uint16_t checksum; 96 96 /** Message specific data. 97 97 */ … … 99 99 /** Echo specific data. 100 100 */ 101 icmp_echo_t echo;101 icmp_echo_t echo; 102 102 /** Proposed gateway value. 103 103 */ 104 in_addr_t gateway;104 in_addr_t gateway; 105 105 /** Fragmentation needed specific data. 106 106 */ … … 109 109 * Must be zero. 110 110 */ 111 icmp_param_t reserved;111 icmp_param_t reserved; 112 112 /** Proposed MTU. 113 113 */ 114 icmp_param_t mtu;114 icmp_param_t mtu; 115 115 } frag; 116 116 /** Parameter problem specific data. … … 119 119 /** Problem pointer. 120 120 */ 121 icmp_param_t pointer;121 icmp_param_t pointer; 122 122 /** Reserved field. 123 123 * Must be zero. 124 124 */ 125 icmp_param_t reserved;125 icmp_param_t reserved; 126 126 } param; 127 127 } un; -
uspace/srv/net/tl/icmp/icmp_messages.h
raa85487 raadf01e 82 82 * @param[in] call The message call structure. 83 83 */ 84 #define ICMP_GET_CODE( call ) ( icmp_code_t ) IPC_GET_ARG1( * call)84 #define ICMP_GET_CODE(call) (icmp_code_t) IPC_GET_ARG1(*call) 85 85 86 86 /** Returns the ICMP link MTU message parameter. 87 87 * @param[in] call The message call structure. 88 88 */ 89 #define ICMP_GET_MTU( call ) ( icmp_param_t ) IPC_GET_ARG3( * call)89 #define ICMP_GET_MTU(call) (icmp_param_t) IPC_GET_ARG3(*call) 90 90 91 91 /** Returns the pointer message parameter. 92 92 * @param[in] call The message call structure. 93 93 */ 94 #define ICMP_GET_POINTER( call ) ( icmp_param_t ) IPC_GET_ARG3( * call)94 #define ICMP_GET_POINTER(call) (icmp_param_t) IPC_GET_ARG3(*call) 95 95 96 96 /** Returns the size message parameter. 97 97 * @param[in] call The message call structure. 98 98 */ 99 #define ICMP_GET_SIZE( call ) ( size_t ) IPC_GET_ARG1( call)99 #define ICMP_GET_SIZE(call) (size_t) IPC_GET_ARG1(call) 100 100 101 101 /** Returns the timeout message parameter. 102 102 * @param[in] call The message call structure. 103 103 */ 104 #define ICMP_GET_TIMEOUT( call ) (( suseconds_t ) IPC_GET_ARG2( call))104 #define ICMP_GET_TIMEOUT(call) ((suseconds_t) IPC_GET_ARG2(call)) 105 105 106 106 /** Returns the time to live message parameter. 107 107 * @param[in] call The message call structure. 108 108 */ 109 #define ICMP_GET_TTL( call ) ( ip_ttl_t ) IPC_GET_ARG3( call)109 #define ICMP_GET_TTL(call) (ip_ttl_t) IPC_GET_ARG3(call) 110 110 111 111 /** Returns the type of service message parameter. 112 112 * @param[in] call The message call structure. 113 113 */ 114 #define ICMP_GET_TOS( call ) ( ip_tos_t ) IPC_GET_ARG4( call)114 #define ICMP_GET_TOS(call) (ip_tos_t) IPC_GET_ARG4(call) 115 115 116 116 /** Returns the dont fragment message parameter. 117 117 * @param[in] call The message call structure. 118 118 */ 119 #define ICMP_GET_DONT_FRAGMENT( call ) ( int ) IPC_GET_ARG5( call)119 #define ICMP_GET_DONT_FRAGMENT(call) (int) IPC_GET_ARG5(call) 120 120 121 121 /*@}*/ -
uspace/srv/net/tl/icmp/icmp_module.c
raa85487 raadf01e 61 61 * @see NAME 62 62 */ 63 void module_print_name( void);63 void module_print_name(void); 64 64 65 65 /** Starts the ICMP module. … … 70 70 * @returns Other error codes as defined for the REGISTER_ME() macro function. 71 71 */ 72 int module_start( async_client_conn_t client_connection);72 int module_start(async_client_conn_t client_connection); 73 73 74 74 /** Processes the ICMP message. … … 80 80 * @returns Other error codes as defined for the icmp_message() function. 81 81 */ 82 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 83 84 84 /** ICMP module global data. … … 86 86 extern icmp_globals_t icmp_globals; 87 87 88 void module_print_name( void){89 printf( "%s", NAME);88 void module_print_name(void){ 89 printf("%s", NAME); 90 90 } 91 91 92 int module_start( async_client_conn_t client_connection){92 int module_start(async_client_conn_t client_connection){ 93 93 ERROR_DECLARE; 94 94 95 ipcarg_t phonehash;95 ipcarg_t phonehash; 96 96 97 async_set_client_connection( client_connection);98 icmp_globals.net_phone = net_connect_module( SERVICE_NETWORKING);99 if( icmp_globals.net_phone < 0){97 async_set_client_connection(client_connection); 98 icmp_globals.net_phone = net_connect_module(SERVICE_NETWORKING); 99 if(icmp_globals.net_phone < 0){ 100 100 return icmp_globals.net_phone; 101 101 } 102 ERROR_PROPAGATE( pm_init());103 if( ERROR_OCCURRED( icmp_initialize( client_connection))104 || ERROR_OCCURRED( REGISTER_ME( SERVICE_ICMP, & phonehash))){102 ERROR_PROPAGATE(pm_init()); 103 if(ERROR_OCCURRED(icmp_initialize(client_connection)) 104 || ERROR_OCCURRED(REGISTER_ME(SERVICE_ICMP, &phonehash))){ 105 105 pm_destroy(); 106 106 return ERROR_CODE; … … 113 113 } 114 114 115 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){116 return icmp_message( callid, call, answer, answer_count);115 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 116 return icmp_message(callid, call, answer, answer_count); 117 117 } 118 118 -
uspace/srv/net/tl/icmp/icmp_module.h
raa85487 raadf01e 47 47 * @returns ENOMEM if there is not enough memory left. 48 48 */ 49 int icmp_initialize( async_client_conn_t client_connection);49 int icmp_initialize(async_client_conn_t client_connection); 50 50 51 51 /** Processes the ICMP message. … … 59 59 * @see IS_NET_ICMP_MESSAGE() 60 60 */ 61 int icmp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);61 int icmp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 62 62 63 63 #endif -
uspace/srv/net/tl/icmp/icmp_remote.c
raa85487 raadf01e 53 53 #include "icmp_messages.h" 54 54 55 int icmp_destination_unreachable_msg( int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){56 async_msg_3( icmp_phone, NET_ICMP_DEST_UNREACH, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet ), ( ipcarg_t ) mtu);55 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){ 56 async_msg_3(icmp_phone, NET_ICMP_DEST_UNREACH, (ipcarg_t) code, (ipcarg_t) packet_get_id(packet), (ipcarg_t) mtu); 57 57 return EOK; 58 58 } 59 59 60 int icmp_source_quench_msg( int icmp_phone, packet_t packet){61 async_msg_2( icmp_phone, NET_ICMP_SOURCE_QUENCH, 0, ( ipcarg_t ) packet_get_id( packet));60 int icmp_source_quench_msg(int icmp_phone, packet_t packet){ 61 async_msg_2(icmp_phone, NET_ICMP_SOURCE_QUENCH, 0, (ipcarg_t) packet_get_id(packet)); 62 62 return EOK; 63 63 } 64 64 65 int icmp_time_exceeded_msg( int icmp_phone, icmp_code_t code, packet_t packet){66 async_msg_2( icmp_phone, NET_ICMP_TIME_EXCEEDED, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet));65 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t packet){ 66 async_msg_2(icmp_phone, NET_ICMP_TIME_EXCEEDED, (ipcarg_t) code, (ipcarg_t) packet_get_id(packet)); 67 67 return EOK; 68 68 } 69 69 70 int icmp_parameter_problem_msg( int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){71 async_msg_3( icmp_phone, NET_ICMP_PARAMETERPROB, ( ipcarg_t ) code, ( ipcarg_t ) packet_get_id( packet ), ( ipcarg_t ) pointer);70 int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){ 71 async_msg_3(icmp_phone, NET_ICMP_PARAMETERPROB, (ipcarg_t) code, (ipcarg_t) packet_get_id(packet), (ipcarg_t) pointer); 72 72 return EOK; 73 73 } -
uspace/srv/net/tl/tcp/tcp.c
raa85487 raadf01e 123 123 * @param[in] higher_equal The last value in the interval. 124 124 */ 125 #define IS_IN_INTERVAL_OVERFLOW( lower, value, higher_equal ) (((( lower ) < ( value )) && ((( value ) <= ( higher_equal )) || (( higher_equal ) < ( lower )))) || ((( value ) <= ( higher_equal )) && (( higher_equal ) < ( lower))))125 #define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) ((((lower) < (value)) && (((value) <= (higher_equal)) || ((higher_equal) < (lower)))) || (((value) <= (higher_equal)) && ((higher_equal) < (lower)))) 126 126 127 127 /** Type definition of the TCP timeout. … … 142 142 /** TCP global data are going to be read only. 143 143 */ 144 int globals_read_only;144 int globals_read_only; 145 145 /** Socket port. 146 146 */ 147 int port;147 int port; 148 148 /** Local sockets. 149 149 */ 150 socket_cores_ref local_sockets;150 socket_cores_ref local_sockets; 151 151 /** Socket identifier. 152 152 */ 153 int socket_id;153 int socket_id; 154 154 /** Socket state. 155 155 */ 156 tcp_socket_state_t state;156 tcp_socket_state_t state; 157 157 /** Sent packet sequence number. 158 158 */ 159 int sequence_number;159 int sequence_number; 160 160 /** Timeout in microseconds. 161 161 */ 162 suseconds_t timeout;162 suseconds_t timeout; 163 163 /** Port map key. 164 164 */ 165 char * key;165 char * key; 166 166 /** Port map key length. 167 167 */ 168 size_t key_length;168 size_t key_length; 169 169 }; 170 170 … … 174 174 * @return The result parameter. 175 175 */ 176 int tcp_release_and_return( packet_t packet, int result);177 178 void tcp_prepare_operation_header( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize);179 int tcp_prepare_timeout( int ( * timeout_function )( void * tcp_timeout_t ), socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, int globals_read_only);180 void tcp_free_socket_data( socket_core_ref socket);181 int tcp_timeout( void * data);182 int tcp_release_after_timeout( void * data);183 int tcp_process_packet( device_id_t device_id, packet_t packet, services_t error);184 int tcp_connect_core( socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen);185 int tcp_queue_prepare_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);186 int tcp_queue_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);187 packet_t tcp_get_packets_to_send( socket_core_ref socket, tcp_socket_data_ref socket_data);188 void tcp_send_packets( device_id_t device_id, packet_t packet);189 void tcp_process_acknowledgement( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header);190 packet_t tcp_send_prepare_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number);191 packet_t tcp_prepare_copy( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number);192 void tcp_retransmit_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number);193 int tcp_create_notification_packet( packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize);194 void tcp_refresh_socket_data( tcp_socket_data_ref socket_data);195 void tcp_initialize_socket_data( tcp_socket_data_ref socket_data);196 int tcp_process_listen( socket_core_ref listening_socket, tcp_socket_data_ref listening_socket_data, tcp_header_ref header, packet_t packet, struct sockaddr * src, struct sockaddr * dest, size_t addrlen);197 int tcp_process_syn_sent( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);198 int tcp_process_syn_received( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);199 int tcp_process_established( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length);200 int tcp_queue_received_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length);201 202 int tcp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error);203 int tcp_process_client_messages( ipc_callid_t callid, ipc_call_t call);204 int tcp_listen_message( socket_cores_ref local_sockets, int socket_id, int backlog);205 int tcp_connect_message( socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen);206 int 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, int new_socket_id, size_t * data_fragment_size, size_t * addrlen);209 int tcp_close_message( socket_cores_ref local_sockets, int socket_id);176 int tcp_release_and_return(packet_t packet, int result); 177 178 void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize); 179 int tcp_prepare_timeout(int (*timeout_function)(void * tcp_timeout_t), socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, int globals_read_only); 180 void tcp_free_socket_data(socket_core_ref socket); 181 int tcp_timeout(void * data); 182 int tcp_release_after_timeout(void * data); 183 int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error); 184 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen); 185 int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length); 186 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length); 187 packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data); 188 void tcp_send_packets(device_id_t device_id, packet_t packet); 189 void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header); 190 packet_t tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number); 191 packet_t tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number); 192 void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number); 193 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize); 194 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data); 195 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data); 196 int tcp_process_listen(socket_core_ref listening_socket, tcp_socket_data_ref listening_socket_data, tcp_header_ref header, packet_t packet, struct sockaddr * src, struct sockaddr * dest, size_t addrlen); 197 int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 198 int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 199 int tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length); 200 int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length); 201 202 int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error); 203 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 204 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog); 205 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen); 206 int 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, int new_socket_id, size_t * data_fragment_size, size_t * addrlen); 209 int tcp_close_message(socket_cores_ref local_sockets, int socket_id); 210 210 211 211 /** TCP global data. … … 213 213 tcp_globals_t tcp_globals; 214 214 215 int tcp_initialize( async_client_conn_t client_connection){215 int tcp_initialize(async_client_conn_t client_connection){ 216 216 ERROR_DECLARE; 217 217 218 assert( client_connection);219 fibril_rwlock_initialize( & tcp_globals.lock);220 fibril_rwlock_write_lock( & tcp_globals.lock);221 tcp_globals.icmp_phone = icmp_connect_module( SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);222 tcp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, client_connection, tcp_received_msg);223 if( tcp_globals.ip_phone < 0){218 assert(client_connection); 219 fibril_rwlock_initialize(&tcp_globals.lock); 220 fibril_rwlock_write_lock(&tcp_globals.lock); 221 tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT); 222 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, client_connection, tcp_received_msg); 223 if(tcp_globals.ip_phone < 0){ 224 224 return tcp_globals.ip_phone; 225 225 } 226 ERROR_PROPAGATE( socket_ports_initialize( & tcp_globals.sockets));227 if( ERROR_OCCURRED( packet_dimensions_initialize( & tcp_globals.dimensions))){228 socket_ports_destroy( & tcp_globals.sockets);226 ERROR_PROPAGATE(socket_ports_initialize(&tcp_globals.sockets)); 227 if(ERROR_OCCURRED(packet_dimensions_initialize(&tcp_globals.dimensions))){ 228 socket_ports_destroy(&tcp_globals.sockets); 229 229 return ERROR_CODE; 230 230 } 231 231 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; 232 fibril_rwlock_write_unlock( & tcp_globals.lock);232 fibril_rwlock_write_unlock(&tcp_globals.lock); 233 233 return EOK; 234 234 } 235 235 236 int tcp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error){236 int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){ 237 237 ERROR_DECLARE; 238 238 239 if( receiver != SERVICE_TCP ) return EREFUSED; 240 fibril_rwlock_write_lock( & tcp_globals.lock ); 241 if( ERROR_OCCURRED( tcp_process_packet( device_id, packet, error ))){ 242 fibril_rwlock_write_unlock( & tcp_globals.lock ); 243 } 244 printf( "receive %d \n", ERROR_CODE ); 239 if(receiver != SERVICE_TCP){ 240 return EREFUSED; 241 } 242 fibril_rwlock_write_lock(&tcp_globals.lock); 243 if(ERROR_OCCURRED(tcp_process_packet(device_id, packet, error))){ 244 fibril_rwlock_write_unlock(&tcp_globals.lock); 245 } 246 printf("receive %d \n", ERROR_CODE); 245 247 246 248 return ERROR_CODE; 247 249 } 248 250 249 int tcp_process_packet( device_id_t device_id, packet_t packet, services_t error){251 int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error){ 250 252 ERROR_DECLARE; 251 253 252 size_t length;253 size_t offset;254 int result;255 tcp_header_ref header;256 socket_core_ref socket;257 tcp_socket_data_ref socket_data;258 packet_t next_packet;259 size_t total_length;260 uint32_t checksum;261 int fragments;262 icmp_type_t type;263 icmp_code_t code;264 struct sockaddr * src;265 struct sockaddr * dest;266 size_t addrlen;267 268 printf( "p1 \n");269 if( error){270 switch( error){254 size_t length; 255 size_t offset; 256 int result; 257 tcp_header_ref header; 258 socket_core_ref socket; 259 tcp_socket_data_ref socket_data; 260 packet_t next_packet; 261 size_t total_length; 262 uint32_t checksum; 263 int fragments; 264 icmp_type_t type; 265 icmp_code_t code; 266 struct sockaddr * src; 267 struct sockaddr * dest; 268 size_t addrlen; 269 270 printf("p1 \n"); 271 if(error){ 272 switch(error){ 271 273 case SERVICE_ICMP: 272 274 // process error 273 result = icmp_client_process_packet( packet, & type, & code, NULL, NULL);274 if( result < 0){275 return tcp_release_and_return( packet, result);276 } 277 length = ( size_t) result;278 if( ERROR_OCCURRED( packet_trim( packet, length, 0))){279 return tcp_release_and_return( packet, ERROR_CODE);275 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 276 if(result < 0){ 277 return tcp_release_and_return(packet, result); 278 } 279 length = (size_t) result; 280 if(ERROR_OCCURRED(packet_trim(packet, length, 0))){ 281 return tcp_release_and_return(packet, ERROR_CODE); 280 282 } 281 283 break; 282 284 default: 283 return tcp_release_and_return( packet, ENOTSUP);285 return tcp_release_and_return(packet, ENOTSUP); 284 286 } 285 287 } 286 288 287 289 // TODO process received ipopts? 288 result = ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL);289 // printf("ip len %d\n", result );290 if( result < 0){291 return tcp_release_and_return( packet, result);292 } 293 offset = ( size_t) result;294 295 length = packet_get_data_length( packet);296 // printf("packet len %d\n", length );297 if( length <= 0){298 return tcp_release_and_return( packet, EINVAL);299 } 300 if( length < TCP_HEADER_SIZE + offset){301 return tcp_release_and_return( packet, NO_DATA);290 result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL); 291 // printf("ip len %d\n", result); 292 if(result < 0){ 293 return tcp_release_and_return(packet, result); 294 } 295 offset = (size_t) result; 296 297 length = packet_get_data_length(packet); 298 // printf("packet len %d\n", length); 299 if(length <= 0){ 300 return tcp_release_and_return(packet, EINVAL); 301 } 302 if(length < TCP_HEADER_SIZE + offset){ 303 return tcp_release_and_return(packet, NO_DATA); 302 304 } 303 305 304 306 // trim all but TCP header 305 if( ERROR_OCCURRED( packet_trim( packet, offset, 0))){306 return tcp_release_and_return( packet, ERROR_CODE);307 if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){ 308 return tcp_release_and_return(packet, ERROR_CODE); 307 309 } 308 310 309 311 // get tcp header 310 header = ( tcp_header_ref ) packet_get_data( packet);311 if( ! header){312 return tcp_release_and_return( packet, NO_DATA);313 } 314 // printf( "header len %d, port %d \n", TCP_HEADER_LENGTH( header ), ntohs( header->destination_port));315 316 result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest);317 if( result <= 0){318 return tcp_release_and_return( packet, result);319 } 320 addrlen = ( size_t) result;321 322 if( ERROR_OCCURRED( tl_set_address_port( src, addrlen, ntohs( header->source_port)))){323 return tcp_release_and_return( packet, ERROR_CODE);312 header = (tcp_header_ref) packet_get_data(packet); 313 if(! header){ 314 return tcp_release_and_return(packet, NO_DATA); 315 } 316 // printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header), ntohs(header->destination_port)); 317 318 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); 319 if(result <= 0){ 320 return tcp_release_and_return(packet, result); 321 } 322 addrlen = (size_t) result; 323 324 if(ERROR_OCCURRED(tl_set_address_port(src, addrlen, ntohs(header->source_port)))){ 325 return tcp_release_and_return(packet, ERROR_CODE); 324 326 } 325 327 326 328 // find the destination socket 327 socket = socket_port_find( & tcp_globals.sockets, ntohs( header->destination_port ), ( const char * ) src, addrlen);328 if( ! socket){329 socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), (const char *) src, addrlen); 330 if(! socket){ 329 331 // printf("listening?\n"); 330 332 // find the listening destination socket 331 socket = socket_port_find( & tcp_globals.sockets, ntohs( header->destination_port ), SOCKET_MAP_KEY_LISTENING, 0);332 if( ! socket){333 if( tl_prepare_icmp_packet( tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error ) == EOK){334 icmp_destination_unreachable_msg( tcp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet);333 socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0); 334 if(! socket){ 335 if(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error) == EOK){ 336 icmp_destination_unreachable_msg(tcp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet); 335 337 } 336 338 return EADDRNOTAVAIL; 337 339 } 338 340 } 339 printf("socket id %d\n", socket->socket_id );340 socket_data = ( tcp_socket_data_ref) socket->specific_data;341 assert( socket_data);341 printf("socket id %d\n", socket->socket_id); 342 socket_data = (tcp_socket_data_ref) socket->specific_data; 343 assert(socket_data); 342 344 343 345 // some data received, clear the timeout counter … … 351 353 do{ 352 354 ++ fragments; 353 length = packet_get_data_length( next_packet);354 if( length <= 0){355 return tcp_release_and_return( packet, NO_DATA);355 length = packet_get_data_length(next_packet); 356 if(length <= 0){ 357 return tcp_release_and_return(packet, NO_DATA); 356 358 } 357 359 total_length += length; 358 360 // add partial checksum if set 359 if( ! error){360 checksum = compute_checksum( checksum, packet_get_data( packet ), packet_get_data_length( packet));361 } 362 }while(( next_packet = pq_next( next_packet)));363 // printf( "fragments %d of %d bytes\n", fragments, total_length);361 if(! error){ 362 checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet)); 363 } 364 }while((next_packet = pq_next(next_packet))); 365 // printf("fragments %d of %d bytes\n", fragments, total_length); 364 366 365 367 // printf("lock?\n"); 366 fibril_rwlock_write_lock( socket_data->local_lock);368 fibril_rwlock_write_lock(socket_data->local_lock); 367 369 // printf("locked\n"); 368 if( ! error){369 if( socket_data->state == TCP_SOCKET_LISTEN){370 if( socket_data->pseudo_header){371 free( socket_data->pseudo_header);370 if(! error){ 371 if(socket_data->state == TCP_SOCKET_LISTEN){ 372 if(socket_data->pseudo_header){ 373 free(socket_data->pseudo_header); 372 374 socket_data->pseudo_header = NULL; 373 375 socket_data->headerlen = 0; 374 376 } 375 if( ERROR_OCCURRED( ip_client_get_pseudo_header( IPPROTO_TCP, src, addrlen, dest, addrlen, total_length, & socket_data->pseudo_header, & socket_data->headerlen))){376 fibril_rwlock_write_unlock( socket_data->local_lock);377 return tcp_release_and_return( packet, ERROR_CODE);378 } 379 }else if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( socket_data->pseudo_header, socket_data->headerlen, total_length))){380 fibril_rwlock_write_unlock( socket_data->local_lock);381 return tcp_release_and_return( packet, ERROR_CODE);382 } 383 checksum = compute_checksum( checksum, socket_data->pseudo_header, socket_data->headerlen);384 if( flip_checksum( compact_checksum( checksum )) != IP_CHECKSUM_ZERO){385 printf( "checksum err %x -> %x\n", header->checksum, flip_checksum( compact_checksum( checksum)));386 fibril_rwlock_write_unlock( socket_data->local_lock);387 if( ! ERROR_OCCURRED( tl_prepare_icmp_packet( tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error))){377 if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen, dest, addrlen, total_length, &socket_data->pseudo_header, &socket_data->headerlen))){ 378 fibril_rwlock_write_unlock(socket_data->local_lock); 379 return tcp_release_and_return(packet, ERROR_CODE); 380 } 381 }else if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, total_length))){ 382 fibril_rwlock_write_unlock(socket_data->local_lock); 383 return tcp_release_and_return(packet, ERROR_CODE); 384 } 385 checksum = compute_checksum(checksum, socket_data->pseudo_header, socket_data->headerlen); 386 if(flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO){ 387 printf("checksum err %x -> %x\n", header->checksum, flip_checksum(compact_checksum(checksum))); 388 fibril_rwlock_write_unlock(socket_data->local_lock); 389 if(! ERROR_OCCURRED(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error))){ 388 390 // checksum error ICMP 389 icmp_parameter_problem_msg( tcp_globals.icmp_phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->checksum )) - (( size_t ) (( void * ) header )), packet);391 icmp_parameter_problem_msg(tcp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet); 390 392 } 391 393 return EINVAL; … … 393 395 } 394 396 395 fibril_rwlock_read_unlock( & tcp_globals.lock);397 fibril_rwlock_read_unlock(&tcp_globals.lock); 396 398 397 399 // TODO error reporting/handling 398 // printf( "st %d\n", socket_data->state);399 switch( socket_data->state){400 // printf("st %d\n", socket_data->state); 401 switch(socket_data->state){ 400 402 case TCP_SOCKET_LISTEN: 401 ERROR_CODE = tcp_process_listen( socket, socket_data, header, packet, src, dest, addrlen);403 ERROR_CODE = tcp_process_listen(socket, socket_data, header, packet, src, dest, addrlen); 402 404 break; 403 405 case TCP_SOCKET_SYN_RECEIVED: 404 ERROR_CODE = tcp_process_syn_received( socket, socket_data, header, packet);406 ERROR_CODE = tcp_process_syn_received(socket, socket_data, header, packet); 405 407 break; 406 408 case TCP_SOCKET_SYN_SENT: 407 ERROR_CODE = tcp_process_syn_sent( socket, socket_data, header, packet);409 ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header, packet); 408 410 break; 409 411 case TCP_SOCKET_FIN_WAIT_1: … … 416 418 // ack releasing the socket gets processed later 417 419 case TCP_SOCKET_ESTABLISHED: 418 ERROR_CODE = tcp_process_established( socket, socket_data, header, packet, fragments, total_length);420 ERROR_CODE = tcp_process_established(socket, socket_data, header, packet, fragments, total_length); 419 421 break; 420 422 default: 421 pq_release( tcp_globals.net_phone, packet_get_id( packet));422 } 423 424 if( ERROR_CODE != EOK){425 printf( "process %d\n", ERROR_CODE);426 fibril_rwlock_write_unlock( socket_data->local_lock);423 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 424 } 425 426 if(ERROR_CODE != EOK){ 427 printf("process %d\n", ERROR_CODE); 428 fibril_rwlock_write_unlock(socket_data->local_lock); 427 429 } 428 430 return EOK; 429 431 } 430 432 431 int tcp_process_established( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length){433 int tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length){ 432 434 ERROR_DECLARE; 433 435 434 packet_t next_packet;435 packet_t tmp_packet;436 uint32_t old_incoming;437 size_t order;438 uint32_t sequence_number;439 size_t length;440 size_t offset;441 uint32_t new_sequence_number;442 443 assert( socket);444 assert( socket_data);445 assert( socket->specific_data == socket_data);446 assert( header);447 assert( packet);448 449 new_sequence_number = ntohl( header->sequence_number);436 packet_t next_packet; 437 packet_t tmp_packet; 438 uint32_t old_incoming; 439 size_t order; 440 uint32_t sequence_number; 441 size_t length; 442 size_t offset; 443 uint32_t new_sequence_number; 444 445 assert(socket); 446 assert(socket_data); 447 assert(socket->specific_data == socket_data); 448 assert(header); 449 assert(packet); 450 451 new_sequence_number = ntohl(header->sequence_number); 450 452 old_incoming = socket_data->next_incoming; 451 453 452 if( header->finalize){454 if(header->finalize){ 453 455 socket_data->fin_incoming = new_sequence_number; 454 456 } 455 457 456 // printf( "pe %d < %d <= %d\n", new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length);458 // printf("pe %d < %d <= %d\n", new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length); 457 459 // trim begining if containing expected data 458 if( IS_IN_INTERVAL_OVERFLOW( new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length)){460 if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length)){ 459 461 // get the acknowledged offset 460 if( socket_data->next_incoming < new_sequence_number){462 if(socket_data->next_incoming < new_sequence_number){ 461 463 offset = new_sequence_number - socket_data->next_incoming; 462 464 }else{ 463 465 offset = socket_data->next_incoming - new_sequence_number; 464 466 } 465 // printf( "offset %d\n", offset);467 // printf("offset %d\n", offset); 466 468 new_sequence_number += offset; 467 469 total_length -= offset; 468 length = packet_get_data_length( packet);470 length = packet_get_data_length(packet); 469 471 // trim the acknowledged data 470 while( length <= offset){472 while(length <= offset){ 471 473 // release the acknowledged packets 472 next_packet = pq_next( packet);473 pq_release( tcp_globals.net_phone, packet_get_id( packet));474 next_packet = pq_next(packet); 475 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 474 476 packet = next_packet; 475 477 offset -= length; 476 length = packet_get_data_length( packet);477 } 478 if(( offset > 0)479 && ( ERROR_OCCURRED( packet_trim( packet, offset, 0)))){480 return tcp_release_and_return( packet, ERROR_CODE);481 } 482 assert( new_sequence_number == socket_data->next_incoming);478 length = packet_get_data_length(packet); 479 } 480 if((offset > 0) 481 && (ERROR_OCCURRED(packet_trim(packet, offset, 0)))){ 482 return tcp_release_and_return(packet, ERROR_CODE); 483 } 484 assert(new_sequence_number == socket_data->next_incoming); 483 485 } 484 486 485 487 // release if overflowing the window 486 // if( IS_IN_INTERVAL_OVERFLOW( socket_data->next_incoming + socket_data->window, new_sequence_number, new_sequence_number + total_length)){487 // return tcp_release_and_return( packet, EOVERFLOW);488 // if(IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming + socket_data->window, new_sequence_number, new_sequence_number + total_length)){ 489 // return tcp_release_and_return(packet, EOVERFLOW); 488 490 // } 489 491 490 492 /* 491 493 // trim end if overflowing the window 492 if( IS_IN_INTERVAL_OVERFLOW( new_sequence_number, socket_data->next_incoming + socket_data->window, new_sequence_number + total_length)){494 if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming + socket_data->window, new_sequence_number + total_length)){ 493 495 // get the allowed data length 494 if( socket_data->next_incoming + socket_data->window < new_sequence_number){496 if(socket_data->next_incoming + socket_data->window < new_sequence_number){ 495 497 offset = new_sequence_number - socket_data->next_incoming + socket_data->window; 496 498 }else{ … … 499 501 next_packet = packet; 500 502 // trim the overflowing data 501 while( next_packet && ( offset > 0)){502 length = packet_get_data_length( packet);503 if( length <= offset){504 next_packet = pq_next( next_packet);505 }else if( ERROR_OCCURRED( packet_trim( next_packet, 0, length - offset))){506 return tcp_release_and_return( packet, ERROR_CODE);503 while(next_packet && (offset > 0)){ 504 length = packet_get_data_length(packet); 505 if(length <= offset){ 506 next_packet = pq_next(next_packet); 507 }else if(ERROR_OCCURRED(packet_trim(next_packet, 0, length - offset))){ 508 return tcp_release_and_return(packet, ERROR_CODE); 507 509 } 508 510 offset -= length; … … 510 512 } 511 513 // release the overflowing packets 512 next_packet = pq_next( next_packet);513 if( next_packet){514 next_packet = pq_next(next_packet); 515 if(next_packet){ 514 516 tmp_packet = next_packet; 515 next_packet = pq_next( next_packet);516 pq_insert_after( tmp_packet, next_packet);517 pq_release( tcp_globals.net_phone, packet_get_id( tmp_packet));518 } 519 assert( new_sequence_number + total_length == socket_data->next_incoming + socket_data->window);517 next_packet = pq_next(next_packet); 518 pq_insert_after(tmp_packet, next_packet); 519 pq_release(tcp_globals.net_phone, packet_get_id(tmp_packet)); 520 } 521 assert(new_sequence_number + total_length == socket_data->next_incoming + socket_data->window); 520 522 } 521 523 */ 522 524 // the expected one arrived? 523 if( new_sequence_number == socket_data->next_incoming){525 if(new_sequence_number == socket_data->next_incoming){ 524 526 printf("expected\n"); 525 527 // process acknowledgement 526 tcp_process_acknowledgement( socket, socket_data, header);528 tcp_process_acknowledgement(socket, socket_data, header); 527 529 528 530 // remove the header 529 total_length -= TCP_HEADER_LENGTH( header);530 if( ERROR_OCCURRED( packet_trim( packet, TCP_HEADER_LENGTH( header ), 0))){531 return tcp_release_and_return( packet, ERROR_CODE);532 } 533 534 if( total_length){535 ERROR_PROPAGATE( tcp_queue_received_packet( socket, socket_data, packet, fragments, total_length));531 total_length -= TCP_HEADER_LENGTH(header); 532 if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){ 533 return tcp_release_and_return(packet, ERROR_CODE); 534 } 535 536 if(total_length){ 537 ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, fragments, total_length)); 536 538 }else{ 537 539 total_length = 1; … … 539 541 socket_data->next_incoming = old_incoming + total_length; 540 542 packet = socket_data->incoming; 541 while( packet){542 if( ERROR_OCCURRED( pq_get_order( socket_data->incoming, & order, NULL))){543 while(packet){ 544 if(ERROR_OCCURRED(pq_get_order(socket_data->incoming, &order, NULL))){ 543 545 // remove the corrupted packet 544 next_packet = pq_detach( packet);545 if( packet == socket_data->incoming){546 next_packet = pq_detach(packet); 547 if(packet == socket_data->incoming){ 546 548 socket_data->incoming = next_packet; 547 549 } 548 pq_release( tcp_globals.net_phone, packet_get_id( packet));550 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 549 551 packet = next_packet; 550 552 continue; 551 553 } 552 sequence_number = ( uint32_t) order;553 if( IS_IN_INTERVAL_OVERFLOW( sequence_number, old_incoming, socket_data->next_incoming)){554 sequence_number = (uint32_t) order; 555 if(IS_IN_INTERVAL_OVERFLOW(sequence_number, old_incoming, socket_data->next_incoming)){ 554 556 // move to the next 555 packet = pq_next( packet);557 packet = pq_next(packet); 556 558 // coninual data? 557 }else if( IS_IN_INTERVAL_OVERFLOW( old_incoming, sequence_number, socket_data->next_incoming)){559 }else if(IS_IN_INTERVAL_OVERFLOW(old_incoming, sequence_number, socket_data->next_incoming)){ 558 560 // detach the packet 559 next_packet = pq_detach( packet);560 if( packet == socket_data->incoming){561 next_packet = pq_detach(packet); 562 if(packet == socket_data->incoming){ 561 563 socket_data->incoming = next_packet; 562 564 } 563 565 // get data length 564 length = packet_get_data_length( packet);566 length = packet_get_data_length(packet); 565 567 new_sequence_number = sequence_number + length; 566 if( length <= 0){568 if(length <= 0){ 567 569 // remove the empty packet 568 pq_release( tcp_globals.net_phone, packet_get_id( packet));570 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 569 571 packet = next_packet; 570 572 continue; 571 573 } 572 574 // exactly following 573 if( sequence_number == socket_data->next_incoming){575 if(sequence_number == socket_data->next_incoming){ 574 576 // queue received data 575 ERROR_PROPAGATE( tcp_queue_received_packet( socket, socket_data, packet, 1, packet_get_data_length( packet)));577 ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet))); 576 578 socket_data->next_incoming = new_sequence_number; 577 579 packet = next_packet; 578 580 continue; 579 581 // at least partly following data? 580 }else if( IS_IN_INTERVAL_OVERFLOW( sequence_number, socket_data->next_incoming, new_sequence_number)){581 if( socket_data->next_incoming < new_sequence_number){582 }else if(IS_IN_INTERVAL_OVERFLOW(sequence_number, socket_data->next_incoming, new_sequence_number)){ 583 if(socket_data->next_incoming < new_sequence_number){ 582 584 length = new_sequence_number - socket_data->next_incoming; 583 585 }else{ 584 586 length = socket_data->next_incoming - new_sequence_number; 585 587 } 586 if( ! ERROR_OCCURRED( packet_trim( packet, length, 0))){588 if(! ERROR_OCCURRED(packet_trim(packet, length, 0))){ 587 589 // queue received data 588 ERROR_PROPAGATE( tcp_queue_received_packet( socket, socket_data, packet, 1, packet_get_data_length( packet)));590 ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet))); 589 591 socket_data->next_incoming = new_sequence_number; 590 592 packet = next_packet; … … 593 595 } 594 596 // remove the duplicit or corrupted packet 595 pq_release( tcp_globals.net_phone, packet_get_id( packet));597 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 596 598 packet = next_packet; 597 599 continue; … … 600 602 } 601 603 } 602 }else if( IS_IN_INTERVAL( socket_data->next_incoming, new_sequence_number, socket_data->next_incoming + socket_data->window)){604 }else if(IS_IN_INTERVAL(socket_data->next_incoming, new_sequence_number, socket_data->next_incoming + socket_data->window)){ 603 605 printf("in window\n"); 604 606 // process acknowledgement 605 tcp_process_acknowledgement( socket, socket_data, header);607 tcp_process_acknowledgement(socket, socket_data, header); 606 608 607 609 // remove the header 608 total_length -= TCP_HEADER_LENGTH( header);609 if( ERROR_OCCURRED( packet_trim( packet, TCP_HEADER_LENGTH( header ), 0))){610 return tcp_release_and_return( packet, ERROR_CODE);611 } 612 613 next_packet = pq_detach( packet);614 length = packet_get_data_length( packet);615 if( ERROR_OCCURRED( pq_add( & socket_data->incoming, packet, new_sequence_number, length))){610 total_length -= TCP_HEADER_LENGTH(header); 611 if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){ 612 return tcp_release_and_return(packet, ERROR_CODE); 613 } 614 615 next_packet = pq_detach(packet); 616 length = packet_get_data_length(packet); 617 if(ERROR_OCCURRED(pq_add(&socket_data->incoming, packet, new_sequence_number, length))){ 616 618 // remove the corrupted packets 617 pq_release( tcp_globals.net_phone, packet_get_id( packet));618 pq_release( tcp_globals.net_phone, packet_get_id( next_packet));619 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 620 pq_release(tcp_globals.net_phone, packet_get_id(next_packet)); 619 621 }else{ 620 while( next_packet){622 while(next_packet){ 621 623 new_sequence_number += length; 622 tmp_packet = pq_detach( next_packet);623 length = packet_get_data_length( next_packet);624 if( ERROR_OCCURRED( pq_set_order( next_packet, new_sequence_number, length))625 || ERROR_OCCURRED( pq_insert_after( packet, next_packet))){626 pq_release( tcp_globals.net_phone, packet_get_id( next_packet));624 tmp_packet = pq_detach(next_packet); 625 length = packet_get_data_length(next_packet); 626 if(ERROR_OCCURRED(pq_set_order(next_packet, new_sequence_number, length)) 627 || ERROR_OCCURRED(pq_insert_after(packet, next_packet))){ 628 pq_release(tcp_globals.net_phone, packet_get_id(next_packet)); 627 629 } 628 630 next_packet = tmp_packet; … … 632 634 printf("unexpected\n"); 633 635 // release duplicite or restricted 634 pq_release( tcp_globals.net_phone, packet_get_id( packet));636 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 635 637 } 636 638 637 639 // change state according to the acknowledging incoming fin 638 if( IS_IN_INTERVAL_OVERFLOW( old_incoming, socket_data->fin_incoming, socket_data->next_incoming)){639 switch( socket_data->state){640 if(IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming, socket_data->next_incoming)){ 641 switch(socket_data->state){ 640 642 case TCP_SOCKET_FIN_WAIT_1: 641 643 case TCP_SOCKET_FIN_WAIT_2: … … 650 652 } 651 653 652 packet = tcp_get_packets_to_send( socket, socket_data);653 if( ! packet){654 packet = tcp_get_packets_to_send(socket, socket_data); 655 if(! packet){ 654 656 // create the notification packet 655 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 0, 0));656 ERROR_PROPAGATE( tcp_queue_prepare_packet( socket, socket_data, packet, 1));657 packet = tcp_send_prepare_packet( socket, socket_data, packet, 1, socket_data->last_outgoing + 1);658 } 659 fibril_rwlock_write_unlock( socket_data->local_lock);657 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 0)); 658 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, 1)); 659 packet = tcp_send_prepare_packet(socket, socket_data, packet, 1, socket_data->last_outgoing + 1); 660 } 661 fibril_rwlock_write_unlock(socket_data->local_lock); 660 662 // send the packet 661 tcp_send_packets( socket_data->device_id, packet);663 tcp_send_packets(socket_data->device_id, packet); 662 664 return EOK; 663 665 } 664 666 665 int tcp_queue_received_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length){667 int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length){ 666 668 ERROR_DECLARE; 667 669 668 packet_dimension_ref packet_dimension;669 670 assert( socket);671 assert( socket_data);672 assert( socket->specific_data == socket_data);673 assert( packet);674 assert( fragments >= 1);675 assert( socket_data->window > total_length);670 packet_dimension_ref packet_dimension; 671 672 assert(socket); 673 assert(socket_data); 674 assert(socket->specific_data == socket_data); 675 assert(packet); 676 assert(fragments >= 1); 677 assert(socket_data->window > total_length); 676 678 677 679 // queue the received packet 678 if( ERROR_OCCURRED( dyn_fifo_push( & socket->received, packet_get_id( packet ), SOCKET_MAX_RECEIVED_SIZE))679 || ERROR_OCCURRED( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension))){680 return tcp_release_and_return( packet, ERROR_CODE);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))){ 682 return tcp_release_and_return(packet, ERROR_CODE); 681 683 } 682 684 … … 685 687 686 688 // notify the destination socket 687 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);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); 688 690 return EOK; 689 691 } 690 692 691 int tcp_process_syn_sent( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){693 int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){ 692 694 ERROR_DECLARE; 693 695 694 packet_t next_packet;695 696 assert( socket);697 assert( socket_data);698 assert( socket->specific_data == socket_data);699 assert( header);700 assert( packet);701 702 if( header->synchronize){696 packet_t next_packet; 697 698 assert(socket); 699 assert(socket_data); 700 assert(socket->specific_data == socket_data); 701 assert(header); 702 assert(packet); 703 704 if(header->synchronize){ 703 705 // process acknowledgement 704 tcp_process_acknowledgement( socket, socket_data, header);705 706 socket_data->next_incoming = ntohl( header->sequence_number) + 1;706 tcp_process_acknowledgement(socket, socket_data, header); 707 708 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 707 709 // release additional packets 708 next_packet = pq_detach( packet);709 if( next_packet){710 pq_release( tcp_globals.net_phone, packet_get_id( next_packet));710 next_packet = pq_detach(packet); 711 if(next_packet){ 712 pq_release(tcp_globals.net_phone, packet_get_id(next_packet)); 711 713 } 712 714 // trim if longer than the header 713 if(( packet_get_data_length( packet ) > sizeof( * header))714 && ERROR_OCCURRED( packet_trim( packet, 0, packet_get_data_length( packet ) - sizeof( * header)))){715 return tcp_release_and_return( packet, ERROR_CODE);716 } 717 tcp_prepare_operation_header( socket, socket_data, header, 0, 0);718 fibril_mutex_lock( & socket_data->operation.mutex);719 socket_data->operation.result = tcp_queue_packet( socket, socket_data, packet, 1);720 if( socket_data->operation.result == EOK){715 if((packet_get_data_length(packet) > sizeof(*header)) 716 && ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){ 717 return tcp_release_and_return(packet, ERROR_CODE); 718 } 719 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 720 fibril_mutex_lock(&socket_data->operation.mutex); 721 socket_data->operation.result = tcp_queue_packet(socket, socket_data, packet, 1); 722 if(socket_data->operation.result == EOK){ 721 723 socket_data->state = TCP_SOCKET_ESTABLISHED; 722 packet = tcp_get_packets_to_send( socket, socket_data);723 if( packet){724 fibril_rwlock_write_unlock( socket_data->local_lock);724 packet = tcp_get_packets_to_send(socket, socket_data); 725 if(packet){ 726 fibril_rwlock_write_unlock(socket_data->local_lock); 725 727 // send the packet 726 tcp_send_packets( socket_data->device_id, packet);728 tcp_send_packets(socket_data->device_id, packet); 727 729 // signal the result 728 fibril_condvar_signal( & socket_data->operation.condvar);729 fibril_mutex_unlock( & socket_data->operation.mutex);730 fibril_condvar_signal(&socket_data->operation.condvar); 731 fibril_mutex_unlock(&socket_data->operation.mutex); 730 732 return EOK; 731 733 } 732 734 } 733 fibril_mutex_unlock( & socket_data->operation.mutex);734 } 735 return tcp_release_and_return( packet, EINVAL);736 } 737 738 int tcp_process_listen( socket_core_ref listening_socket, tcp_socket_data_ref listening_socket_data, tcp_header_ref header, packet_t packet, struct sockaddr * src, struct sockaddr * dest, size_t addrlen){735 fibril_mutex_unlock(&socket_data->operation.mutex); 736 } 737 return tcp_release_and_return(packet, EINVAL); 738 } 739 740 int tcp_process_listen(socket_core_ref listening_socket, tcp_socket_data_ref listening_socket_data, tcp_header_ref header, packet_t packet, struct sockaddr * src, struct sockaddr * dest, size_t addrlen){ 739 741 ERROR_DECLARE; 740 742 741 packet_t next_packet;742 socket_core_ref socket;743 tcp_socket_data_ref socket_data;744 int socket_id;745 int listening_socket_id = listening_socket->socket_id;746 int listening_port = listening_socket->port;747 748 assert( listening_socket);749 assert( listening_socket_data);750 assert( listening_socket->specific_data == listening_socket_data);751 assert( header);752 assert( packet);753 754 // printf( "syn %d\n", header->synchronize);755 if( header->synchronize){756 socket_data = ( tcp_socket_data_ref ) malloc( sizeof( * socket_data));757 if( ! socket_data){758 return tcp_release_and_return( packet, ENOMEM);743 packet_t next_packet; 744 socket_core_ref socket; 745 tcp_socket_data_ref socket_data; 746 int socket_id; 747 int listening_socket_id = listening_socket->socket_id; 748 int listening_port = listening_socket->port; 749 750 assert(listening_socket); 751 assert(listening_socket_data); 752 assert(listening_socket->specific_data == listening_socket_data); 753 assert(header); 754 assert(packet); 755 756 // printf("syn %d\n", header->synchronize); 757 if(header->synchronize){ 758 socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data)); 759 if(! socket_data){ 760 return tcp_release_and_return(packet, ENOMEM); 759 761 }else{ 760 tcp_initialize_socket_data( socket_data);762 tcp_initialize_socket_data(socket_data); 761 763 socket_data->local_lock = listening_socket_data->local_lock; 762 764 socket_data->local_sockets = listening_socket_data->local_sockets; 763 765 socket_data->listening_socket_id = listening_socket->socket_id; 764 766 765 socket_data->next_incoming = ntohl( header->sequence_number);766 socket_data->treshold = socket_data->next_incoming + ntohs( header->window);767 socket_data->next_incoming = ntohl(header->sequence_number); 768 socket_data->treshold = socket_data->next_incoming + ntohs(header->window); 767 769 768 770 socket_data->addrlen = addrlen; 769 socket_data->addr = malloc( socket_data->addrlen);770 if( ! socket_data->addr){771 free( socket_data);772 return tcp_release_and_return( packet, ENOMEM);773 } 774 memcpy( socket_data->addr, src, socket_data->addrlen);775 776 socket_data->dest_port = ntohs( header->source_port);777 if( ERROR_OCCURRED( tl_set_address_port( socket_data->addr, socket_data->addrlen, socket_data->dest_port))){778 free( socket_data->addr);779 free( socket_data);780 pq_release( tcp_globals.net_phone, packet_get_id( packet));771 socket_data->addr = malloc(socket_data->addrlen); 772 if(! socket_data->addr){ 773 free(socket_data); 774 return tcp_release_and_return(packet, ENOMEM); 775 } 776 memcpy(socket_data->addr, src, socket_data->addrlen); 777 778 socket_data->dest_port = ntohs(header->source_port); 779 if(ERROR_OCCURRED(tl_set_address_port(socket_data->addr, socket_data->addrlen, socket_data->dest_port))){ 780 free(socket_data->addr); 781 free(socket_data); 782 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 781 783 return ERROR_CODE; 782 784 } 783 785 784 // printf( "addr %p\n", socket_data->addr, socket_data->addrlen);786 // printf("addr %p\n", socket_data->addr, socket_data->addrlen); 785 787 // create a socket 786 788 socket_id = -1; 787 if( ERROR_OCCURRED( socket_create( socket_data->local_sockets, listening_socket->phone, socket_data, & socket_id))){788 free( socket_data->addr);789 free( socket_data);790 return tcp_release_and_return( packet, ERROR_CODE);789 if(ERROR_OCCURRED(socket_create(socket_data->local_sockets, listening_socket->phone, socket_data, &socket_id))){ 790 free(socket_data->addr); 791 free(socket_data); 792 return tcp_release_and_return(packet, ERROR_CODE); 791 793 } 792 794 … … 797 799 listening_socket_data->headerlen = 0; 798 800 799 fibril_rwlock_write_unlock( socket_data->local_lock);801 fibril_rwlock_write_unlock(socket_data->local_lock); 800 802 // printf("list lg\n"); 801 fibril_rwlock_write_lock( & tcp_globals.lock);803 fibril_rwlock_write_lock(&tcp_globals.lock); 802 804 // printf("list locked\n"); 803 805 // find the destination socket 804 listening_socket = socket_port_find( & tcp_globals.sockets, listening_port, SOCKET_MAP_KEY_LISTENING, 0);805 if(( ! listening_socket ) || ( listening_socket->socket_id != listening_socket_id)){806 fibril_rwlock_write_unlock( & tcp_globals.lock);806 listening_socket = socket_port_find(&tcp_globals.sockets, listening_port, SOCKET_MAP_KEY_LISTENING, 0); 807 if((! listening_socket) || (listening_socket->socket_id != listening_socket_id)){ 808 fibril_rwlock_write_unlock(&tcp_globals.lock); 807 809 // a shadow may remain until app hangs up 808 return tcp_release_and_return( packet, EOK/*ENOTSOCK*/);809 } 810 // printf("port %d\n", listening_socket->port );811 listening_socket_data = ( tcp_socket_data_ref) listening_socket->specific_data;812 assert( listening_socket_data);810 return tcp_release_and_return(packet, EOK/*ENOTSOCK*/); 811 } 812 // printf("port %d\n", listening_socket->port); 813 listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data; 814 assert(listening_socket_data); 813 815 814 816 // printf("list ll\n"); 815 fibril_rwlock_write_lock( listening_socket_data->local_lock);817 fibril_rwlock_write_lock(listening_socket_data->local_lock); 816 818 // printf("list locked\n"); 817 819 818 socket = socket_cores_find( listening_socket_data->local_sockets, socket_id);819 if( ! socket){820 socket = socket_cores_find(listening_socket_data->local_sockets, socket_id); 821 if(! socket){ 820 822 // where is the socket?!? 821 fibril_rwlock_write_unlock( & tcp_globals.lock);823 fibril_rwlock_write_unlock(&tcp_globals.lock); 822 824 return ENOTSOCK; 823 825 } 824 socket_data = ( tcp_socket_data_ref) socket->specific_data;825 assert( socket_data);826 socket_data = (tcp_socket_data_ref) socket->specific_data; 827 assert(socket_data); 826 828 827 829 // uint8_t * data = socket_data->addr; 828 // printf( "addr %d of %x %x %x %x-%x %x %x %x-%x %x %x %x-%x %x %x %x\n", socket_data->addrlen, data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ], data[ 6 ], data[ 7 ], data[ 8 ], data[ 9 ], data[ 10 ], data[ 11 ], data[ 12 ], data[ 13 ], data[ 14 ], data[ 15 ]);829 830 ERROR_CODE = socket_port_add( & tcp_globals.sockets, listening_port, socket, ( const char * ) socket_data->addr, socket_data->addrlen);831 assert( socket == socket_port_find( & tcp_globals.sockets, listening_port, ( const char * ) socket_data->addr, socket_data->addrlen));832 //ERROR_CODE = socket_bind_free_port( & tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port);830 // printf("addr %d of %x %x %x %x-%x %x %x %x-%x %x %x %x-%x %x %x %x\n", socket_data->addrlen, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); 831 832 ERROR_CODE = socket_port_add(&tcp_globals.sockets, listening_port, socket, (const char *) socket_data->addr, socket_data->addrlen); 833 assert(socket == socket_port_find(&tcp_globals.sockets, listening_port, (const char *) socket_data->addr, socket_data->addrlen)); 834 //ERROR_CODE = socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port); 833 835 //tcp_globals.last_used_port = socket->port; 834 // printf("bound %d\n", socket->port );835 fibril_rwlock_write_unlock( & tcp_globals.lock);836 if( ERROR_CODE != EOK){837 socket_destroy( tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, & tcp_globals.sockets, tcp_free_socket_data);838 return tcp_release_and_return( packet, ERROR_CODE);836 // printf("bound %d\n", socket->port); 837 fibril_rwlock_write_unlock(&tcp_globals.lock); 838 if(ERROR_CODE != EOK){ 839 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 840 return tcp_release_and_return(packet, ERROR_CODE); 839 841 } 840 842 841 843 socket_data->state = TCP_SOCKET_LISTEN; 842 socket_data->next_incoming = ntohl( header->sequence_number) + 1;844 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 843 845 // release additional packets 844 next_packet = pq_detach( packet);845 if( next_packet){846 pq_release( tcp_globals.net_phone, packet_get_id( next_packet));846 next_packet = pq_detach(packet); 847 if(next_packet){ 848 pq_release(tcp_globals.net_phone, packet_get_id(next_packet)); 847 849 } 848 850 // trim if longer than the header 849 if(( packet_get_data_length( packet ) > sizeof( * header))850 && ERROR_OCCURRED( packet_trim( packet, 0, packet_get_data_length( packet ) - sizeof( * header)))){851 socket_destroy( tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, & tcp_globals.sockets, tcp_free_socket_data);852 return tcp_release_and_return( packet, ERROR_CODE);853 } 854 tcp_prepare_operation_header( socket, socket_data, header, 1, 0);855 if( ERROR_OCCURRED( tcp_queue_packet( socket, socket_data, packet, 1))){856 socket_destroy( tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, & tcp_globals.sockets, tcp_free_socket_data);851 if((packet_get_data_length(packet) > sizeof(*header)) 852 && ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){ 853 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 854 return tcp_release_and_return(packet, ERROR_CODE); 855 } 856 tcp_prepare_operation_header(socket, socket_data, header, 1, 0); 857 if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))){ 858 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 857 859 return ERROR_CODE; 858 860 } 859 packet = tcp_get_packets_to_send( socket, socket_data);860 // printf("send %d\n", packet_get_id( packet));861 if( ! packet){862 socket_destroy( tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, & tcp_globals.sockets, tcp_free_socket_data);861 packet = tcp_get_packets_to_send(socket, socket_data); 862 // printf("send %d\n", packet_get_id(packet)); 863 if(! packet){ 864 socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 863 865 return EINVAL; 864 866 }else{ 865 867 socket_data->state = TCP_SOCKET_SYN_RECEIVED; 866 868 // printf("unlock\n"); 867 fibril_rwlock_write_unlock( socket_data->local_lock);869 fibril_rwlock_write_unlock(socket_data->local_lock); 868 870 // send the packet 869 tcp_send_packets( socket_data->device_id, packet);871 tcp_send_packets(socket_data->device_id, packet); 870 872 return EOK; 871 873 } 872 874 } 873 875 } 874 return tcp_release_and_return( packet, EINVAL);875 } 876 877 int tcp_process_syn_received( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){876 return tcp_release_and_return(packet, EINVAL); 877 } 878 879 int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){ 878 880 ERROR_DECLARE; 879 881 880 socket_core_ref listening_socket;881 tcp_socket_data_ref listening_socket_data;882 883 assert( socket);884 assert( socket_data);885 assert( socket->specific_data == socket_data);886 assert( header);887 assert( packet);882 socket_core_ref listening_socket; 883 tcp_socket_data_ref listening_socket_data; 884 885 assert(socket); 886 assert(socket_data); 887 assert(socket->specific_data == socket_data); 888 assert(header); 889 assert(packet); 888 890 889 891 printf("syn_rec\n"); 890 if( header->acknowledge){892 if(header->acknowledge){ 891 893 // process acknowledgement 892 tcp_process_acknowledgement( socket, socket_data, header);893 894 socket_data->next_incoming = ntohl( header->sequence_number);// + 1;895 pq_release( tcp_globals.net_phone, packet_get_id( packet));894 tcp_process_acknowledgement(socket, socket_data, header); 895 896 socket_data->next_incoming = ntohl(header->sequence_number);// + 1; 897 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 896 898 socket_data->state = TCP_SOCKET_ESTABLISHED; 897 listening_socket = socket_cores_find( socket_data->local_sockets, socket_data->listening_socket_id);898 if( listening_socket){899 listening_socket_data = ( tcp_socket_data_ref) listening_socket->specific_data;900 assert( listening_socket_data);899 listening_socket = socket_cores_find(socket_data->local_sockets, socket_data->listening_socket_id); 900 if(listening_socket){ 901 listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data; 902 assert(listening_socket_data); 901 903 902 904 // queue the received packet 903 if( ! ERROR_OCCURRED( dyn_fifo_push( & listening_socket->accepted, ( -1 * socket->socket_id ), listening_socket_data->backlog))){905 if(! ERROR_OCCURRED(dyn_fifo_push(&listening_socket->accepted, (-1 * socket->socket_id), listening_socket_data->backlog))){ 904 906 // notify the destination socket 905 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);906 fibril_rwlock_write_unlock( socket_data->local_lock);907 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); 908 fibril_rwlock_write_unlock(socket_data->local_lock); 907 909 return EOK; 908 910 } … … 912 914 913 915 // create the notification packet 914 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 0, 1));916 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1)); 915 917 916 918 // send the packet 917 ERROR_PROPAGATE( tcp_queue_packet( socket, socket_data, packet, 1));919 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1)); 918 920 919 921 // flush packets 920 packet = tcp_get_packets_to_send( socket, socket_data);921 fibril_rwlock_write_unlock( socket_data->local_lock);922 if( packet){922 packet = tcp_get_packets_to_send(socket, socket_data); 923 fibril_rwlock_write_unlock(socket_data->local_lock); 924 if(packet){ 923 925 // send the packet 924 tcp_send_packets( socket_data->device_id, packet);926 tcp_send_packets(socket_data->device_id, packet); 925 927 } 926 928 return EOK; 927 929 }else{ 928 return tcp_release_and_return( packet, EINVAL);930 return tcp_release_and_return(packet, EINVAL); 929 931 } 930 932 return EINVAL; 931 933 } 932 934 933 void tcp_process_acknowledgement( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header){934 size_t number;935 size_t length;936 packet_t packet;937 packet_t next;938 packet_t acknowledged = NULL;939 uint32_t old;940 941 assert( socket);942 assert( socket_data);943 assert( socket->specific_data == socket_data);944 assert( header);945 946 if( header->acknowledge){947 number = ntohl( header->acknowledgement_number);935 void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header){ 936 size_t number; 937 size_t length; 938 packet_t packet; 939 packet_t next; 940 packet_t acknowledged = NULL; 941 uint32_t old; 942 943 assert(socket); 944 assert(socket_data); 945 assert(socket->specific_data == socket_data); 946 assert(header); 947 948 if(header->acknowledge){ 949 number = ntohl(header->acknowledgement_number); 948 950 // if more data acknowledged 949 if( number != socket_data->expected){951 if(number != socket_data->expected){ 950 952 old = socket_data->expected; 951 if( IS_IN_INTERVAL_OVERFLOW( old, socket_data->fin_outgoing, number)){952 switch( socket_data->state){953 if(IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing, number)){ 954 switch(socket_data->state){ 953 955 case TCP_SOCKET_FIN_WAIT_1: 954 956 socket_data->state = TCP_SOCKET_FIN_WAIT_2; … … 957 959 case TCP_SOCKET_CLOSING: 958 960 // fin acknowledged - release the socket in another fibril 959 tcp_prepare_timeout( tcp_release_after_timeout, socket, socket_data, 0, TCP_SOCKET_TIME_WAIT, NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true);961 tcp_prepare_timeout(tcp_release_after_timeout, socket, socket_data, 0, TCP_SOCKET_TIME_WAIT, NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true); 960 962 break; 961 963 default: … … 964 966 } 965 967 // update the treshold if higher than set 966 if( number + ntohs( header->window ) > socket_data->expected + socket_data->treshold){967 socket_data->treshold = number + ntohs( header->window) - socket_data->expected;968 if(number + ntohs(header->window) > socket_data->expected + socket_data->treshold){ 969 socket_data->treshold = number + ntohs(header->window) - socket_data->expected; 968 970 } 969 971 // set new expected sequence number … … 971 973 socket_data->expected_count = 1; 972 974 packet = socket_data->outgoing; 973 while( pq_get_order( packet, & number, & length ) == EOK){974 if( IS_IN_INTERVAL_OVERFLOW(( uint32_t ) old, ( uint32_t )( number + length ), ( uint32_t ) socket_data->expected)){975 next = pq_detach( packet);976 if( packet == socket_data->outgoing){975 while(pq_get_order(packet, &number, &length) == EOK){ 976 if(IS_IN_INTERVAL_OVERFLOW((uint32_t) old, (uint32_t)(number + length), (uint32_t) socket_data->expected)){ 977 next = pq_detach(packet); 978 if(packet == socket_data->outgoing){ 977 979 socket_data->outgoing = next; 978 980 } 979 981 // add to acknowledged or release 980 if( pq_add( & acknowledged, packet, 0, 0 ) != EOK){981 pq_release( tcp_globals.net_phone, packet_get_id( packet));982 if(pq_add(&acknowledged, packet, 0, 0) != EOK){ 983 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 982 984 } 983 985 packet = next; 984 }else if( old < socket_data->expected){986 }else if(old < socket_data->expected){ 985 987 break; 986 988 } 987 989 } 988 990 // release acknowledged 989 if( acknowledged){990 pq_release( tcp_globals.net_phone, packet_get_id( acknowledged));991 if(acknowledged){ 992 pq_release(tcp_globals.net_phone, packet_get_id(acknowledged)); 991 993 } 992 994 return; 993 995 // if the same as the previous time 994 }else if( number == socket_data->expected){996 }else if(number == socket_data->expected){ 995 997 // increase the counter 996 998 ++ socket_data->expected_count; 997 if( socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT){999 if(socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT){ 998 1000 socket_data->expected_count = 1; 999 1001 // TODO retransmit lock 1000 //tcp_retransmit_packet( socket, socket_data, number);1001 } 1002 } 1003 } 1004 } 1005 1006 int tcp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){1002 //tcp_retransmit_packet(socket, socket_data, number); 1003 } 1004 } 1005 } 1006 } 1007 1008 int tcp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 1007 1009 ERROR_DECLARE; 1008 1010 1009 packet_t packet;1010 1011 assert( call);1012 assert( answer);1013 assert( answer_count);1014 1015 * answer_count = 0;1016 switch( IPC_GET_METHOD( * call)){1011 packet_t packet; 1012 1013 assert(call); 1014 assert(answer); 1015 assert(answer_count); 1016 1017 *answer_count = 0; 1018 switch(IPC_GET_METHOD(*call)){ 1017 1019 case NET_TL_RECEIVED: 1018 //fibril_rwlock_read_lock( & tcp_globals.lock);1019 if( ! ERROR_OCCURRED( packet_translate( tcp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){1020 ERROR_CODE = tcp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_TCP, IPC_GET_ERROR( call));1021 } 1022 //fibril_rwlock_read_unlock( & tcp_globals.lock);1020 //fibril_rwlock_read_lock(&tcp_globals.lock); 1021 if(! ERROR_OCCURRED(packet_translate(tcp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 1022 ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP, IPC_GET_ERROR(call)); 1023 } 1024 //fibril_rwlock_read_unlock(&tcp_globals.lock); 1023 1025 return ERROR_CODE; 1024 1026 case IPC_M_CONNECT_TO_ME: 1025 return tcp_process_client_messages( callid, * call);1027 return tcp_process_client_messages(callid, * call); 1026 1028 } 1027 1029 return ENOTSUP; 1028 1030 } 1029 1031 1030 void tcp_refresh_socket_data( tcp_socket_data_ref socket_data){1031 assert( socket_data);1032 1033 bzero( socket_data, sizeof( * socket_data));1032 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data){ 1033 assert(socket_data); 1034 1035 bzero(socket_data, sizeof(*socket_data)); 1034 1036 socket_data->state = TCP_SOCKET_INITIAL; 1035 1037 socket_data->device_id = DEVICE_INVALID_ID; … … 1043 1045 } 1044 1046 1045 void tcp_initialize_socket_data( tcp_socket_data_ref socket_data){1046 assert( socket_data);1047 1048 tcp_refresh_socket_data( socket_data);1049 fibril_mutex_initialize( & socket_data->operation.mutex);1050 fibril_condvar_initialize( & socket_data->operation.condvar);1047 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data){ 1048 assert(socket_data); 1049 1050 tcp_refresh_socket_data(socket_data); 1051 fibril_mutex_initialize(&socket_data->operation.mutex); 1052 fibril_condvar_initialize(&socket_data->operation.condvar); 1051 1053 socket_data->data_fragment_size = MAX_TCP_FRAGMENT_SIZE; 1052 1054 } 1053 1055 1054 int tcp_process_client_messages( ipc_callid_t callid, ipc_call_t call){1055 int res;1056 bool keep_on_going = true;1057 socket_cores_t local_sockets;1058 int app_phone = IPC_GET_PHONE( & call);1059 struct sockaddr * addr;1060 size_t addrlen;1061 fibril_rwlock_t lock;1062 ipc_call_t answer;1063 int answer_count;1064 tcp_socket_data_ref socket_data;1065 socket_core_ref socket;1066 packet_dimension_ref packet_dimension;1056 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call){ 1057 int res; 1058 bool keep_on_going = true; 1059 socket_cores_t local_sockets; 1060 int app_phone = IPC_GET_PHONE(&call); 1061 struct sockaddr * addr; 1062 size_t addrlen; 1063 fibril_rwlock_t lock; 1064 ipc_call_t answer; 1065 int answer_count; 1066 tcp_socket_data_ref socket_data; 1067 socket_core_ref socket; 1068 packet_dimension_ref packet_dimension; 1067 1069 1068 1070 /* … … 1073 1075 answer_count = 0; 1074 1076 1075 socket_cores_initialize( & local_sockets);1076 fibril_rwlock_initialize( & lock);1077 1078 while( keep_on_going){1077 socket_cores_initialize(&local_sockets); 1078 fibril_rwlock_initialize(&lock); 1079 1080 while(keep_on_going){ 1079 1081 1080 1082 // answer the call 1081 answer_call( callid, res, & answer, answer_count);1083 answer_call(callid, res, &answer, answer_count); 1082 1084 1083 1085 // refresh data 1084 refresh_answer( & answer, & answer_count);1086 refresh_answer(&answer, &answer_count); 1085 1087 1086 1088 // get the next call 1087 callid = async_get_call( & call);1089 callid = async_get_call(&call); 1088 1090 1089 1091 // process the call 1090 switch( IPC_GET_METHOD( call)){1092 switch(IPC_GET_METHOD(call)){ 1091 1093 case IPC_M_PHONE_HUNGUP: 1092 1094 keep_on_going = false; … … 1094 1096 break; 1095 1097 case NET_SOCKET: 1096 socket_data = ( tcp_socket_data_ref ) malloc( sizeof( * socket_data));1097 if( ! socket_data){1098 socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data)); 1099 if(! socket_data){ 1098 1100 res = ENOMEM; 1099 1101 }else{ 1100 tcp_initialize_socket_data( socket_data);1101 socket_data->local_lock = & lock;1102 socket_data->local_sockets = & local_sockets;1103 fibril_rwlock_write_lock( & lock);1104 * SOCKET_SET_SOCKET_ID( answer ) = SOCKET_GET_SOCKET_ID( call);1105 res = socket_create( & local_sockets, app_phone, socket_data, SOCKET_SET_SOCKET_ID( answer));1106 fibril_rwlock_write_unlock( & lock);1107 if( res == EOK){1108 if( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, DEVICE_INVALID_ID, & packet_dimension ) == EOK){1109 * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size);1102 tcp_initialize_socket_data(socket_data); 1103 socket_data->local_lock = &lock; 1104 socket_data->local_sockets = &local_sockets; 1105 fibril_rwlock_write_lock(&lock); 1106 *SOCKET_SET_SOCKET_ID(answer) = SOCKET_GET_SOCKET_ID(call); 1107 res = socket_create(&local_sockets, app_phone, socket_data, SOCKET_SET_SOCKET_ID(answer)); 1108 fibril_rwlock_write_unlock(&lock); 1109 if(res == EOK){ 1110 if(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){ 1111 *SOCKET_SET_DATA_FRAGMENT_SIZE(answer) = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size); 1110 1112 } 1111 // * SOCKET_SET_DATA_FRAGMENT_SIZE( answer) = MAX_TCP_FRAGMENT_SIZE;1112 * SOCKET_SET_HEADER_SIZE( answer) = TCP_HEADER_SIZE;1113 // *SOCKET_SET_DATA_FRAGMENT_SIZE(answer) = MAX_TCP_FRAGMENT_SIZE; 1114 *SOCKET_SET_HEADER_SIZE(answer) = TCP_HEADER_SIZE; 1113 1115 answer_count = 3; 1114 1116 }else{ 1115 free( socket_data);1117 free(socket_data); 1116 1118 } 1117 1119 } 1118 1120 break; 1119 1121 case NET_SOCKET_BIND: 1120 res = data_receive(( void ** ) & addr, & addrlen);1121 if( res == EOK){1122 fibril_rwlock_write_lock( & tcp_globals.lock);1123 fibril_rwlock_write_lock( & lock);1124 res = socket_bind( & local_sockets, & tcp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port);1125 if( res == EOK){1126 socket = socket_cores_find( & local_sockets, SOCKET_GET_SOCKET_ID( call));1127 if( socket){1128 socket_data = ( tcp_socket_data_ref) socket->specific_data;1129 assert( socket_data);1122 res = data_receive((void **) &addr, &addrlen); 1123 if(res == EOK){ 1124 fibril_rwlock_write_lock(&tcp_globals.lock); 1125 fibril_rwlock_write_lock(&lock); 1126 res = socket_bind(&local_sockets, &tcp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port); 1127 if(res == EOK){ 1128 socket = socket_cores_find(&local_sockets, SOCKET_GET_SOCKET_ID(call)); 1129 if(socket){ 1130 socket_data = (tcp_socket_data_ref) socket->specific_data; 1131 assert(socket_data); 1130 1132 socket_data->state = TCP_SOCKET_LISTEN; 1131 1133 } 1132 1134 } 1133 fibril_rwlock_write_unlock( & lock);1134 fibril_rwlock_write_unlock( & tcp_globals.lock);1135 free( addr);1135 fibril_rwlock_write_unlock(&lock); 1136 fibril_rwlock_write_unlock(&tcp_globals.lock); 1137 free(addr); 1136 1138 } 1137 1139 break; 1138 1140 case NET_SOCKET_LISTEN: 1139 fibril_rwlock_read_lock( & tcp_globals.lock);1140 // fibril_rwlock_write_lock( & tcp_globals.lock);1141 fibril_rwlock_write_lock( & lock);1142 res = tcp_listen_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_BACKLOG( call));1143 fibril_rwlock_write_unlock( & lock);1144 // fibril_rwlock_write_unlock( & tcp_globals.lock);1145 fibril_rwlock_read_unlock( & tcp_globals.lock);1141 fibril_rwlock_read_lock(&tcp_globals.lock); 1142 // fibril_rwlock_write_lock(&tcp_globals.lock); 1143 fibril_rwlock_write_lock(&lock); 1144 res = tcp_listen_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_BACKLOG(call)); 1145 fibril_rwlock_write_unlock(&lock); 1146 // fibril_rwlock_write_unlock(&tcp_globals.lock); 1147 fibril_rwlock_read_unlock(&tcp_globals.lock); 1146 1148 break; 1147 1149 case NET_SOCKET_CONNECT: 1148 res = data_receive(( void ** ) & addr, & addrlen);1149 if( res == EOK){1150 res = data_receive((void **) &addr, &addrlen); 1151 if(res == EOK){ 1150 1152 // the global lock may be released in the tcp_connect_message() function 1151 fibril_rwlock_write_lock( & tcp_globals.lock);1152 fibril_rwlock_write_lock( & lock);1153 res = tcp_connect_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen);1154 if( res != EOK){1155 fibril_rwlock_write_unlock( & lock);1156 fibril_rwlock_write_unlock( & tcp_globals.lock);1157 free( addr);1153 fibril_rwlock_write_lock(&tcp_globals.lock); 1154 fibril_rwlock_write_lock(&lock); 1155 res = tcp_connect_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen); 1156 if(res != EOK){ 1157 fibril_rwlock_write_unlock(&lock); 1158 fibril_rwlock_write_unlock(&tcp_globals.lock); 1159 free(addr); 1158 1160 } 1159 1161 } 1160 1162 break; 1161 1163 case NET_SOCKET_ACCEPT: 1162 fibril_rwlock_read_lock( & tcp_globals.lock);1163 fibril_rwlock_write_lock( & lock);1164 res = tcp_accept_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_NEW_SOCKET_ID( call ), SOCKET_SET_DATA_FRAGMENT_SIZE( answer ), & addrlen);1165 fibril_rwlock_write_unlock( & lock);1166 fibril_rwlock_read_unlock( & tcp_globals.lock);1167 if( res > 0){1168 * SOCKET_SET_SOCKET_ID( answer) = res;1169 * SOCKET_SET_ADDRESS_LENGTH( answer) = addrlen;1164 fibril_rwlock_read_lock(&tcp_globals.lock); 1165 fibril_rwlock_write_lock(&lock); 1166 res = tcp_accept_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_NEW_SOCKET_ID(call), SOCKET_SET_DATA_FRAGMENT_SIZE(answer), &addrlen); 1167 fibril_rwlock_write_unlock(&lock); 1168 fibril_rwlock_read_unlock(&tcp_globals.lock); 1169 if(res > 0){ 1170 *SOCKET_SET_SOCKET_ID(answer) = res; 1171 *SOCKET_SET_ADDRESS_LENGTH(answer) = addrlen; 1170 1172 answer_count = 3; 1171 1173 } 1172 1174 break; 1173 1175 case NET_SOCKET_SEND: 1174 fibril_rwlock_read_lock( & tcp_globals.lock);1175 fibril_rwlock_write_lock( & lock);1176 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));1177 if( res != EOK){1178 fibril_rwlock_write_unlock( & lock);1179 fibril_rwlock_read_unlock( & tcp_globals.lock);1176 fibril_rwlock_read_lock(&tcp_globals.lock); 1177 fibril_rwlock_write_lock(&lock); 1178 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)); 1179 if(res != EOK){ 1180 fibril_rwlock_write_unlock(&lock); 1181 fibril_rwlock_read_unlock(&tcp_globals.lock); 1180 1182 }else{ 1181 1183 answer_count = 2; … … 1183 1185 break; 1184 1186 case NET_SOCKET_SENDTO: 1185 res = data_receive(( void ** ) & addr, & addrlen);1186 if( res == EOK){1187 fibril_rwlock_read_lock( & tcp_globals.lock);1188 fibril_rwlock_write_lock( & lock);1189 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));1190 if( res != EOK){1191 fibril_rwlock_write_unlock( & lock);1192 fibril_rwlock_read_unlock( & tcp_globals.lock);1187 res = data_receive((void **) &addr, &addrlen); 1188 if(res == EOK){ 1189 fibril_rwlock_read_lock(&tcp_globals.lock); 1190 fibril_rwlock_write_lock(&lock); 1191 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)); 1192 if(res != EOK){ 1193 fibril_rwlock_write_unlock(&lock); 1194 fibril_rwlock_read_unlock(&tcp_globals.lock); 1193 1195 }else{ 1194 1196 answer_count = 2; 1195 1197 } 1196 free( addr);1198 free(addr); 1197 1199 } 1198 1200 break; 1199 1201 case NET_SOCKET_RECV: 1200 fibril_rwlock_read_lock( & tcp_globals.lock);1201 fibril_rwlock_write_lock( & lock);1202 res = tcp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ), NULL);1203 fibril_rwlock_write_unlock( & lock);1204 fibril_rwlock_read_unlock( & tcp_globals.lock);1205 if( res > 0){1206 * SOCKET_SET_READ_DATA_LENGTH( answer) = res;1202 fibril_rwlock_read_lock(&tcp_globals.lock); 1203 fibril_rwlock_write_lock(&lock); 1204 res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), NULL); 1205 fibril_rwlock_write_unlock(&lock); 1206 fibril_rwlock_read_unlock(&tcp_globals.lock); 1207 if(res > 0){ 1208 *SOCKET_SET_READ_DATA_LENGTH(answer) = res; 1207 1209 answer_count = 1; 1208 1210 res = EOK; … … 1210 1212 break; 1211 1213 case NET_SOCKET_RECVFROM: 1212 fibril_rwlock_read_lock( & tcp_globals.lock);1213 fibril_rwlock_write_lock( & lock);1214 res = tcp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ), & addrlen);1215 fibril_rwlock_write_unlock( & lock);1216 fibril_rwlock_read_unlock( & tcp_globals.lock);1217 if( res > 0){1218 * SOCKET_SET_READ_DATA_LENGTH( answer) = res;1219 * SOCKET_SET_ADDRESS_LENGTH( answer) = addrlen;1214 fibril_rwlock_read_lock(&tcp_globals.lock); 1215 fibril_rwlock_write_lock(&lock); 1216 res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen); 1217 fibril_rwlock_write_unlock(&lock); 1218 fibril_rwlock_read_unlock(&tcp_globals.lock); 1219 if(res > 0){ 1220 *SOCKET_SET_READ_DATA_LENGTH(answer) = res; 1221 *SOCKET_SET_ADDRESS_LENGTH(answer) = addrlen; 1220 1222 answer_count = 3; 1221 1223 res = EOK; … … 1223 1225 break; 1224 1226 case NET_SOCKET_CLOSE: 1225 fibril_rwlock_write_lock( & tcp_globals.lock);1226 fibril_rwlock_write_lock( & lock);1227 res = tcp_close_message( & local_sockets, SOCKET_GET_SOCKET_ID( call));1228 if( res != EOK){1229 fibril_rwlock_write_unlock( & lock);1230 fibril_rwlock_write_unlock( & tcp_globals.lock);1227 fibril_rwlock_write_lock(&tcp_globals.lock); 1228 fibril_rwlock_write_lock(&lock); 1229 res = tcp_close_message(&local_sockets, SOCKET_GET_SOCKET_ID(call)); 1230 if(res != EOK){ 1231 fibril_rwlock_write_unlock(&lock); 1232 fibril_rwlock_write_unlock(&tcp_globals.lock); 1231 1233 } 1232 1234 break; … … 1241 1243 printf("release\n"); 1242 1244 // release all local sockets 1243 socket_cores_release( tcp_globals.net_phone, & local_sockets, & tcp_globals.sockets, tcp_free_socket_data);1245 socket_cores_release(tcp_globals.net_phone, &local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 1244 1246 1245 1247 return EOK; 1246 1248 } 1247 1249 1248 int tcp_timeout( void * data){1249 tcp_timeout_ref timeout = data;1250 int keep_write_lock = false;1251 socket_core_ref socket;1252 tcp_socket_data_ref socket_data;1253 1254 assert( timeout);1250 int tcp_timeout(void * data){ 1251 tcp_timeout_ref timeout = data; 1252 int keep_write_lock = false; 1253 socket_core_ref socket; 1254 tcp_socket_data_ref socket_data; 1255 1256 assert(timeout); 1255 1257 1256 1258 // sleep the given timeout 1257 async_usleep( timeout->timeout);1259 async_usleep(timeout->timeout); 1258 1260 // lock the globals 1259 if( timeout->globals_read_only){1260 fibril_rwlock_read_lock( & tcp_globals.lock);1261 if(timeout->globals_read_only){ 1262 fibril_rwlock_read_lock(&tcp_globals.lock); 1261 1263 }else{ 1262 fibril_rwlock_write_lock( & tcp_globals.lock);1264 fibril_rwlock_write_lock(&tcp_globals.lock); 1263 1265 } 1264 1266 // find the pending operation socket 1265 socket = socket_port_find( & tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length);1266 if( socket && ( socket->socket_id == timeout->socket_id)){1267 socket_data = ( tcp_socket_data_ref) socket->specific_data;1268 assert( socket_data);1269 if( socket_data->local_sockets == timeout->local_sockets){1270 fibril_rwlock_write_lock( socket_data->local_lock);1271 if( timeout->sequence_number){1267 socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length); 1268 if(socket && (socket->socket_id == timeout->socket_id)){ 1269 socket_data = (tcp_socket_data_ref) socket->specific_data; 1270 assert(socket_data); 1271 if(socket_data->local_sockets == timeout->local_sockets){ 1272 fibril_rwlock_write_lock(socket_data->local_lock); 1273 if(timeout->sequence_number){ 1272 1274 // increase the timeout counter; 1273 1275 ++ socket_data->timeout_count; 1274 if( socket_data->timeout_count == TCP_MAX_TIMEOUTS){1276 if(socket_data->timeout_count == TCP_MAX_TIMEOUTS){ 1275 1277 // TODO release as connection lost 1276 //tcp_refresh_socket_data( socket_data);1278 //tcp_refresh_socket_data(socket_data); 1277 1279 }else{ 1278 1280 // retransmit 1279 tcp_retransmit_packet( socket, socket_data, timeout->sequence_number);1280 } 1281 fibril_rwlock_write_unlock( socket_data->local_lock);1281 tcp_retransmit_packet(socket, socket_data, timeout->sequence_number); 1282 } 1283 fibril_rwlock_write_unlock(socket_data->local_lock); 1282 1284 }else{ 1283 fibril_mutex_lock( & socket_data->operation.mutex);1285 fibril_mutex_lock(&socket_data->operation.mutex); 1284 1286 // set the timeout operation result if state not changed 1285 if( socket_data->state == timeout->state){1287 if(socket_data->state == timeout->state){ 1286 1288 socket_data->operation.result = ETIMEOUT; 1287 1289 // notify the main fibril 1288 fibril_condvar_signal( & socket_data->operation.condvar);1290 fibril_condvar_signal(&socket_data->operation.condvar); 1289 1291 // keep the global write lock 1290 1292 keep_write_lock = true; … … 1292 1294 // operation is ok, do nothing 1293 1295 // unlocking from now on, so the unlock order does not matter... 1294 fibril_rwlock_write_unlock( socket_data->local_lock);1295 } 1296 fibril_mutex_unlock( & socket_data->operation.mutex);1296 fibril_rwlock_write_unlock(socket_data->local_lock); 1297 } 1298 fibril_mutex_unlock(&socket_data->operation.mutex); 1297 1299 } 1298 1300 } 1299 1301 } 1300 1302 // unlock only if no socket 1301 if( timeout->globals_read_only){1302 fibril_rwlock_read_unlock( & tcp_globals.lock);1303 }else if( ! keep_write_lock){1303 if(timeout->globals_read_only){ 1304 fibril_rwlock_read_unlock(&tcp_globals.lock); 1305 }else if(! keep_write_lock){ 1304 1306 // release if not desired 1305 fibril_rwlock_write_unlock( & tcp_globals.lock);1307 fibril_rwlock_write_unlock(&tcp_globals.lock); 1306 1308 } 1307 1309 // release the timeout structure 1308 free( timeout);1310 free(timeout); 1309 1311 return EOK; 1310 1312 } 1311 1313 1312 int tcp_release_after_timeout( void * data){1313 tcp_timeout_ref timeout = data;1314 socket_core_ref socket;1315 tcp_socket_data_ref socket_data;1316 fibril_rwlock_t * local_lock;1317 1318 assert( timeout);1314 int tcp_release_after_timeout(void * data){ 1315 tcp_timeout_ref timeout = data; 1316 socket_core_ref socket; 1317 tcp_socket_data_ref socket_data; 1318 fibril_rwlock_t * local_lock; 1319 1320 assert(timeout); 1319 1321 1320 1322 // sleep the given timeout 1321 async_usleep( timeout->timeout);1323 async_usleep(timeout->timeout); 1322 1324 // lock the globals 1323 fibril_rwlock_write_lock( & tcp_globals.lock);1325 fibril_rwlock_write_lock(&tcp_globals.lock); 1324 1326 // find the pending operation socket 1325 socket = socket_port_find( & tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length);1326 if( socket && ( socket->socket_id == timeout->socket_id)){1327 socket_data = ( tcp_socket_data_ref) socket->specific_data;1328 assert( socket_data);1329 if( socket_data->local_sockets == timeout->local_sockets){1327 socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length); 1328 if(socket && (socket->socket_id == timeout->socket_id)){ 1329 socket_data = (tcp_socket_data_ref) socket->specific_data; 1330 assert(socket_data); 1331 if(socket_data->local_sockets == timeout->local_sockets){ 1330 1332 local_lock = socket_data->local_lock; 1331 fibril_rwlock_write_lock( local_lock);1332 socket_destroy( tcp_globals.net_phone, timeout->socket_id, timeout->local_sockets, & tcp_globals.sockets, tcp_free_socket_data);1333 fibril_rwlock_write_unlock( local_lock);1333 fibril_rwlock_write_lock(local_lock); 1334 socket_destroy(tcp_globals.net_phone, timeout->socket_id, timeout->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 1335 fibril_rwlock_write_unlock(local_lock); 1334 1336 } 1335 1337 } 1336 1338 // unlock the globals 1337 fibril_rwlock_write_unlock( & tcp_globals.lock);1339 fibril_rwlock_write_unlock(&tcp_globals.lock); 1338 1340 // release the timeout structure 1339 free( timeout);1341 free(timeout); 1340 1342 return EOK; 1341 1343 } 1342 1344 1343 void tcp_retransmit_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){1344 packet_t packet;1345 packet_t copy;1346 size_t data_length;1347 1348 assert( socket);1349 assert( socket_data);1350 assert( socket->specific_data == socket_data);1345 void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){ 1346 packet_t packet; 1347 packet_t copy; 1348 size_t data_length; 1349 1350 assert(socket); 1351 assert(socket_data); 1352 assert(socket->specific_data == socket_data); 1351 1353 1352 1354 // sent packet? 1353 packet = pq_find( socket_data->outgoing, sequence_number);1354 printf("retransmit %d\n", packet_get_id( packet));1355 if( packet){1356 pq_get_order( packet, NULL, & data_length);1357 copy = tcp_prepare_copy( socket, socket_data, packet, data_length, sequence_number);1358 fibril_rwlock_write_unlock( socket_data->local_lock);1359 // printf( "r send %d\n", packet_get_id( packet));1360 if( copy){1361 tcp_send_packets( socket_data->device_id, copy);1355 packet = pq_find(socket_data->outgoing, sequence_number); 1356 printf("retransmit %d\n", packet_get_id(packet)); 1357 if(packet){ 1358 pq_get_order(packet, NULL, &data_length); 1359 copy = tcp_prepare_copy(socket, socket_data, packet, data_length, sequence_number); 1360 fibril_rwlock_write_unlock(socket_data->local_lock); 1361 // printf("r send %d\n", packet_get_id(packet)); 1362 if(copy){ 1363 tcp_send_packets(socket_data->device_id, copy); 1362 1364 } 1363 1365 }else{ 1364 fibril_rwlock_write_unlock( socket_data->local_lock ); 1365 } 1366 } 1367 1368 int tcp_listen_message( socket_cores_ref local_sockets, int socket_id, int backlog ){ 1369 socket_core_ref socket; 1370 tcp_socket_data_ref socket_data; 1371 1372 assert( local_sockets ); 1373 1374 if( backlog < 0 ) return EINVAL; 1366 fibril_rwlock_write_unlock(socket_data->local_lock); 1367 } 1368 } 1369 1370 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog){ 1371 socket_core_ref socket; 1372 tcp_socket_data_ref socket_data; 1373 1374 assert(local_sockets); 1375 1376 if(backlog < 0){ 1377 return EINVAL; 1378 } 1375 1379 // find the socket 1376 socket = socket_cores_find( local_sockets, socket_id ); 1377 if( ! socket ) return ENOTSOCK; 1380 socket = socket_cores_find(local_sockets, socket_id); 1381 if(! socket){ 1382 return ENOTSOCK; 1383 } 1378 1384 // get the socket specific data 1379 socket_data = ( tcp_socket_data_ref) socket->specific_data;1380 assert( socket_data);1385 socket_data = (tcp_socket_data_ref) socket->specific_data; 1386 assert(socket_data); 1381 1387 // set the backlog 1382 1388 socket_data->backlog = backlog; … … 1384 1390 } 1385 1391 1386 int tcp_connect_message( socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){1392 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){ 1387 1393 ERROR_DECLARE; 1388 1394 1389 socket_core_ref socket;1390 1391 assert( local_sockets);1392 assert( addr);1393 assert( addrlen > 0);1395 socket_core_ref socket; 1396 1397 assert(local_sockets); 1398 assert(addr); 1399 assert(addrlen > 0); 1394 1400 1395 1401 // find the socket 1396 socket = socket_cores_find( local_sockets, socket_id ); 1397 if( ! socket ) return ENOTSOCK; 1398 if( ERROR_OCCURRED( tcp_connect_core( socket, local_sockets, addr, addrlen ))){ 1399 tcp_free_socket_data( socket ); 1402 socket = socket_cores_find(local_sockets, socket_id); 1403 if(! socket){ 1404 return ENOTSOCK; 1405 } 1406 if(ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr, addrlen))){ 1407 tcp_free_socket_data(socket); 1400 1408 // unbind if bound 1401 if( socket->port > 0){1402 socket_ports_exclude( & tcp_globals.sockets, socket->port);1409 if(socket->port > 0){ 1410 socket_ports_exclude(&tcp_globals.sockets, socket->port); 1403 1411 socket->port = 0; 1404 1412 } … … 1407 1415 } 1408 1416 1409 int tcp_connect_core( socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){1417 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){ 1410 1418 ERROR_DECLARE; 1411 1419 1412 tcp_socket_data_ref socket_data;1413 packet_t packet;1414 1415 assert( socket);1416 assert( addr);1417 assert( addrlen > 0);1420 tcp_socket_data_ref socket_data; 1421 packet_t packet; 1422 1423 assert(socket); 1424 assert(addr); 1425 assert(addrlen > 0); 1418 1426 1419 1427 // get the socket specific data 1420 socket_data = ( tcp_socket_data_ref) socket->specific_data;1421 assert( socket_data);1422 assert( socket->specific_data == socket_data);1423 if(( socket_data->state != TCP_SOCKET_INITIAL)1424 && (( socket_data->state != TCP_SOCKET_LISTEN ) || ( socket->port <= 0))){1428 socket_data = (tcp_socket_data_ref) socket->specific_data; 1429 assert(socket_data); 1430 assert(socket->specific_data == socket_data); 1431 if((socket_data->state != TCP_SOCKET_INITIAL) 1432 && ((socket_data->state != TCP_SOCKET_LISTEN) || (socket->port <= 0))){ 1425 1433 return EINVAL; 1426 1434 } 1427 1435 // get the destination port 1428 ERROR_PROPAGATE( tl_get_address_port( addr, addrlen, & socket_data->dest_port));1429 if( socket->port <= 0){1436 ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &socket_data->dest_port)); 1437 if(socket->port <= 0){ 1430 1438 // try to find a free port 1431 ERROR_PROPAGATE( socket_bind_free_port( & tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port));1439 ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port)); 1432 1440 // set the next port as the search starting port number 1433 1441 tcp_globals.last_used_port = socket->port; 1434 1442 } 1435 ERROR_PROPAGATE( ip_get_route_req( tcp_globals.ip_phone, IPPROTO_TCP, addr, addrlen, & socket_data->device_id, & socket_data->pseudo_header, & socket_data->headerlen));1443 ERROR_PROPAGATE(ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP, addr, addrlen, &socket_data->device_id, &socket_data->pseudo_header, &socket_data->headerlen)); 1436 1444 1437 1445 // create the notification packet 1438 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 1, 0));1446 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 1, 0)); 1439 1447 1440 1448 // unlock the globals and wait for an operation 1441 fibril_rwlock_write_unlock( & tcp_globals.lock);1449 fibril_rwlock_write_unlock(&tcp_globals.lock); 1442 1450 1443 1451 socket_data->addr = addr; 1444 1452 socket_data->addrlen = addrlen; 1445 1453 // send the packet 1446 if( ERROR_OCCURRED( tcp_queue_packet( socket, socket_data, packet, 1))1447 || ERROR_OCCURRED( tcp_prepare_timeout( tcp_timeout, socket, socket_data, 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))){1454 if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1)) 1455 || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))){ 1448 1456 socket_data->addr = NULL; 1449 1457 socket_data->addrlen = 0; 1450 fibril_rwlock_write_lock( & tcp_globals.lock);1458 fibril_rwlock_write_lock(&tcp_globals.lock); 1451 1459 }else{ 1452 packet = tcp_get_packets_to_send( socket, socket_data);1453 if( packet){1454 fibril_mutex_lock( & socket_data->operation.mutex);1455 fibril_rwlock_write_unlock( socket_data->local_lock);1460 packet = tcp_get_packets_to_send(socket, socket_data); 1461 if(packet){ 1462 fibril_mutex_lock(&socket_data->operation.mutex); 1463 fibril_rwlock_write_unlock(socket_data->local_lock); 1456 1464 // send the packet 1457 printf( "connecting %d\n", packet_get_id( packet));1458 tcp_send_packets( socket_data->device_id, packet);1465 printf("connecting %d\n", packet_get_id(packet)); 1466 tcp_send_packets(socket_data->device_id, packet); 1459 1467 // wait for a reply 1460 fibril_condvar_wait( & socket_data->operation.condvar, & socket_data->operation.mutex);1468 fibril_condvar_wait(&socket_data->operation.condvar, &socket_data->operation.mutex); 1461 1469 ERROR_CODE = socket_data->operation.result; 1462 if( ERROR_CODE != EOK){1470 if(ERROR_CODE != EOK){ 1463 1471 socket_data->addr = NULL; 1464 1472 socket_data->addrlen = 0; … … 1471 1479 } 1472 1480 1473 fibril_mutex_unlock( & socket_data->operation.mutex);1481 fibril_mutex_unlock(&socket_data->operation.mutex); 1474 1482 1475 1483 // return the result … … 1477 1485 } 1478 1486 1479 int tcp_queue_prepare_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){1487 int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){ 1480 1488 ERROR_DECLARE; 1481 1489 1482 tcp_header_ref header;1483 1484 assert( socket);1485 assert( socket_data);1486 assert( socket->specific_data == socket_data);1490 tcp_header_ref header; 1491 1492 assert(socket); 1493 assert(socket_data); 1494 assert(socket->specific_data == socket_data); 1487 1495 1488 1496 // get tcp header 1489 header = ( tcp_header_ref ) packet_get_data( packet ); 1490 if( ! header ) return NO_DATA; 1491 header->destination_port = htons( socket_data->dest_port ); 1492 header->source_port = htons( socket->port ); 1493 header->sequence_number = htonl( socket_data->next_outgoing ); 1494 if( ERROR_OCCURRED( packet_set_addr( packet, NULL, ( uint8_t * ) socket_data->addr, socket_data->addrlen ))){ 1495 return tcp_release_and_return( packet, EINVAL ); 1497 header = (tcp_header_ref) packet_get_data(packet); 1498 if(! header){ 1499 return NO_DATA; 1500 } 1501 header->destination_port = htons(socket_data->dest_port); 1502 header->source_port = htons(socket->port); 1503 header->sequence_number = htonl(socket_data->next_outgoing); 1504 if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr, socket_data->addrlen))){ 1505 return tcp_release_and_return(packet, EINVAL); 1496 1506 } 1497 1507 // remember the outgoing FIN 1498 if( header->finalize){1508 if(header->finalize){ 1499 1509 socket_data->fin_outgoing = socket_data->next_outgoing; 1500 1510 } … … 1502 1512 } 1503 1513 1504 int tcp_queue_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){1514 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){ 1505 1515 ERROR_DECLARE; 1506 1516 1507 assert( socket);1508 assert( socket_data);1509 assert( socket->specific_data == socket_data);1510 1511 ERROR_PROPAGATE( tcp_queue_prepare_packet( socket, socket_data, packet, data_length));1512 1513 if( ERROR_OCCURRED( pq_add( & socket_data->outgoing, packet, socket_data->next_outgoing, data_length))){1514 return tcp_release_and_return( packet, ERROR_CODE);1517 assert(socket); 1518 assert(socket_data); 1519 assert(socket->specific_data == socket_data); 1520 1521 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, data_length)); 1522 1523 if(ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing, data_length))){ 1524 return tcp_release_and_return(packet, ERROR_CODE); 1515 1525 } 1516 1526 socket_data->next_outgoing += data_length; … … 1518 1528 } 1519 1529 1520 packet_t tcp_get_packets_to_send( socket_core_ref socket, tcp_socket_data_ref socket_data){1530 packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data){ 1521 1531 ERROR_DECLARE; 1522 1532 1523 packet_t packet;1524 packet_t copy;1525 packet_t sending = NULL;1526 packet_t previous = NULL;1527 size_t data_length;1528 1529 assert( socket);1530 assert( socket_data);1531 assert( socket->specific_data == socket_data);1532 1533 packet = pq_find( socket_data->outgoing, socket_data->last_outgoing + 1);1534 while( packet){1535 pq_get_order( packet, NULL, & data_length);1533 packet_t packet; 1534 packet_t copy; 1535 packet_t sending = NULL; 1536 packet_t previous = NULL; 1537 size_t data_length; 1538 1539 assert(socket); 1540 assert(socket_data); 1541 assert(socket->specific_data == socket_data); 1542 1543 packet = pq_find(socket_data->outgoing, socket_data->last_outgoing + 1); 1544 while(packet){ 1545 pq_get_order(packet, NULL, &data_length); 1536 1546 // send only if fits into the window 1537 1547 // respecting the possible overflow 1538 if( IS_IN_INTERVAL_OVERFLOW(( uint32_t ) socket_data->last_outgoing, ( uint32_t )( socket_data->last_outgoing + data_length ), ( uint32_t )( socket_data->expected + socket_data->treshold))){1539 copy = tcp_prepare_copy( socket, socket_data, packet, data_length, socket_data->last_outgoing + 1);1540 if( ! copy){1548 if(IS_IN_INTERVAL_OVERFLOW((uint32_t) socket_data->last_outgoing, (uint32_t)(socket_data->last_outgoing + data_length), (uint32_t)(socket_data->expected + socket_data->treshold))){ 1549 copy = tcp_prepare_copy(socket, socket_data, packet, data_length, socket_data->last_outgoing + 1); 1550 if(! copy){ 1541 1551 return sending; 1542 1552 } 1543 if( ! sending){1553 if(! sending){ 1544 1554 sending = copy; 1545 1555 }else{ 1546 if( ERROR_OCCURRED( pq_insert_after( previous, copy))){1547 pq_release( tcp_globals.net_phone, packet_get_id( copy));1556 if(ERROR_OCCURRED(pq_insert_after(previous, copy))){ 1557 pq_release(tcp_globals.net_phone, packet_get_id(copy)); 1548 1558 return sending; 1549 1559 } 1550 1560 } 1551 1561 previous = copy; 1552 packet = pq_next( packet);1562 packet = pq_next(packet); 1553 1563 // overflow occurred ? 1554 if(( ! packet ) && ( socket_data->last_outgoing > socket_data->next_outgoing)){1564 if((! packet) && (socket_data->last_outgoing > socket_data->next_outgoing)){ 1555 1565 printf("gpts overflow\n"); 1556 1566 // continue from the beginning … … 1565 1575 } 1566 1576 1567 packet_t tcp_send_prepare_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){1577 packet_t tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){ 1568 1578 ERROR_DECLARE; 1569 1579 1570 tcp_header_ref header;1571 uint32_t checksum;1572 1573 assert( socket);1574 assert( socket_data);1575 assert( socket->specific_data == socket_data);1580 tcp_header_ref header; 1581 uint32_t checksum; 1582 1583 assert(socket); 1584 assert(socket_data); 1585 assert(socket->specific_data == socket_data); 1576 1586 1577 1587 // adjust the pseudo header 1578 if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length( packet)))){1579 pq_release( tcp_globals.net_phone, packet_get_id( packet));1588 if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length(packet)))){ 1589 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1580 1590 return NULL; 1581 1591 } 1582 1592 1583 1593 // get the header 1584 header = ( tcp_header_ref ) packet_get_data( packet);1585 if( ! header){1586 pq_release( tcp_globals.net_phone, packet_get_id( packet));1594 header = (tcp_header_ref) packet_get_data(packet); 1595 if(! header){ 1596 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1587 1597 return NULL; 1588 1598 } 1589 assert( ntohl( header->sequence_number ) == sequence_number);1599 assert(ntohl(header->sequence_number) == sequence_number); 1590 1600 1591 1601 // adjust the header 1592 if( socket_data->next_incoming){1593 header->acknowledgement_number = htonl( socket_data->next_incoming);1602 if(socket_data->next_incoming){ 1603 header->acknowledgement_number = htonl(socket_data->next_incoming); 1594 1604 header->acknowledge = 1; 1595 1605 } 1596 header->window = htons( socket_data->window);1606 header->window = htons(socket_data->window); 1597 1607 1598 1608 // checksum 1599 1609 header->checksum = 0; 1600 checksum = compute_checksum( 0, socket_data->pseudo_header, socket_data->headerlen);1601 checksum = compute_checksum( checksum, ( uint8_t * ) packet_get_data( packet ), packet_get_data_length( packet));1602 header->checksum = htons( flip_checksum( compact_checksum( checksum)));1610 checksum = compute_checksum(0, socket_data->pseudo_header, socket_data->headerlen); 1611 checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet), packet_get_data_length(packet)); 1612 header->checksum = htons(flip_checksum(compact_checksum(checksum))); 1603 1613 // prepare the packet 1604 if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_TCP, 0, 0, 0, 0))1614 if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0)) 1605 1615 // prepare the timeout 1606 || ERROR_OCCURRED( tcp_prepare_timeout( tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true))){1607 pq_release( tcp_globals.net_phone, packet_get_id( packet));1616 || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true))){ 1617 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1608 1618 return NULL; 1609 1619 } … … 1611 1621 } 1612 1622 1613 packet_t tcp_prepare_copy( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){1614 packet_t copy;1615 1616 assert( socket);1617 assert( socket_data);1618 assert( socket->specific_data == socket_data);1623 packet_t tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){ 1624 packet_t copy; 1625 1626 assert(socket); 1627 assert(socket_data); 1628 assert(socket->specific_data == socket_data); 1619 1629 1620 1630 // make a copy of the packet 1621 copy = packet_get_copy( tcp_globals.net_phone, packet ); 1622 if( ! copy ) return NULL; 1623 1624 return tcp_send_prepare_packet( socket, socket_data, copy, data_length, sequence_number ); 1625 } 1626 1627 void tcp_send_packets( device_id_t device_id, packet_t packet ){ 1628 packet_t next; 1629 1630 while( packet ){ 1631 next = pq_detach( packet ); 1632 ip_send_msg( tcp_globals.ip_phone, device_id, packet, SERVICE_TCP, 0 ); 1631 copy = packet_get_copy(tcp_globals.net_phone, packet); 1632 if(! copy){ 1633 return NULL; 1634 } 1635 1636 return tcp_send_prepare_packet(socket, socket_data, copy, data_length, sequence_number); 1637 } 1638 1639 void tcp_send_packets(device_id_t device_id, packet_t packet){ 1640 packet_t next; 1641 1642 while(packet){ 1643 next = pq_detach(packet); 1644 ip_send_msg(tcp_globals.ip_phone, device_id, packet, SERVICE_TCP, 0); 1633 1645 packet = next; 1634 1646 } 1635 1647 } 1636 1648 1637 void tcp_prepare_operation_header( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize){1638 assert( socket);1639 assert( socket_data);1640 assert( socket->specific_data == socket_data);1641 assert( header);1642 1643 bzero( header, sizeof( * header));1644 header->source_port = htons( socket->port);1645 header->source_port = htons( socket_data->dest_port);1646 header->header_length = TCP_COMPUTE_HEADER_LENGTH( sizeof( * header));1649 void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize){ 1650 assert(socket); 1651 assert(socket_data); 1652 assert(socket->specific_data == socket_data); 1653 assert(header); 1654 1655 bzero(header, sizeof(*header)); 1656 header->source_port = htons(socket->port); 1657 header->source_port = htons(socket_data->dest_port); 1658 header->header_length = TCP_COMPUTE_HEADER_LENGTH(sizeof(*header)); 1647 1659 header->synchronize = synchronize; 1648 1660 header->finalize = finalize; 1649 1661 } 1650 1662 1651 int tcp_prepare_timeout( int ( * timeout_function )( void * tcp_timeout_t ), socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, int globals_read_only){1652 tcp_timeout_ref operation_timeout;1653 fid_t fibril;1654 1655 assert( socket);1656 assert( socket_data);1657 assert( socket->specific_data == socket_data);1663 int tcp_prepare_timeout(int (*timeout_function)(void * tcp_timeout_t), socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, int globals_read_only){ 1664 tcp_timeout_ref operation_timeout; 1665 fid_t fibril; 1666 1667 assert(socket); 1668 assert(socket_data); 1669 assert(socket->specific_data == socket_data); 1658 1670 1659 1671 // prepare the timeout with key bundle structure 1660 operation_timeout = malloc( sizeof( * operation_timeout ) + socket->key_length + 1 ); 1661 if( ! operation_timeout ) return ENOMEM; 1662 bzero( operation_timeout, sizeof( * operation_timeout )); 1672 operation_timeout = malloc(sizeof(*operation_timeout) + socket->key_length + 1); 1673 if(! operation_timeout){ 1674 return ENOMEM; 1675 } 1676 bzero(operation_timeout, sizeof(*operation_timeout)); 1663 1677 operation_timeout->globals_read_only = globals_read_only; 1664 1678 operation_timeout->port = socket->port; … … 1670 1684 1671 1685 // copy the key 1672 operation_timeout->key = (( char * ) operation_timeout ) + sizeof( * operation_timeout);1686 operation_timeout->key = ((char *) operation_timeout) + sizeof(*operation_timeout); 1673 1687 operation_timeout->key_length = socket->key_length; 1674 memcpy( operation_timeout->key, socket->key, socket->key_length);1675 operation_timeout->key[ operation_timeout->key_length] = '\0';1688 memcpy(operation_timeout->key, socket->key, socket->key_length); 1689 operation_timeout->key[operation_timeout->key_length] = '\0'; 1676 1690 1677 1691 // prepare the timeouting thread 1678 fibril = fibril_create( timeout_function, operation_timeout);1679 if( ! fibril){1680 free( operation_timeout);1692 fibril = fibril_create(timeout_function, operation_timeout); 1693 if(! fibril){ 1694 free(operation_timeout); 1681 1695 return EPARTY; 1682 1696 } 1683 // fibril_mutex_lock( & socket_data->operation.mutex);1697 // fibril_mutex_lock(&socket_data->operation.mutex); 1684 1698 // start the timeouting fibril 1685 fibril_add_ready( fibril);1699 fibril_add_ready(fibril); 1686 1700 //socket_data->state = state; 1687 1701 return EOK; 1688 1702 } 1689 1703 1690 int tcp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){1704 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){ 1691 1705 ERROR_DECLARE; 1692 1706 1693 socket_core_ref socket;1694 tcp_socket_data_ref socket_data;1695 int packet_id;1696 packet_t packet;1697 size_t length;1698 1699 assert( local_sockets);1707 socket_core_ref socket; 1708 tcp_socket_data_ref socket_data; 1709 int packet_id; 1710 packet_t packet; 1711 size_t length; 1712 1713 assert(local_sockets); 1700 1714 1701 1715 // find the socket 1702 socket = socket_cores_find( local_sockets, socket_id ); 1703 if( ! socket ) return ENOTSOCK; 1716 socket = socket_cores_find(local_sockets, socket_id); 1717 if(! socket){ 1718 return ENOTSOCK; 1719 } 1704 1720 // get the socket specific data 1705 if( ! socket->specific_data ) return NO_DATA; 1706 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1721 if(! socket->specific_data){ 1722 return NO_DATA; 1723 } 1724 socket_data = (tcp_socket_data_ref) socket->specific_data; 1707 1725 1708 1726 // check state 1709 if(( socket_data->state != TCP_SOCKET_ESTABLISHED ) && ( socket_data->state != TCP_SOCKET_CLOSE_WAIT)){1727 if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){ 1710 1728 return ENOTCONN; 1711 1729 } 1712 1730 1713 1731 // send the source address if desired 1714 if( addrlen){1715 ERROR_PROPAGATE( data_reply( socket_data->addr, socket_data->addrlen));1716 * addrlen = socket_data->addrlen;1732 if(addrlen){ 1733 ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen)); 1734 *addrlen = socket_data->addrlen; 1717 1735 } 1718 1736 1719 1737 // get the next received packet 1720 packet_id = dyn_fifo_value( & socket->received ); 1721 if( packet_id < 0 ) return NO_DATA; 1722 ERROR_PROPAGATE( packet_translate( tcp_globals.net_phone, & packet, packet_id )); 1738 packet_id = dyn_fifo_value(&socket->received); 1739 if(packet_id < 0){ 1740 return NO_DATA; 1741 } 1742 ERROR_PROPAGATE(packet_translate(tcp_globals.net_phone, &packet, packet_id)); 1723 1743 1724 1744 // reply the packets 1725 ERROR_PROPAGATE( socket_reply_packets( packet, & length));1745 ERROR_PROPAGATE(socket_reply_packets(packet, &length)); 1726 1746 1727 1747 // release the packet 1728 dyn_fifo_pop( & socket->received);1729 pq_release( tcp_globals.net_phone, packet_get_id( packet));1748 dyn_fifo_pop(&socket->received); 1749 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1730 1750 // return the total length 1731 return ( int) length;1732 } 1733 1734 int tcp_send_message( socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags){1751 return (int) length; 1752 } 1753 1754 int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags){ 1735 1755 ERROR_DECLARE; 1736 1756 1737 socket_core_ref socket;1738 tcp_socket_data_ref socket_data;1739 packet_dimension_ref packet_dimension;1740 packet_t packet;1741 size_t total_length;1742 tcp_header_ref header;1743 int index;1744 int result;1745 1746 assert( local_sockets);1747 assert( data_fragment_size);1757 socket_core_ref socket; 1758 tcp_socket_data_ref socket_data; 1759 packet_dimension_ref packet_dimension; 1760 packet_t packet; 1761 size_t total_length; 1762 tcp_header_ref header; 1763 int index; 1764 int result; 1765 1766 assert(local_sockets); 1767 assert(data_fragment_size); 1748 1768 1749 1769 // find the socket 1750 socket = socket_cores_find( local_sockets, socket_id ); 1751 if( ! socket ) return ENOTSOCK; 1770 socket = socket_cores_find(local_sockets, socket_id); 1771 if(! socket){ 1772 return ENOTSOCK; 1773 } 1752 1774 // get the socket specific data 1753 if( ! socket->specific_data ) return NO_DATA; 1754 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1775 if(! socket->specific_data){ 1776 return NO_DATA; 1777 } 1778 socket_data = (tcp_socket_data_ref) socket->specific_data; 1755 1779 1756 1780 // check state 1757 if(( socket_data->state != TCP_SOCKET_ESTABLISHED ) && ( socket_data->state != TCP_SOCKET_CLOSE_WAIT)){1781 if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){ 1758 1782 return ENOTCONN; 1759 1783 } 1760 1784 1761 ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension));1762 1763 * data_fragment_size = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size);1764 1765 for( index = 0; index < fragments; ++ index){1785 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1786 1787 *data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size); 1788 1789 for(index = 0; index < fragments; ++ index){ 1766 1790 // read the data fragment 1767 result = tl_socket_read_packet_data( tcp_globals.net_phone, & packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen ); 1768 if( result < 0 ) return result; 1769 total_length = ( size_t ) result; 1791 result = tl_socket_read_packet_data(tcp_globals.net_phone, &packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen); 1792 if(result < 0){ 1793 return result; 1794 } 1795 total_length = (size_t) result; 1770 1796 // prefix the tcp header 1771 header = PACKET_PREFIX( packet, tcp_header_t);1772 if( ! header){1773 return tcp_release_and_return( packet, ENOMEM);1774 } 1775 tcp_prepare_operation_header( socket, socket_data, header, 0, 0);1776 ERROR_PROPAGATE( tcp_queue_packet( socket, socket_data, packet, 0));1797 header = PACKET_PREFIX(packet, tcp_header_t); 1798 if(! header){ 1799 return tcp_release_and_return(packet, ENOMEM); 1800 } 1801 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 1802 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 0)); 1777 1803 } 1778 1804 1779 1805 // flush packets 1780 packet = tcp_get_packets_to_send( socket, socket_data);1781 fibril_rwlock_write_unlock( socket_data->local_lock);1782 fibril_rwlock_read_unlock( & tcp_globals.lock);1783 if( packet){1806 packet = tcp_get_packets_to_send(socket, socket_data); 1807 fibril_rwlock_write_unlock(socket_data->local_lock); 1808 fibril_rwlock_read_unlock(&tcp_globals.lock); 1809 if(packet){ 1784 1810 // send the packet 1785 tcp_send_packets( socket_data->device_id, packet);1811 tcp_send_packets(socket_data->device_id, packet); 1786 1812 } 1787 1813 … … 1789 1815 } 1790 1816 1791 int tcp_close_message( socket_cores_ref local_sockets, int socket_id){1817 int tcp_close_message(socket_cores_ref local_sockets, int socket_id){ 1792 1818 ERROR_DECLARE; 1793 1819 1794 socket_core_ref socket;1795 tcp_socket_data_ref socket_data;1796 packet_t packet;1820 socket_core_ref socket; 1821 tcp_socket_data_ref socket_data; 1822 packet_t packet; 1797 1823 1798 1824 // find the socket 1799 socket = socket_cores_find( local_sockets, socket_id ); 1800 if( ! socket ) return ENOTSOCK; 1825 socket = socket_cores_find(local_sockets, socket_id); 1826 if(! socket){ 1827 return ENOTSOCK; 1828 } 1801 1829 // get the socket specific data 1802 socket_data = ( tcp_socket_data_ref) socket->specific_data;1803 assert( socket_data);1830 socket_data = (tcp_socket_data_ref) socket->specific_data; 1831 assert(socket_data); 1804 1832 1805 1833 // check state 1806 switch( socket_data->state){1834 switch(socket_data->state){ 1807 1835 case TCP_SOCKET_ESTABLISHED: 1808 1836 socket_data->state = TCP_SOCKET_FIN_WAIT_1; … … 1814 1842 default: 1815 1843 // just destroy 1816 if( ! ERROR_OCCURRED( socket_destroy( tcp_globals.net_phone, socket_id, local_sockets, & tcp_globals.sockets, tcp_free_socket_data))){1817 fibril_rwlock_write_unlock( socket_data->local_lock);1818 fibril_rwlock_write_unlock( & tcp_globals.lock);1844 if(! ERROR_OCCURRED(socket_destroy(tcp_globals.net_phone, socket_id, local_sockets, &tcp_globals.sockets, tcp_free_socket_data))){ 1845 fibril_rwlock_write_unlock(socket_data->local_lock); 1846 fibril_rwlock_write_unlock(&tcp_globals.lock); 1819 1847 } 1820 1848 return ERROR_CODE; … … 1824 1852 1825 1853 // create the notification packet 1826 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 0, 1));1854 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1)); 1827 1855 1828 1856 // send the packet 1829 ERROR_PROPAGATE( tcp_queue_packet( socket, socket_data, packet, 1));1857 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1)); 1830 1858 1831 1859 // flush packets 1832 packet = tcp_get_packets_to_send( socket, socket_data);1833 fibril_rwlock_write_unlock( socket_data->local_lock);1834 fibril_rwlock_write_unlock( & tcp_globals.lock);1835 if( packet){1860 packet = tcp_get_packets_to_send(socket, socket_data); 1861 fibril_rwlock_write_unlock(socket_data->local_lock); 1862 fibril_rwlock_write_unlock(&tcp_globals.lock); 1863 if(packet){ 1836 1864 // send the packet 1837 tcp_send_packets( socket_data->device_id, packet);1865 tcp_send_packets(socket_data->device_id, packet); 1838 1866 } 1839 1867 return EOK; 1840 1868 } 1841 1869 1842 int tcp_create_notification_packet( packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){1870 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){ 1843 1871 ERROR_DECLARE; 1844 1872 1845 packet_dimension_ref packet_dimension;1846 tcp_header_ref header;1847 1848 assert( packet);1873 packet_dimension_ref packet_dimension; 1874 tcp_header_ref header; 1875 1876 assert(packet); 1849 1877 1850 1878 // get the device packet dimension 1851 ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension));1879 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1852 1880 // get a new packet 1853 * packet = packet_get_4( tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix ); 1854 if( ! * packet ) return ENOMEM; 1881 *packet = packet_get_4(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix); 1882 if(! * packet){ 1883 return ENOMEM; 1884 } 1855 1885 // allocate space in the packet 1856 header = PACKET_SUFFIX( * packet, tcp_header_t);1857 if( ! header){1858 tcp_release_and_return( * packet, ENOMEM);1859 } 1860 1861 tcp_prepare_operation_header( socket, socket_data, header, synchronize, finalize);1886 header = PACKET_SUFFIX(*packet, tcp_header_t); 1887 if(! header){ 1888 tcp_release_and_return(*packet, ENOMEM); 1889 } 1890 1891 tcp_prepare_operation_header(socket, socket_data, header, synchronize, finalize); 1862 1892 return EOK; 1863 1893 } 1864 1894 1865 int tcp_accept_message( socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen){1895 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen){ 1866 1896 ERROR_DECLARE; 1867 1897 1868 socket_core_ref accepted;1869 socket_core_ref socket;1870 tcp_socket_data_ref socket_data;1871 packet_dimension_ref packet_dimension;1872 1873 assert( local_sockets);1874 assert( data_fragment_size);1875 assert( addrlen);1898 socket_core_ref accepted; 1899 socket_core_ref socket; 1900 tcp_socket_data_ref socket_data; 1901 packet_dimension_ref packet_dimension; 1902 1903 assert(local_sockets); 1904 assert(data_fragment_size); 1905 assert(addrlen); 1876 1906 1877 1907 // find the socket 1878 socket = socket_cores_find( local_sockets, socket_id ); 1879 if( ! socket ) return ENOTSOCK; 1908 socket = socket_cores_find(local_sockets, socket_id); 1909 if(! socket){ 1910 return ENOTSOCK; 1911 } 1880 1912 // get the socket specific data 1881 socket_data = ( tcp_socket_data_ref) socket->specific_data;1882 assert( socket_data);1913 socket_data = (tcp_socket_data_ref) socket->specific_data; 1914 assert(socket_data); 1883 1915 1884 1916 // check state 1885 if( socket_data->state != TCP_SOCKET_LISTEN){1917 if(socket_data->state != TCP_SOCKET_LISTEN){ 1886 1918 return EINVAL; 1887 1919 } 1888 1920 1889 1921 do{ 1890 socket_id = dyn_fifo_value( & socket->accepted ); 1891 if( socket_id < 0 ) return ENOTSOCK; 1922 socket_id = dyn_fifo_value(&socket->accepted); 1923 if(socket_id < 0){ 1924 return ENOTSOCK; 1925 } 1892 1926 socket_id *= -1; 1893 1927 1894 accepted = socket_cores_find( local_sockets, socket_id ); 1895 if( ! accepted ) return ENOTSOCK; 1928 accepted = socket_cores_find(local_sockets, socket_id); 1929 if(! accepted){ 1930 return ENOTSOCK; 1931 } 1896 1932 // get the socket specific data 1897 socket_data = ( tcp_socket_data_ref) accepted->specific_data;1898 assert( socket_data);1933 socket_data = (tcp_socket_data_ref) accepted->specific_data; 1934 assert(socket_data); 1899 1935 // TODO can it be in another state? 1900 if( socket_data->state == TCP_SOCKET_ESTABLISHED){1901 ERROR_PROPAGATE( data_reply( socket_data->addr, socket_data->addrlen));1902 ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension));1903 * addrlen = socket_data->addrlen;1904 * data_fragment_size = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size);1905 if( new_socket_id > 0){1906 ERROR_PROPAGATE( socket_cores_update( local_sockets, accepted->socket_id, new_socket_id));1936 if(socket_data->state == TCP_SOCKET_ESTABLISHED){ 1937 ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen)); 1938 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1939 *addrlen = socket_data->addrlen; 1940 *data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size); 1941 if(new_socket_id > 0){ 1942 ERROR_PROPAGATE(socket_cores_update(local_sockets, accepted->socket_id, new_socket_id)); 1907 1943 accepted->socket_id = new_socket_id; 1908 1944 } 1909 1945 } 1910 dyn_fifo_pop( & socket->accepted);1911 }while( socket_data->state != TCP_SOCKET_ESTABLISHED);1912 printf("ret accept %d\n", accepted->socket_id );1946 dyn_fifo_pop(&socket->accepted); 1947 }while(socket_data->state != TCP_SOCKET_ESTABLISHED); 1948 printf("ret accept %d\n", accepted->socket_id); 1913 1949 return accepted->socket_id; 1914 1950 } 1915 1951 1916 void tcp_free_socket_data( socket_core_ref socket){1917 tcp_socket_data_ref socket_data;1918 1919 assert( socket);1920 1921 printf( "destroy_socket %d\n", socket->socket_id);1952 void tcp_free_socket_data(socket_core_ref socket){ 1953 tcp_socket_data_ref socket_data; 1954 1955 assert(socket); 1956 1957 printf("destroy_socket %d\n", socket->socket_id); 1922 1958 1923 1959 // get the socket specific data 1924 socket_data = ( tcp_socket_data_ref) socket->specific_data;1925 assert( socket_data);1960 socket_data = (tcp_socket_data_ref) socket->specific_data; 1961 assert(socket_data); 1926 1962 //free the pseudo header 1927 if( socket_data->pseudo_header){1928 if( socket_data->headerlen){1963 if(socket_data->pseudo_header){ 1964 if(socket_data->headerlen){ 1929 1965 printf("d pseudo\n"); 1930 free( socket_data->pseudo_header);1966 free(socket_data->pseudo_header); 1931 1967 socket_data->headerlen = 0; 1932 1968 } … … 1935 1971 socket_data->headerlen = 0; 1936 1972 // free the address 1937 if( socket_data->addr){1938 if( socket_data->addrlen){1973 if(socket_data->addr){ 1974 if(socket_data->addrlen){ 1939 1975 printf("d addr\n"); 1940 free( socket_data->addr);1976 free(socket_data->addr); 1941 1977 socket_data->addrlen = 0; 1942 1978 } … … 1946 1982 } 1947 1983 1948 int tcp_release_and_return( packet_t packet, int result){1949 pq_release( tcp_globals.net_phone, packet_get_id( packet));1984 int tcp_release_and_return(packet_t packet, int result){ 1985 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1950 1986 return result; 1951 1987 } -
uspace/srv/net/tl/tcp/tcp.h
raa85487 raadf01e 150 150 /** Operation result. 151 151 */ 152 int result;152 int result; 153 153 /** Safety lock. 154 154 */ 155 fibril_mutex_t mutex;155 fibril_mutex_t mutex; 156 156 /** Operation result signaling. 157 157 */ 158 fibril_condvar_t condvar;158 fibril_condvar_t condvar; 159 159 }; 160 160 … … 164 164 /** TCP socket state. 165 165 */ 166 tcp_socket_state_t state;166 tcp_socket_state_t state; 167 167 /** Data fragment size. 168 168 * Sending optimalization. 169 169 */ 170 size_t data_fragment_size;170 size_t data_fragment_size; 171 171 /** Device identifier. 172 172 */ 173 device_id_t device_id;173 device_id_t device_id; 174 174 /** Listening backlog. 175 175 * The maximal number of connected but not yet accepted sockets. 176 176 */ 177 int backlog;177 int backlog; 178 178 // /** Segment size. 179 179 // */ … … 182 182 * Set if this socket is an accepted one. 183 183 */ 184 int listening_socket_id;184 int listening_socket_id; 185 185 /** Treshold size in bytes. 186 186 */ 187 size_t treshold;187 size_t treshold; 188 188 /** Window size in bytes. 189 189 */ 190 size_t window;190 size_t window; 191 191 /** Acknowledgement timeout. 192 192 */ 193 suseconds_t timeout;193 suseconds_t timeout; 194 194 /** Last acknowledged byte. 195 195 */ 196 uint32_t acknowledged;196 uint32_t acknowledged; 197 197 /** Next incoming sequence number. 198 198 */ 199 uint32_t next_incoming;199 uint32_t next_incoming; 200 200 /** Incoming FIN. 201 201 */ 202 uint32_t fin_incoming;202 uint32_t fin_incoming; 203 203 /** Next outgoing sequence number. 204 204 */ 205 uint32_t next_outgoing;205 uint32_t next_outgoing; 206 206 /** Last outgoing sequence number. 207 207 */ 208 uint32_t last_outgoing;208 uint32_t last_outgoing; 209 209 /** Outgoing FIN. 210 210 */ 211 uint32_t fin_outgoing;211 uint32_t fin_outgoing; 212 212 /** Expected sequence number by the remote host. 213 213 * The sequence number the other host expects. 214 214 * The notification is sent only upon a packet reecival. 215 215 */ 216 uint32_t expected;216 uint32_t expected; 217 217 /** Expected sequence number counter. 218 218 * Counts the number of received notifications for the same sequence number. 219 219 */ 220 int expected_count;220 int expected_count; 221 221 /** Incoming packet queue. 222 222 * Packets are buffered until received in the right order. … … 225 225 * Packets metric is set as their data length. 226 226 */ 227 packet_t incoming;227 packet_t incoming; 228 228 /** Outgoing packet queue. 229 229 * Packets are buffered until acknowledged by the remote host in the right order. … … 232 232 * Packets metric is set as their data length. 233 233 */ 234 packet_t outgoing;234 packet_t outgoing; 235 235 /** IP pseudo header. 236 236 */ 237 ip_pseudo_header_ref pseudo_header;237 ip_pseudo_header_ref pseudo_header; 238 238 /** IP pseudo header length. 239 239 */ 240 size_t headerlen;240 size_t headerlen; 241 241 /** Remote host address. 242 242 */ 243 struct sockaddr * addr;243 struct sockaddr * addr; 244 244 /** Remote host address length. 245 245 */ 246 socklen_t addrlen;246 socklen_t addrlen; 247 247 /** Remote host port. 248 248 */ 249 uint16_t dest_port;249 uint16_t dest_port; 250 250 /** Parent local sockets. 251 251 */ 252 socket_cores_ref local_sockets;252 socket_cores_ref local_sockets; 253 253 /** Local sockets safety lock. 254 254 * May be locked for writing while holding the global lock for reading when changing the local sockets only. … … 258 258 * @see tcp_globals:lock 259 259 */ 260 fibril_rwlock_t * local_lock;260 fibril_rwlock_t * local_lock; 261 261 /** Pending operation data. 262 262 */ 263 tcp_operation_t operation;263 tcp_operation_t operation; 264 264 /** Timeouts in a row counter. 265 265 * If TCP_MAX_TIMEOUTS is reached, the connection is lost. 266 266 */ 267 int timeout_count;267 int timeout_count; 268 268 }; 269 269 … … 273 273 /** Networking module phone. 274 274 */ 275 int net_phone;275 int net_phone; 276 276 /** IP module phone. 277 277 */ 278 int ip_phone;278 int ip_phone; 279 279 /** ICMP module phone. 280 280 */ 281 int icmp_phone;281 int icmp_phone; 282 282 /** Last used free port. 283 283 */ 284 int last_used_port;284 int last_used_port; 285 285 /** Active sockets. 286 286 */ 287 socket_ports_t sockets;287 socket_ports_t sockets; 288 288 /** Device packet dimensions. 289 289 */ 290 packet_dimensions_t dimensions;290 packet_dimensions_t dimensions; 291 291 /** Safety lock. 292 292 * Write lock is used only for adding or removing socket ports. 293 293 */ 294 fibril_rwlock_t lock;294 fibril_rwlock_t lock; 295 295 }; 296 296 -
uspace/srv/net/tl/tcp/tcp_header.h
raa85487 raadf01e 43 43 /** TCP header size in bytes. 44 44 */ 45 #define TCP_HEADER_SIZE sizeof( tcp_header_t)45 #define TCP_HEADER_SIZE sizeof(tcp_header_t) 46 46 47 47 /** Returns the actual TCP header length in bytes. 48 48 * @param[in] header The TCP packet header. 49 49 */ 50 #define TCP_HEADER_LENGTH( header ) (( header )->header_length * 4u)50 #define TCP_HEADER_LENGTH(header) ((header)->header_length * 4u) 51 51 52 52 /** Returns the TCP header length. 53 53 * @param[in] length The TCP header length in bytes. 54 54 */ 55 #define TCP_COMPUTE_HEADER_LENGTH( length ) (( uint8_t ) (( length ) / 4u))55 #define TCP_COMPUTE_HEADER_LENGTH(length) ((uint8_t) ((length) / 4u)) 56 56 57 57 /** Type definition of the transmission datagram header. … … 90 90 /** The source port number. 91 91 */ 92 uint16_t source_port;92 uint16_t source_port; 93 93 /** The destination port number. 94 94 */ 95 uint16_t destination_port;95 uint16_t destination_port; 96 96 /** The sequence number of the first data octet in this segment (except when SYN is present). 97 97 * If SYN is present the sequence number is the initial sequence number (ISN) and the first data octet is ISN+1. 98 98 */ 99 uint32_t sequence_number;99 uint32_t sequence_number; 100 100 /** If the ACK control bit is set this field contains the value of the next sequence number the sender of the segment is expecting to receive. 101 101 * Once a~connection is established this is always sent. 102 102 * @see acknowledge 103 103 */ 104 uint32_t acknowledgement_number;104 uint32_t acknowledgement_number; 105 105 #ifdef ARCH_IS_BIG_ENDIAN 106 106 /** The number of 32~bit words in the TCP Header. … … 108 108 * The TCP header (even one including options) is an integral number of 32~bits long. 109 109 */ 110 uint8_t header_length:4;110 uint8_t header_length:4; 111 111 /** Four bits reserved for future use. 112 112 * Must be zero. 113 113 */ 114 uint8_t reserved1:4;114 uint8_t reserved1:4; 115 115 #else 116 116 /** Four bits reserved for future use. 117 117 * Must be zero. 118 118 */ 119 uint8_t reserved1:4;119 uint8_t reserved1:4; 120 120 /** The number of 32~bit words in the TCP Header. 121 121 * This indicates where the data begins. 122 122 * The TCP header (even one including options) is an integral number of 32~bits long. 123 123 */ 124 uint8_t header_length:4;124 uint8_t header_length:4; 125 125 #endif 126 126 #ifdef ARCH_IS_BIG_ENDIAN … … 128 128 * Must be zero. 129 129 */ 130 uint8_t reserved2:2;130 uint8_t reserved2:2; 131 131 /** Urgent Pointer field significant. 132 132 * @see tcp_header:urgent_pointer 133 133 */ 134 uint8_t urgent:1;134 uint8_t urgent:1; 135 135 /** Acknowledgment field significant 136 136 * @see tcp_header:acknowledgement_number 137 137 */ 138 uint8_t acknowledge:1;138 uint8_t acknowledge:1; 139 139 /** Push function. 140 140 */ 141 uint8_t push:1;141 uint8_t push:1; 142 142 /** Reset the connection. 143 143 */ 144 uint8_t reset:1;144 uint8_t reset:1; 145 145 /** Synchronize the sequence numbers. 146 146 */ 147 uint8_t synchronize:1;147 uint8_t synchronize:1; 148 148 /** No more data from the sender. 149 149 */ 150 uint8_t finalize:1;150 uint8_t finalize:1; 151 151 #else 152 152 /** No more data from the sender. 153 153 */ 154 uint8_t finalize:1;154 uint8_t finalize:1; 155 155 /** Synchronize the sequence numbers. 156 156 */ 157 uint8_t synchronize:1;157 uint8_t synchronize:1; 158 158 /** Reset the connection. 159 159 */ 160 uint8_t reset:1;160 uint8_t reset:1; 161 161 /** Push function. 162 162 */ 163 uint8_t push:1;163 uint8_t push:1; 164 164 /** Acknowledgment field significant. 165 165 * @see tcp_header:acknowledgement_number 166 166 */ 167 uint8_t acknowledge:1;167 uint8_t acknowledge:1; 168 168 /** Urgent Pointer field significant. 169 169 * @see tcp_header:urgent_pointer 170 170 */ 171 uint8_t urgent:1;171 uint8_t urgent:1; 172 172 /** Two bits reserved for future use. 173 173 * Must be zero. 174 174 */ 175 uint8_t reserved2:2;175 uint8_t reserved2:2; 176 176 #endif 177 177 /** The number of data octets beginning with the one indicated in the acknowledgment field which the sender of this segment is willing to accept. 178 178 * @see tcp_header:acknowledge 179 179 */ 180 uint16_t window;180 uint16_t window; 181 181 /** The checksum field is the 16~bit one's complement of the one's complement sum of all 16~bit words in the header and text. 182 182 * If a~segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a~16~bit word for checksum purposes. … … 188 188 * If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic). 189 189 */ 190 uint16_t checksum;190 uint16_t checksum; 191 191 /** This field communicates the current value of the urgent pointer as a~positive offset from the sequence number in this segment. 192 192 * The urgent pointer points to the sequence number of the octet following the urgent data. … … 194 194 * @see tcp_header:urgent 195 195 */ 196 uint16_t urgent_pointer;196 uint16_t urgent_pointer; 197 197 } __attribute__ ((packed)); 198 198 … … 202 202 /** Option type. 203 203 */ 204 uint8_t type;204 uint8_t type; 205 205 /** Option length. 206 206 */ 207 uint8_t length;207 uint8_t length; 208 208 }; 209 209 … … 215 215 * @see TCPOPT_MAX_SEGMENT_SIZE_LENGTH 216 216 */ 217 tcp_option_t option;217 tcp_option_t option; 218 218 /** Maximum segment size in bytes. 219 219 */ 220 uint16_t max_segment_size;220 uint16_t max_segment_size; 221 221 } __attribute__ ((packed)); 222 222 -
uspace/srv/net/tl/tcp/tcp_module.c
raa85487 raadf01e 63 63 * @see NAME 64 64 */ 65 void module_print_name( void);65 void module_print_name(void); 66 66 67 67 /** Starts the TCP module. … … 72 72 * @returns Other error codes as defined for the REGISTER_ME() macro function. 73 73 */ 74 int module_start( async_client_conn_t client_connection);74 int module_start(async_client_conn_t client_connection); 75 75 76 76 /** Processes the TCP message. … … 82 82 * @returns Other error codes as defined for the tcp_message() function. 83 83 */ 84 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);84 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 85 85 86 86 /** TCP module global data. … … 88 88 extern tcp_globals_t tcp_globals; 89 89 90 void module_print_name( void){91 printf( "%s", NAME);90 void module_print_name(void){ 91 printf("%s", NAME); 92 92 } 93 93 94 int module_start( async_client_conn_t client_connection){94 int module_start(async_client_conn_t client_connection){ 95 95 ERROR_DECLARE; 96 96 97 ipcarg_t phonehash;97 ipcarg_t phonehash; 98 98 99 async_set_client_connection( client_connection);100 tcp_globals.net_phone = net_connect_module( SERVICE_NETWORKING);101 ERROR_PROPAGATE( pm_init());102 if( ERROR_OCCURRED( tcp_initialize( client_connection))103 || ERROR_OCCURRED( REGISTER_ME( SERVICE_TCP, & phonehash))){99 async_set_client_connection(client_connection); 100 tcp_globals.net_phone = net_connect_module(SERVICE_NETWORKING); 101 ERROR_PROPAGATE(pm_init()); 102 if(ERROR_OCCURRED(tcp_initialize(client_connection)) 103 || ERROR_OCCURRED(REGISTER_ME(SERVICE_TCP, &phonehash))){ 104 104 pm_destroy(); 105 105 return ERROR_CODE; … … 112 112 } 113 113 114 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){115 return tcp_message( callid, call, answer, answer_count);114 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 115 return tcp_message(callid, call, answer, answer_count); 116 116 } 117 117 -
uspace/srv/net/tl/tcp/tcp_module.h
raa85487 raadf01e 47 47 * @returns ENOMEM if there is not enough memory left. 48 48 */ 49 int tcp_initialize( async_client_conn_t client_connection);49 int tcp_initialize(async_client_conn_t client_connection); 50 50 51 51 /** Processes the TCP message. … … 59 59 * @see IS_NET_TCP_MESSAGE() 60 60 */ 61 int tcp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);61 int tcp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 62 62 63 63 #endif -
uspace/srv/net/tl/tl_common.c
raa85487 raadf01e 55 55 #include "tl_common.h" 56 56 57 DEVICE_MAP_IMPLEMENT( packet_dimensions, packet_dimension_t ); 58 59 int tl_get_address_port( const struct sockaddr * addr, int addrlen, uint16_t * port ){ 60 const struct sockaddr_in * address_in; 61 const struct sockaddr_in6 * address_in6; 62 63 if(( addrlen <= 0 ) || (( size_t ) addrlen < sizeof( struct sockaddr ))) return EINVAL; 64 switch( addr->sa_family ){ 57 DEVICE_MAP_IMPLEMENT(packet_dimensions, packet_dimension_t); 58 59 int tl_get_address_port(const struct sockaddr * addr, int addrlen, uint16_t * port){ 60 const struct sockaddr_in * address_in; 61 const struct sockaddr_in6 * address_in6; 62 63 if((addrlen <= 0) || ((size_t) addrlen < sizeof(struct sockaddr))){ 64 return EINVAL; 65 } 66 switch(addr->sa_family){ 65 67 case AF_INET: 66 if( addrlen != sizeof( struct sockaddr_in )) return EINVAL; 67 address_in = ( struct sockaddr_in * ) addr; 68 * port = ntohs( address_in->sin_port ); 68 if(addrlen != sizeof(struct sockaddr_in)){ 69 return EINVAL; 70 } 71 address_in = (struct sockaddr_in *) addr; 72 *port = ntohs(address_in->sin_port); 69 73 break; 70 74 case AF_INET6: 71 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; 72 address_in6 = ( struct sockaddr_in6 * ) addr; 73 * port = ntohs( address_in6->sin6_port ); 75 if(addrlen != sizeof(struct sockaddr_in6)){ 76 return EINVAL; 77 } 78 address_in6 = (struct sockaddr_in6 *) addr; 79 *port = ntohs(address_in6->sin6_port); 74 80 break; 75 81 default: … … 79 85 } 80 86 81 int tl_get_ip_packet_dimension( int ip_phone, packet_dimensions_ref packet_dimensions, device_id_t device_id, packet_dimension_ref * packet_dimension){87 int tl_get_ip_packet_dimension(int ip_phone, packet_dimensions_ref packet_dimensions, device_id_t device_id, packet_dimension_ref * packet_dimension){ 82 88 ERROR_DECLARE; 83 89 84 if( ! packet_dimension ) return EBADMEM; 85 86 * packet_dimension = packet_dimensions_find( packet_dimensions, device_id ); 87 if( ! * packet_dimension ){ 90 if(! packet_dimension){ 91 return EBADMEM; 92 } 93 94 *packet_dimension = packet_dimensions_find(packet_dimensions, device_id); 95 if(! * packet_dimension){ 88 96 // ask for and remember them if not found 89 * packet_dimension = malloc( sizeof( ** packet_dimension )); 90 if( ! * packet_dimension ) return ENOMEM; 91 if( ERROR_OCCURRED( ip_packet_size_req( ip_phone, device_id, * packet_dimension ))){ 92 free( * packet_dimension ); 97 *packet_dimension = malloc(sizeof(** packet_dimension)); 98 if(! * packet_dimension){ 99 return ENOMEM; 100 } 101 if(ERROR_OCCURRED(ip_packet_size_req(ip_phone, device_id, * packet_dimension))){ 102 free(*packet_dimension); 93 103 return ERROR_CODE; 94 104 } 95 ERROR_CODE = packet_dimensions_add( packet_dimensions, device_id, * packet_dimension);96 if( ERROR_CODE < 0){97 free( * packet_dimension);105 ERROR_CODE = packet_dimensions_add(packet_dimensions, device_id, * packet_dimension); 106 if(ERROR_CODE < 0){ 107 free(*packet_dimension); 98 108 return ERROR_CODE; 99 109 } … … 102 112 } 103 113 104 int tl_update_ip_packet_dimension( packet_dimensions_ref packet_dimensions, device_id_t device_id, size_t content ){ 105 packet_dimension_ref packet_dimension; 106 107 packet_dimension = packet_dimensions_find( packet_dimensions, device_id ); 108 if( ! packet_dimension ) return ENOENT; 114 int tl_update_ip_packet_dimension(packet_dimensions_ref packet_dimensions, device_id_t device_id, size_t content){ 115 packet_dimension_ref packet_dimension; 116 117 packet_dimension = packet_dimensions_find(packet_dimensions, device_id); 118 if(! packet_dimension){ 119 return ENOENT; 120 } 109 121 packet_dimension->content = content; 110 if( device_id != DEVICE_INVALID_ID){111 packet_dimension = packet_dimensions_find( packet_dimensions, DEVICE_INVALID_ID);112 if( packet_dimension){113 if( packet_dimension->content >= content){122 if(device_id != DEVICE_INVALID_ID){ 123 packet_dimension = packet_dimensions_find(packet_dimensions, DEVICE_INVALID_ID); 124 if(packet_dimension){ 125 if(packet_dimension->content >= content){ 114 126 packet_dimension->content = content; 115 127 }else{ 116 packet_dimensions_exclude( packet_dimensions, DEVICE_INVALID_ID);128 packet_dimensions_exclude(packet_dimensions, DEVICE_INVALID_ID); 117 129 } 118 130 } … … 121 133 } 122 134 123 int tl_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port ){ 124 struct sockaddr_in * address_in; 125 struct sockaddr_in6 * address_in6; 126 size_t length; 127 128 if( addrlen < 0 ) return EINVAL; 129 length = ( size_t ) addrlen; 130 if( length < sizeof( struct sockaddr )) return EINVAL; 131 switch( addr->sa_family ){ 135 int tl_set_address_port(struct sockaddr * addr, int addrlen, uint16_t port){ 136 struct sockaddr_in * address_in; 137 struct sockaddr_in6 * address_in6; 138 size_t length; 139 140 if(addrlen < 0){ 141 return EINVAL; 142 } 143 length = (size_t) addrlen; 144 if(length < sizeof(struct sockaddr)){ 145 return EINVAL; 146 } 147 switch(addr->sa_family){ 132 148 case AF_INET: 133 if( length != sizeof( struct sockaddr_in )) return EINVAL; 134 address_in = ( struct sockaddr_in * ) addr; 135 address_in->sin_port = htons( port ); 149 if(length != sizeof(struct sockaddr_in)){ 150 return EINVAL; 151 } 152 address_in = (struct sockaddr_in *) addr; 153 address_in->sin_port = htons(port); 136 154 return EOK; 137 155 case AF_INET6: 138 if( length != sizeof( struct sockaddr_in6 )) return EINVAL; 139 address_in6 = ( struct sockaddr_in6 * ) addr; 140 address_in6->sin6_port = htons( port ); 156 if(length != sizeof(struct sockaddr_in6)){ 157 return EINVAL; 158 } 159 address_in6 = (struct sockaddr_in6 *) addr; 160 address_in6->sin6_port = htons(port); 141 161 return EOK; 142 162 default: … … 145 165 } 146 166 147 int tl_prepare_icmp_packet( int packet_phone, int icmp_phone, packet_t packet, services_t error){148 packet_t next;149 uint8_t * src;150 int length;167 int tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t packet, services_t error){ 168 packet_t next; 169 uint8_t * src; 170 int length; 151 171 152 172 // detach the first packet and release the others 153 next = pq_detach( packet);154 if( next){155 pq_release( packet_phone, packet_get_id( next));156 } 157 length = packet_get_addr( packet, & src, NULL);158 if(( length > 0)159 && ( ! error)160 && ( icmp_phone >= 0)173 next = pq_detach(packet); 174 if(next){ 175 pq_release(packet_phone, packet_get_id(next)); 176 } 177 length = packet_get_addr(packet, &src, NULL); 178 if((length > 0) 179 && (! error) 180 && (icmp_phone >= 0) 161 181 // set both addresses to the source one (avoids the source address deletion before setting the destination one) 162 && ( packet_set_addr( packet, src, src, ( size_t ) length ) == EOK)){182 && (packet_set_addr(packet, src, src, (size_t) length) == EOK)){ 163 183 return EOK; 164 184 }else{ 165 pq_release( packet_phone, packet_get_id( packet));185 pq_release(packet_phone, packet_get_id(packet)); 166 186 } 167 187 return ENOENT; 168 188 } 169 189 170 int tl_socket_read_packet_data( int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen){190 int tl_socket_read_packet_data(int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen){ 171 191 ERROR_DECLARE; 172 192 173 ipc_callid_t callid; 174 size_t length; 175 void * data; 176 177 if( ! dimension ) return EINVAL; 193 ipc_callid_t callid; 194 size_t length; 195 void * data; 196 197 if(! dimension){ 198 return EINVAL; 199 } 178 200 // get the data length 179 if( ! async_data_write_receive( & callid, & length )) return EINVAL; 201 if(! async_data_write_receive(&callid, &length)){ 202 return EINVAL; 203 } 180 204 // get a new packet 181 * packet = packet_get_4( packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix ); 182 if( ! packet ) return ENOMEM; 205 *packet = packet_get_4(packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix); 206 if(! packet){ 207 return ENOMEM; 208 } 183 209 // allocate space in the packet 184 data = packet_suffix( * packet, length);185 if( ! data){186 pq_release( packet_phone, packet_get_id( * packet));210 data = packet_suffix(*packet, length); 211 if(! data){ 212 pq_release(packet_phone, packet_get_id(*packet)); 187 213 return ENOMEM; 188 214 } 189 215 // read the data into the packet 190 if( ERROR_OCCURRED( async_data_write_finalize( callid, data, length))216 if(ERROR_OCCURRED(async_data_write_finalize(callid, data, length)) 191 217 // set the packet destination address 192 || ERROR_OCCURRED( packet_set_addr( * packet, NULL, ( uint8_t * ) addr, addrlen))){193 pq_release( packet_phone, packet_get_id( * packet));218 || ERROR_OCCURRED(packet_set_addr(*packet, NULL, (uint8_t *) addr, addrlen))){ 219 pq_release(packet_phone, packet_get_id(*packet)); 194 220 return ERROR_CODE; 195 221 } 196 return ( int) length;222 return (int) length; 197 223 } 198 224 -
uspace/srv/net/tl/tl_common.h
raa85487 raadf01e 48 48 * @see device.h 49 49 */ 50 DEVICE_MAP_DECLARE( packet_dimensions, packet_dimension_t);50 DEVICE_MAP_DECLARE(packet_dimensions, packet_dimension_t); 51 51 52 52 /** Gets the address port. … … 59 59 * @returns EAFNOSUPPORT if the address family is not supported. 60 60 */ 61 int tl_get_address_port( const struct sockaddr * addr, int addrlen, uint16_t * port);61 int tl_get_address_port(const struct sockaddr * addr, int addrlen, uint16_t * port); 62 62 63 63 /** Gets IP packet dimensions. … … 74 74 * @returns Other codes as defined for the ip_packet_size_req() function. 75 75 */ 76 int tl_get_ip_packet_dimension( int ip_phone, packet_dimensions_ref packet_dimensions, device_id_t device_id, packet_dimension_ref * packet_dimension);76 int tl_get_ip_packet_dimension(int ip_phone, packet_dimensions_ref packet_dimensions, device_id_t device_id, packet_dimension_ref * packet_dimension); 77 77 78 78 /** Updates IP device packet dimensions cache. … … 83 83 * @returns ENOENT if the packet dimension is not cached. 84 84 */ 85 int tl_update_ip_packet_dimension( packet_dimensions_ref packet_dimensions, device_id_t device_id, size_t content);85 int tl_update_ip_packet_dimension(packet_dimensions_ref packet_dimensions, device_id_t device_id, size_t content); 86 86 87 87 /** Sets the address port. … … 94 94 * @returns EAFNOSUPPORT if the address family is not supported. 95 95 */ 96 int tl_set_address_port( struct sockaddr * addr, int addrlen, uint16_t port);96 int tl_set_address_port(struct sockaddr * addr, int addrlen, uint16_t port); 97 97 98 98 /** Prepares the packet for ICMP error notification. … … 106 106 * @returns ENOENT if no packet may be sent. 107 107 */ 108 int tl_prepare_icmp_packet( int packet_phone, int icmp_phone, packet_t packet, services_t error);108 int tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t packet, services_t error); 109 109 110 110 /** Receives data from the socket into a packet. … … 120 120 * @returns Other error codes as defined for the async_data_read_finalize() function. 121 121 */ 122 int tl_socket_read_packet_data( int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen);122 int tl_socket_read_packet_data(int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen); 123 123 124 124 #endif -
uspace/srv/net/tl/udp/udp.c
raa85487 raadf01e 104 104 * @returns Other error codes as defined for the udp_process_packet() function. 105 105 */ 106 int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error);106 int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error); 107 107 108 108 /** Processes the received UDP packet queue. … … 121 121 * @returns Other error codes as defined for the ip_client_process_packet() function. 122 122 */ 123 int udp_process_packet( device_id_t device_id, packet_t packet, services_t error);123 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error); 124 124 125 125 /** Releases the packet and returns the result. … … 128 128 * @return The result parameter. 129 129 */ 130 int udp_release_and_return( packet_t packet, int result);130 int udp_release_and_return(packet_t packet, int result); 131 131 132 132 /** @name Socket messages processing functions … … 141 141 * @see socket.h 142 142 */ 143 int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call);143 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 144 144 145 145 /** Sends data from the socket to the remote address. … … 164 164 * @returns Other error codes as defined for the ip_send_msg() function. 165 165 */ 166 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);166 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); 167 167 168 168 /** Receives data to the socket. … … 181 181 * @returns Other error codes as defined for the data_reply() function. 182 182 */ 183 int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen);183 int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen); 184 184 185 185 /*@}*/ … … 189 189 udp_globals_t udp_globals; 190 190 191 int udp_initialize( async_client_conn_t client_connection){191 int udp_initialize(async_client_conn_t client_connection){ 192 192 ERROR_DECLARE; 193 193 194 measured_string_t names[] = {{ str_dup("UDP_CHECKSUM_COMPUTING"), 22 }, { str_dup("UDP_AUTOBINDING"), 15}};195 measured_string_ref configuration;196 size_t count = sizeof( names ) / sizeof( measured_string_t);197 char * data;198 199 fibril_rwlock_initialize( & udp_globals.lock);200 fibril_rwlock_write_lock( & udp_globals.lock);201 udp_globals.icmp_phone = icmp_connect_module( SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);202 udp_globals.ip_phone = ip_bind_service( SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg);203 if( udp_globals.ip_phone < 0){194 measured_string_t names[] = {{str_dup("UDP_CHECKSUM_COMPUTING"), 22}, {str_dup("UDP_AUTOBINDING"), 15}}; 195 measured_string_ref configuration; 196 size_t count = sizeof(names) / sizeof(measured_string_t); 197 char * data; 198 199 fibril_rwlock_initialize(&udp_globals.lock); 200 fibril_rwlock_write_lock(&udp_globals.lock); 201 udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT); 202 udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg); 203 if(udp_globals.ip_phone < 0){ 204 204 return udp_globals.ip_phone; 205 205 } 206 206 // read default packet dimensions 207 ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.packet_dimension));208 ERROR_PROPAGATE( socket_ports_initialize( & udp_globals.sockets));209 if( ERROR_OCCURRED( packet_dimensions_initialize( & udp_globals.dimensions))){210 socket_ports_destroy( & udp_globals.sockets);207 ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension)); 208 ERROR_PROPAGATE(socket_ports_initialize(&udp_globals.sockets)); 209 if(ERROR_OCCURRED(packet_dimensions_initialize(&udp_globals.dimensions))){ 210 socket_ports_destroy(&udp_globals.sockets); 211 211 return ERROR_CODE; 212 212 } 213 udp_globals.packet_dimension.prefix += sizeof( udp_header_t);214 udp_globals.packet_dimension.content -= sizeof( udp_header_t);213 udp_globals.packet_dimension.prefix += sizeof(udp_header_t); 214 udp_globals.packet_dimension.content -= sizeof(udp_header_t); 215 215 udp_globals.last_used_port = UDP_FREE_PORTS_START - 1; 216 216 // get configuration 217 217 udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING; 218 218 udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING; 219 configuration = & names[ 0];220 ERROR_PROPAGATE( net_get_conf_req( udp_globals.net_phone, & configuration, count, & data));221 if( configuration){222 if( configuration[ 0 ].value){223 udp_globals.checksum_computing = ( configuration[ 0 ].value[ 0 ] == 'y');224 } 225 if( configuration[ 1 ].value){226 udp_globals.autobinding = ( configuration[ 1 ].value[ 0 ] == 'y');227 } 228 net_free_settings( configuration, data);229 } 230 fibril_rwlock_write_unlock( & udp_globals.lock);219 configuration = &names[0]; 220 ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration, count, &data)); 221 if(configuration){ 222 if(configuration[0].value){ 223 udp_globals.checksum_computing = (configuration[0].value[0] == 'y'); 224 } 225 if(configuration[1].value){ 226 udp_globals.autobinding = (configuration[1].value[0] == 'y'); 227 } 228 net_free_settings(configuration, data); 229 } 230 fibril_rwlock_write_unlock(&udp_globals.lock); 231 231 return EOK; 232 232 } 233 233 234 int udp_received_msg( device_id_t device_id, packet_t packet, services_t receiver, services_t error){235 int result;236 237 fibril_rwlock_write_lock( & udp_globals.lock);238 result = udp_process_packet( device_id, packet, error);239 if( result != EOK){240 fibril_rwlock_write_unlock( & udp_globals.lock);234 int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){ 235 int result; 236 237 fibril_rwlock_write_lock(&udp_globals.lock); 238 result = udp_process_packet(device_id, packet, error); 239 if(result != EOK){ 240 fibril_rwlock_write_unlock(&udp_globals.lock); 241 241 } 242 242 … … 244 244 } 245 245 246 int udp_process_packet( device_id_t device_id, packet_t packet, services_t error){246 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error){ 247 247 ERROR_DECLARE; 248 248 249 size_t length;250 size_t offset;251 int result;252 udp_header_ref header;253 socket_core_ref socket;254 packet_t next_packet;255 size_t total_length;256 uint32_t checksum;257 int fragments;258 packet_t tmp_packet;259 icmp_type_t type;260 icmp_code_t code;261 ip_pseudo_header_ref ip_header;262 struct sockaddr * src;263 struct sockaddr * dest;264 packet_dimension_ref packet_dimension;265 266 if( error){267 switch( error){249 size_t length; 250 size_t offset; 251 int result; 252 udp_header_ref header; 253 socket_core_ref socket; 254 packet_t next_packet; 255 size_t total_length; 256 uint32_t checksum; 257 int fragments; 258 packet_t tmp_packet; 259 icmp_type_t type; 260 icmp_code_t code; 261 ip_pseudo_header_ref ip_header; 262 struct sockaddr * src; 263 struct sockaddr * dest; 264 packet_dimension_ref packet_dimension; 265 266 if(error){ 267 switch(error){ 268 268 case SERVICE_ICMP: 269 269 // ignore error 270 // length = icmp_client_header_length( packet);270 // length = icmp_client_header_length(packet); 271 271 // process error 272 result = icmp_client_process_packet( packet, & type, & code, NULL, NULL);273 if( result < 0){274 return udp_release_and_return( packet, result);272 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 273 if(result < 0){ 274 return udp_release_and_return(packet, result); 275 275 } 276 length = ( size_t) result;277 if( ERROR_OCCURRED( packet_trim( packet, length, 0))){278 return udp_release_and_return( packet, ERROR_CODE);276 length = (size_t) result; 277 if(ERROR_OCCURRED(packet_trim(packet, length, 0))){ 278 return udp_release_and_return(packet, ERROR_CODE); 279 279 } 280 280 break; 281 281 default: 282 return udp_release_and_return( packet, ENOTSUP);282 return udp_release_and_return(packet, ENOTSUP); 283 283 } 284 284 } 285 285 // TODO process received ipopts? 286 result = ip_client_process_packet( packet, NULL, NULL, NULL, NULL, NULL);287 if( result < 0){288 return udp_release_and_return( packet, result);289 } 290 offset = ( size_t) result;291 292 length = packet_get_data_length( packet);293 if( length <= 0){294 return udp_release_and_return( packet, EINVAL);295 } 296 if( length < UDP_HEADER_SIZE + offset){297 return udp_release_and_return( packet, NO_DATA);286 result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL); 287 if(result < 0){ 288 return udp_release_and_return(packet, result); 289 } 290 offset = (size_t) result; 291 292 length = packet_get_data_length(packet); 293 if(length <= 0){ 294 return udp_release_and_return(packet, EINVAL); 295 } 296 if(length < UDP_HEADER_SIZE + offset){ 297 return udp_release_and_return(packet, NO_DATA); 298 298 } 299 299 300 300 // trim all but UDP header 301 if( ERROR_OCCURRED( packet_trim( packet, offset, 0))){302 return udp_release_and_return( packet, ERROR_CODE);301 if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){ 302 return udp_release_and_return(packet, ERROR_CODE); 303 303 } 304 304 305 305 // get udp header 306 header = ( udp_header_ref ) packet_get_data( packet);307 if( ! header){308 return udp_release_and_return( packet, NO_DATA);306 header = (udp_header_ref) packet_get_data(packet); 307 if(! header){ 308 return udp_release_and_return(packet, NO_DATA); 309 309 } 310 310 // find the destination socket 311 socket = socket_port_find( & udp_globals.sockets, ntohs( header->destination_port ), SOCKET_MAP_KEY_LISTENING, 0);312 if( ! socket){313 if( tl_prepare_icmp_packet( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ) == EOK){314 icmp_destination_unreachable_msg( udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet);311 socket = socket_port_find(&udp_globals.sockets, ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0); 312 if(! socket){ 313 if(tl_prepare_icmp_packet(udp_globals.net_phone, udp_globals.icmp_phone, packet, error) == EOK){ 314 icmp_destination_unreachable_msg(udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet); 315 315 } 316 316 return EADDRNOTAVAIL; … … 320 320 next_packet = packet; 321 321 fragments = 0; 322 total_length = ntohs( header->total_length);322 total_length = ntohs(header->total_length); 323 323 // compute header checksum if set 324 if( header->checksum && ( ! error)){325 result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest);326 if( result <= 0){327 return udp_release_and_return( packet, result);328 } 329 if( ERROR_OCCURRED( ip_client_get_pseudo_header( IPPROTO_UDP, src, result, dest, result, total_length, & ip_header, & length))){330 return udp_release_and_return( packet, ERROR_CODE);324 if(header->checksum && (! error)){ 325 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); 326 if(result <= 0){ 327 return udp_release_and_return(packet, result); 328 } 329 if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP, src, result, dest, result, total_length, &ip_header, &length))){ 330 return udp_release_and_return(packet, ERROR_CODE); 331 331 }else{ 332 checksum = compute_checksum( 0, ip_header, length);332 checksum = compute_checksum(0, ip_header, length); 333 333 // the udp header checksum will be added with the first fragment later 334 free( ip_header);334 free(ip_header); 335 335 } 336 336 }else{ … … 341 341 do{ 342 342 ++ fragments; 343 length = packet_get_data_length( next_packet);344 if( length <= 0){345 return udp_release_and_return( packet, NO_DATA);346 } 347 if( total_length < length){348 if( ERROR_OCCURRED( packet_trim( next_packet, 0, length - total_length))){349 return udp_release_and_return( packet, ERROR_CODE);343 length = packet_get_data_length(next_packet); 344 if(length <= 0){ 345 return udp_release_and_return(packet, NO_DATA); 346 } 347 if(total_length < length){ 348 if(ERROR_OCCURRED(packet_trim(next_packet, 0, length - total_length))){ 349 return udp_release_and_return(packet, ERROR_CODE); 350 350 } 351 351 // add partial checksum if set 352 if( header->checksum){353 checksum = compute_checksum( checksum, packet_get_data( packet ), packet_get_data_length( packet));352 if(header->checksum){ 353 checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet)); 354 354 } 355 355 // relese the rest of the packet fragments 356 tmp_packet = pq_next( next_packet);357 while( tmp_packet){358 next_packet = pq_detach( tmp_packet);359 pq_release( udp_globals.net_phone, packet_get_id( tmp_packet));356 tmp_packet = pq_next(next_packet); 357 while(tmp_packet){ 358 next_packet = pq_detach(tmp_packet); 359 pq_release(udp_globals.net_phone, packet_get_id(tmp_packet)); 360 360 tmp_packet = next_packet; 361 361 } … … 365 365 total_length -= length; 366 366 // add partial checksum if set 367 if( header->checksum){368 checksum = compute_checksum( checksum, packet_get_data( packet ), packet_get_data_length( packet));369 } 370 }while(( next_packet = pq_next( next_packet )) && ( total_length > 0));367 if(header->checksum){ 368 checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet)); 369 } 370 }while((next_packet = pq_next(next_packet)) && (total_length > 0)); 371 371 372 372 // check checksum 373 if( header->checksum){374 if( flip_checksum( compact_checksum( checksum )) != IP_CHECKSUM_ZERO){375 if( tl_prepare_icmp_packet( udp_globals.net_phone, udp_globals.icmp_phone, packet, error ) == EOK){373 if(header->checksum){ 374 if(flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO){ 375 if(tl_prepare_icmp_packet(udp_globals.net_phone, udp_globals.icmp_phone, packet, error) == EOK){ 376 376 // checksum error ICMP 377 icmp_parameter_problem_msg( udp_globals.icmp_phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->checksum )) - (( size_t ) (( void * ) header )), packet);377 icmp_parameter_problem_msg(udp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet); 378 378 } 379 379 return EINVAL; … … 382 382 383 383 // queue the received packet 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))){386 return udp_release_and_return( packet, ERROR_CODE);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))){ 386 return udp_release_and_return(packet, ERROR_CODE); 387 387 } 388 388 389 389 // notify the destination socket 390 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);390 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 392 return EOK; 393 393 } 394 394 395 int udp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){395 int udp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 396 396 ERROR_DECLARE; 397 397 398 packet_t packet;399 400 * answer_count = 0;401 switch( IPC_GET_METHOD( * call)){398 packet_t packet; 399 400 *answer_count = 0; 401 switch(IPC_GET_METHOD(*call)){ 402 402 case NET_TL_RECEIVED: 403 if( ! ERROR_OCCURRED( packet_translate( udp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){404 ERROR_CODE = udp_received_msg( IPC_GET_DEVICE( call ), packet, SERVICE_UDP, IPC_GET_ERROR( call));403 if(! ERROR_OCCURRED(packet_translate(udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 404 ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_UDP, IPC_GET_ERROR(call)); 405 405 } 406 406 return ERROR_CODE; 407 407 case IPC_M_CONNECT_TO_ME: 408 return udp_process_client_messages( callid, * call);408 return udp_process_client_messages(callid, * call); 409 409 } 410 410 return ENOTSUP; 411 411 } 412 412 413 int udp_process_client_messages( ipc_callid_t callid, ipc_call_t call){414 int res;415 bool keep_on_going = true;416 socket_cores_t local_sockets;417 int app_phone = IPC_GET_PHONE( & call);418 struct sockaddr * addr;419 size_t addrlen;420 fibril_rwlock_t lock;421 ipc_call_t answer;422 int answer_count;423 packet_dimension_ref packet_dimension;413 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call){ 414 int res; 415 bool keep_on_going = true; 416 socket_cores_t local_sockets; 417 int app_phone = IPC_GET_PHONE(&call); 418 struct sockaddr * addr; 419 size_t addrlen; 420 fibril_rwlock_t lock; 421 ipc_call_t answer; 422 int answer_count; 423 packet_dimension_ref packet_dimension; 424 424 425 425 /* … … 432 432 // The client connection is only in one fibril and therefore no additional locks are needed. 433 433 434 socket_cores_initialize( & local_sockets);435 fibril_rwlock_initialize( & lock);436 437 while( keep_on_going){434 socket_cores_initialize(&local_sockets); 435 fibril_rwlock_initialize(&lock); 436 437 while(keep_on_going){ 438 438 439 439 // answer the call 440 answer_call( callid, res, & answer, answer_count);440 answer_call(callid, res, &answer, answer_count); 441 441 442 442 // refresh data 443 refresh_answer( & answer, & answer_count);443 refresh_answer(&answer, &answer_count); 444 444 445 445 // get the next call 446 callid = async_get_call( & call);446 callid = async_get_call(&call); 447 447 448 448 // process the call 449 switch( IPC_GET_METHOD( call)){449 switch(IPC_GET_METHOD(call)){ 450 450 case IPC_M_PHONE_HUNGUP: 451 451 keep_on_going = false; … … 453 453 break; 454 454 case NET_SOCKET: 455 fibril_rwlock_write_lock( & lock);456 * SOCKET_SET_SOCKET_ID( answer ) = SOCKET_GET_SOCKET_ID( call);457 res = socket_create( & local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID( answer));458 fibril_rwlock_write_unlock( & lock);459 if( res == EOK){460 if( tl_get_ip_packet_dimension( udp_globals.ip_phone, & udp_globals.dimensions, DEVICE_INVALID_ID, & packet_dimension ) == EOK){461 * SOCKET_SET_DATA_FRAGMENT_SIZE( answer) = packet_dimension->content;455 fibril_rwlock_write_lock(&lock); 456 *SOCKET_SET_SOCKET_ID(answer) = SOCKET_GET_SOCKET_ID(call); 457 res = socket_create(&local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID(answer)); 458 fibril_rwlock_write_unlock(&lock); 459 if(res == EOK){ 460 if(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){ 461 *SOCKET_SET_DATA_FRAGMENT_SIZE(answer) = packet_dimension->content; 462 462 } 463 // * SOCKET_SET_DATA_FRAGMENT_SIZE( answer) = MAX_UDP_FRAGMENT_SIZE;464 * SOCKET_SET_HEADER_SIZE( answer) = UDP_HEADER_SIZE;463 // *SOCKET_SET_DATA_FRAGMENT_SIZE(answer) = MAX_UDP_FRAGMENT_SIZE; 464 *SOCKET_SET_HEADER_SIZE(answer) = UDP_HEADER_SIZE; 465 465 answer_count = 3; 466 466 } 467 467 break; 468 468 case NET_SOCKET_BIND: 469 res = data_receive(( void ** ) & addr, & addrlen);470 if( res == EOK){471 fibril_rwlock_read_lock( & lock);472 fibril_rwlock_write_lock( & udp_globals.lock);473 res = socket_bind( & local_sockets, & udp_globals.sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port);474 fibril_rwlock_write_unlock( & udp_globals.lock);475 fibril_rwlock_read_unlock( & lock);476 free( addr);469 res = data_receive((void **) &addr, &addrlen); 470 if(res == EOK){ 471 fibril_rwlock_read_lock(&lock); 472 fibril_rwlock_write_lock(&udp_globals.lock); 473 res = socket_bind(&local_sockets, &udp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port); 474 fibril_rwlock_write_unlock(&udp_globals.lock); 475 fibril_rwlock_read_unlock(&lock); 476 free(addr); 477 477 } 478 478 break; 479 479 case NET_SOCKET_SENDTO: 480 res = data_receive(( void ** ) & addr, & addrlen);481 if( res == EOK){482 fibril_rwlock_read_lock( & lock);483 fibril_rwlock_write_lock( & udp_globals.lock);484 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));485 if( res != EOK){486 fibril_rwlock_write_unlock( & udp_globals.lock);480 res = data_receive((void **) &addr, &addrlen); 481 if(res == EOK){ 482 fibril_rwlock_read_lock(&lock); 483 fibril_rwlock_write_lock(&udp_globals.lock); 484 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)); 485 if(res != EOK){ 486 fibril_rwlock_write_unlock(&udp_globals.lock); 487 487 }else{ 488 488 answer_count = 2; 489 489 } 490 fibril_rwlock_read_unlock( & lock);491 free( addr);490 fibril_rwlock_read_unlock(&lock); 491 free(addr); 492 492 } 493 493 break; 494 494 case NET_SOCKET_RECVFROM: 495 fibril_rwlock_read_lock( & lock);496 fibril_rwlock_write_lock( & udp_globals.lock);497 res = udp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ), & addrlen);498 fibril_rwlock_write_unlock( & udp_globals.lock);499 fibril_rwlock_read_unlock( & lock);500 if( res > 0){501 * SOCKET_SET_READ_DATA_LENGTH( answer) = res;502 * SOCKET_SET_ADDRESS_LENGTH( answer) = addrlen;495 fibril_rwlock_read_lock(&lock); 496 fibril_rwlock_write_lock(&udp_globals.lock); 497 res = udp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen); 498 fibril_rwlock_write_unlock(&udp_globals.lock); 499 fibril_rwlock_read_unlock(&lock); 500 if(res > 0){ 501 *SOCKET_SET_READ_DATA_LENGTH(answer) = res; 502 *SOCKET_SET_ADDRESS_LENGTH(answer) = addrlen; 503 503 answer_count = 3; 504 504 res = EOK; … … 506 506 break; 507 507 case NET_SOCKET_CLOSE: 508 fibril_rwlock_write_lock( & lock);509 fibril_rwlock_write_lock( & udp_globals.lock);510 res = socket_destroy( udp_globals.net_phone, SOCKET_GET_SOCKET_ID( call ), & local_sockets, & udp_globals.sockets, NULL);511 fibril_rwlock_write_unlock( & udp_globals.lock);512 fibril_rwlock_write_unlock( & lock);508 fibril_rwlock_write_lock(&lock); 509 fibril_rwlock_write_lock(&udp_globals.lock); 510 res = socket_destroy(udp_globals.net_phone, SOCKET_GET_SOCKET_ID(call), &local_sockets, &udp_globals.sockets, NULL); 511 fibril_rwlock_write_unlock(&udp_globals.lock); 512 fibril_rwlock_write_unlock(&lock); 513 513 break; 514 514 case NET_SOCKET_GETSOCKOPT: … … 521 521 522 522 // release all local sockets 523 socket_cores_release( udp_globals.net_phone, & local_sockets, & udp_globals.sockets, NULL);523 socket_cores_release(udp_globals.net_phone, &local_sockets, &udp_globals.sockets, NULL); 524 524 525 525 return res; 526 526 } 527 527 528 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){528 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){ 529 529 ERROR_DECLARE; 530 530 531 socket_core_ref socket; 532 packet_t packet; 533 packet_t next_packet; 534 udp_header_ref header; 535 int index; 536 size_t total_length; 537 int result; 538 uint16_t dest_port; 539 uint32_t checksum; 540 ip_pseudo_header_ref ip_header; 541 size_t headerlen; 542 device_id_t device_id; 543 packet_dimension_ref packet_dimension; 544 545 ERROR_PROPAGATE( tl_get_address_port( addr, addrlen, & dest_port )); 546 547 socket = socket_cores_find( local_sockets, socket_id ); 548 if( ! socket ) return ENOTSOCK; 549 550 if(( socket->port <= 0 ) && udp_globals.autobinding ){ 531 socket_core_ref socket; 532 packet_t packet; 533 packet_t next_packet; 534 udp_header_ref header; 535 int index; 536 size_t total_length; 537 int result; 538 uint16_t dest_port; 539 uint32_t checksum; 540 ip_pseudo_header_ref ip_header; 541 size_t headerlen; 542 device_id_t device_id; 543 packet_dimension_ref packet_dimension; 544 545 ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &dest_port)); 546 547 socket = socket_cores_find(local_sockets, socket_id); 548 if(! socket){ 549 return ENOTSOCK; 550 } 551 552 if((socket->port <= 0) && udp_globals.autobinding){ 551 553 // bind the socket to a random free port if not bound 552 554 // do{ 553 555 // try to find a free port 554 // fibril_rwlock_read_unlock( & udp_globals.lock);555 // fibril_rwlock_write_lock( & udp_globals.lock);556 // fibril_rwlock_read_unlock(&udp_globals.lock); 557 // fibril_rwlock_write_lock(&udp_globals.lock); 556 558 // might be changed in the meantime 557 // if( socket->port <= 0){558 if( ERROR_OCCURRED( socket_bind_free_port( & udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port))){559 // fibril_rwlock_write_unlock( & udp_globals.lock);560 // fibril_rwlock_read_lock( & udp_globals.lock);559 // if(socket->port <= 0){ 560 if(ERROR_OCCURRED(socket_bind_free_port(&udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port))){ 561 // fibril_rwlock_write_unlock(&udp_globals.lock); 562 // fibril_rwlock_read_lock(&udp_globals.lock); 561 563 return ERROR_CODE; 562 564 } … … 564 566 udp_globals.last_used_port = socket->port; 565 567 // } 566 // fibril_rwlock_write_unlock( & udp_globals.lock);567 // fibril_rwlock_read_lock( & udp_globals.lock);568 // fibril_rwlock_write_unlock(&udp_globals.lock); 569 // fibril_rwlock_read_lock(&udp_globals.lock); 568 570 // might be changed in the meantime 569 // }while( socket->port <= 0);570 } 571 572 if( udp_globals.checksum_computing){573 if( ERROR_OCCURRED( ip_get_route_req( udp_globals.ip_phone, IPPROTO_UDP, addr, addrlen, & device_id, & ip_header, & headerlen))){574 return udp_release_and_return( packet, ERROR_CODE);571 // }while(socket->port <= 0); 572 } 573 574 if(udp_globals.checksum_computing){ 575 if(ERROR_OCCURRED(ip_get_route_req(udp_globals.ip_phone, IPPROTO_UDP, addr, addrlen, &device_id, &ip_header, &headerlen))){ 576 return udp_release_and_return(packet, ERROR_CODE); 575 577 } 576 578 // get the device packet dimension 577 // ERROR_PROPAGATE( tl_get_ip_packet_dimension( udp_globals.ip_phone, & udp_globals.dimensions, device_id, & packet_dimension));579 // ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension)); 578 580 } 579 581 // }else{ 580 582 // do not ask all the time 581 ERROR_PROPAGATE( ip_packet_size_req( udp_globals.ip_phone, -1, & udp_globals.packet_dimension));582 packet_dimension = & udp_globals.packet_dimension;583 ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension)); 584 packet_dimension = &udp_globals.packet_dimension; 583 585 // } 584 586 585 587 // read the first packet fragment 586 result = tl_socket_read_packet_data( udp_globals.net_phone, & packet, UDP_HEADER_SIZE, packet_dimension, addr, addrlen ); 587 if( result < 0 ) return result; 588 total_length = ( size_t ) result; 589 if( udp_globals.checksum_computing ){ 590 checksum = compute_checksum( 0, packet_get_data( packet ), packet_get_data_length( packet )); 588 result = tl_socket_read_packet_data(udp_globals.net_phone, &packet, UDP_HEADER_SIZE, packet_dimension, addr, addrlen); 589 if(result < 0){ 590 return result; 591 } 592 total_length = (size_t) result; 593 if(udp_globals.checksum_computing){ 594 checksum = compute_checksum(0, packet_get_data(packet), packet_get_data_length(packet)); 591 595 }else{ 592 596 checksum = 0; 593 597 } 594 598 // prefix the udp header 595 header = PACKET_PREFIX( packet, udp_header_t);596 if( ! header){597 return udp_release_and_return( packet, ENOMEM);598 } 599 bzero( header, sizeof( * header));599 header = PACKET_PREFIX(packet, udp_header_t); 600 if(! header){ 601 return udp_release_and_return(packet, ENOMEM); 602 } 603 bzero(header, sizeof(*header)); 600 604 // read the rest of the packet fragments 601 for( index = 1; index < fragments; ++ index){602 result = tl_socket_read_packet_data( udp_globals.net_phone, & next_packet, 0, packet_dimension, addr, addrlen);603 if( result < 0){604 return udp_release_and_return( packet, result);605 } 606 if( ERROR_OCCURRED( pq_add( & packet, next_packet, index, 0))){607 return udp_release_and_return( packet, ERROR_CODE);608 } 609 total_length += ( size_t) result;610 if( udp_globals.checksum_computing){611 checksum = compute_checksum( checksum, packet_get_data( next_packet ), packet_get_data_length( next_packet));605 for(index = 1; index < fragments; ++ index){ 606 result = tl_socket_read_packet_data(udp_globals.net_phone, &next_packet, 0, packet_dimension, addr, addrlen); 607 if(result < 0){ 608 return udp_release_and_return(packet, result); 609 } 610 if(ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0))){ 611 return udp_release_and_return(packet, ERROR_CODE); 612 } 613 total_length += (size_t) result; 614 if(udp_globals.checksum_computing){ 615 checksum = compute_checksum(checksum, packet_get_data(next_packet), packet_get_data_length(next_packet)); 612 616 } 613 617 } 614 618 // set the udp header 615 header->source_port = htons(( socket->port > 0 ) ? socket->port : 0);616 header->destination_port = htons( dest_port);617 header->total_length = htons( total_length + sizeof( * header));619 header->source_port = htons((socket->port > 0) ? socket->port : 0); 620 header->destination_port = htons(dest_port); 621 header->total_length = htons(total_length + sizeof(*header)); 618 622 header->checksum = 0; 619 if( udp_globals.checksum_computing){623 if(udp_globals.checksum_computing){ 620 624 // update the pseudo header 621 if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( ip_header, headerlen, total_length + UDP_HEADER_SIZE))){622 free( ip_header);623 return udp_release_and_return( packet, ERROR_CODE);625 if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(ip_header, headerlen, total_length + UDP_HEADER_SIZE))){ 626 free(ip_header); 627 return udp_release_and_return(packet, ERROR_CODE); 624 628 } 625 629 // finish the checksum computation 626 checksum = compute_checksum( checksum, ip_header, headerlen);627 checksum = compute_checksum( checksum, ( uint8_t * ) header, sizeof( * header));628 header->checksum = htons( flip_checksum( compact_checksum( checksum)));629 free( ip_header);630 checksum = compute_checksum(checksum, ip_header, headerlen); 631 checksum = compute_checksum(checksum, (uint8_t *) header, sizeof(*header)); 632 header->checksum = htons(flip_checksum(compact_checksum(checksum))); 633 free(ip_header); 630 634 }else{ 631 635 device_id = DEVICE_INVALID_ID; 632 636 } 633 637 // prepare the first packet fragment 634 if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_UDP, 0, 0, 0, 0))){635 return udp_release_and_return( packet, ERROR_CODE);638 if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0, 0, 0))){ 639 return udp_release_and_return(packet, ERROR_CODE); 636 640 } 637 641 // send the packet 638 fibril_rwlock_write_unlock( & udp_globals.lock);639 ip_send_msg( udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);642 fibril_rwlock_write_unlock(&udp_globals.lock); 643 ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0); 640 644 return EOK; 641 645 } 642 646 643 int udp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){647 int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){ 644 648 ERROR_DECLARE; 645 649 646 socket_core_ref socket;647 int packet_id;648 packet_t packet;649 udp_header_ref header;650 struct sockaddr * addr;651 size_t length;652 uint8_t * data;653 int result;650 socket_core_ref socket; 651 int packet_id; 652 packet_t packet; 653 udp_header_ref header; 654 struct sockaddr * addr; 655 size_t length; 656 uint8_t * data; 657 int result; 654 658 655 659 // find the socket 656 socket = socket_cores_find( local_sockets, socket_id ); 657 if( ! socket ) return ENOTSOCK; 660 socket = socket_cores_find(local_sockets, socket_id); 661 if(! socket){ 662 return ENOTSOCK; 663 } 658 664 // get the next received packet 659 packet_id = dyn_fifo_value( & socket->received ); 660 if( packet_id < 0 ) return NO_DATA; 661 ERROR_PROPAGATE( packet_translate( udp_globals.net_phone, & packet, packet_id )); 665 packet_id = dyn_fifo_value(&socket->received); 666 if(packet_id < 0){ 667 return NO_DATA; 668 } 669 ERROR_PROPAGATE(packet_translate(udp_globals.net_phone, &packet, packet_id)); 662 670 // get udp header 663 data = packet_get_data( packet);664 if( ! data){665 pq_release( udp_globals.net_phone, packet_id);671 data = packet_get_data(packet); 672 if(! data){ 673 pq_release(udp_globals.net_phone, packet_id); 666 674 return NO_DATA; 667 675 } 668 header = ( udp_header_ref) data;676 header = (udp_header_ref) data; 669 677 670 678 // set the source address port 671 result = packet_get_addr( packet, ( uint8_t ** ) & addr, NULL);672 if( ERROR_OCCURRED( tl_set_address_port( addr, result, ntohs( header->source_port)))){673 pq_release( udp_globals.net_phone, packet_id);679 result = packet_get_addr(packet, (uint8_t **) &addr, NULL); 680 if(ERROR_OCCURRED(tl_set_address_port(addr, result, ntohs(header->source_port)))){ 681 pq_release(udp_globals.net_phone, packet_id); 674 682 return ERROR_CODE; 675 683 } 676 * addrlen = ( size_t) result;684 *addrlen = (size_t) result; 677 685 // send the source address 678 ERROR_PROPAGATE( data_reply( addr, * addrlen));686 ERROR_PROPAGATE(data_reply(addr, * addrlen)); 679 687 680 688 // trim the header 681 ERROR_PROPAGATE( packet_trim( packet, UDP_HEADER_SIZE, 0));689 ERROR_PROPAGATE(packet_trim(packet, UDP_HEADER_SIZE, 0)); 682 690 683 691 // reply the packets 684 ERROR_PROPAGATE( socket_reply_packets( packet, & length));692 ERROR_PROPAGATE(socket_reply_packets(packet, &length)); 685 693 686 694 // release the packet 687 dyn_fifo_pop( & socket->received);688 pq_release( udp_globals.net_phone, packet_get_id( packet));695 dyn_fifo_pop(&socket->received); 696 pq_release(udp_globals.net_phone, packet_get_id(packet)); 689 697 // return the total length 690 return ( int) length;698 return (int) length; 691 699 } 692 700 693 int udp_release_and_return( packet_t packet, int result){694 pq_release( udp_globals.net_phone, packet_get_id( packet));701 int udp_release_and_return(packet_t packet, int result){ 702 pq_release(udp_globals.net_phone, packet_get_id(packet)); 695 703 return result; 696 704 } -
uspace/srv/net/tl/udp/udp.h
raa85487 raadf01e 54 54 /** Networking module phone. 55 55 */ 56 int net_phone;56 int net_phone; 57 57 /** IP module phone. 58 58 */ 59 int ip_phone;59 int ip_phone; 60 60 /** ICMP module phone. 61 61 */ 62 int icmp_phone;62 int icmp_phone; 63 63 /** Packet dimension. 64 64 */ 65 packet_dimension_t packet_dimension;65 packet_dimension_t packet_dimension; 66 66 /** Indicates whether UDP checksum computing is enabled. 67 67 */ 68 int checksum_computing;68 int checksum_computing; 69 69 /** Indicates whether UDP autobnding on send is enabled. 70 70 */ 71 int autobinding;71 int autobinding; 72 72 /** Last used free port. 73 73 */ 74 int last_used_port;74 int last_used_port; 75 75 /** Active sockets. 76 76 */ 77 socket_ports_t sockets;77 socket_ports_t sockets; 78 78 /** Device packet dimensions. 79 79 */ 80 packet_dimensions_t dimensions;80 packet_dimensions_t dimensions; 81 81 /** Safety lock. 82 82 */ 83 fibril_rwlock_t lock;83 fibril_rwlock_t lock; 84 84 }; 85 85 -
uspace/srv/net/tl/udp/udp_header.h
raa85487 raadf01e 43 43 /** UDP header size in bytes. 44 44 */ 45 #define UDP_HEADER_SIZE sizeof( udp_header_t)45 #define UDP_HEADER_SIZE sizeof(udp_header_t) 46 46 47 47 /** Type definition of the user datagram header. … … 61 61 * If not used, a value of zero is inserted. 62 62 */ 63 uint16_t source_port;63 uint16_t source_port; 64 64 /** Destination port has a meaning within the context of a particular internet destination address. 65 65 */ 66 uint16_t destination_port;66 uint16_t destination_port; 67 67 /** Length is the length in octets of this user datagram including this header and the data. 68 68 * This means the minimum value of the length is eight. 69 69 */ 70 uint16_t total_length;70 uint16_t total_length; 71 71 /** Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header, the UDP header, and the data, padded with zero octets at the end (if necessary) to make a multiple of two octets. 72 72 * The pseudo header conceptually prefixed to the UDP header contains the source address, the destination address, the protocol, and the UDP length. … … 75 75 * An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care). 76 76 */ 77 uint16_t checksum;77 uint16_t checksum; 78 78 } __attribute__ ((packed)); 79 79 -
uspace/srv/net/tl/udp/udp_module.c
raa85487 raadf01e 61 61 * @see NAME 62 62 */ 63 void module_print_name( void);63 void module_print_name(void); 64 64 65 65 /** Starts the UDP module. … … 70 70 * @returns Other error codes as defined for the REGISTER_ME() macro function. 71 71 */ 72 int module_start( async_client_conn_t client_connection);72 int module_start(async_client_conn_t client_connection); 73 73 74 74 /** Processes the UDP message. … … 80 80 * @returns Other error codes as defined for the udp_message() function. 81 81 */ 82 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 83 84 84 /** UDP module global data. … … 86 86 extern udp_globals_t udp_globals; 87 87 88 void module_print_name( void){89 printf( "%s", NAME);88 void module_print_name(void){ 89 printf("%s", NAME); 90 90 } 91 91 92 int module_start( async_client_conn_t client_connection){92 int module_start(async_client_conn_t client_connection){ 93 93 ERROR_DECLARE; 94 94 95 ipcarg_t phonehash;95 ipcarg_t phonehash; 96 96 97 async_set_client_connection( client_connection);98 udp_globals.net_phone = net_connect_module( SERVICE_NETWORKING);99 if( udp_globals.net_phone < 0){97 async_set_client_connection(client_connection); 98 udp_globals.net_phone = net_connect_module(SERVICE_NETWORKING); 99 if(udp_globals.net_phone < 0){ 100 100 return udp_globals.net_phone; 101 101 } 102 ERROR_PROPAGATE( pm_init());103 if( ERROR_OCCURRED( udp_initialize( client_connection))104 || ERROR_OCCURRED( REGISTER_ME( SERVICE_UDP, & phonehash))){102 ERROR_PROPAGATE(pm_init()); 103 if(ERROR_OCCURRED(udp_initialize(client_connection)) 104 || ERROR_OCCURRED(REGISTER_ME(SERVICE_UDP, &phonehash))){ 105 105 pm_destroy(); 106 106 return ERROR_CODE; … … 113 113 } 114 114 115 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){116 return udp_message( callid, call, answer, answer_count);115 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 116 return udp_message(callid, call, answer, answer_count); 117 117 } 118 118 -
uspace/srv/net/tl/udp/udp_module.h
raa85487 raadf01e 47 47 * @returns ENOMEM if there is not enough memory left. 48 48 */ 49 int udp_initialize( async_client_conn_t client_connection);49 int udp_initialize(async_client_conn_t client_connection); 50 50 51 51 /** Processes the UDP message. … … 59 59 * @see IS_NET_UDP_MESSAGE() 60 60 */ 61 int udp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);61 int udp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 62 62 63 63 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
