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