Changeset 89e57cee in mainline
- Timestamp:
- 2010-11-02T22:02:45Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 457a6f5
- Parents:
- ba1a2fd
- Location:
- uspace/srv/net/tl/tcp
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/tcp.c
rba1a2fd r89e57cee 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * TCP module implementation. 35 * @see tcp.h 36 36 */ 37 38 #include "tcp.h" 39 #include "tcp_header.h" 40 #include "tcp_module.h" 37 41 38 42 #include <assert.h> … … 72 76 #include <tl_interface.h> 73 77 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 * 112 * the possible overflow. 113 113 * 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. 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. 118 119 */ 119 120 #define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \ … … 165 166 }; 166 167 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); 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); 245 224 246 225 /** TCP global data. */ 247 226 tcp_globals_t tcp_globals; 248 227 228 /** Initializes the TCP module. 229 * 230 * @param[in] client_connection The client connection processing function. The 231 * module skeleton propagates its own one. 232 * @returns EOK on success. 233 * @returns ENOMEM if there is not enough memory left. 234 */ 249 235 int tcp_initialize(async_client_conn_t client_connection) 250 236 { … … 314 300 size_t addrlen; 315 301 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 } 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); 335 318 } 336 319 … … 379 362 ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 380 363 0); 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 387 388 389 390 } 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 391 374 printf("socket id %d\n", socket->socket_id); 392 375 socket_data = (tcp_socket_data_ref) socket->specific_data; … … 402 385 total_length = 0; 403 386 do { 404 ++fragments;387 fragments++; 405 388 length = packet_get_data_length(next_packet); 406 389 if (length <= 0) … … 421 404 422 405 if (error) 423 goto error;406 goto has_error_service; 424 407 425 408 if (socket_data->state == TCP_SOCKET_LISTEN) { 426 427 409 if (socket_data->pseudo_header) { 428 410 free(socket_data->pseudo_header); … … 464 446 } 465 447 466 error:448 has_error_service: 467 449 fibril_rwlock_read_unlock(&tcp_globals.lock); 468 450 … … 507 489 int 508 490 tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, 509 tcp_header_ref header, packet_t packet, int fragments, 510 size_t total_length) 491 tcp_header_ref header, packet_t packet, int fragments, size_t total_length) 511 492 { 512 493 ERROR_DECLARE; … … 684 665 continue; 685 666 // at least partly following data? 686 } else if (IS_IN_INTERVAL_OVERFLOW(687 sequence_number, socket_data->next_incoming,688 new_sequence_number)) {667 } 668 if (IS_IN_INTERVAL_OVERFLOW(sequence_number, 669 socket_data->next_incoming, new_sequence_number)) { 689 670 if (socket_data->next_incoming < 690 671 new_sequence_number) { … … 961 942 listening_socket = socket_port_find(&tcp_globals.sockets, 962 943 listening_port, SOCKET_MAP_KEY_LISTENING, 0); 963 if ( (!listening_socket)||944 if (!listening_socket || 964 945 (listening_socket->socket_id != listening_socket_id)) { 965 946 fibril_rwlock_write_unlock(&tcp_globals.lock); … … 1191 1172 if (number == socket_data->expected) { 1192 1173 // increase the counter 1193 ++socket_data->expected_count;1174 socket_data->expected_count++; 1194 1175 if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) { 1195 1176 socket_data->expected_count = 1; … … 1200 1181 } 1201 1182 1202 int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, 1203 ipc_call_t * answer, int *answer_count) 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) 1204 1199 { 1205 1200 ERROR_DECLARE; … … 1521 1516 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1522 1517 timeout->key, timeout->key_length); 1523 if (! (socket && (socket->socket_id == timeout->socket_id)))1518 if (!socket || (socket->socket_id != timeout->socket_id)) 1524 1519 goto out; 1525 1520 … … 1532 1527 if (timeout->sequence_number) { 1533 1528 // increase the timeout counter; 1534 ++socket_data->timeout_count;1529 socket_data->timeout_count++; 1535 1530 if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) { 1536 1531 // TODO release as connection lost … … 1744 1739 ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 1745 1740 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) { 1746 1747 1741 socket_data->addr = NULL; 1748 1742 socket_data->addrlen = 0; 1749 1743 fibril_rwlock_write_lock(&tcp_globals.lock); 1750 1751 1744 } else { 1752 1753 1745 packet = tcp_get_packets_to_send(socket, socket_data); 1754 1746 if (packet) { … … 1876 1868 packet = pq_next(packet); 1877 1869 // overflow occurred ? 1878 if ( (!packet)&&1870 if (!packet && 1879 1871 (socket_data->last_outgoing > socket_data->next_outgoing)) { 1880 1872 printf("gpts overflow\n"); … … 2044 2036 int 2045 2037 tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 2046 size_t * 2038 size_t *addrlen) 2047 2039 { 2048 2040 ERROR_DECLARE; … … 2099 2091 int 2100 2092 tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, 2101 size_t * 2093 size_t *data_fragment_size, int flags) 2102 2094 { 2103 2095 ERROR_DECLARE; … … 2138 2130 packet_dimension->content : socket_data->data_fragment_size); 2139 2131 2140 for (index = 0; index < fragments; ++index) {2132 for (index = 0; index < fragments; index++) { 2141 2133 // read the data fragment 2142 2134 result = tl_socket_read_packet_data(tcp_globals.net_phone, … … 2235 2227 2236 2228 int 2237 tcp_create_notification_packet(packet_t * 2229 tcp_create_notification_packet(packet_t *packet, socket_core_ref socket, 2238 2230 tcp_socket_data_ref socket_data, int synchronize, int finalize) 2239 2231 { … … 2271 2263 int 2272 2264 tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 2273 int new_socket_id, size_t * data_fragment_size, size_t *addrlen)2265 int new_socket_id, size_t *data_fragment_size, size_t *addrlen) 2274 2266 { 2275 2267 ERROR_DECLARE; … … 2373 2365 } 2374 2366 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 */ 2375 2373 int tcp_release_and_return(packet_t packet, int result) 2376 2374 { … … 2381 2379 /** Default thread for new connections. 2382 2380 * 2383 * @param[in] iidThe initial message identifier.2384 * @param[in] icallThe initial message call structure.2381 * @param[in] iid The initial message identifier. 2382 * @param[in] icall The initial message call structure. 2385 2383 * 2386 2384 */ … … 2397 2395 int answer_count; 2398 2396 2399 /* 2400 Clear the answer structure 2401 */ 2397 /* Clear the answer structure */ 2402 2398 refresh_answer(&answer, &answer_count); 2403 2399 2404 /* 2405 Fetch the next message 2406 */ 2400 /* Fetch the next message */ 2407 2401 ipc_call_t call; 2408 2402 ipc_callid_t callid = async_get_call(&call); 2409 2403 2410 /* 2411 Process the message 2412 */ 2404 /* Process the message */ 2413 2405 int res = tl_module_message_standalone(callid, &call, &answer, 2414 2406 &answer_count); 2415 2407 2416 2408 /* 2417 End if said to either by the message or the processing result 2409 * End if told to either by the message or the processing 2410 * result. 2418 2411 */ 2419 2412 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || … … 2430 2423 /** Starts the module. 2431 2424 * 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 * 2425 * @returns EOK on success. 2426 * @returns Other error codes as defined for each specific module 2427 * start function. 2438 2428 */ 2439 2429 int -
uspace/srv/net/tl/tcp/tcp.h
rba1a2fd r89e57cee 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 */ 36 37 #ifndef __NET_TCP_H__38 #define __NET_TCP_H__34 * TCP module. 35 */ 36 37 #ifndef NET_TCP_H_ 38 #define NET_TCP_H_ 39 39 40 40 #include <fibril_synch.h> … … 46 46 47 47 /** Type definition of the TCP global data. 48 * 49 */ 50 typedef struct tcp_globals 48 * @see tcp_globals 49 */ 50 typedef struct tcp_globals tcp_globals_t; 51 51 52 52 /** Type definition of the TCP socket specific data. 53 * 54 */ 55 typedef struct tcp_socket_data 53 * @see tcp_socket_data 54 */ 55 typedef struct tcp_socket_data tcp_socket_data_t; 56 56 57 57 /** Type definition of the TCP socket specific data pointer. 58 * 59 */ 60 typedef tcp_socket_data_t * 58 * @see tcp_socket_data 59 */ 60 typedef tcp_socket_data_t *tcp_socket_data_ref; 61 61 62 62 /** Type definition of the TCP operation data. 63 * 64 */ 65 typedef struct tcp_operation 63 * @see tcp_operation 64 */ 65 typedef struct tcp_operation tcp_operation_t; 66 66 67 67 /** Type definition of the TCP operation data pointer. 68 * 69 */ 70 typedef tcp_operation_t * 68 * @see tcp_operation 69 */ 70 typedef tcp_operation_t *tcp_operation_ref; 71 71 72 72 /** TCP socket state type definition. 73 * @see tcp_socket_state 74 */ 75 typedef enum tcp_socket_state tcp_socket_state_t; 76 77 /** TCP socket state. 78 */ 79 enum tcp_socket_state{ 73 * @see tcp_socket_state 74 */ 75 typedef enum tcp_socket_state tcp_socket_state_t; 76 77 /** TCP socket state. */ 78 enum tcp_socket_state { 80 79 /** Initial. 81 * Not connected or bound. 80 * 81 * Not connected or bound. 82 82 */ 83 83 TCP_SOCKET_INITIAL, 84 84 85 /** Listening. 85 * Awaiting a connection request from another TCP layer. 86 * When SYN is received a new bound socket in the TCP_SOCKET_SYN_RECEIVED state should be created. 86 * 87 * Awaiting a connection request from another TCP layer. 88 * When SYN is received a new bound socket in the 89 * TCP_SOCKET_SYN_RECEIVED state should be created. 87 90 */ 88 91 TCP_SOCKET_LISTEN, 92 89 93 /** Connecting issued. 90 * A~SYN has been sent, and TCP is awaiting the response SYN. 91 * Should continue to the TCP_SOCKET_ESTABLISHED state. 94 * 95 * A SYN has been sent, and TCP is awaiting the response SYN. 96 * Should continue to the TCP_SOCKET_ESTABLISHED state. 92 97 */ 93 98 TCP_SOCKET_SYN_SENT, 99 94 100 /** Connecting received. 95 * A~SYN has been received, a~SYN has been sent, and TCP is awaiting an ACK. 96 * Should continue to the TCP_SOCKET_ESTABLISHED state. 101 * 102 * A SYN has been received, a SYN has been sent, and TCP is awaiting an 103 * ACK. Should continue to the TCP_SOCKET_ESTABLISHED state. 97 104 */ 98 105 TCP_SOCKET_SYN_RECEIVED, 106 99 107 /** Connected. 100 * The three-way handshake has been completed. 108 * 109 * The three-way handshake has been completed. 101 110 */ 102 111 TCP_SOCKET_ESTABLISHED, 112 103 113 /** Closing started. 104 * The local application has issued a~CLOSE. 105 * TCP has sent a~FIN, and is awaiting an ACK or a~FIN. 106 * Should continue to the TCP_SOCKET_FIN_WAIT_2 state when an ACK is received. 107 * Should continue to the TCP_SOCKET_CLOSING state when a~FIN is received. 114 * 115 * The local application has issued a CLOSE. 116 * TCP has sent a FIN, and is awaiting an ACK or a FIN. 117 * Should continue to the TCP_SOCKET_FIN_WAIT_2 state when an ACK is 118 * received. 119 * Should continue to the TCP_SOCKET_CLOSING state when a FIN is 120 * received. 108 121 */ 109 122 TCP_SOCKET_FIN_WAIT_1, 123 110 124 /** Closing confirmed. 111 * A~FIN has been sent, and an ACK received. 112 * TCP is awaiting a~FIN from the remote TCP layer. 113 * Should continue to the TCP_SOCKET_CLOSING state. 125 * 126 * A FIN has been sent, and an ACK received. 127 * TCP is awaiting a~FIN from the remote TCP layer. 128 * Should continue to the TCP_SOCKET_CLOSING state. 114 129 */ 115 130 TCP_SOCKET_FIN_WAIT_2, 131 116 132 /** Closing. 117 * A FIN has been sent, a FIN has been received, and an ACK has been sent. 118 * TCP is awaiting an ACK for the FIN that was sent. 119 * Should continue to the TCP_SOCKET_TIME_WAIT state. 133 * 134 * A FIN has been sent, a FIN has been received, and an ACK has been 135 * sent. 136 * TCP is awaiting an ACK for the FIN that was sent. 137 * Should continue to the TCP_SOCKET_TIME_WAIT state. 120 138 */ 121 139 TCP_SOCKET_CLOSING, 140 122 141 /** Closing received. 123 * TCP has received a~FIN, and has sent an ACK. 124 * It is awaiting a~close request from the local application before sending a~FIN. 125 * Should continue to the TCP_SOCKET_SOCKET_LAST_ACK state. 142 * 143 * TCP has received a FIN, and has sent an ACK. 144 * It is awaiting a close request from the local application before 145 * sending a FIN. 146 * Should continue to the TCP_SOCKET_SOCKET_LAST_ACK state. 126 147 */ 127 148 TCP_SOCKET_CLOSE_WAIT, 128 /** 129 * A~FIN has been received, and an ACK and a~FIN have been sent. 130 * TCP is awaiting an ACK. 131 * Should continue to the TCP_SOCKET_TIME_WAIT state. 149 150 /** 151 * A FIN has been received, and an ACK and a FIN have been sent. 152 * TCP is awaiting an ACK. 153 * Should continue to the TCP_SOCKET_TIME_WAIT state. 132 154 */ 133 155 TCP_SOCKET_LAST_ACK, 156 134 157 /** Closing finished. 135 * FINs have been received and ACK’d, and TCP is waiting two MSLs to remove the connection from the table. 158 * 159 * FINs have been received and ACK’d, and TCP is waiting two MSLs to 160 * remove the connection from the table. 136 161 */ 137 162 TCP_SOCKET_TIME_WAIT, 163 138 164 /** Closed. 139 * Imaginary, this indicates that a~connection has been removed from the connection table. 165 * 166 * Imaginary, this indicates that a connection has been removed from 167 * the connection table. 140 168 */ 141 169 TCP_SOCKET_CLOSED 142 170 }; 143 171 144 /** TCP operation data. 145 */ 146 struct tcp_operation{ 147 /** Operation result. 148 */ 172 /** TCP operation data. */ 173 struct tcp_operation { 174 /** Operation result. */ 149 175 int result; 150 /** Safety lock. 151 */ 176 /** Safety lock. */ 152 177 fibril_mutex_t mutex; 153 /** Operation result signaling. 154 */ 178 /** Operation result signaling. */ 155 179 fibril_condvar_t condvar; 156 180 }; 157 181 158 /** TCP socket specific data. 159 */ 160 struct tcp_socket_data{ 161 /** TCP socket state. 162 */ 182 /** TCP socket specific data. */ 183 struct tcp_socket_data { 184 /** TCP socket state. */ 163 185 tcp_socket_state_t state; 164 /** Data fragment size. 165 * Sending optimalization. 186 187 /** 188 * Data fragment size. 189 * Sending optimalization. 166 190 */ 167 191 size_t data_fragment_size; 168 /** Device identifier.169 */192 193 /** Device identifier. */ 170 194 device_id_t device_id; 171 /** Listening backlog. 172 * The maximal number of connected but not yet accepted sockets. 195 196 /** 197 * Listening backlog. 198 * The maximal number of connected but not yet accepted sockets. 173 199 */ 174 200 int backlog; 175 // /** Segment size. 176 // */ 177 // size_t segment_size; 178 /** Parent listening socket identifier. 179 * Set if this socket is an accepted one. 201 202 // /** Segment size. */ 203 // size_t segment_size; 204 205 /** 206 * Parent listening socket identifier. 207 * Set if this socket is an accepted one. 180 208 */ 181 209 int listening_socket_id; 182 /** Treshold size in bytes.183 */210 211 /** Treshold size in bytes. */ 184 212 size_t treshold; 185 /** Window size in bytes. 186 */ 213 /** Window size in bytes. */ 187 214 size_t window; 188 /** Acknowledgement timeout. 189 */ 215 /** Acknowledgement timeout. */ 190 216 suseconds_t timeout; 191 /** Last acknowledged byte. 192 */ 217 /** Last acknowledged byte. */ 193 218 uint32_t acknowledged; 194 /** Next incoming sequence number. 195 */ 219 /** Next incoming sequence number. */ 196 220 uint32_t next_incoming; 197 /** Incoming FIN. 198 */ 221 /** Incoming FIN. */ 199 222 uint32_t fin_incoming; 200 /** Next outgoing sequence number. 201 */ 223 /** Next outgoing sequence number. */ 202 224 uint32_t next_outgoing; 203 /** Last outgoing sequence number. 204 */ 225 /** Last outgoing sequence number. */ 205 226 uint32_t last_outgoing; 206 /** Outgoing FIN. 207 */ 227 /** Outgoing FIN. */ 208 228 uint32_t fin_outgoing; 209 /** Expected sequence number by the remote host. 210 * The sequence number the other host expects. 211 * The notification is sent only upon a packet reecival. 229 230 /** 231 * Expected sequence number by the remote host. 232 * The sequence number the other host expects. 233 * The notification is sent only upon a packet reecival. 212 234 */ 213 235 uint32_t expected; 214 /** Expected sequence number counter. 215 * Counts the number of received notifications for the same sequence number. 236 237 /** 238 * Expected sequence number counter. 239 * Counts the number of received notifications for the same sequence 240 * number. 216 241 */ 217 242 int expected_count; 243 218 244 /** Incoming packet queue. 219 * Packets are buffered until received in the right order. 220 * The packets are excluded after successfully read. 221 * Packets are sorted by their starting byte. 222 * Packets metric is set as their data length. 245 * 246 * Packets are buffered until received in the right order. 247 * The packets are excluded after successfully read. 248 * Packets are sorted by their starting byte. 249 * Packets metric is set as their data length. 223 250 */ 224 251 packet_t incoming; 252 225 253 /** Outgoing packet queue. 226 * Packets are buffered until acknowledged by the remote host in the right order. 227 * The packets are excluded after acknowledged. 228 * Packets are sorted by their starting byte. 229 * Packets metric is set as their data length. 254 * 255 * Packets are buffered until acknowledged by the remote host in the 256 * right order. 257 * The packets are excluded after acknowledged. 258 * Packets are sorted by their starting byte. 259 * Packets metric is set as their data length. 230 260 */ 231 261 packet_t outgoing; 232 /** IP pseudo header.233 */262 263 /** IP pseudo header. */ 234 264 void *pseudo_header; 235 /** IP pseudo header length. 236 */ 265 /** IP pseudo header length. */ 237 266 size_t headerlen; 238 /** Remote host address. 239 */ 240 struct sockaddr * addr; 241 /** Remote host address length. 242 */ 267 /** Remote host address. */ 268 struct sockaddr *addr; 269 /** Remote host address length. */ 243 270 socklen_t addrlen; 244 /** Remote host port. 245 */ 271 /** Remote host port. */ 246 272 uint16_t dest_port; 247 /** Parent local sockets. 248 */ 273 /** Parent local sockets. */ 249 274 socket_cores_ref local_sockets; 275 250 276 /** Local sockets safety lock. 251 * May be locked for writing while holding the global lock for reading when changing the local sockets only. 252 * The global lock may to be locked only before locking the local lock. 253 * The global lock may be locked more weakly than the local lock. 254 * The global lock may be released before releasing the local lock. 255 * @see tcp_globals:lock 256 */ 257 fibril_rwlock_t * local_lock; 258 /** Pending operation data. 259 */ 277 * 278 * May be locked for writing while holding the global lock for reading 279 * when changing the local sockets only. 280 * The global lock may be locked only before locking the local lock. 281 * The global lock may be locked more weakly than the local lock. 282 * The global lock may be released before releasing the local lock. 283 * @see tcp_globals:lock 284 */ 285 fibril_rwlock_t *local_lock; 286 287 /** Pending operation data. */ 260 288 tcp_operation_t operation; 261 /** Timeouts in a row counter. 262 * If TCP_MAX_TIMEOUTS is reached, the connection is lost. 289 290 /** 291 * Timeouts in a row counter. 292 * If TCP_MAX_TIMEOUTS is reached, the connection is lost. 263 293 */ 264 294 int timeout_count; 265 295 }; 266 296 267 /** TCP global data. 268 */ 269 struct tcp_globals{ 270 /** Networking module phone. 271 */ 297 /** TCP global data. */ 298 struct tcp_globals { 299 /** Networking module phone. */ 272 300 int net_phone; 273 /** IP module phone. 274 */ 301 /** IP module phone. */ 275 302 int ip_phone; 276 /** ICMP module phone. 277 */ 303 /** ICMP module phone. */ 278 304 int icmp_phone; 279 /** Last used free port. 280 */ 305 /** Last used free port. */ 281 306 int last_used_port; 282 /** Active sockets. 283 */ 307 /** Active sockets. */ 284 308 socket_ports_t sockets; 285 /** Device packet dimensions. 286 */ 309 /** Device packet dimensions. */ 287 310 packet_dimensions_t dimensions; 288 /** Safety lock. 289 * Write lock is used only for adding or removing socket ports. 311 312 /** 313 * Safety lock. 314 * Write lock is used only for adding or removing socket ports. 290 315 */ 291 316 fibril_rwlock_t lock; … … 296 321 /** @} 297 322 */ 298 -
uspace/srv/net/tl/tcp/tcp_header.h
rba1a2fd r89e57cee 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * Based on the RFC~793.34 * TCP header definition. 35 * Based on the RFC 793. 36 36 */ 37 37 38 #ifndef __NET_TCP_HEADER_H__39 #define __NET_TCP_HEADER_H__38 #ifndef NET_TCP_HEADER_H_ 39 #define NET_TCP_HEADER_H_ 40 40 41 41 #include <sys/types.h> 42 42 43 /** TCP header size in bytes. 44 */ 45 #define TCP_HEADER_SIZE sizeof(tcp_header_t) 43 /** TCP header size in bytes. */ 44 #define TCP_HEADER_SIZE sizeof(tcp_header_t) 46 45 47 46 /** Returns the actual TCP header length in bytes. 48 * 47 * @param[in] header The TCP packet header. 49 48 */ 50 #define TCP_HEADER_LENGTH(header) ((header)->header_length * 4 u)49 #define TCP_HEADER_LENGTH(header) ((header)->header_length * 4U) 51 50 52 51 /** Returns the TCP header length. 53 * 52 * @param[in] length The TCP header length in bytes. 54 53 */ 55 #define TCP_COMPUTE_HEADER_LENGTH(length) ((uint8_t) ((length) / 4u))54 #define TCP_COMPUTE_HEADER_LENGTH(length) ((uint8_t) ((length) / 4U)) 56 55 57 56 /** Type definition of the transmission datagram header. 58 * 57 * @see tcp_header 59 58 */ 60 typedef struct tcp_header 59 typedef struct tcp_header tcp_header_t; 61 60 62 61 /** Type definition of the transmission datagram header pointer. 63 * 62 * @see tcp_header 64 63 */ 65 typedef tcp_header_t * 64 typedef tcp_header_t *tcp_header_ref; 66 65 67 66 /** Type definition of the transmission datagram header option. 68 * 67 * @see tcp_option 69 68 */ 70 typedef struct tcp_option 69 typedef struct tcp_option tcp_option_t; 71 70 72 71 /** Type definition of the transmission datagram header option pointer. 73 * 72 * @see tcp_option 74 73 */ 75 typedef tcp_option_t * 74 typedef tcp_option_t *tcp_option_ref; 76 75 77 /** Type definition of the Maximum segment size TCP option. 78 * @see ... 79 */ 80 typedef struct tcp_max_segment_size_option tcp_max_segment_size_option_t; 76 /** Type definition of the Maximum segment size TCP option. */ 77 typedef struct tcp_max_segment_size_option tcp_max_segment_size_option_t; 81 78 82 79 /** Type definition of the Maximum segment size TCP option pointer. 83 * 80 * @see tcp_max_segment_size_option 84 81 */ 85 typedef tcp_max_segment_size_option_t * 82 typedef tcp_max_segment_size_option_t *tcp_max_segment_size_option_ref; 86 83 87 /** Transmission datagram header. 88 */ 89 struct tcp_header{ 90 /** The source port number. 91 */ 84 /** Transmission datagram header. */ 85 struct tcp_header { 92 86 uint16_t source_port; 93 /** The destination port number.94 */95 87 uint16_t destination_port; 96 /** The sequence number of the first data octet in this segment (except when SYN is present).97 * If SYN is present the sequence number is the initial sequence number (ISN) and the first data octet is ISN+1.98 */99 88 uint32_t sequence_number; 100 /** If the ACK control bit is set this field contains the value of the next sequence number the sender of the segment is expecting to receive.101 * Once a~connection is established this is always sent.102 * @see acknowledge103 */104 89 uint32_t acknowledgement_number; 90 105 91 #ifdef ARCH_IS_BIG_ENDIAN 106 /** The number of 32~bit words in the TCP Header.107 * This indicates where the data begins.108 * The TCP header (even one including options) is an integral number of 32~bits long.109 */110 92 uint8_t header_length:4; 111 /** Four bits reserved for future use.112 * Must be zero.113 */114 93 uint8_t reserved1:4; 115 94 #else 116 /** Four bits reserved for future use.117 * Must be zero.118 */119 95 uint8_t reserved1:4; 120 /** The number of 32~bit words in the TCP Header.121 * This indicates where the data begins.122 * The TCP header (even one including options) is an integral number of 32~bits long.123 */124 96 uint8_t header_length:4; 125 97 #endif 98 126 99 #ifdef ARCH_IS_BIG_ENDIAN 127 /** Two bits reserved for future use.128 * Must be zero.129 */130 100 uint8_t reserved2:2; 131 /** Urgent Pointer field significant.132 * @see tcp_header:urgent_pointer133 */134 101 uint8_t urgent:1; 135 /** Acknowledgment field significant136 * @see tcp_header:acknowledgement_number137 */138 102 uint8_t acknowledge:1; 139 /** Push function.140 */141 103 uint8_t push:1; 142 /** Reset the connection.143 */144 104 uint8_t reset:1; 145 /** Synchronize the sequence numbers.146 */147 105 uint8_t synchronize:1; 148 /** No more data from the sender.149 */150 106 uint8_t finalize:1; 151 107 #else 152 /** No more data from the sender.153 */154 108 uint8_t finalize:1; 155 /** Synchronize the sequence numbers.156 */157 109 uint8_t synchronize:1; 158 /** Reset the connection.159 */160 110 uint8_t reset:1; 161 /** Push function.162 */163 111 uint8_t push:1; 164 /** Acknowledgment field significant.165 * @see tcp_header:acknowledgement_number166 */167 112 uint8_t acknowledge:1; 168 /** Urgent Pointer field significant.169 * @see tcp_header:urgent_pointer170 */171 113 uint8_t urgent:1; 172 /** Two bits reserved for future use.173 * Must be zero.174 */175 114 uint8_t reserved2:2; 176 115 #endif 177 /** The number of data octets beginning with the one indicated in the acknowledgment field which the sender of this segment is willing to accept. 178 * @see tcp_header:acknowledge 179 */ 116 180 117 uint16_t window; 181 /** The checksum field is the 16~bit one's complement of the one's complement sum of all 16~bit words in the header and text.182 * If a~segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a~16~bit word for checksum purposes.183 * The pad is not transmitted as part of the segment.184 * While computing the checksum, the checksum field itself is replaced with zeros.185 * The checksum also coves a~pseudo header conceptually.186 * The pseudo header conceptually prefixed to the TCP header contains the source address, the destination address, the protocol, and the TCP length.187 * This information gives protection against misrouted datagrams.188 * If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic).189 */190 118 uint16_t checksum; 191 /** This field communicates the current value of the urgent pointer as a~positive offset from the sequence number in this segment.192 * The urgent pointer points to the sequence number of the octet following the urgent data.193 * This field is only be interpreted in segments with the URG control bit set.194 * @see tcp_header:urgent195 */196 119 uint16_t urgent_pointer; 197 120 } __attribute__ ((packed)); 198 121 199 /** Transmission datagram header option. 200 */ 201 struct tcp_option{ 202 /** Option type. 203 */ 122 /** Transmission datagram header option. */ 123 struct tcp_option { 124 /** Option type. */ 204 125 uint8_t type; 205 /** Option length. 206 */ 126 /** Option length. */ 207 127 uint8_t length; 208 128 }; 209 129 210 /** Maximum segment size TCP option. 211 */ 212 struct tcp_max_segment_size_option{ 130 /** Maximum segment size TCP option. */ 131 struct tcp_max_segment_size_option { 213 132 /** TCP option. 214 * 215 * 133 * @see TCPOPT_MAX_SEGMENT_SIZE 134 * @see TCPOPT_MAX_SEGMENT_SIZE_LENGTH 216 135 */ 217 136 tcp_option_t option; 218 /** Maximum segment size in bytes.219 */137 138 /** Maximum segment size in bytes. */ 220 139 uint16_t max_segment_size; 221 140 } __attribute__ ((packed)); -
uspace/srv/net/tl/tcp/tcp_module.c
rba1a2fd r89e57cee 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * TCP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 34 * TCP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry 37 * points. 38 * @see module.c 38 39 */ 40 41 #include "tcp.h" 42 #include "tcp_module.h" 39 43 40 44 #include <async.h> … … 46 50 #include <net/ip_protocols.h> 47 51 #include <net/modules.h> 48 49 52 #include <net/packet.h> 50 53 #include <net_interface.h> 54 51 55 #include <ip_interface.h> 52 56 #include <tl_local.h> 53 57 54 #include "tcp.h" 55 #include "tcp_module.h" 58 /** TCP module global data. */ 59 extern tcp_globals_t tcp_globals; 56 60 57 /** TCP module global data.58 */59 extern tcp_globals_t tcp_globals;60 61 /** Starts the TCP module.62 * Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop.63 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.64 * @returns EOK on successful module termination.65 * @returns Other error codes as defined for the tcp_initialize() function.66 * @returns Other error codes as defined for the REGISTER_ME() macro function.67 */68 61 int tl_module_start_standalone(async_client_conn_t client_connection) 69 62 { … … 75 68 76 69 ipcarg_t phonehash; 77 if (ERROR_OCCURRED(tcp_initialize(client_connection)) 78 ||ERROR_OCCURRED(REGISTER_ME(SERVICE_TCP, &phonehash))) {70 if (ERROR_OCCURRED(tcp_initialize(client_connection)) || 71 ERROR_OCCURRED(REGISTER_ME(SERVICE_TCP, &phonehash))) { 79 72 pm_destroy(); 80 73 return ERROR_CODE; … … 87 80 } 88 81 89 /** Processes the TCP message. 90 * @param[in] callid The message identifier. 91 * @param[in] call The message parameters. 92 * @param[out] answer The message answer parameters. 93 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 94 * @returns EOK on success. 95 * @returns Other error codes as defined for the tcp_message() function. 96 */ 97 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 82 int 83 tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 84 ipc_call_t *answer, int *answer_count) 85 { 98 86 return tcp_message_standalone(callid, call, answer, answer_count); 99 87 } -
uspace/srv/net/tl/tcp/tcp_module.h
rba1a2fd r89e57cee 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * TCP module functions. 35 * The functions are used as TCP module entry points. 36 36 */ 37 37 38 #ifndef __NET_TCP_MODULE_H__39 #define __NET_TCP_MODULE_H__38 #ifndef NET_TCP_MODULE_H_ 39 #define NET_TCP_MODULE_H_ 40 40 41 41 #include <async.h> 42 42 #include <ipc/ipc.h> 43 43 44 /** Initializes the TCP module. 45 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 46 * @returns EOK on success. 47 * @returns ENOMEM if there is not enough memory left. 48 */ 49 extern int tcp_initialize(async_client_conn_t client_connection); 50 51 /** Processes the TCP message. 52 * @param[in] callid The message identifier. 53 * @param[in] call The message parameters. 54 * @param[out] answer The message answer parameters. 55 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 56 * @returns EOK on success. 57 * @returns ENOTSUP if the message is not known. 58 * @see tcp_interface.h 59 * @see IS_NET_TCP_MESSAGE() 60 */ 61 extern int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 44 extern int tcp_initialize(async_client_conn_t); 45 extern int tcp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *, 46 int *); 62 47 63 48 #endif
Note:
See TracChangeset
for help on using the changeset viewer.