Changeset 858fc90 in mainline for uspace/srv/net/tl/tcp/tcp.c
- Timestamp:
- 2010-03-15T19:35:25Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6092b56e
- Parents:
- 92307f1 (diff), 4684368 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/tcp.c
r92307f1 r858fc90 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 } 1242 1243 // release the application phone 1244 ipc_hangup(app_phone); 1238 1245 1239 1246 printf("release\n"); 1240 1247 // release all local sockets 1241 socket_cores_release( tcp_globals.net_phone, & local_sockets, & tcp_globals.sockets, tcp_free_socket_data);1248 socket_cores_release(tcp_globals.net_phone, &local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 1242 1249 1243 1250 return EOK; 1244 1251 } 1245 1252 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);1253 int tcp_timeout(void * data){ 1254 tcp_timeout_ref timeout = data; 1255 int keep_write_lock = false; 1256 socket_core_ref socket; 1257 tcp_socket_data_ref socket_data; 1258 1259 assert(timeout); 1253 1260 1254 1261 // sleep the given timeout 1255 async_usleep( timeout->timeout);1262 async_usleep(timeout->timeout); 1256 1263 // lock the globals 1257 if( timeout->globals_read_only){1258 fibril_rwlock_read_lock( & tcp_globals.lock);1264 if(timeout->globals_read_only){ 1265 fibril_rwlock_read_lock(&tcp_globals.lock); 1259 1266 }else{ 1260 fibril_rwlock_write_lock( & tcp_globals.lock);1267 fibril_rwlock_write_lock(&tcp_globals.lock); 1261 1268 } 1262 1269 // 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){1270 socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length); 1271 if(socket && (socket->socket_id == timeout->socket_id)){ 1272 socket_data = (tcp_socket_data_ref) socket->specific_data; 1273 assert(socket_data); 1274 if(socket_data->local_sockets == timeout->local_sockets){ 1275 fibril_rwlock_write_lock(socket_data->local_lock); 1276 if(timeout->sequence_number){ 1270 1277 // increase the timeout counter; 1271 1278 ++ socket_data->timeout_count; 1272 if( socket_data->timeout_count == TCP_MAX_TIMEOUTS){1279 if(socket_data->timeout_count == TCP_MAX_TIMEOUTS){ 1273 1280 // TODO release as connection lost 1274 //tcp_refresh_socket_data( socket_data ); 1275 } 1276 // retransmit 1277 // TODO enable retransmit 1278 //tcp_retransmit_packet( socket, socket_data, timeout->sequence_number ); 1279 fibril_rwlock_write_unlock( socket_data->local_lock ); 1281 //tcp_refresh_socket_data(socket_data); 1282 fibril_rwlock_write_unlock(socket_data->local_lock); 1283 }else{ 1284 // retransmit 1285 // tcp_retransmit_packet(socket, socket_data, timeout->sequence_number); 1286 fibril_rwlock_write_unlock(socket_data->local_lock); 1287 } 1280 1288 }else{ 1281 fibril_mutex_lock( & socket_data->operation.mutex);1289 fibril_mutex_lock(&socket_data->operation.mutex); 1282 1290 // set the timeout operation result if state not changed 1283 if( socket_data->state == timeout->state){1291 if(socket_data->state == timeout->state){ 1284 1292 socket_data->operation.result = ETIMEOUT; 1285 1293 // notify the main fibril 1286 fibril_condvar_signal( & socket_data->operation.condvar);1294 fibril_condvar_signal(&socket_data->operation.condvar); 1287 1295 // keep the global write lock 1288 1296 keep_write_lock = true; … … 1290 1298 // operation is ok, do nothing 1291 1299 // 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);1300 fibril_rwlock_write_unlock(socket_data->local_lock); 1301 } 1302 fibril_mutex_unlock(&socket_data->operation.mutex); 1295 1303 } 1296 1304 } 1297 1305 } 1298 1306 // 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){1307 if(timeout->globals_read_only){ 1308 fibril_rwlock_read_unlock(&tcp_globals.lock); 1309 }else if(! keep_write_lock){ 1302 1310 // release if not desired 1303 fibril_rwlock_write_unlock( & tcp_globals.lock);1311 fibril_rwlock_write_unlock(&tcp_globals.lock); 1304 1312 } 1305 1313 // release the timeout structure 1306 free( timeout);1314 free(timeout); 1307 1315 return EOK; 1308 1316 } 1309 1317 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);1318 int tcp_release_after_timeout(void * data){ 1319 tcp_timeout_ref timeout = data; 1320 socket_core_ref socket; 1321 tcp_socket_data_ref socket_data; 1322 fibril_rwlock_t * local_lock; 1323 1324 assert(timeout); 1317 1325 1318 1326 // sleep the given timeout 1319 async_usleep( timeout->timeout);1327 async_usleep(timeout->timeout); 1320 1328 // lock the globals 1321 fibril_rwlock_write_lock( & tcp_globals.lock);1329 fibril_rwlock_write_lock(&tcp_globals.lock); 1322 1330 // 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){1331 socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length); 1332 if(socket && (socket->socket_id == timeout->socket_id)){ 1333 socket_data = (tcp_socket_data_ref) socket->specific_data; 1334 assert(socket_data); 1335 if(socket_data->local_sockets == timeout->local_sockets){ 1328 1336 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);1337 fibril_rwlock_write_lock(local_lock); 1338 socket_destroy(tcp_globals.net_phone, timeout->socket_id, timeout->local_sockets, &tcp_globals.sockets, tcp_free_socket_data); 1339 fibril_rwlock_write_unlock(local_lock); 1332 1340 } 1333 1341 } 1334 1342 // unlock the globals 1335 fibril_rwlock_write_unlock( & tcp_globals.lock);1343 fibril_rwlock_write_unlock(&tcp_globals.lock); 1336 1344 // release the timeout structure 1337 free( timeout);1345 free(timeout); 1338 1346 return EOK; 1339 1347 } 1340 1348 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);1349 void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){ 1350 packet_t packet; 1351 packet_t copy; 1352 size_t data_length; 1353 1354 assert(socket); 1355 assert(socket_data); 1356 assert(socket->specific_data == socket_data); 1349 1357 1350 1358 // 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);1359 packet = pq_find(socket_data->outgoing, sequence_number); 1360 printf("retransmit %d\n", packet_get_id(packet)); 1361 if(packet){ 1362 pq_get_order(packet, NULL, &data_length); 1363 copy = tcp_prepare_copy(socket, socket_data, packet, data_length, sequence_number); 1364 fibril_rwlock_write_unlock(socket_data->local_lock); 1365 // printf("r send %d\n", packet_get_id(packet)); 1366 if(copy){ 1367 tcp_send_packets(socket_data->device_id, copy); 1360 1368 } 1361 1369 }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; 1370 fibril_rwlock_write_unlock(socket_data->local_lock); 1371 } 1372 } 1373 1374 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog){ 1375 socket_core_ref socket; 1376 tcp_socket_data_ref socket_data; 1377 1378 assert(local_sockets); 1379 1380 if(backlog < 0){ 1381 return EINVAL; 1382 } 1373 1383 // find the socket 1374 socket = socket_cores_find( local_sockets, socket_id ); 1375 if( ! socket ) return ENOTSOCK; 1384 socket = socket_cores_find(local_sockets, socket_id); 1385 if(! socket){ 1386 return ENOTSOCK; 1387 } 1376 1388 // get the socket specific data 1377 socket_data = ( tcp_socket_data_ref) socket->specific_data;1378 assert( socket_data);1389 socket_data = (tcp_socket_data_ref) socket->specific_data; 1390 assert(socket_data); 1379 1391 // set the backlog 1380 1392 socket_data->backlog = backlog; … … 1382 1394 } 1383 1395 1384 int tcp_connect_message( socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){1396 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){ 1385 1397 ERROR_DECLARE; 1386 1398 1387 socket_core_ref 1388 1389 assert( local_sockets);1390 assert( addr);1391 assert( addrlen > 0);1399 socket_core_ref socket; 1400 1401 assert(local_sockets); 1402 assert(addr); 1403 assert(addrlen > 0); 1392 1404 1393 1405 // 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 ); 1406 socket = socket_cores_find(local_sockets, socket_id); 1407 if(! socket){ 1408 return ENOTSOCK; 1409 } 1410 if(ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr, addrlen))){ 1411 tcp_free_socket_data(socket); 1398 1412 // unbind if bound 1399 if( socket->port > 0){1400 socket_ports_exclude( & tcp_globals.sockets, socket->port);1413 if(socket->port > 0){ 1414 socket_ports_exclude(&tcp_globals.sockets, socket->port); 1401 1415 socket->port = 0; 1402 1416 } … … 1405 1419 } 1406 1420 1407 int tcp_connect_core( socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){1421 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){ 1408 1422 ERROR_DECLARE; 1409 1423 1410 tcp_socket_data_ref 1411 packet_t 1412 1413 assert( socket);1414 assert( addr);1415 assert( addrlen > 0);1424 tcp_socket_data_ref socket_data; 1425 packet_t packet; 1426 1427 assert(socket); 1428 assert(addr); 1429 assert(addrlen > 0); 1416 1430 1417 1431 // 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))){1432 socket_data = (tcp_socket_data_ref) socket->specific_data; 1433 assert(socket_data); 1434 assert(socket->specific_data == socket_data); 1435 if((socket_data->state != TCP_SOCKET_INITIAL) 1436 && ((socket_data->state != TCP_SOCKET_LISTEN) || (socket->port <= 0))){ 1423 1437 return EINVAL; 1424 1438 } 1425 1439 // get the destination port 1426 ERROR_PROPAGATE( tl_get_address_port( addr, addrlen, & socket_data->dest_port));1427 if( socket->port <= 0){1440 ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &socket_data->dest_port)); 1441 if(socket->port <= 0){ 1428 1442 // 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));1443 ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port)); 1430 1444 // set the next port as the search starting port number 1431 1445 tcp_globals.last_used_port = socket->port; 1432 1446 } 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));1447 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 1448 1435 1449 // create the notification packet 1436 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 1, 0));1450 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 1, 0)); 1437 1451 1438 1452 // unlock the globals and wait for an operation 1439 fibril_rwlock_write_unlock( & tcp_globals.lock);1453 fibril_rwlock_write_unlock(&tcp_globals.lock); 1440 1454 1441 1455 socket_data->addr = addr; 1442 1456 socket_data->addrlen = addrlen; 1443 1457 // 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))){1458 if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1)) 1459 || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))){ 1446 1460 socket_data->addr = NULL; 1447 1461 socket_data->addrlen = 0; 1448 fibril_rwlock_write_lock( & tcp_globals.lock);1462 fibril_rwlock_write_lock(&tcp_globals.lock); 1449 1463 }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);1464 packet = tcp_get_packets_to_send(socket, socket_data); 1465 if(packet){ 1466 fibril_mutex_lock(&socket_data->operation.mutex); 1467 fibril_rwlock_write_unlock(socket_data->local_lock); 1454 1468 // send the packet 1455 printf( "connecting %d\n", packet_get_id( packet));1456 tcp_send_packets( socket_data->device_id, packet);1469 printf("connecting %d\n", packet_get_id(packet)); 1470 tcp_send_packets(socket_data->device_id, packet); 1457 1471 // wait for a reply 1458 fibril_condvar_wait( & socket_data->operation.condvar, & socket_data->operation.mutex);1472 fibril_condvar_wait(&socket_data->operation.condvar, &socket_data->operation.mutex); 1459 1473 ERROR_CODE = socket_data->operation.result; 1460 if( ERROR_CODE != EOK){1474 if(ERROR_CODE != EOK){ 1461 1475 socket_data->addr = NULL; 1462 1476 socket_data->addrlen = 0; … … 1469 1483 } 1470 1484 1471 fibril_mutex_unlock( & socket_data->operation.mutex);1485 fibril_mutex_unlock(&socket_data->operation.mutex); 1472 1486 1473 1487 // return the result … … 1475 1489 } 1476 1490 1477 int tcp_queue_prepare_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){1491 int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){ 1478 1492 ERROR_DECLARE; 1479 1493 1480 tcp_header_ref 1481 1482 assert( socket);1483 assert( socket_data);1484 assert( socket->specific_data == socket_data);1494 tcp_header_ref header; 1495 1496 assert(socket); 1497 assert(socket_data); 1498 assert(socket->specific_data == socket_data); 1485 1499 1486 1500 // 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 ); 1501 header = (tcp_header_ref) packet_get_data(packet); 1502 if(! header){ 1503 return NO_DATA; 1504 } 1505 header->destination_port = htons(socket_data->dest_port); 1506 header->source_port = htons(socket->port); 1507 header->sequence_number = htonl(socket_data->next_outgoing); 1508 if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr, socket_data->addrlen))){ 1509 return tcp_release_and_return(packet, EINVAL); 1494 1510 } 1495 1511 // remember the outgoing FIN 1496 if( header->finalize){1512 if(header->finalize){ 1497 1513 socket_data->fin_outgoing = socket_data->next_outgoing; 1498 1514 } … … 1500 1516 } 1501 1517 1502 int tcp_queue_packet( socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){1518 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){ 1503 1519 ERROR_DECLARE; 1504 1520 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);1521 assert(socket); 1522 assert(socket_data); 1523 assert(socket->specific_data == socket_data); 1524 1525 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, data_length)); 1526 1527 if(ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing, data_length))){ 1528 return tcp_release_and_return(packet, ERROR_CODE); 1513 1529 } 1514 1530 socket_data->next_outgoing += data_length; … … 1516 1532 } 1517 1533 1518 packet_t tcp_get_packets_to_send( socket_core_ref socket, tcp_socket_data_ref socket_data){1534 packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data){ 1519 1535 ERROR_DECLARE; 1520 1536 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);1537 packet_t packet; 1538 packet_t copy; 1539 packet_t sending = NULL; 1540 packet_t previous = NULL; 1541 size_t data_length; 1542 1543 assert(socket); 1544 assert(socket_data); 1545 assert(socket->specific_data == socket_data); 1546 1547 packet = pq_find(socket_data->outgoing, socket_data->last_outgoing + 1); 1548 while(packet){ 1549 pq_get_order(packet, NULL, &data_length); 1534 1550 // send only if fits into the window 1535 1551 // 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){1552 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))){ 1553 copy = tcp_prepare_copy(socket, socket_data, packet, data_length, socket_data->last_outgoing + 1); 1554 if(! copy){ 1539 1555 return sending; 1540 1556 } 1541 if( ! sending){1557 if(! sending){ 1542 1558 sending = copy; 1543 1559 }else{ 1544 if( ERROR_OCCURRED( pq_insert_after( previous, copy))){1545 pq_release( tcp_globals.net_phone, packet_get_id( copy));1560 if(ERROR_OCCURRED(pq_insert_after(previous, copy))){ 1561 pq_release(tcp_globals.net_phone, packet_get_id(copy)); 1546 1562 return sending; 1547 1563 } 1548 1564 } 1549 1565 previous = copy; 1550 packet = pq_next( packet);1566 packet = pq_next(packet); 1551 1567 // overflow occurred ? 1552 if(( ! packet ) && ( socket_data->last_outgoing > socket_data->next_outgoing)){1568 if((! packet) && (socket_data->last_outgoing > socket_data->next_outgoing)){ 1553 1569 printf("gpts overflow\n"); 1554 1570 // continue from the beginning … … 1563 1579 } 1564 1580 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){1581 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 1582 ERROR_DECLARE; 1567 1583 1568 tcp_header_ref 1569 uint32_t 1570 1571 assert( socket);1572 assert( socket_data);1573 assert( socket->specific_data == socket_data);1584 tcp_header_ref header; 1585 uint32_t checksum; 1586 1587 assert(socket); 1588 assert(socket_data); 1589 assert(socket->specific_data == socket_data); 1574 1590 1575 1591 // 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));1592 if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length(packet)))){ 1593 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1578 1594 return NULL; 1579 1595 } 1580 1596 1581 1597 // 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));1598 header = (tcp_header_ref) packet_get_data(packet); 1599 if(! header){ 1600 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1585 1601 return NULL; 1586 1602 } 1587 assert( ntohl( header->sequence_number ) == sequence_number);1603 assert(ntohl(header->sequence_number) == sequence_number); 1588 1604 1589 1605 // adjust the header 1590 if( socket_data->next_incoming){1591 header->acknowledgement_number = htonl( socket_data->next_incoming);1606 if(socket_data->next_incoming){ 1607 header->acknowledgement_number = htonl(socket_data->next_incoming); 1592 1608 header->acknowledge = 1; 1593 1609 } 1594 header->window = htons( socket_data->window);1610 header->window = htons(socket_data->window); 1595 1611 1596 1612 // checksum 1597 1613 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)));1614 checksum = compute_checksum(0, socket_data->pseudo_header, socket_data->headerlen); 1615 checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet), packet_get_data_length(packet)); 1616 header->checksum = htons(flip_checksum(compact_checksum(checksum))); 1601 1617 // prepare the packet 1602 if( ERROR_OCCURRED( ip_client_prepare_packet( packet, IPPROTO_TCP, 0, 0, 0, 0))1618 if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0)) 1603 1619 // 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));1620 || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true))){ 1621 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1606 1622 return NULL; 1607 1623 } … … 1609 1625 } 1610 1626 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);1627 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){ 1628 packet_t copy; 1629 1630 assert(socket); 1631 assert(socket_data); 1632 assert(socket->specific_data == socket_data); 1617 1633 1618 1634 // 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 ); 1635 copy = packet_get_copy(tcp_globals.net_phone, packet); 1636 if(! copy){ 1637 return NULL; 1638 } 1639 1640 return tcp_send_prepare_packet(socket, socket_data, copy, data_length, sequence_number); 1641 } 1642 1643 void tcp_send_packets(device_id_t device_id, packet_t packet){ 1644 packet_t next; 1645 1646 while(packet){ 1647 next = pq_detach(packet); 1648 ip_send_msg(tcp_globals.ip_phone, device_id, packet, SERVICE_TCP, 0); 1631 1649 packet = next; 1632 1650 } 1633 1651 } 1634 1652 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));1653 void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize){ 1654 assert(socket); 1655 assert(socket_data); 1656 assert(socket->specific_data == socket_data); 1657 assert(header); 1658 1659 bzero(header, sizeof(*header)); 1660 header->source_port = htons(socket->port); 1661 header->source_port = htons(socket_data->dest_port); 1662 header->header_length = TCP_COMPUTE_HEADER_LENGTH(sizeof(*header)); 1645 1663 header->synchronize = synchronize; 1646 1664 header->finalize = finalize; 1647 1665 } 1648 1666 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);1667 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){ 1668 tcp_timeout_ref operation_timeout; 1669 fid_t fibril; 1670 1671 assert(socket); 1672 assert(socket_data); 1673 assert(socket->specific_data == socket_data); 1656 1674 1657 1675 // 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 )); 1676 operation_timeout = malloc(sizeof(*operation_timeout) + socket->key_length + 1); 1677 if(! operation_timeout){ 1678 return ENOMEM; 1679 } 1680 bzero(operation_timeout, sizeof(*operation_timeout)); 1661 1681 operation_timeout->globals_read_only = globals_read_only; 1662 1682 operation_timeout->port = socket->port; … … 1668 1688 1669 1689 // copy the key 1670 operation_timeout->key = (( char * ) operation_timeout ) + sizeof( * operation_timeout);1690 operation_timeout->key = ((char *) operation_timeout) + sizeof(*operation_timeout); 1671 1691 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';1692 memcpy(operation_timeout->key, socket->key, socket->key_length); 1693 operation_timeout->key[operation_timeout->key_length] = '\0'; 1674 1694 1675 1695 // prepare the timeouting thread 1676 fibril = fibril_create( timeout_function, operation_timeout);1677 if( ! fibril){1678 free( operation_timeout);1696 fibril = fibril_create(timeout_function, operation_timeout); 1697 if(! fibril){ 1698 free(operation_timeout); 1679 1699 return EPARTY; 1680 1700 } 1681 // fibril_mutex_lock( & socket_data->operation.mutex);1701 // fibril_mutex_lock(&socket_data->operation.mutex); 1682 1702 // start the timeouting fibril 1683 fibril_add_ready( fibril);1703 fibril_add_ready(fibril); 1684 1704 //socket_data->state = state; 1685 1705 return EOK; 1686 1706 } 1687 1707 1688 int tcp_recvfrom_message( socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){1708 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){ 1689 1709 ERROR_DECLARE; 1690 1710 1691 socket_core_ref 1692 tcp_socket_data_ref 1693 int 1694 packet_t 1695 size_t 1696 1697 assert( local_sockets);1711 socket_core_ref socket; 1712 tcp_socket_data_ref socket_data; 1713 int packet_id; 1714 packet_t packet; 1715 size_t length; 1716 1717 assert(local_sockets); 1698 1718 1699 1719 // find the socket 1700 socket = socket_cores_find( local_sockets, socket_id ); 1701 if( ! socket ) return ENOTSOCK; 1720 socket = socket_cores_find(local_sockets, socket_id); 1721 if(! socket){ 1722 return ENOTSOCK; 1723 } 1702 1724 // get the socket specific data 1703 if( ! socket->specific_data ) return NO_DATA; 1704 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1725 if(! socket->specific_data){ 1726 return NO_DATA; 1727 } 1728 socket_data = (tcp_socket_data_ref) socket->specific_data; 1705 1729 1706 1730 // check state 1707 if(( socket_data->state != TCP_SOCKET_ESTABLISHED ) && ( socket_data->state != TCP_SOCKET_CLOSE_WAIT)){1731 if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){ 1708 1732 return ENOTCONN; 1709 1733 } 1710 1734 1711 1735 // send the source address if desired 1712 if( addrlen){1713 ERROR_PROPAGATE( data_reply( socket_data->addr, socket_data->addrlen));1714 * 1736 if(addrlen){ 1737 ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen)); 1738 *addrlen = socket_data->addrlen; 1715 1739 } 1716 1740 1717 1741 // 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 )); 1742 packet_id = dyn_fifo_value(&socket->received); 1743 if(packet_id < 0){ 1744 return NO_DATA; 1745 } 1746 ERROR_PROPAGATE(packet_translate(tcp_globals.net_phone, &packet, packet_id)); 1721 1747 1722 1748 // reply the packets 1723 ERROR_PROPAGATE( socket_reply_packets( packet, & length));1749 ERROR_PROPAGATE(socket_reply_packets(packet, &length)); 1724 1750 1725 1751 // release the packet 1726 dyn_fifo_pop( & socket->received);1727 pq_release( tcp_globals.net_phone, packet_get_id( packet));1752 dyn_fifo_pop(&socket->received); 1753 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1728 1754 // 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){1755 return (int) length; 1756 } 1757 1758 int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags){ 1733 1759 ERROR_DECLARE; 1734 1760 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);1761 socket_core_ref socket; 1762 tcp_socket_data_ref socket_data; 1763 packet_dimension_ref packet_dimension; 1764 packet_t packet; 1765 size_t total_length; 1766 tcp_header_ref header; 1767 int index; 1768 int result; 1769 1770 assert(local_sockets); 1771 assert(data_fragment_size); 1746 1772 1747 1773 // find the socket 1748 socket = socket_cores_find( local_sockets, socket_id ); 1749 if( ! socket ) return ENOTSOCK; 1774 socket = socket_cores_find(local_sockets, socket_id); 1775 if(! socket){ 1776 return ENOTSOCK; 1777 } 1750 1778 // get the socket specific data 1751 if( ! socket->specific_data ) return NO_DATA; 1752 socket_data = ( tcp_socket_data_ref ) socket->specific_data; 1779 if(! socket->specific_data){ 1780 return NO_DATA; 1781 } 1782 socket_data = (tcp_socket_data_ref) socket->specific_data; 1753 1783 1754 1784 // check state 1755 if(( socket_data->state != TCP_SOCKET_ESTABLISHED ) && ( socket_data->state != TCP_SOCKET_CLOSE_WAIT)){1785 if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){ 1756 1786 return ENOTCONN; 1757 1787 } 1758 1788 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){1789 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1790 1791 *data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size); 1792 1793 for(index = 0; index < fragments; ++ index){ 1764 1794 // 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; 1795 result = tl_socket_read_packet_data(tcp_globals.net_phone, &packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen); 1796 if(result < 0){ 1797 return result; 1798 } 1799 total_length = (size_t) result; 1768 1800 // 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));1801 header = PACKET_PREFIX(packet, tcp_header_t); 1802 if(! header){ 1803 return tcp_release_and_return(packet, ENOMEM); 1804 } 1805 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 1806 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 0)); 1775 1807 } 1776 1808 1777 1809 // 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){1810 packet = tcp_get_packets_to_send(socket, socket_data); 1811 fibril_rwlock_write_unlock(socket_data->local_lock); 1812 fibril_rwlock_read_unlock(&tcp_globals.lock); 1813 if(packet){ 1782 1814 // send the packet 1783 tcp_send_packets( socket_data->device_id, packet);1815 tcp_send_packets(socket_data->device_id, packet); 1784 1816 } 1785 1817 … … 1787 1819 } 1788 1820 1789 int tcp_close_message( socket_cores_ref local_sockets, int socket_id){1821 int tcp_close_message(socket_cores_ref local_sockets, int socket_id){ 1790 1822 ERROR_DECLARE; 1791 1823 1792 socket_core_ref 1793 tcp_socket_data_ref 1794 packet_t 1824 socket_core_ref socket; 1825 tcp_socket_data_ref socket_data; 1826 packet_t packet; 1795 1827 1796 1828 // find the socket 1797 socket = socket_cores_find( local_sockets, socket_id ); 1798 if( ! socket ) return ENOTSOCK; 1829 socket = socket_cores_find(local_sockets, socket_id); 1830 if(! socket){ 1831 return ENOTSOCK; 1832 } 1799 1833 // get the socket specific data 1800 socket_data = ( tcp_socket_data_ref) socket->specific_data;1801 assert( socket_data);1834 socket_data = (tcp_socket_data_ref) socket->specific_data; 1835 assert(socket_data); 1802 1836 1803 1837 // check state 1804 switch( socket_data->state){1838 switch(socket_data->state){ 1805 1839 case TCP_SOCKET_ESTABLISHED: 1806 1840 socket_data->state = TCP_SOCKET_FIN_WAIT_1; … … 1812 1846 default: 1813 1847 // 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);1848 if(! ERROR_OCCURRED(socket_destroy(tcp_globals.net_phone, socket_id, local_sockets, &tcp_globals.sockets, tcp_free_socket_data))){ 1849 fibril_rwlock_write_unlock(socket_data->local_lock); 1850 fibril_rwlock_write_unlock(&tcp_globals.lock); 1817 1851 } 1818 1852 return ERROR_CODE; … … 1822 1856 1823 1857 // create the notification packet 1824 ERROR_PROPAGATE( tcp_create_notification_packet( & packet, socket, socket_data, 0, 1));1858 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1)); 1825 1859 1826 1860 // send the packet 1827 ERROR_PROPAGATE( tcp_queue_packet( socket, socket_data, packet, 1));1861 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1)); 1828 1862 1829 1863 // 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){1864 packet = tcp_get_packets_to_send(socket, socket_data); 1865 fibril_rwlock_write_unlock(socket_data->local_lock); 1866 fibril_rwlock_write_unlock(&tcp_globals.lock); 1867 if(packet){ 1834 1868 // send the packet 1835 tcp_send_packets( socket_data->device_id, packet);1869 tcp_send_packets(socket_data->device_id, packet); 1836 1870 } 1837 1871 return EOK; 1838 1872 } 1839 1873 1840 int tcp_create_notification_packet( packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){1874 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){ 1841 1875 ERROR_DECLARE; 1842 1876 1843 packet_dimension_ref 1844 tcp_header_ref 1845 1846 assert( packet);1877 packet_dimension_ref packet_dimension; 1878 tcp_header_ref header; 1879 1880 assert(packet); 1847 1881 1848 1882 // 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));1883 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1850 1884 // 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; 1885 *packet = packet_get_4(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix); 1886 if(! * packet){ 1887 return ENOMEM; 1888 } 1853 1889 // 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);1890 header = PACKET_SUFFIX(*packet, tcp_header_t); 1891 if(! header){ 1892 tcp_release_and_return(*packet, ENOMEM); 1893 } 1894 1895 tcp_prepare_operation_header(socket, socket_data, header, synchronize, finalize); 1860 1896 return EOK; 1861 1897 } 1862 1898 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){1899 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 1900 ERROR_DECLARE; 1865 1901 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);1902 socket_core_ref accepted; 1903 socket_core_ref socket; 1904 tcp_socket_data_ref socket_data; 1905 packet_dimension_ref packet_dimension; 1906 1907 assert(local_sockets); 1908 assert(data_fragment_size); 1909 assert(addrlen); 1874 1910 1875 1911 // find the socket 1876 socket = socket_cores_find( local_sockets, socket_id ); 1877 if( ! socket ) return ENOTSOCK; 1912 socket = socket_cores_find(local_sockets, socket_id); 1913 if(! socket){ 1914 return ENOTSOCK; 1915 } 1878 1916 // get the socket specific data 1879 socket_data = ( tcp_socket_data_ref) socket->specific_data;1880 assert( socket_data);1917 socket_data = (tcp_socket_data_ref) socket->specific_data; 1918 assert(socket_data); 1881 1919 1882 1920 // check state 1883 if( socket_data->state != TCP_SOCKET_LISTEN){1921 if(socket_data->state != TCP_SOCKET_LISTEN){ 1884 1922 return EINVAL; 1885 1923 } 1886 1924 1887 1925 do{ 1888 socket_id = dyn_fifo_value( & socket->accepted ); 1889 if( socket_id < 0 ) return ENOTSOCK; 1926 socket_id = dyn_fifo_value(&socket->accepted); 1927 if(socket_id < 0){ 1928 return ENOTSOCK; 1929 } 1890 1930 socket_id *= -1; 1891 1931 1892 accepted = socket_cores_find( local_sockets, socket_id ); 1893 if( ! accepted ) return ENOTSOCK; 1932 accepted = socket_cores_find(local_sockets, socket_id); 1933 if(! accepted){ 1934 return ENOTSOCK; 1935 } 1894 1936 // get the socket specific data 1895 socket_data = ( tcp_socket_data_ref) accepted->specific_data;1896 assert( socket_data);1937 socket_data = (tcp_socket_data_ref) accepted->specific_data; 1938 assert(socket_data); 1897 1939 // 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));1940 if(socket_data->state == TCP_SOCKET_ESTABLISHED){ 1941 ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen)); 1942 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 1943 *addrlen = socket_data->addrlen; 1944 *data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size); 1945 if(new_socket_id > 0){ 1946 ERROR_PROPAGATE(socket_cores_update(local_sockets, accepted->socket_id, new_socket_id)); 1905 1947 accepted->socket_id = new_socket_id; 1906 1948 } 1907 1949 } 1908 dyn_fifo_pop( & socket->accepted);1909 }while( socket_data->state != TCP_SOCKET_ESTABLISHED);1910 printf("ret accept %d\n", accepted->socket_id 1950 dyn_fifo_pop(&socket->accepted); 1951 }while(socket_data->state != TCP_SOCKET_ESTABLISHED); 1952 printf("ret accept %d\n", accepted->socket_id); 1911 1953 return accepted->socket_id; 1912 1954 } 1913 1955 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);1956 void tcp_free_socket_data(socket_core_ref socket){ 1957 tcp_socket_data_ref socket_data; 1958 1959 assert(socket); 1960 1961 printf("destroy_socket %d\n", socket->socket_id); 1920 1962 1921 1963 // get the socket specific data 1922 socket_data = ( tcp_socket_data_ref) socket->specific_data;1923 assert( socket_data);1964 socket_data = (tcp_socket_data_ref) socket->specific_data; 1965 assert(socket_data); 1924 1966 //free the pseudo header 1925 if( socket_data->pseudo_header){1926 if( socket_data->headerlen){1967 if(socket_data->pseudo_header){ 1968 if(socket_data->headerlen){ 1927 1969 printf("d pseudo\n"); 1928 free( socket_data->pseudo_header);1970 free(socket_data->pseudo_header); 1929 1971 socket_data->headerlen = 0; 1930 1972 } … … 1933 1975 socket_data->headerlen = 0; 1934 1976 // free the address 1935 if( socket_data->addr){1936 if( socket_data->addrlen){1977 if(socket_data->addr){ 1978 if(socket_data->addrlen){ 1937 1979 printf("d addr\n"); 1938 free( socket_data->addr);1980 free(socket_data->addr); 1939 1981 socket_data->addrlen = 0; 1940 1982 } … … 1944 1986 } 1945 1987 1946 int tcp_release_and_return( packet_t packet, int result){1947 pq_release( tcp_globals.net_phone, packet_get_id( packet));1988 int tcp_release_and_return(packet_t packet, int result){ 1989 pq_release(tcp_globals.net_phone, packet_get_id(packet)); 1948 1990 return result; 1949 1991 }
Note:
See TracChangeset
for help on using the changeset viewer.