Changes in uspace/srv/net/tl/tcp/tcp.c [89e57cee:472020fc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/tcp.c
r89e57cee r472020fc 28 28 29 29 /** @addtogroup tcp 30 * @{30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * TCP module implementation.35 * @see tcp.h34 * TCP module implementation. 35 * @see tcp.h 36 36 */ 37 38 #include "tcp.h"39 #include "tcp_header.h"40 #include "tcp_module.h"41 37 42 38 #include <assert.h> … … 76 72 #include <tl_interface.h> 77 73 74 #include "tcp.h" 75 #include "tcp_header.h" 76 #include "tcp_module.h" 77 78 78 /** TCP module name. */ 79 79 #define NAME "TCP protocol" … … 110 110 111 111 /** Returns a value indicating whether the value is in the interval respecting 112 * the possible overflow.112 * the possible overflow. 113 113 * 114 * The high end and/or the value may overflow, be lower than the low value. 115 * 116 * @param[in] lower The last value before the interval. 117 * @param[in] value The value to be checked. 118 * @param[in] higher_equal The last value in the interval. 114 * The high end and/or the value may overflow, be lower than the low value. 115 * @param[in] lower The last value before the interval. 116 * @param[in] value The value to be checked. 117 * @param[in] higher_equal The last value in the interval. 119 118 */ 120 119 #define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \ … … 166 165 }; 167 166 168 static int tcp_release_and_return(packet_t, int); 169 static void tcp_prepare_operation_header(socket_core_ref, tcp_socket_data_ref, 170 tcp_header_ref, int synchronize, int); 171 static int tcp_prepare_timeout(int (*)(void *), socket_core_ref, 172 tcp_socket_data_ref, size_t, tcp_socket_state_t, suseconds_t, int); 173 static void tcp_free_socket_data(socket_core_ref); 174 175 static int tcp_timeout(void *); 176 177 static int tcp_release_after_timeout(void *); 178 179 static int tcp_process_packet(device_id_t, packet_t, services_t); 180 static int tcp_connect_core(socket_core_ref, socket_cores_ref, 181 struct sockaddr *, socklen_t); 182 static int tcp_queue_prepare_packet(socket_core_ref, tcp_socket_data_ref, 183 packet_t, size_t); 184 static int tcp_queue_packet(socket_core_ref, tcp_socket_data_ref, packet_t, 185 size_t); 186 static packet_t tcp_get_packets_to_send(socket_core_ref, tcp_socket_data_ref); 187 static void tcp_send_packets(device_id_t, packet_t); 188 189 static void tcp_process_acknowledgement(socket_core_ref, tcp_socket_data_ref, 190 tcp_header_ref); 191 static packet_t tcp_send_prepare_packet(socket_core_ref, tcp_socket_data_ref, 192 packet_t, size_t, size_t); 193 static packet_t tcp_prepare_copy(socket_core_ref, tcp_socket_data_ref, packet_t, 194 size_t, size_t); 195 /* static */ void tcp_retransmit_packet(socket_core_ref, tcp_socket_data_ref, 196 size_t); 197 static int tcp_create_notification_packet(packet_t *, socket_core_ref, 198 tcp_socket_data_ref, int, int); 199 static void tcp_refresh_socket_data(tcp_socket_data_ref); 200 201 static void tcp_initialize_socket_data(tcp_socket_data_ref); 202 203 static int tcp_process_listen(socket_core_ref, tcp_socket_data_ref, 204 tcp_header_ref, packet_t, struct sockaddr *, struct sockaddr *, size_t); 205 static int tcp_process_syn_sent(socket_core_ref, tcp_socket_data_ref, 206 tcp_header_ref, packet_t); 207 static int tcp_process_syn_received(socket_core_ref, tcp_socket_data_ref, 208 tcp_header_ref, packet_t); 209 static int tcp_process_established(socket_core_ref, tcp_socket_data_ref, 210 tcp_header_ref, packet_t, int, size_t); 211 static int tcp_queue_received_packet(socket_core_ref, tcp_socket_data_ref, 212 packet_t, int, size_t); 213 214 static int tcp_received_msg(device_id_t, packet_t, services_t, services_t); 215 static int tcp_process_client_messages(ipc_callid_t, ipc_call_t); 216 217 static int tcp_listen_message(socket_cores_ref, int, int); 218 static int tcp_connect_message(socket_cores_ref, int, struct sockaddr *, 219 socklen_t); 220 static int tcp_recvfrom_message(socket_cores_ref, int, int, size_t *); 221 static int tcp_send_message(socket_cores_ref, int, int, size_t *, int); 222 static int tcp_accept_message(socket_cores_ref, int, int, size_t *, size_t *); 223 static int tcp_close_message(socket_cores_ref, int); 167 /** Releases the packet and returns the result. 168 * @param[in] packet The packet queue to be released. 169 * @param[in] result The result to be returned. 170 * @return The result parameter. 171 */ 172 int tcp_release_and_return(packet_t packet, int result); 173 174 void tcp_prepare_operation_header(socket_core_ref socket, 175 tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, 176 int finalize); 177 int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t), 178 socket_core_ref socket, tcp_socket_data_ref socket_data, 179 size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, 180 int globals_read_only); 181 void tcp_free_socket_data(socket_core_ref socket); 182 183 int tcp_timeout(void *data); 184 185 int tcp_release_after_timeout(void *data); 186 187 int tcp_process_packet(device_id_t device_id, packet_t packet, 188 services_t error); 189 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, 190 struct sockaddr *addr, socklen_t addrlen); 191 int tcp_queue_prepare_packet(socket_core_ref socket, 192 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length); 193 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, 194 packet_t packet, size_t data_length); 195 packet_t tcp_get_packets_to_send(socket_core_ref socket, 196 tcp_socket_data_ref socket_data); 197 void tcp_send_packets(device_id_t device_id, packet_t packet); 198 199 void tcp_process_acknowledgement(socket_core_ref socket, 200 tcp_socket_data_ref socket_data, tcp_header_ref header); 201 packet_t tcp_send_prepare_packet(socket_core_ref socket, 202 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, 203 size_t sequence_number); 204 packet_t tcp_prepare_copy(socket_core_ref socket, 205 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, 206 size_t sequence_number); 207 void tcp_retransmit_packet(socket_core_ref socket, 208 tcp_socket_data_ref socket_data, size_t sequence_number); 209 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, 210 tcp_socket_data_ref socket_data, int synchronize, int finalize); 211 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data); 212 213 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data); 214 215 int tcp_process_listen(socket_core_ref listening_socket, 216 tcp_socket_data_ref listening_socket_data, tcp_header_ref header, 217 packet_t packet, struct sockaddr *src, struct sockaddr *dest, 218 size_t addrlen); 219 int tcp_process_syn_sent(socket_core_ref socket, 220 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 221 int tcp_process_syn_received(socket_core_ref socket, 222 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 223 int tcp_process_established(socket_core_ref socket, 224 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, 225 int fragments, size_t total_length); 226 int tcp_queue_received_packet(socket_core_ref socket, 227 tcp_socket_data_ref socket_data, packet_t packet, int fragments, 228 size_t total_length); 229 230 int tcp_received_msg(device_id_t device_id, packet_t packet, 231 services_t receiver, services_t error); 232 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 233 234 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, 235 int backlog); 236 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, 237 struct sockaddr *addr, socklen_t addrlen); 238 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, 239 int flags, size_t * addrlen); 240 int tcp_send_message(socket_cores_ref local_sockets, int socket_id, 241 int fragments, size_t * data_fragment_size, int flags); 242 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 243 int new_socket_id, size_t * data_fragment_size, size_t * addrlen); 244 int tcp_close_message(socket_cores_ref local_sockets, int socket_id); 224 245 225 246 /** TCP global data. */ 226 247 tcp_globals_t tcp_globals; 227 248 228 /** Initializes the TCP module.229 *230 * @param[in] client_connection The client connection processing function. The231 * module skeleton propagates its own one.232 * @returns EOK on success.233 * @returns ENOMEM if there is not enough memory left.234 */235 249 int tcp_initialize(async_client_conn_t client_connection) 236 250 { … … 300 314 size_t addrlen; 301 315 302 switch (error) { 303 case SERVICE_NONE: 304 break; 305 case SERVICE_ICMP: 306 // process error 307 result = icmp_client_process_packet(packet, &type, &code, NULL, 308 NULL); 309 if (result < 0) 310 return tcp_release_and_return(packet, result); 311 312 length = (size_t) result; 313 if (ERROR_OCCURRED(packet_trim(packet, length, 0))) 314 return tcp_release_and_return(packet, ERROR_CODE); 315 break; 316 default: 317 return tcp_release_and_return(packet, ENOTSUP); 316 if (error) { 317 switch (error) { 318 case SERVICE_ICMP: 319 // process error 320 result = icmp_client_process_packet(packet, &type, 321 &code, NULL, NULL); 322 if (result < 0) 323 return tcp_release_and_return(packet, result); 324 325 length = (size_t) result; 326 if (ERROR_OCCURRED(packet_trim(packet, length, 0))) { 327 return tcp_release_and_return(packet, 328 ERROR_CODE); 329 } 330 break; 331 332 default: 333 return tcp_release_and_return(packet, ENOTSUP); 334 } 318 335 } 319 336 … … 362 379 ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 363 380 0); 364 }365 if (!socket) {366 if (tl_prepare_icmp_packet(tcp_globals.net_phone,367 tcp_globals.icmp_phone, packet, error) == EOK) {368 icmp_destination_unreachable_msg(tcp_globals.icmp_phone,369 ICMP_PORT_UNREACH,0, packet);370 }371 return EADDRNOTAVAIL;372 }373 381 if (!socket) { 382 if (tl_prepare_icmp_packet(tcp_globals.net_phone, 383 tcp_globals.icmp_phone, packet, error) == EOK) { 384 icmp_destination_unreachable_msg( 385 tcp_globals.icmp_phone, ICMP_PORT_UNREACH, 386 0, packet); 387 } 388 return EADDRNOTAVAIL; 389 } 390 } 374 391 printf("socket id %d\n", socket->socket_id); 375 392 socket_data = (tcp_socket_data_ref) socket->specific_data; … … 385 402 total_length = 0; 386 403 do { 387 fragments++;404 ++fragments; 388 405 length = packet_get_data_length(next_packet); 389 406 if (length <= 0) … … 404 421 405 422 if (error) 406 goto has_error_service;423 goto error; 407 424 408 425 if (socket_data->state == TCP_SOCKET_LISTEN) { 426 409 427 if (socket_data->pseudo_header) { 410 428 free(socket_data->pseudo_header); … … 446 464 } 447 465 448 has_error_service:466 error: 449 467 fibril_rwlock_read_unlock(&tcp_globals.lock); 450 468 … … 489 507 int 490 508 tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, 491 tcp_header_ref header, packet_t packet, int fragments, size_t total_length) 509 tcp_header_ref header, packet_t packet, int fragments, 510 size_t total_length) 492 511 { 493 512 ERROR_DECLARE; … … 665 684 continue; 666 685 // at least partly following data? 667 } 668 if (IS_IN_INTERVAL_OVERFLOW(sequence_number,669 socket_data->next_incoming,new_sequence_number)) {686 } else if (IS_IN_INTERVAL_OVERFLOW( 687 sequence_number, socket_data->next_incoming, 688 new_sequence_number)) { 670 689 if (socket_data->next_incoming < 671 690 new_sequence_number) { … … 942 961 listening_socket = socket_port_find(&tcp_globals.sockets, 943 962 listening_port, SOCKET_MAP_KEY_LISTENING, 0); 944 if ( !listening_socket||963 if ((!listening_socket) || 945 964 (listening_socket->socket_id != listening_socket_id)) { 946 965 fibril_rwlock_write_unlock(&tcp_globals.lock); … … 1172 1191 if (number == socket_data->expected) { 1173 1192 // increase the counter 1174 socket_data->expected_count++;1193 ++socket_data->expected_count; 1175 1194 if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) { 1176 1195 socket_data->expected_count = 1; … … 1181 1200 } 1182 1201 1183 /** Processes the TCP message. 1184 * 1185 * @param[in] callid The message identifier. 1186 * @param[in] call The message parameters. 1187 * @param[out] answer The message answer parameters. 1188 * @param[out] answer_count The last parameter for the actual answer in the 1189 * answer parameter. 1190 * @returns EOK on success. 1191 * @returns ENOTSUP if the message is not known. 1192 * 1193 * @see tcp_interface.h 1194 * @see IS_NET_TCP_MESSAGE() 1195 */ 1196 int 1197 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 1198 ipc_call_t *answer, int *answer_count) 1202 int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, 1203 ipc_call_t * answer, int *answer_count) 1199 1204 { 1200 1205 ERROR_DECLARE; … … 1516 1521 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1517 1522 timeout->key, timeout->key_length); 1518 if (! socket || (socket->socket_id != timeout->socket_id))1523 if (!(socket && (socket->socket_id == timeout->socket_id))) 1519 1524 goto out; 1520 1525 … … 1527 1532 if (timeout->sequence_number) { 1528 1533 // increase the timeout counter; 1529 socket_data->timeout_count++;1534 ++socket_data->timeout_count; 1530 1535 if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) { 1531 1536 // TODO release as connection lost … … 1739 1744 ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 1740 1745 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) { 1746 1741 1747 socket_data->addr = NULL; 1742 1748 socket_data->addrlen = 0; 1743 1749 fibril_rwlock_write_lock(&tcp_globals.lock); 1750 1744 1751 } else { 1752 1745 1753 packet = tcp_get_packets_to_send(socket, socket_data); 1746 1754 if (packet) { … … 1868 1876 packet = pq_next(packet); 1869 1877 // overflow occurred ? 1870 if ( !packet&&1878 if ((!packet) && 1871 1879 (socket_data->last_outgoing > socket_data->next_outgoing)) { 1872 1880 printf("gpts overflow\n"); … … 2036 2044 int 2037 2045 tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 2038 size_t * addrlen)2046 size_t * addrlen) 2039 2047 { 2040 2048 ERROR_DECLARE; … … 2091 2099 int 2092 2100 tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, 2093 size_t * data_fragment_size, int flags)2101 size_t * data_fragment_size, int flags) 2094 2102 { 2095 2103 ERROR_DECLARE; … … 2130 2138 packet_dimension->content : socket_data->data_fragment_size); 2131 2139 2132 for (index = 0; index < fragments; index++) {2140 for (index = 0; index < fragments; ++index) { 2133 2141 // read the data fragment 2134 2142 result = tl_socket_read_packet_data(tcp_globals.net_phone, … … 2227 2235 2228 2236 int 2229 tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,2237 tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, 2230 2238 tcp_socket_data_ref socket_data, int synchronize, int finalize) 2231 2239 { … … 2263 2271 int 2264 2272 tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 2265 int new_socket_id, size_t * data_fragment_size, size_t *addrlen)2273 int new_socket_id, size_t * data_fragment_size, size_t * addrlen) 2266 2274 { 2267 2275 ERROR_DECLARE; … … 2365 2373 } 2366 2374 2367 /** Releases the packet and returns the result.2368 *2369 * @param[in] packet The packet queue to be released.2370 * @param[in] result The result to be returned.2371 * @return The result parameter.2372 */2373 2375 int tcp_release_and_return(packet_t packet, int result) 2374 2376 { … … 2379 2381 /** Default thread for new connections. 2380 2382 * 2381 * @param[in] iidThe initial message identifier.2382 * @param[in] icallThe initial message call structure.2383 * @param[in] iid The initial message identifier. 2384 * @param[in] icall The initial message call structure. 2383 2385 * 2384 2386 */ … … 2395 2397 int answer_count; 2396 2398 2397 /* Clear the answer structure */ 2399 /* 2400 Clear the answer structure 2401 */ 2398 2402 refresh_answer(&answer, &answer_count); 2399 2403 2400 /* Fetch the next message */ 2404 /* 2405 Fetch the next message 2406 */ 2401 2407 ipc_call_t call; 2402 2408 ipc_callid_t callid = async_get_call(&call); 2403 2409 2404 /* Process the message */ 2410 /* 2411 Process the message 2412 */ 2405 2413 int res = tl_module_message_standalone(callid, &call, &answer, 2406 2414 &answer_count); 2407 2415 2408 2416 /* 2409 * End if told to either by the message or the processing 2410 * result. 2417 End if said to either by the message or the processing result 2411 2418 */ 2412 2419 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || … … 2423 2430 /** Starts the module. 2424 2431 * 2425 * @returns EOK on success. 2426 * @returns Other error codes as defined for each specific module 2427 * start function. 2432 * @param argc The count of the command line arguments. Ignored parameter. 2433 * @param argv The command line parameters. Ignored parameter. 2434 * 2435 * @returns EOK on success. 2436 * @returns Other error codes as defined for each specific module start function. 2437 * 2428 2438 */ 2429 2439 int
Note:
See TracChangeset
for help on using the changeset viewer.