Changes in uspace/srv/net/tl/tcp/tcp.c [aadf01e:1e2e0c1e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/tcp.c
raadf01e r1e2e0c1e 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 144 int globals_read_only; 145 145 /** Socket port. 146 146 */ 147 int 147 int port; 148 148 /** Local sockets. 149 149 */ 150 socket_cores_ref 150 socket_cores_ref local_sockets; 151 151 /** Socket identifier. 152 152 */ 153 int 153 int socket_id; 154 154 /** Socket state. 155 155 */ 156 tcp_socket_state_t 156 tcp_socket_state_t state; 157 157 /** Sent packet sequence number. 158 158 */ 159 int 159 int sequence_number; 160 160 /** Timeout in microseconds. 161 161 */ 162 suseconds_t 162 suseconds_t timeout; 163 163 /** Port map key. 164 164 */ 165 char * 165 char * key; 166 166 /** Port map key length. 167 167 */ 168 size_t 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){ 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); 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 ); 247 245 248 246 return ERROR_CODE; 249 247 } 250 248 251 int tcp_process_packet( device_id_t device_id, packet_t packet, services_t error){249 int tcp_process_packet( device_id_t device_id, packet_t packet, services_t error ){ 252 250 ERROR_DECLARE; 253 251 254 size_t 255 size_t 256 int 257 tcp_header_ref 258 socket_core_ref 259 tcp_socket_data_ref 260 packet_t 261 size_t 262 uint32_t 263 int 264 icmp_type_t 265 icmp_code_t 266 struct sockaddr * 267 struct sockaddr * 268 size_t 269 270 printf( "p1 \n");271 if( error){272 switch( error){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 ){ 273 271 case SERVICE_ICMP: 274 272 // process error 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);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 ); 282 280 } 283 281 break; 284 282 default: 285 return tcp_release_and_return( packet, ENOTSUP);283 return tcp_release_and_return( packet, ENOTSUP ); 286 284 } 287 285 } 288 286 289 287 // TODO process received ipopts? 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);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 ); 304 302 } 305 303 306 304 // trim all but TCP header 307 if( ERROR_OCCURRED(packet_trim(packet, offset, 0))){308 return tcp_release_and_return( packet, ERROR_CODE);305 if( ERROR_OCCURRED( packet_trim( packet, offset, 0 ))){ 306 return tcp_release_and_return( packet, ERROR_CODE ); 309 307 } 310 308 311 309 // get tcp header 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);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 ); 326 324 } 327 325 328 326 // find the destination socket 329 socket = socket_port_find( &tcp_globals.sockets, ntohs(header->destination_port), (const char *) src, addrlen);330 if( ! socket){327 socket = socket_port_find( & tcp_globals.sockets, ntohs( header->destination_port ), ( const char * ) src, addrlen ); 328 if( ! socket ){ 331 329 // printf("listening?\n"); 332 330 // find the listening destination socket 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);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 ); 337 335 } 338 336 return EADDRNOTAVAIL; 339 337 } 340 338 } 341 printf("socket id %d\n", socket->socket_id );342 socket_data = ( tcp_socket_data_ref) socket->specific_data;343 assert( socket_data);339 printf("socket id %d\n", socket->socket_id ); 340 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 341 assert( socket_data ); 344 342 345 343 // some data received, clear the timeout counter … … 353 351 do{ 354 352 ++ fragments; 355 length = packet_get_data_length( next_packet);356 if( length <= 0){357 return tcp_release_and_return( packet, NO_DATA);353 length = packet_get_data_length( next_packet ); 354 if( length <= 0 ){ 355 return tcp_release_and_return( packet, NO_DATA ); 358 356 } 359 357 total_length += length; 360 358 // add partial checksum if set 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);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 ); 366 364 367 365 // printf("lock?\n"); 368 fibril_rwlock_write_lock( socket_data->local_lock);366 fibril_rwlock_write_lock( socket_data->local_lock ); 369 367 // printf("locked\n"); 370 if( ! error){371 if( socket_data->state == TCP_SOCKET_LISTEN){372 if( socket_data->pseudo_header){373 free( socket_data->pseudo_header);368 if( ! error ){ 369 if( socket_data->state == TCP_SOCKET_LISTEN ){ 370 if( socket_data->pseudo_header ){ 371 free( socket_data->pseudo_header ); 374 372 socket_data->pseudo_header = NULL; 375 373 socket_data->headerlen = 0; 376 374 } 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))){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 ))){ 390 388 // checksum error ICMP 391 icmp_parameter_problem_msg( tcp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet);389 icmp_parameter_problem_msg( tcp_globals.icmp_phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->checksum )) - (( size_t ) (( void * ) header )), packet ); 392 390 } 393 391 return EINVAL; … … 395 393 } 396 394 397 fibril_rwlock_read_unlock( &tcp_globals.lock);395 fibril_rwlock_read_unlock( & tcp_globals.lock ); 398 396 399 397 // TODO error reporting/handling 400 // printf( "st %d\n", socket_data->state);401 switch( socket_data->state){398 // printf( "st %d\n", socket_data->state ); 399 switch( socket_data->state ){ 402 400 case TCP_SOCKET_LISTEN: 403 ERROR_CODE = tcp_process_listen( socket, socket_data, header, packet, src, dest, addrlen);401 ERROR_CODE = tcp_process_listen( socket, socket_data, header, packet, src, dest, addrlen ); 404 402 break; 405 403 case TCP_SOCKET_SYN_RECEIVED: 406 ERROR_CODE = tcp_process_syn_received( socket, socket_data, header, packet);404 ERROR_CODE = tcp_process_syn_received( socket, socket_data, header, packet ); 407 405 break; 408 406 case TCP_SOCKET_SYN_SENT: 409 ERROR_CODE = tcp_process_syn_sent( socket, socket_data, header, packet);407 ERROR_CODE = tcp_process_syn_sent( socket, socket_data, header, packet ); 410 408 break; 411 409 case TCP_SOCKET_FIN_WAIT_1: … … 418 416 // ack releasing the socket gets processed later 419 417 case TCP_SOCKET_ESTABLISHED: 420 ERROR_CODE = tcp_process_established( socket, socket_data, header, packet, fragments, total_length);418 ERROR_CODE = tcp_process_established( socket, socket_data, header, packet, fragments, total_length ); 421 419 break; 422 420 default: 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);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 ); 429 427 } 430 428 return EOK; 431 429 } 432 430 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){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 ){ 434 432 ERROR_DECLARE; 435 433 436 packet_t 437 packet_t 438 uint32_t 439 size_t 440 uint32_t 441 size_t 442 size_t 443 uint32_t 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);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 ); 452 450 old_incoming = socket_data->next_incoming; 453 451 454 if( header->finalize){452 if( header->finalize ){ 455 453 socket_data->fin_incoming = new_sequence_number; 456 454 } 457 455 458 // printf( "pe %d < %d <= %d\n", new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length);456 // printf( "pe %d < %d <= %d\n", new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length ); 459 457 // trim begining if containing expected data 460 if( IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length)){458 if( IS_IN_INTERVAL_OVERFLOW( new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length )){ 461 459 // get the acknowledged offset 462 if( socket_data->next_incoming < new_sequence_number){460 if( socket_data->next_incoming < new_sequence_number ){ 463 461 offset = new_sequence_number - socket_data->next_incoming; 464 462 }else{ 465 463 offset = socket_data->next_incoming - new_sequence_number; 466 464 } 467 // printf( "offset %d\n", offset);465 // printf( "offset %d\n", offset ); 468 466 new_sequence_number += offset; 469 467 total_length -= offset; 470 length = packet_get_data_length( packet);468 length = packet_get_data_length( packet ); 471 469 // trim the acknowledged data 472 while( length <= offset){470 while( length <= offset ){ 473 471 // release the acknowledged packets 474 next_packet = pq_next( packet);475 pq_release( tcp_globals.net_phone, packet_get_id(packet));472 next_packet = pq_next( packet ); 473 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 476 474 packet = next_packet; 477 475 offset -= length; 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);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 ); 485 483 } 486 484 487 485 // release if overflowing the window 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);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 ); 490 488 // } 491 489 492 490 /* 493 491 // trim end if overflowing the window 494 if( IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming + socket_data->window, new_sequence_number + total_length)){492 if( IS_IN_INTERVAL_OVERFLOW( new_sequence_number, socket_data->next_incoming + socket_data->window, new_sequence_number + total_length )){ 495 493 // get the allowed data length 496 if( socket_data->next_incoming + socket_data->window < new_sequence_number){494 if( socket_data->next_incoming + socket_data->window < new_sequence_number ){ 497 495 offset = new_sequence_number - socket_data->next_incoming + socket_data->window; 498 496 }else{ … … 501 499 next_packet = packet; 502 500 // trim the overflowing data 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);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 ); 509 507 } 510 508 offset -= length; … … 512 510 } 513 511 // release the overflowing packets 514 next_packet = pq_next( next_packet);515 if( next_packet){512 next_packet = pq_next( next_packet ); 513 if( next_packet ){ 516 514 tmp_packet = next_packet; 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);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 ); 522 520 } 523 521 */ 524 522 // the expected one arrived? 525 if( new_sequence_number == socket_data->next_incoming){523 if( new_sequence_number == socket_data->next_incoming ){ 526 524 printf("expected\n"); 527 525 // process acknowledgement 528 tcp_process_acknowledgement( socket, socket_data, header);526 tcp_process_acknowledgement( socket, socket_data, header ); 529 527 530 528 // remove the header 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));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 )); 538 536 }else{ 539 537 total_length = 1; … … 541 539 socket_data->next_incoming = old_incoming + total_length; 542 540 packet = socket_data->incoming; 543 while( packet){544 if( ERROR_OCCURRED(pq_get_order(socket_data->incoming, &order, NULL))){541 while( packet ){ 542 if( ERROR_OCCURRED( pq_get_order( socket_data->incoming, & order, NULL ))){ 545 543 // remove the corrupted packet 546 next_packet = pq_detach( packet);547 if( packet == socket_data->incoming){544 next_packet = pq_detach( packet ); 545 if( packet == socket_data->incoming ){ 548 546 socket_data->incoming = next_packet; 549 547 } 550 pq_release( tcp_globals.net_phone, packet_get_id(packet));548 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 551 549 packet = next_packet; 552 550 continue; 553 551 } 554 sequence_number = ( uint32_t) order;555 if( IS_IN_INTERVAL_OVERFLOW(sequence_number, old_incoming, socket_data->next_incoming)){552 sequence_number = ( uint32_t ) order; 553 if( IS_IN_INTERVAL_OVERFLOW( sequence_number, old_incoming, socket_data->next_incoming )){ 556 554 // move to the next 557 packet = pq_next( packet);555 packet = pq_next( packet ); 558 556 // coninual data? 559 }else if( IS_IN_INTERVAL_OVERFLOW(old_incoming, sequence_number, socket_data->next_incoming)){557 }else if( IS_IN_INTERVAL_OVERFLOW( old_incoming, sequence_number, socket_data->next_incoming )){ 560 558 // detach the packet 561 next_packet = pq_detach( packet);562 if( packet == socket_data->incoming){559 next_packet = pq_detach( packet ); 560 if( packet == socket_data->incoming ){ 563 561 socket_data->incoming = next_packet; 564 562 } 565 563 // get data length 566 length = packet_get_data_length( packet);564 length = packet_get_data_length( packet ); 567 565 new_sequence_number = sequence_number + length; 568 if( length <= 0){566 if( length <= 0 ){ 569 567 // remove the empty packet 570 pq_release( tcp_globals.net_phone, packet_get_id(packet));568 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 571 569 packet = next_packet; 572 570 continue; 573 571 } 574 572 // exactly following 575 if( sequence_number == socket_data->next_incoming){573 if( sequence_number == socket_data->next_incoming ){ 576 574 // queue received data 577 ERROR_PROPAGATE( tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet)));575 ERROR_PROPAGATE( tcp_queue_received_packet( socket, socket_data, packet, 1, packet_get_data_length( packet ))); 578 576 socket_data->next_incoming = new_sequence_number; 579 577 packet = next_packet; 580 578 continue; 581 579 // at least partly following data? 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){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 ){ 584 582 length = new_sequence_number - socket_data->next_incoming; 585 583 }else{ 586 584 length = socket_data->next_incoming - new_sequence_number; 587 585 } 588 if( ! ERROR_OCCURRED(packet_trim(packet, length, 0))){586 if( ! ERROR_OCCURRED( packet_trim( packet, length, 0 ))){ 589 587 // queue received data 590 ERROR_PROPAGATE( tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet)));588 ERROR_PROPAGATE( tcp_queue_received_packet( socket, socket_data, packet, 1, packet_get_data_length( packet ))); 591 589 socket_data->next_incoming = new_sequence_number; 592 590 packet = next_packet; … … 595 593 } 596 594 // remove the duplicit or corrupted packet 597 pq_release( tcp_globals.net_phone, packet_get_id(packet));595 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 598 596 packet = next_packet; 599 597 continue; … … 602 600 } 603 601 } 604 }else if( IS_IN_INTERVAL(socket_data->next_incoming, new_sequence_number, socket_data->next_incoming + socket_data->window)){602 }else if( IS_IN_INTERVAL( socket_data->next_incoming, new_sequence_number, socket_data->next_incoming + socket_data->window )){ 605 603 printf("in window\n"); 606 604 // process acknowledgement 607 tcp_process_acknowledgement( socket, socket_data, header);605 tcp_process_acknowledgement( socket, socket_data, header ); 608 606 609 607 // remove the header 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))){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 ))){ 618 616 // remove the corrupted packets 619 pq_release( tcp_globals.net_phone, packet_get_id(packet));620 pq_release( tcp_globals.net_phone, packet_get_id(next_packet));617 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 618 pq_release( tcp_globals.net_phone, packet_get_id( next_packet )); 621 619 }else{ 622 while( next_packet){620 while( next_packet ){ 623 621 new_sequence_number += length; 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));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 )); 629 627 } 630 628 next_packet = tmp_packet; … … 634 632 printf("unexpected\n"); 635 633 // release duplicite or restricted 636 pq_release( tcp_globals.net_phone, packet_get_id(packet));634 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 637 635 } 638 636 639 637 // change state according to the acknowledging incoming fin 640 if( IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming, socket_data->next_incoming)){641 switch( socket_data->state){638 if( IS_IN_INTERVAL_OVERFLOW( old_incoming, socket_data->fin_incoming, socket_data->next_incoming )){ 639 switch( socket_data->state ){ 642 640 case TCP_SOCKET_FIN_WAIT_1: 643 641 case TCP_SOCKET_FIN_WAIT_2: … … 652 650 } 653 651 654 packet = tcp_get_packets_to_send( socket, socket_data);655 if( ! packet){652 packet = tcp_get_packets_to_send( socket, socket_data ); 653 if( ! packet ){ 656 654 // create the notification packet 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);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 ); 662 660 // send the packet 663 tcp_send_packets( socket_data->device_id, packet);661 tcp_send_packets( socket_data->device_id, packet ); 664 662 return EOK; 665 663 } 666 664 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){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 ){ 668 666 ERROR_DECLARE; 669 667 670 packet_dimension_ref 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);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 ); 678 676 679 677 // queue the received packet 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);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 ); 683 681 } 684 682 … … 687 685 688 686 // notify the destination socket 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);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 ); 690 688 return EOK; 691 689 } 692 690 693 int tcp_process_syn_sent( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){691 int tcp_process_syn_sent( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet ){ 694 692 ERROR_DECLARE; 695 693 696 packet_t 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){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 ){ 705 703 // process acknowledgement 706 tcp_process_acknowledgement( socket, socket_data, header);707 708 socket_data->next_incoming = ntohl( header->sequence_number) + 1;704 tcp_process_acknowledgement( socket, socket_data, header ); 705 706 socket_data->next_incoming = ntohl( header->sequence_number ) + 1; 709 707 // release additional packets 710 next_packet = pq_detach( packet);711 if( next_packet){712 pq_release( tcp_globals.net_phone, packet_get_id(next_packet));708 next_packet = pq_detach( packet ); 709 if( next_packet ){ 710 pq_release( tcp_globals.net_phone, packet_get_id( next_packet )); 713 711 } 714 712 // trim if longer than the header 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){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 ){ 723 721 socket_data->state = TCP_SOCKET_ESTABLISHED; 724 packet = tcp_get_packets_to_send( socket, socket_data);725 if( packet){726 fibril_rwlock_write_unlock( socket_data->local_lock);722 packet = tcp_get_packets_to_send( socket, socket_data ); 723 if( packet ){ 724 fibril_rwlock_write_unlock( socket_data->local_lock ); 727 725 // send the packet 728 tcp_send_packets( socket_data->device_id, packet);726 tcp_send_packets( socket_data->device_id, packet ); 729 727 // signal the result 730 fibril_condvar_signal( &socket_data->operation.condvar);731 fibril_mutex_unlock( &socket_data->operation.mutex);728 fibril_condvar_signal( & socket_data->operation.condvar ); 729 fibril_mutex_unlock( & socket_data->operation.mutex ); 732 730 return EOK; 733 731 } 734 732 } 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){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 ){ 741 739 ERROR_DECLARE; 742 740 743 packet_t 744 socket_core_ref 745 tcp_socket_data_ref 746 int 747 int 748 int 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);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 ); 761 759 }else{ 762 tcp_initialize_socket_data( socket_data);760 tcp_initialize_socket_data( socket_data ); 763 761 socket_data->local_lock = listening_socket_data->local_lock; 764 762 socket_data->local_sockets = listening_socket_data->local_sockets; 765 763 socket_data->listening_socket_id = listening_socket->socket_id; 766 764 767 socket_data->next_incoming = ntohl( header->sequence_number);768 socket_data->treshold = socket_data->next_incoming + ntohs( header->window);765 socket_data->next_incoming = ntohl( header->sequence_number ); 766 socket_data->treshold = socket_data->next_incoming + ntohs( header->window ); 769 767 770 768 socket_data->addrlen = addrlen; 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));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 )); 783 781 return ERROR_CODE; 784 782 } 785 783 786 // printf( "addr %p\n", socket_data->addr, socket_data->addrlen);784 // printf( "addr %p\n", socket_data->addr, socket_data->addrlen ); 787 785 // create a socket 788 786 socket_id = -1; 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);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 ); 793 791 } 794 792 … … 799 797 listening_socket_data->headerlen = 0; 800 798 801 fibril_rwlock_write_unlock( socket_data->local_lock);799 fibril_rwlock_write_unlock( socket_data->local_lock ); 802 800 // printf("list lg\n"); 803 fibril_rwlock_write_lock( &tcp_globals.lock);801 fibril_rwlock_write_lock( & tcp_globals.lock ); 804 802 // printf("list locked\n"); 805 803 // find the destination socket 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);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 ); 809 807 // a shadow may remain until app hangs up 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);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 ); 815 813 816 814 // printf("list ll\n"); 817 fibril_rwlock_write_lock( listening_socket_data->local_lock);815 fibril_rwlock_write_lock( listening_socket_data->local_lock ); 818 816 // printf("list locked\n"); 819 817 820 socket = socket_cores_find( listening_socket_data->local_sockets, socket_id);821 if( ! socket){818 socket = socket_cores_find( listening_socket_data->local_sockets, socket_id ); 819 if( ! socket ){ 822 820 // where is the socket?!? 823 fibril_rwlock_write_unlock( &tcp_globals.lock);821 fibril_rwlock_write_unlock( & tcp_globals.lock ); 824 822 return ENOTSOCK; 825 823 } 826 socket_data = ( tcp_socket_data_ref) socket->specific_data;827 assert( socket_data);824 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 825 assert( socket_data ); 828 826 829 827 // uint8_t * data = socket_data->addr; 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);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 ); 835 833 //tcp_globals.last_used_port = socket->port; 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);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 ); 841 839 } 842 840 843 841 socket_data->state = TCP_SOCKET_LISTEN; 844 socket_data->next_incoming = ntohl( header->sequence_number) + 1;842 socket_data->next_incoming = ntohl( header->sequence_number ) + 1; 845 843 // release additional packets 846 next_packet = pq_detach( packet);847 if( next_packet){848 pq_release( tcp_globals.net_phone, packet_get_id(next_packet));844 next_packet = pq_detach( packet ); 845 if( next_packet ){ 846 pq_release( tcp_globals.net_phone, packet_get_id( next_packet )); 849 847 } 850 848 // trim if longer than the header 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);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 ); 859 857 return ERROR_CODE; 860 858 } 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);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 ); 865 863 return EINVAL; 866 864 }else{ 867 865 socket_data->state = TCP_SOCKET_SYN_RECEIVED; 868 866 // printf("unlock\n"); 869 fibril_rwlock_write_unlock( socket_data->local_lock);867 fibril_rwlock_write_unlock( socket_data->local_lock ); 870 868 // send the packet 871 tcp_send_packets( socket_data->device_id, packet);869 tcp_send_packets( socket_data->device_id, packet ); 872 870 return EOK; 873 871 } 874 872 } 875 873 } 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){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 ){ 880 878 ERROR_DECLARE; 881 879 882 socket_core_ref 883 tcp_socket_data_ref 884 885 assert( socket);886 assert( socket_data);887 assert( socket->specific_data == socket_data);888 assert( header);889 assert( packet);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 ); 890 888 891 889 printf("syn_rec\n"); 892 if( header->acknowledge){890 if( header->acknowledge ){ 893 891 // process acknowledgement 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));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 )); 898 896 socket_data->state = TCP_SOCKET_ESTABLISHED; 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);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 ); 903 901 904 902 // queue the received packet 905 if( ! ERROR_OCCURRED(dyn_fifo_push(&listening_socket->accepted, (-1 * socket->socket_id), listening_socket_data->backlog))){903 if( ! ERROR_OCCURRED( dyn_fifo_push( & listening_socket->accepted, ( -1 * socket->socket_id ), listening_socket_data->backlog ))){ 906 904 // notify the destination socket 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);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 ); 909 907 return EOK; 910 908 } … … 914 912 915 913 // create the notification packet 916 ERROR_PROPAGATE( tcp_create_notification_packet(&packet, socket, socket_data, 0, 1));914 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 0, 1 )); 917 915 918 916 // send the packet 919 ERROR_PROPAGATE( tcp_queue_packet(socket, socket_data, packet, 1));917 ERROR_PROPAGATE( tcp_queue_packet( socket, socket_data, packet, 1 )); 920 918 921 919 // flush packets 922 packet = tcp_get_packets_to_send( socket, socket_data);923 fibril_rwlock_write_unlock( socket_data->local_lock);924 if( packet){920 packet = tcp_get_packets_to_send( socket, socket_data ); 921 fibril_rwlock_write_unlock( socket_data->local_lock ); 922 if( packet ){ 925 923 // send the packet 926 tcp_send_packets( socket_data->device_id, packet);924 tcp_send_packets( socket_data->device_id, packet ); 927 925 } 928 926 return EOK; 929 927 }else{ 930 return tcp_release_and_return( packet, EINVAL);928 return tcp_release_and_return( packet, EINVAL ); 931 929 } 932 930 return EINVAL; 933 931 } 934 932 935 void tcp_process_acknowledgement( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header){936 size_t 937 size_t 938 packet_t 939 packet_t 940 packet_t 941 uint32_t 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);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 ); 950 948 // if more data acknowledged 951 if( number != socket_data->expected){949 if( number != socket_data->expected ){ 952 950 old = socket_data->expected; 953 if( IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing, number)){954 switch( socket_data->state){951 if( IS_IN_INTERVAL_OVERFLOW( old, socket_data->fin_outgoing, number )){ 952 switch( socket_data->state ){ 955 953 case TCP_SOCKET_FIN_WAIT_1: 956 954 socket_data->state = TCP_SOCKET_FIN_WAIT_2; … … 959 957 case TCP_SOCKET_CLOSING: 960 958 // fin acknowledged - release the socket in another fibril 961 tcp_prepare_timeout( tcp_release_after_timeout, socket, socket_data, 0, TCP_SOCKET_TIME_WAIT, NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true);959 tcp_prepare_timeout( tcp_release_after_timeout, socket, socket_data, 0, TCP_SOCKET_TIME_WAIT, NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true ); 962 960 break; 963 961 default: … … 966 964 } 967 965 // update the treshold if higher than set 968 if( number + ntohs(header->window) > socket_data->expected + socket_data->treshold){969 socket_data->treshold = number + ntohs( header->window) - socket_data->expected;966 if( number + ntohs( header->window ) > socket_data->expected + socket_data->treshold ){ 967 socket_data->treshold = number + ntohs( header->window ) - socket_data->expected; 970 968 } 971 969 // set new expected sequence number … … 973 971 socket_data->expected_count = 1; 974 972 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){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 ){ 979 977 socket_data->outgoing = next; 980 978 } 981 979 // add to acknowledged or release 982 if( pq_add(&acknowledged, packet, 0, 0) != EOK){983 pq_release( tcp_globals.net_phone, packet_get_id(packet));980 if( pq_add( & acknowledged, packet, 0, 0 ) != EOK ){ 981 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 984 982 } 985 983 packet = next; 986 }else if( old < socket_data->expected){984 }else if( old < socket_data->expected ){ 987 985 break; 988 986 } 989 987 } 990 988 // release acknowledged 991 if( acknowledged){992 pq_release( tcp_globals.net_phone, packet_get_id(acknowledged));989 if( acknowledged ){ 990 pq_release( tcp_globals.net_phone, packet_get_id( acknowledged )); 993 991 } 994 992 return; 995 993 // if the same as the previous time 996 }else if( number == socket_data->expected){994 }else if( number == socket_data->expected ){ 997 995 // increase the counter 998 996 ++ socket_data->expected_count; 999 if( socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT){997 if( socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT ){ 1000 998 socket_data->expected_count = 1; 1001 999 // TODO retransmit lock 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){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 ){ 1009 1007 ERROR_DECLARE; 1010 1008 1011 packet_t 1012 1013 assert( call);1014 assert( answer);1015 assert( answer_count);1016 1017 * answer_count = 0;1018 switch( IPC_GET_METHOD(*call)){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 )){ 1019 1017 case NET_TL_RECEIVED: 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);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 ); 1025 1023 return ERROR_CODE; 1026 1024 case IPC_M_CONNECT_TO_ME: 1027 return tcp_process_client_messages( callid, * call);1025 return tcp_process_client_messages( callid, * call ); 1028 1026 } 1029 1027 return ENOTSUP; 1030 1028 } 1031 1029 1032 void tcp_refresh_socket_data( tcp_socket_data_ref socket_data){1033 assert( socket_data);1034 1035 bzero( socket_data, sizeof(*socket_data));1030 void tcp_refresh_socket_data( tcp_socket_data_ref socket_data ){ 1031 assert( socket_data ); 1032 1033 bzero( socket_data, sizeof( * socket_data )); 1036 1034 socket_data->state = TCP_SOCKET_INITIAL; 1037 1035 socket_data->device_id = DEVICE_INVALID_ID; … … 1045 1043 } 1046 1044 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);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 ); 1053 1051 socket_data->data_fragment_size = MAX_TCP_FRAGMENT_SIZE; 1054 1052 } 1055 1053 1056 int tcp_process_client_messages( ipc_callid_t callid, ipc_call_t call){1057 int 1058 bool 1059 socket_cores_t 1060 int app_phone = IPC_GET_PHONE(&call);1061 struct sockaddr * 1062 size_t 1063 fibril_rwlock_t 1064 ipc_call_t 1065 int 1066 tcp_socket_data_ref 1067 socket_core_ref 1068 packet_dimension_ref 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; 1069 1067 1070 1068 /* … … 1072 1070 * - Answer the first IPC_M_CONNECT_ME_TO call. 1073 1071 */ 1074 res = EOK; 1075 answer_count = 0; 1076 1077 socket_cores_initialize(&local_sockets); 1078 fibril_rwlock_initialize(&lock); 1079 1080 while(keep_on_going){ 1081 1082 // answer the call 1083 answer_call(callid, res, &answer, answer_count); 1084 1072 ipc_answer_0( callid, EOK ); 1073 1074 socket_cores_initialize( & local_sockets ); 1075 fibril_rwlock_initialize( & lock ); 1076 1077 while( keep_on_going ){ 1085 1078 // refresh data 1086 refresh_answer(&answer, &answer_count); 1087 1088 // get the next call 1089 callid = async_get_call(&call); 1090 1091 // process the call 1092 switch(IPC_GET_METHOD(call)){ 1079 refresh_answer( & answer, & answer_count ); 1080 1081 callid = async_get_call( & call ); 1082 // printf( "message %d\n", IPC_GET_METHOD( * call )); 1083 1084 switch( IPC_GET_METHOD( call )){ 1093 1085 case IPC_M_PHONE_HUNGUP: 1094 1086 keep_on_going = false; 1095 res = E HANGUP;1087 res = EOK; 1096 1088 break; 1097 1089 case NET_SOCKET: 1098 socket_data = ( tcp_socket_data_ref) malloc(sizeof(*socket_data));1099 if( ! socket_data){1090 socket_data = ( tcp_socket_data_ref ) malloc( sizeof( * socket_data )); 1091 if( ! socket_data ){ 1100 1092 res = ENOMEM; 1101 1093 }else{ 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);1094 tcp_initialize_socket_data( socket_data ); 1095 socket_data->local_lock = & lock; 1096 socket_data->local_sockets = & local_sockets; 1097 fibril_rwlock_write_lock( & lock ); 1098 * SOCKET_SET_SOCKET_ID( answer ) = SOCKET_GET_SOCKET_ID( call ); 1099 res = socket_create( & local_sockets, app_phone, socket_data, SOCKET_SET_SOCKET_ID( answer )); 1100 fibril_rwlock_write_unlock( & lock ); 1101 if( res == EOK ){ 1102 if( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, DEVICE_INVALID_ID, & packet_dimension ) == EOK ){ 1103 * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size ); 1112 1104 } 1113 // * SOCKET_SET_DATA_FRAGMENT_SIZE(answer) = MAX_TCP_FRAGMENT_SIZE;1114 * SOCKET_SET_HEADER_SIZE(answer) = TCP_HEADER_SIZE;1105 // * SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) = MAX_TCP_FRAGMENT_SIZE; 1106 * SOCKET_SET_HEADER_SIZE( answer ) = TCP_HEADER_SIZE; 1115 1107 answer_count = 3; 1116 1108 }else{ 1117 free( socket_data);1109 free( socket_data ); 1118 1110 } 1119 1111 } 1120 1112 break; 1121 1113 case NET_SOCKET_BIND: 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);1114 res = data_receive(( void ** ) & addr, & addrlen ); 1115 if( res == EOK ){ 1116 fibril_rwlock_write_lock( & tcp_globals.lock ); 1117 fibril_rwlock_write_lock( & lock ); 1118 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 ); 1119 if( res == EOK ){ 1120 socket = socket_cores_find( & local_sockets, SOCKET_GET_SOCKET_ID( call )); 1121 if( socket ){ 1122 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1123 assert( socket_data ); 1132 1124 socket_data->state = TCP_SOCKET_LISTEN; 1133 1125 } 1134 1126 } 1135 fibril_rwlock_write_unlock( &lock);1136 fibril_rwlock_write_unlock( &tcp_globals.lock);1137 free( addr);1127 fibril_rwlock_write_unlock( & lock ); 1128 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1129 free( addr ); 1138 1130 } 1139 1131 break; 1140 1132 case NET_SOCKET_LISTEN: 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);1133 fibril_rwlock_read_lock( & tcp_globals.lock ); 1134 // fibril_rwlock_write_lock( & tcp_globals.lock ); 1135 fibril_rwlock_write_lock( & lock ); 1136 res = tcp_listen_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_BACKLOG( call )); 1137 fibril_rwlock_write_unlock( & lock ); 1138 // fibril_rwlock_write_unlock( & tcp_globals.lock ); 1139 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1148 1140 break; 1149 1141 case NET_SOCKET_CONNECT: 1150 res = data_receive(( void **) &addr, &addrlen);1151 if( res == EOK){1142 res = data_receive(( void ** ) & addr, & addrlen ); 1143 if( res == EOK ){ 1152 1144 // the global lock may be released in the tcp_connect_message() function 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);1145 fibril_rwlock_write_lock( & tcp_globals.lock ); 1146 fibril_rwlock_write_lock( & lock ); 1147 res = tcp_connect_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), addr, addrlen ); 1148 if( res != EOK ){ 1149 fibril_rwlock_write_unlock( & lock ); 1150 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1151 free( addr ); 1160 1152 } 1161 1153 } 1162 1154 break; 1163 1155 case NET_SOCKET_ACCEPT: 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;1156 fibril_rwlock_read_lock( & tcp_globals.lock ); 1157 fibril_rwlock_write_lock( & lock ); 1158 res = tcp_accept_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_NEW_SOCKET_ID( call ), SOCKET_SET_DATA_FRAGMENT_SIZE( answer ), & addrlen ); 1159 fibril_rwlock_write_unlock( & lock ); 1160 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1161 if( res > 0 ){ 1162 * SOCKET_SET_SOCKET_ID( answer ) = res; 1163 * SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen; 1172 1164 answer_count = 3; 1173 1165 } 1174 1166 break; 1175 1167 case NET_SOCKET_SEND: 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);1168 fibril_rwlock_read_lock( & tcp_globals.lock ); 1169 fibril_rwlock_write_lock( & lock ); 1170 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 )); 1171 if( res != EOK ){ 1172 fibril_rwlock_write_unlock( & lock ); 1173 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1182 1174 }else{ 1183 1175 answer_count = 2; … … 1185 1177 break; 1186 1178 case NET_SOCKET_SENDTO: 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);1179 res = data_receive(( void ** ) & addr, & addrlen ); 1180 if( res == EOK ){ 1181 fibril_rwlock_read_lock( & tcp_globals.lock ); 1182 fibril_rwlock_write_lock( & lock ); 1183 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 )); 1184 if( res != EOK ){ 1185 fibril_rwlock_write_unlock( & lock ); 1186 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1195 1187 }else{ 1196 1188 answer_count = 2; 1197 1189 } 1198 free( addr);1190 free( addr ); 1199 1191 } 1200 1192 break; 1201 1193 case NET_SOCKET_RECV: 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;1194 fibril_rwlock_read_lock( & tcp_globals.lock ); 1195 fibril_rwlock_write_lock( & lock ); 1196 res = tcp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ), NULL ); 1197 fibril_rwlock_write_unlock( & lock ); 1198 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1199 if( res > 0 ){ 1200 * SOCKET_SET_READ_DATA_LENGTH( answer ) = res; 1209 1201 answer_count = 1; 1210 1202 res = EOK; … … 1212 1204 break; 1213 1205 case NET_SOCKET_RECVFROM: 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;1206 fibril_rwlock_read_lock( & tcp_globals.lock ); 1207 fibril_rwlock_write_lock( & lock ); 1208 res = tcp_recvfrom_message( & local_sockets, SOCKET_GET_SOCKET_ID( call ), SOCKET_GET_FLAGS( call ), & addrlen ); 1209 fibril_rwlock_write_unlock( & lock ); 1210 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1211 if( res > 0 ){ 1212 * SOCKET_SET_READ_DATA_LENGTH( answer ) = res; 1213 * SOCKET_SET_ADDRESS_LENGTH( answer ) = addrlen; 1222 1214 answer_count = 3; 1223 1215 res = EOK; … … 1225 1217 break; 1226 1218 case NET_SOCKET_CLOSE: 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);1219 fibril_rwlock_write_lock( & tcp_globals.lock ); 1220 fibril_rwlock_write_lock( & lock ); 1221 res = tcp_close_message( & local_sockets, SOCKET_GET_SOCKET_ID( call )); 1222 if( res != EOK ){ 1223 fibril_rwlock_write_unlock( & lock ); 1224 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1233 1225 } 1234 1226 break; … … 1239 1231 break; 1240 1232 } 1233 1234 // printf( "res = %d\n", res ); 1235 1236 answer_call( callid, res, & answer, answer_count ); 1241 1237 } 1242 1238 1243 1239 printf("release\n"); 1244 1240 // release all local sockets 1245 socket_cores_release( tcp_globals.net_phone, &local_sockets, &tcp_globals.sockets, tcp_free_socket_data);1241 socket_cores_release( tcp_globals.net_phone, & local_sockets, & tcp_globals.sockets, tcp_free_socket_data ); 1246 1242 1247 1243 return EOK; 1248 1244 } 1249 1245 1250 int tcp_timeout( void * data){1251 tcp_timeout_ref 1252 int 1253 socket_core_ref 1254 tcp_socket_data_ref 1255 1256 assert( timeout);1246 int tcp_timeout( void * data ){ 1247 tcp_timeout_ref timeout = data; 1248 int keep_write_lock = false; 1249 socket_core_ref socket; 1250 tcp_socket_data_ref socket_data; 1251 1252 assert( timeout ); 1257 1253 1258 1254 // sleep the given timeout 1259 async_usleep( timeout->timeout);1255 async_usleep( timeout->timeout ); 1260 1256 // lock the globals 1261 if( timeout->globals_read_only){1262 fibril_rwlock_read_lock( &tcp_globals.lock);1257 if( timeout->globals_read_only ){ 1258 fibril_rwlock_read_lock( & tcp_globals.lock ); 1263 1259 }else{ 1264 fibril_rwlock_write_lock( &tcp_globals.lock);1260 fibril_rwlock_write_lock( & tcp_globals.lock ); 1265 1261 } 1266 1262 // find the pending operation socket 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){1263 socket = socket_port_find( & tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length ); 1264 if( socket && ( socket->socket_id == timeout->socket_id )){ 1265 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1266 assert( socket_data ); 1267 if( socket_data->local_sockets == timeout->local_sockets ){ 1268 fibril_rwlock_write_lock( socket_data->local_lock ); 1269 if( timeout->sequence_number ){ 1274 1270 // increase the timeout counter; 1275 1271 ++ socket_data->timeout_count; 1276 if( socket_data->timeout_count == TCP_MAX_TIMEOUTS){1272 if( socket_data->timeout_count == TCP_MAX_TIMEOUTS ){ 1277 1273 // TODO release as connection lost 1278 //tcp_refresh_socket_data( socket_data);1279 } else{1280 1281 tcp_retransmit_packet(socket, socket_data, timeout->sequence_number);1282 }1283 fibril_rwlock_write_unlock( socket_data->local_lock);1274 //tcp_refresh_socket_data( socket_data ); 1275 } 1276 // retransmit 1277 // TODO enable retransmit 1278 //tcp_retransmit_packet( socket, socket_data, timeout->sequence_number ); 1279 fibril_rwlock_write_unlock( socket_data->local_lock ); 1284 1280 }else{ 1285 fibril_mutex_lock( &socket_data->operation.mutex);1281 fibril_mutex_lock( & socket_data->operation.mutex ); 1286 1282 // set the timeout operation result if state not changed 1287 if( socket_data->state == timeout->state){1283 if( socket_data->state == timeout->state ){ 1288 1284 socket_data->operation.result = ETIMEOUT; 1289 1285 // notify the main fibril 1290 fibril_condvar_signal( &socket_data->operation.condvar);1286 fibril_condvar_signal( & socket_data->operation.condvar ); 1291 1287 // keep the global write lock 1292 1288 keep_write_lock = true; … … 1294 1290 // operation is ok, do nothing 1295 1291 // unlocking from now on, so the unlock order does not matter... 1296 fibril_rwlock_write_unlock( socket_data->local_lock);1297 } 1298 fibril_mutex_unlock( &socket_data->operation.mutex);1292 fibril_rwlock_write_unlock( socket_data->local_lock ); 1293 } 1294 fibril_mutex_unlock( & socket_data->operation.mutex ); 1299 1295 } 1300 1296 } 1301 1297 } 1302 1298 // unlock only if no socket 1303 if( timeout->globals_read_only){1304 fibril_rwlock_read_unlock( &tcp_globals.lock);1305 }else if( ! keep_write_lock){1299 if( timeout->globals_read_only ){ 1300 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1301 }else if( ! keep_write_lock ){ 1306 1302 // release if not desired 1307 fibril_rwlock_write_unlock( &tcp_globals.lock);1303 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1308 1304 } 1309 1305 // release the timeout structure 1310 free( timeout);1306 free( timeout ); 1311 1307 return EOK; 1312 1308 } 1313 1309 1314 int tcp_release_after_timeout( void * data){1315 tcp_timeout_ref 1316 socket_core_ref 1317 tcp_socket_data_ref 1318 fibril_rwlock_t * 1319 1320 assert( timeout);1310 int tcp_release_after_timeout( void * data ){ 1311 tcp_timeout_ref timeout = data; 1312 socket_core_ref socket; 1313 tcp_socket_data_ref socket_data; 1314 fibril_rwlock_t * local_lock; 1315 1316 assert( timeout ); 1321 1317 1322 1318 // sleep the given timeout 1323 async_usleep( timeout->timeout);1319 async_usleep( timeout->timeout ); 1324 1320 // lock the globals 1325 fibril_rwlock_write_lock( &tcp_globals.lock);1321 fibril_rwlock_write_lock( & tcp_globals.lock ); 1326 1322 // find the pending operation socket 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){1323 socket = socket_port_find( & tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length ); 1324 if( socket && ( socket->socket_id == timeout->socket_id )){ 1325 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1326 assert( socket_data ); 1327 if( socket_data->local_sockets == timeout->local_sockets ){ 1332 1328 local_lock = socket_data->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);1329 fibril_rwlock_write_lock( local_lock ); 1330 socket_destroy( tcp_globals.net_phone, timeout->socket_id, timeout->local_sockets, & tcp_globals.sockets, tcp_free_socket_data ); 1331 fibril_rwlock_write_unlock( local_lock ); 1336 1332 } 1337 1333 } 1338 1334 // unlock the globals 1339 fibril_rwlock_write_unlock( &tcp_globals.lock);1335 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1340 1336 // release the timeout structure 1341 free( timeout);1337 free( timeout ); 1342 1338 return EOK; 1343 1339 } 1344 1340 1345 void tcp_retransmit_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){1346 packet_t 1347 packet_t 1348 size_t 1349 1350 assert( socket);1351 assert( socket_data);1352 assert( socket->specific_data == socket_data);1341 void tcp_retransmit_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number ){ 1342 packet_t packet; 1343 packet_t copy; 1344 size_t data_length; 1345 1346 assert( socket ); 1347 assert( socket_data ); 1348 assert( socket->specific_data == socket_data ); 1353 1349 1354 1350 // sent packet? 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);1351 packet = pq_find( socket_data->outgoing, sequence_number ); 1352 printf("retransmit %d\n", packet_get_id( packet )); 1353 if( packet ){ 1354 pq_get_order( packet, NULL, & data_length ); 1355 copy = tcp_prepare_copy( socket, socket_data, packet, data_length, sequence_number ); 1356 fibril_rwlock_write_unlock( socket_data->local_lock ); 1357 // printf( "r send %d\n", packet_get_id( packet )); 1358 if( copy ){ 1359 tcp_send_packets( socket_data->device_id, copy ); 1364 1360 } 1365 1361 }else{ 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 } 1362 fibril_rwlock_write_unlock( socket_data->local_lock ); 1363 } 1364 } 1365 1366 int tcp_listen_message( socket_cores_ref local_sockets, int socket_id, int backlog ){ 1367 socket_core_ref socket; 1368 tcp_socket_data_ref socket_data; 1369 1370 assert( local_sockets ); 1371 1372 if( backlog < 0 ) return EINVAL; 1379 1373 // find the socket 1380 socket = socket_cores_find(local_sockets, socket_id); 1381 if(! socket){ 1382 return ENOTSOCK; 1383 } 1374 socket = socket_cores_find( local_sockets, socket_id ); 1375 if( ! socket ) return ENOTSOCK; 1384 1376 // get the socket specific data 1385 socket_data = ( tcp_socket_data_ref) socket->specific_data;1386 assert( socket_data);1377 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1378 assert( socket_data ); 1387 1379 // set the backlog 1388 1380 socket_data->backlog = backlog; … … 1390 1382 } 1391 1383 1392 int tcp_connect_message( socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){1384 int tcp_connect_message( socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen ){ 1393 1385 ERROR_DECLARE; 1394 1386 1395 socket_core_ref 1396 1397 assert( local_sockets);1398 assert( addr);1399 assert( addrlen > 0);1387 socket_core_ref socket; 1388 1389 assert( local_sockets ); 1390 assert( addr ); 1391 assert( addrlen > 0 ); 1400 1392 1401 1393 // find the 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); 1394 socket = socket_cores_find( local_sockets, socket_id ); 1395 if( ! socket ) return ENOTSOCK; 1396 if( ERROR_OCCURRED( tcp_connect_core( socket, local_sockets, addr, addrlen ))){ 1397 tcp_free_socket_data( socket ); 1408 1398 // unbind if bound 1409 if( socket->port > 0){1410 socket_ports_exclude( &tcp_globals.sockets, socket->port);1399 if( socket->port > 0 ){ 1400 socket_ports_exclude( & tcp_globals.sockets, socket->port ); 1411 1401 socket->port = 0; 1412 1402 } … … 1415 1405 } 1416 1406 1417 int tcp_connect_core( socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){1407 int tcp_connect_core( socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen ){ 1418 1408 ERROR_DECLARE; 1419 1409 1420 tcp_socket_data_ref 1421 packet_t 1422 1423 assert( socket);1424 assert( addr);1425 assert( addrlen > 0);1410 tcp_socket_data_ref socket_data; 1411 packet_t packet; 1412 1413 assert( socket ); 1414 assert( addr ); 1415 assert( addrlen > 0 ); 1426 1416 1427 1417 // get the socket specific data 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))){1418 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1419 assert( socket_data ); 1420 assert( socket->specific_data == socket_data ); 1421 if(( socket_data->state != TCP_SOCKET_INITIAL ) 1422 && (( socket_data->state != TCP_SOCKET_LISTEN ) || ( socket->port <= 0 ))){ 1433 1423 return EINVAL; 1434 1424 } 1435 1425 // get the destination port 1436 ERROR_PROPAGATE( tl_get_address_port(addr, addrlen, &socket_data->dest_port));1437 if( socket->port <= 0){1426 ERROR_PROPAGATE( tl_get_address_port( addr, addrlen, & socket_data->dest_port )); 1427 if( socket->port <= 0 ){ 1438 1428 // try to find a free 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));1429 ERROR_PROPAGATE( socket_bind_free_port( & tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port )); 1440 1430 // set the next port as the search starting port number 1441 1431 tcp_globals.last_used_port = socket->port; 1442 1432 } 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));1433 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 )); 1444 1434 1445 1435 // create the notification packet 1446 ERROR_PROPAGATE( tcp_create_notification_packet(&packet, socket, socket_data, 1, 0));1436 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 1, 0 )); 1447 1437 1448 1438 // unlock the globals and wait for an operation 1449 fibril_rwlock_write_unlock( &tcp_globals.lock);1439 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1450 1440 1451 1441 socket_data->addr = addr; 1452 1442 socket_data->addrlen = addrlen; 1453 1443 // send the packet 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))){1444 if( ERROR_OCCURRED( tcp_queue_packet( socket, socket_data, packet, 1 )) 1445 || ERROR_OCCURRED( tcp_prepare_timeout( tcp_timeout, socket, socket_data, 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false ))){ 1456 1446 socket_data->addr = NULL; 1457 1447 socket_data->addrlen = 0; 1458 fibril_rwlock_write_lock( &tcp_globals.lock);1448 fibril_rwlock_write_lock( & tcp_globals.lock ); 1459 1449 }else{ 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);1450 packet = tcp_get_packets_to_send( socket, socket_data ); 1451 if( packet ){ 1452 fibril_mutex_lock( & socket_data->operation.mutex ); 1453 fibril_rwlock_write_unlock( socket_data->local_lock ); 1464 1454 // send the packet 1465 printf( "connecting %d\n", packet_get_id(packet));1466 tcp_send_packets( socket_data->device_id, packet);1455 printf( "connecting %d\n", packet_get_id( packet )); 1456 tcp_send_packets( socket_data->device_id, packet ); 1467 1457 // wait for a reply 1468 fibril_condvar_wait( &socket_data->operation.condvar, &socket_data->operation.mutex);1458 fibril_condvar_wait( & socket_data->operation.condvar, & socket_data->operation.mutex ); 1469 1459 ERROR_CODE = socket_data->operation.result; 1470 if( ERROR_CODE != EOK){1460 if( ERROR_CODE != EOK ){ 1471 1461 socket_data->addr = NULL; 1472 1462 socket_data->addrlen = 0; … … 1479 1469 } 1480 1470 1481 fibril_mutex_unlock( &socket_data->operation.mutex);1471 fibril_mutex_unlock( & socket_data->operation.mutex ); 1482 1472 1483 1473 // return the result … … 1485 1475 } 1486 1476 1487 int tcp_queue_prepare_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){1477 int tcp_queue_prepare_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length ){ 1488 1478 ERROR_DECLARE; 1489 1479 1490 tcp_header_ref 1491 1492 assert( socket);1493 assert( socket_data);1494 assert( socket->specific_data == socket_data);1480 tcp_header_ref header; 1481 1482 assert( socket ); 1483 assert( socket_data ); 1484 assert( socket->specific_data == socket_data ); 1495 1485 1496 1486 // get tcp header 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); 1487 header = ( tcp_header_ref ) packet_get_data( packet ); 1488 if( ! header ) return NO_DATA; 1489 header->destination_port = htons( socket_data->dest_port ); 1490 header->source_port = htons( socket->port ); 1491 header->sequence_number = htonl( socket_data->next_outgoing ); 1492 if( ERROR_OCCURRED( packet_set_addr( packet, NULL, ( uint8_t * ) socket_data->addr, socket_data->addrlen ))){ 1493 return tcp_release_and_return( packet, EINVAL ); 1506 1494 } 1507 1495 // remember the outgoing FIN 1508 if( header->finalize){1496 if( header->finalize ){ 1509 1497 socket_data->fin_outgoing = socket_data->next_outgoing; 1510 1498 } … … 1512 1500 } 1513 1501 1514 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){1502 int tcp_queue_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length ){ 1515 1503 ERROR_DECLARE; 1516 1504 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);1505 assert( socket ); 1506 assert( socket_data ); 1507 assert( socket->specific_data == socket_data ); 1508 1509 ERROR_PROPAGATE( tcp_queue_prepare_packet( socket, socket_data, packet, data_length )); 1510 1511 if( ERROR_OCCURRED( pq_add( & socket_data->outgoing, packet, socket_data->next_outgoing, data_length ))){ 1512 return tcp_release_and_return( packet, ERROR_CODE ); 1525 1513 } 1526 1514 socket_data->next_outgoing += data_length; … … 1528 1516 } 1529 1517 1530 packet_t tcp_get_packets_to_send( socket_core_ref socket, tcp_socket_data_ref socket_data){1518 packet_t tcp_get_packets_to_send( socket_core_ref socket, tcp_socket_data_ref socket_data ){ 1531 1519 ERROR_DECLARE; 1532 1520 1533 packet_t 1534 packet_t 1535 packet_t 1536 packet_t 1537 size_t 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);1521 packet_t packet; 1522 packet_t copy; 1523 packet_t sending = NULL; 1524 packet_t previous = NULL; 1525 size_t data_length; 1526 1527 assert( socket ); 1528 assert( socket_data ); 1529 assert( socket->specific_data == socket_data ); 1530 1531 packet = pq_find( socket_data->outgoing, socket_data->last_outgoing + 1 ); 1532 while( packet ){ 1533 pq_get_order( packet, NULL, & data_length ); 1546 1534 // send only if fits into the window 1547 1535 // respecting the possible overflow 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){1536 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 ))){ 1537 copy = tcp_prepare_copy( socket, socket_data, packet, data_length, socket_data->last_outgoing + 1 ); 1538 if( ! copy ){ 1551 1539 return sending; 1552 1540 } 1553 if( ! sending){1541 if( ! sending ){ 1554 1542 sending = copy; 1555 1543 }else{ 1556 if( ERROR_OCCURRED(pq_insert_after(previous, copy))){1557 pq_release( tcp_globals.net_phone, packet_get_id(copy));1544 if( ERROR_OCCURRED( pq_insert_after( previous, copy ))){ 1545 pq_release( tcp_globals.net_phone, packet_get_id( copy )); 1558 1546 return sending; 1559 1547 } 1560 1548 } 1561 1549 previous = copy; 1562 packet = pq_next( packet);1550 packet = pq_next( packet ); 1563 1551 // overflow occurred ? 1564 if(( ! packet) && (socket_data->last_outgoing > socket_data->next_outgoing)){1552 if(( ! packet ) && ( socket_data->last_outgoing > socket_data->next_outgoing )){ 1565 1553 printf("gpts overflow\n"); 1566 1554 // continue from the beginning … … 1575 1563 } 1576 1564 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){1565 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 ){ 1578 1566 ERROR_DECLARE; 1579 1567 1580 tcp_header_ref 1581 uint32_t 1582 1583 assert( socket);1584 assert( socket_data);1585 assert( socket->specific_data == socket_data);1568 tcp_header_ref header; 1569 uint32_t checksum; 1570 1571 assert( socket ); 1572 assert( socket_data ); 1573 assert( socket->specific_data == socket_data ); 1586 1574 1587 1575 // adjust the pseudo header 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));1576 if( ERROR_OCCURRED( ip_client_set_pseudo_header_data_length( socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length( packet )))){ 1577 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 1590 1578 return NULL; 1591 1579 } 1592 1580 1593 1581 // get the header 1594 header = ( tcp_header_ref) packet_get_data(packet);1595 if( ! header){1596 pq_release( tcp_globals.net_phone, packet_get_id(packet));1582 header = ( tcp_header_ref ) packet_get_data( packet ); 1583 if( ! header ){ 1584 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 1597 1585 return NULL; 1598 1586 } 1599 assert( ntohl(header->sequence_number) == sequence_number);1587 assert( ntohl( header->sequence_number ) == sequence_number ); 1600 1588 1601 1589 // adjust the header 1602 if( socket_data->next_incoming){1603 header->acknowledgement_number = htonl( socket_data->next_incoming);1590 if( socket_data->next_incoming ){ 1591 header->acknowledgement_number = htonl( socket_data->next_incoming ); 1604 1592 header->acknowledge = 1; 1605 1593 } 1606 header->window = htons( socket_data->window);1594 header->window = htons( socket_data->window ); 1607 1595 1608 1596 // checksum 1609 1597 header->checksum = 0; 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)));1598 checksum = compute_checksum( 0, socket_data->pseudo_header, socket_data->headerlen ); 1599 checksum = compute_checksum( checksum, ( uint8_t * ) packet_get_data( packet ), packet_get_data_length( packet )); 1600 header->checksum = htons( flip_checksum( compact_checksum( checksum ))); 1613 1601 // prepare the packet 1614 if( ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0))1602 if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_TCP, 0, 0, 0, 0 )) 1615 1603 // prepare the timeout 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));1604 || ERROR_OCCURRED( tcp_prepare_timeout( tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true ))){ 1605 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 1618 1606 return NULL; 1619 1607 } … … 1621 1609 } 1622 1610 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 1625 1626 assert( socket);1627 assert( socket_data);1628 assert( socket->specific_data == socket_data);1611 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 ){ 1612 packet_t copy; 1613 1614 assert( socket ); 1615 assert( socket_data ); 1616 assert( socket->specific_data == socket_data ); 1629 1617 1630 1618 // make a copy of the packet 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); 1619 copy = packet_get_copy( tcp_globals.net_phone, packet ); 1620 if( ! copy ) return NULL; 1621 1622 return tcp_send_prepare_packet( socket, socket_data, copy, data_length, sequence_number ); 1623 } 1624 1625 void tcp_send_packets( device_id_t device_id, packet_t packet ){ 1626 packet_t next; 1627 1628 while( packet ){ 1629 next = pq_detach( packet ); 1630 ip_send_msg( tcp_globals.ip_phone, device_id, packet, SERVICE_TCP, 0 ); 1645 1631 packet = next; 1646 1632 } 1647 1633 } 1648 1634 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));1635 void tcp_prepare_operation_header( socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize ){ 1636 assert( socket ); 1637 assert( socket_data ); 1638 assert( socket->specific_data == socket_data ); 1639 assert( header ); 1640 1641 bzero( header, sizeof( * header )); 1642 header->source_port = htons( socket->port ); 1643 header->source_port = htons( socket_data->dest_port ); 1644 header->header_length = TCP_COMPUTE_HEADER_LENGTH( sizeof( * header )); 1659 1645 header->synchronize = synchronize; 1660 1646 header->finalize = finalize; 1661 1647 } 1662 1648 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 1665 fid_t 1666 1667 assert( socket);1668 assert( socket_data);1669 assert( socket->specific_data == socket_data);1649 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 ){ 1650 tcp_timeout_ref operation_timeout; 1651 fid_t fibril; 1652 1653 assert( socket ); 1654 assert( socket_data ); 1655 assert( socket->specific_data == socket_data ); 1670 1656 1671 1657 // prepare the timeout with key bundle structure 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)); 1658 operation_timeout = malloc( sizeof( * operation_timeout ) + socket->key_length + 1 ); 1659 if( ! operation_timeout ) return ENOMEM; 1660 bzero( operation_timeout, sizeof( * operation_timeout )); 1677 1661 operation_timeout->globals_read_only = globals_read_only; 1678 1662 operation_timeout->port = socket->port; … … 1684 1668 1685 1669 // copy the key 1686 operation_timeout->key = (( char *) operation_timeout) + sizeof(*operation_timeout);1670 operation_timeout->key = (( char * ) operation_timeout ) + sizeof( * operation_timeout ); 1687 1671 operation_timeout->key_length = socket->key_length; 1688 memcpy( operation_timeout->key, socket->key, socket->key_length);1689 operation_timeout->key[ operation_timeout->key_length] = '\0';1672 memcpy( operation_timeout->key, socket->key, socket->key_length ); 1673 operation_timeout->key[ operation_timeout->key_length ] = '\0'; 1690 1674 1691 1675 // prepare the timeouting thread 1692 fibril = fibril_create( timeout_function, operation_timeout);1693 if( ! fibril){1694 free( operation_timeout);1676 fibril = fibril_create( timeout_function, operation_timeout ); 1677 if( ! fibril ){ 1678 free( operation_timeout ); 1695 1679 return EPARTY; 1696 1680 } 1697 // fibril_mutex_lock( &socket_data->operation.mutex);1681 // fibril_mutex_lock( & socket_data->operation.mutex ); 1698 1682 // start the timeouting fibril 1699 fibril_add_ready( fibril);1683 fibril_add_ready( fibril ); 1700 1684 //socket_data->state = state; 1701 1685 return EOK; 1702 1686 } 1703 1687 1704 int tcp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){1688 int tcp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen ){ 1705 1689 ERROR_DECLARE; 1706 1690 1707 socket_core_ref 1708 tcp_socket_data_ref 1709 int 1710 packet_t 1711 size_t 1712 1713 assert( local_sockets);1691 socket_core_ref socket; 1692 tcp_socket_data_ref socket_data; 1693 int packet_id; 1694 packet_t packet; 1695 size_t length; 1696 1697 assert( local_sockets ); 1714 1698 1715 1699 // find the socket 1716 socket = socket_cores_find(local_sockets, socket_id); 1717 if(! socket){ 1718 return ENOTSOCK; 1719 } 1700 socket = socket_cores_find( local_sockets, socket_id ); 1701 if( ! socket ) return ENOTSOCK; 1720 1702 // get the socket specific data 1721 if(! socket->specific_data){ 1722 return NO_DATA; 1723 } 1724 socket_data = (tcp_socket_data_ref) socket->specific_data; 1703 if( ! socket->specific_data ) return NO_DATA; 1704 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1725 1705 1726 1706 // check state 1727 if(( socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){1707 if(( socket_data->state != TCP_SOCKET_ESTABLISHED ) && ( socket_data->state != TCP_SOCKET_CLOSE_WAIT )){ 1728 1708 return ENOTCONN; 1729 1709 } 1730 1710 1731 1711 // send the source address if desired 1732 if( addrlen){1733 ERROR_PROPAGATE( data_reply(socket_data->addr, socket_data->addrlen));1734 * addrlen = socket_data->addrlen;1712 if( addrlen ){ 1713 ERROR_PROPAGATE( data_reply( socket_data->addr, socket_data->addrlen )); 1714 * addrlen = socket_data->addrlen; 1735 1715 } 1736 1716 1737 1717 // get the next received packet 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)); 1718 packet_id = dyn_fifo_value( & socket->received ); 1719 if( packet_id < 0 ) return NO_DATA; 1720 ERROR_PROPAGATE( packet_translate( tcp_globals.net_phone, & packet, packet_id )); 1743 1721 1744 1722 // reply the packets 1745 ERROR_PROPAGATE( socket_reply_packets(packet, &length));1723 ERROR_PROPAGATE( socket_reply_packets( packet, & length )); 1746 1724 1747 1725 // release the packet 1748 dyn_fifo_pop( &socket->received);1749 pq_release( tcp_globals.net_phone, packet_get_id(packet));1726 dyn_fifo_pop( & socket->received ); 1727 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 1750 1728 // return the total length 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){1729 return ( int ) length; 1730 } 1731 1732 int tcp_send_message( socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags ){ 1755 1733 ERROR_DECLARE; 1756 1734 1757 socket_core_ref 1758 tcp_socket_data_ref 1759 packet_dimension_ref 1760 packet_t 1761 size_t 1762 tcp_header_ref 1763 int 1764 int 1765 1766 assert( local_sockets);1767 assert( data_fragment_size);1735 socket_core_ref socket; 1736 tcp_socket_data_ref socket_data; 1737 packet_dimension_ref packet_dimension; 1738 packet_t packet; 1739 size_t total_length; 1740 tcp_header_ref header; 1741 int index; 1742 int result; 1743 1744 assert( local_sockets ); 1745 assert( data_fragment_size ); 1768 1746 1769 1747 // find the socket 1770 socket = socket_cores_find(local_sockets, socket_id); 1771 if(! socket){ 1772 return ENOTSOCK; 1773 } 1748 socket = socket_cores_find( local_sockets, socket_id ); 1749 if( ! socket ) return ENOTSOCK; 1774 1750 // get the socket specific data 1775 if(! socket->specific_data){ 1776 return NO_DATA; 1777 } 1778 socket_data = (tcp_socket_data_ref) socket->specific_data; 1751 if( ! socket->specific_data ) return NO_DATA; 1752 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1779 1753 1780 1754 // check state 1781 if(( socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){1755 if(( socket_data->state != TCP_SOCKET_ESTABLISHED ) && ( socket_data->state != TCP_SOCKET_CLOSE_WAIT )){ 1782 1756 return ENOTCONN; 1783 1757 } 1784 1758 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){1759 ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension )); 1760 1761 * data_fragment_size = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size ); 1762 1763 for( index = 0; index < fragments; ++ index ){ 1790 1764 // read the data fragment 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; 1765 result = tl_socket_read_packet_data( tcp_globals.net_phone, & packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen ); 1766 if( result < 0 ) return result; 1767 total_length = ( size_t ) result; 1796 1768 // prefix the tcp header 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));1769 header = PACKET_PREFIX( packet, tcp_header_t ); 1770 if( ! header ){ 1771 return tcp_release_and_return( packet, ENOMEM ); 1772 } 1773 tcp_prepare_operation_header( socket, socket_data, header, 0, 0 ); 1774 ERROR_PROPAGATE( tcp_queue_packet( socket, socket_data, packet, 0 )); 1803 1775 } 1804 1776 1805 1777 // flush packets 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){1778 packet = tcp_get_packets_to_send( socket, socket_data ); 1779 fibril_rwlock_write_unlock( socket_data->local_lock ); 1780 fibril_rwlock_read_unlock( & tcp_globals.lock ); 1781 if( packet ){ 1810 1782 // send the packet 1811 tcp_send_packets( socket_data->device_id, packet);1783 tcp_send_packets( socket_data->device_id, packet ); 1812 1784 } 1813 1785 … … 1815 1787 } 1816 1788 1817 int tcp_close_message( socket_cores_ref local_sockets, int socket_id){1789 int tcp_close_message( socket_cores_ref local_sockets, int socket_id ){ 1818 1790 ERROR_DECLARE; 1819 1791 1820 socket_core_ref 1821 tcp_socket_data_ref 1822 packet_t 1792 socket_core_ref socket; 1793 tcp_socket_data_ref socket_data; 1794 packet_t packet; 1823 1795 1824 1796 // find the socket 1825 socket = socket_cores_find(local_sockets, socket_id); 1826 if(! socket){ 1827 return ENOTSOCK; 1828 } 1797 socket = socket_cores_find( local_sockets, socket_id ); 1798 if( ! socket ) return ENOTSOCK; 1829 1799 // get the socket specific data 1830 socket_data = ( tcp_socket_data_ref) socket->specific_data;1831 assert( socket_data);1800 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1801 assert( socket_data ); 1832 1802 1833 1803 // check state 1834 switch( socket_data->state){1804 switch( socket_data->state ){ 1835 1805 case TCP_SOCKET_ESTABLISHED: 1836 1806 socket_data->state = TCP_SOCKET_FIN_WAIT_1; … … 1842 1812 default: 1843 1813 // just destroy 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);1814 if( ! ERROR_OCCURRED( socket_destroy( tcp_globals.net_phone, socket_id, local_sockets, & tcp_globals.sockets, tcp_free_socket_data ))){ 1815 fibril_rwlock_write_unlock( socket_data->local_lock ); 1816 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1847 1817 } 1848 1818 return ERROR_CODE; … … 1852 1822 1853 1823 // create the notification packet 1854 ERROR_PROPAGATE( tcp_create_notification_packet(&packet, socket, socket_data, 0, 1));1824 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 0, 1 )); 1855 1825 1856 1826 // send the packet 1857 ERROR_PROPAGATE( tcp_queue_packet(socket, socket_data, packet, 1));1827 ERROR_PROPAGATE( tcp_queue_packet( socket, socket_data, packet, 1 )); 1858 1828 1859 1829 // flush packets 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){1830 packet = tcp_get_packets_to_send( socket, socket_data ); 1831 fibril_rwlock_write_unlock( socket_data->local_lock ); 1832 fibril_rwlock_write_unlock( & tcp_globals.lock ); 1833 if( packet ){ 1864 1834 // send the packet 1865 tcp_send_packets( socket_data->device_id, packet);1835 tcp_send_packets( socket_data->device_id, packet ); 1866 1836 } 1867 1837 return EOK; 1868 1838 } 1869 1839 1870 int tcp_create_notification_packet( packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){1840 int tcp_create_notification_packet( packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize ){ 1871 1841 ERROR_DECLARE; 1872 1842 1873 packet_dimension_ref 1874 tcp_header_ref 1875 1876 assert( packet);1843 packet_dimension_ref packet_dimension; 1844 tcp_header_ref header; 1845 1846 assert( packet ); 1877 1847 1878 1848 // get the device packet dimension 1879 ERROR_PROPAGATE( tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));1849 ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension )); 1880 1850 // get a new packet 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 } 1851 * packet = packet_get_4( tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix ); 1852 if( ! * packet ) return ENOMEM; 1885 1853 // allocate space in the packet 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);1854 header = PACKET_SUFFIX( * packet, tcp_header_t ); 1855 if( ! header ){ 1856 tcp_release_and_return( * packet, ENOMEM ); 1857 } 1858 1859 tcp_prepare_operation_header( socket, socket_data, header, synchronize, finalize ); 1892 1860 return EOK; 1893 1861 } 1894 1862 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){1863 int tcp_accept_message( socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen ){ 1896 1864 ERROR_DECLARE; 1897 1865 1898 socket_core_ref 1899 socket_core_ref 1900 tcp_socket_data_ref 1901 packet_dimension_ref 1902 1903 assert( local_sockets);1904 assert( data_fragment_size);1905 assert( addrlen);1866 socket_core_ref accepted; 1867 socket_core_ref socket; 1868 tcp_socket_data_ref socket_data; 1869 packet_dimension_ref packet_dimension; 1870 1871 assert( local_sockets ); 1872 assert( data_fragment_size ); 1873 assert( addrlen ); 1906 1874 1907 1875 // find the socket 1908 socket = socket_cores_find(local_sockets, socket_id); 1909 if(! socket){ 1910 return ENOTSOCK; 1911 } 1876 socket = socket_cores_find( local_sockets, socket_id ); 1877 if( ! socket ) return ENOTSOCK; 1912 1878 // get the socket specific data 1913 socket_data = ( tcp_socket_data_ref) socket->specific_data;1914 assert( socket_data);1879 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1880 assert( socket_data ); 1915 1881 1916 1882 // check state 1917 if( socket_data->state != TCP_SOCKET_LISTEN){1883 if( socket_data->state != TCP_SOCKET_LISTEN ){ 1918 1884 return EINVAL; 1919 1885 } 1920 1886 1921 1887 do{ 1922 socket_id = dyn_fifo_value(&socket->accepted); 1923 if(socket_id < 0){ 1924 return ENOTSOCK; 1925 } 1888 socket_id = dyn_fifo_value( & socket->accepted ); 1889 if( socket_id < 0 ) return ENOTSOCK; 1926 1890 socket_id *= -1; 1927 1891 1928 accepted = socket_cores_find(local_sockets, socket_id); 1929 if(! accepted){ 1930 return ENOTSOCK; 1931 } 1892 accepted = socket_cores_find( local_sockets, socket_id ); 1893 if( ! accepted ) return ENOTSOCK; 1932 1894 // get the socket specific data 1933 socket_data = ( tcp_socket_data_ref) accepted->specific_data;1934 assert( socket_data);1895 socket_data = ( tcp_socket_data_ref ) accepted->specific_data; 1896 assert( socket_data ); 1935 1897 // TODO can it be in another state? 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));1898 if( socket_data->state == TCP_SOCKET_ESTABLISHED ){ 1899 ERROR_PROPAGATE( data_reply( socket_data->addr, socket_data->addrlen )); 1900 ERROR_PROPAGATE( tl_get_ip_packet_dimension( tcp_globals.ip_phone, & tcp_globals.dimensions, socket_data->device_id, & packet_dimension )); 1901 * addrlen = socket_data->addrlen; 1902 * data_fragment_size = (( packet_dimension->content < socket_data->data_fragment_size ) ? packet_dimension->content : socket_data->data_fragment_size ); 1903 if( new_socket_id > 0 ){ 1904 ERROR_PROPAGATE( socket_cores_update( local_sockets, accepted->socket_id, new_socket_id )); 1943 1905 accepted->socket_id = new_socket_id; 1944 1906 } 1945 1907 } 1946 dyn_fifo_pop( &socket->accepted);1947 }while( socket_data->state != TCP_SOCKET_ESTABLISHED);1948 printf("ret accept %d\n", accepted->socket_id );1908 dyn_fifo_pop( & socket->accepted ); 1909 }while( socket_data->state != TCP_SOCKET_ESTABLISHED ); 1910 printf("ret accept %d\n", accepted->socket_id ); 1949 1911 return accepted->socket_id; 1950 1912 } 1951 1913 1952 void tcp_free_socket_data( socket_core_ref socket){1953 tcp_socket_data_ref 1954 1955 assert( socket);1956 1957 printf( "destroy_socket %d\n", socket->socket_id);1914 void tcp_free_socket_data( socket_core_ref socket ){ 1915 tcp_socket_data_ref socket_data; 1916 1917 assert( socket ); 1918 1919 printf( "destroy_socket %d\n", socket->socket_id ); 1958 1920 1959 1921 // get the socket specific data 1960 socket_data = ( tcp_socket_data_ref) socket->specific_data;1961 assert( socket_data);1922 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1923 assert( socket_data ); 1962 1924 //free the pseudo header 1963 if( socket_data->pseudo_header){1964 if( socket_data->headerlen){1925 if( socket_data->pseudo_header ){ 1926 if( socket_data->headerlen ){ 1965 1927 printf("d pseudo\n"); 1966 free( socket_data->pseudo_header);1928 free( socket_data->pseudo_header ); 1967 1929 socket_data->headerlen = 0; 1968 1930 } … … 1971 1933 socket_data->headerlen = 0; 1972 1934 // free the address 1973 if( socket_data->addr){1974 if( socket_data->addrlen){1935 if( socket_data->addr ){ 1936 if( socket_data->addrlen ){ 1975 1937 printf("d addr\n"); 1976 free( socket_data->addr);1938 free( socket_data->addr ); 1977 1939 socket_data->addrlen = 0; 1978 1940 } … … 1982 1944 } 1983 1945 1984 int tcp_release_and_return(packet_t packet, int result){1985 pq_release( tcp_globals.net_phone, packet_get_id(packet));1946 int tcp_release_and_return( packet_t packet, int result ){ 1947 pq_release( tcp_globals.net_phone, packet_get_id( packet )); 1986 1948 return result; 1987 1949 }
Note:
See TracChangeset
for help on using the changeset viewer.